Skip to content

Commit 20b1469

Browse files
author
Derek Dowling
committed
Fixing client object prepare bug for POST request missing ID
1 parent ce2afa4 commit 20b1469

File tree

8 files changed

+27
-22
lines changed

8 files changed

+27
-22
lines changed

client.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func NewRequest(method string, urlStr string, object *Object) (*Request, error)
126126
// use Prepare to generate a payload
127127
if object != nil {
128128

129-
payload, err := object.Prepare(request)
129+
payload, err := object.prepare(request, false)
130130
if err != nil {
131131
return nil, fmt.Errorf("Error preparing object: %s", err.Error())
132132
}

client_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func mockClientObjectResponse(object *Object) (*http.Response, error) {
131131
return nil, err
132132
}
133133

134-
resp, err := object.Prepare(req.Request)
134+
resp, err := object.prepare(req.Request, false)
135135
if err != nil {
136136
return nil, err
137137
}
@@ -148,7 +148,7 @@ func mockClientListResponse(list *List) (*http.Response, error) {
148148
return nil, err
149149
}
150150

151-
resp, err := list.Prepare(req.Request)
151+
resp, err := list.prepare(req.Request, false)
152152
if err != nil {
153153
return nil, err
154154
}

error.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ func (e *Error) Error() string {
4545

4646
// Prepare returns a response containing a prepared error list since the JSON
4747
// API specification requires that errors are returned as a list
48-
func (e *Error) Prepare(req *http.Request) (*Response, SendableError) {
48+
func (e *Error) prepare(req *http.Request, response bool) (*Response, SendableError) {
4949
list := &ErrorList{Errors: []*Error{e}}
50-
return list.Prepare(req)
50+
return list.prepare(req, response)
5151
}
5252

5353
// ErrorList is just a wrapped error array that implements Sendable
@@ -76,7 +76,7 @@ func (e *ErrorList) Add(newError *Error) *Error {
7676
}
7777

7878
// Prepare first validates the errors, and then returns an appropriate response
79-
func (e *ErrorList) Prepare(req *http.Request) (*Response, SendableError) {
79+
func (e *ErrorList) prepare(req *http.Request, response bool) (*Response, SendableError) {
8080
if len(e.Errors) == 0 {
8181
return nil, ISE("No errors provided for attempted error response.")
8282
}

list.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type List struct {
88
}
99

1010
// Prepare returns a success status response
11-
func (l *List) Prepare(r *http.Request) (*Response, SendableError) {
11+
func (l *List) prepare(r *http.Request, response bool) (*Response, SendableError) {
1212
return &Response{Data: l.Objects, HTTPStatus: http.StatusOK}, nil
1313
}
1414

list_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func TestList(t *testing.T) {
2424
req := &http.Request{}
2525

2626
Convey("->Prepare()", func() {
27-
response, err := testList.Prepare(req)
27+
response, err := testList.prepare(req, true)
2828
So(err, ShouldBeNil)
2929
So(response.HTTPStatus, ShouldEqual, http.StatusOK)
3030
})

object.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,18 @@ func (o *Object) Unmarshal(objType string, target interface{}) (err SendableErro
8585

8686
// Prepare creates a new JSON single object response with an appropriate HTTP status
8787
// to match the request method type.
88-
func (o *Object) Prepare(r *http.Request) (*Response, SendableError) {
88+
func (o *Object) prepare(r *http.Request, response bool) (*Response, SendableError) {
8989

90-
if len(o.ID) == 0 {
91-
return nil, SpecificationError("ID must be set for Object response")
90+
if o.ID == "" {
91+
92+
// don't error if the client is attempting to performing a POST request, in
93+
// which case, ID shouldn't actually be set
94+
if !response && r.Method != "POST" {
95+
return nil, SpecificationError("ID must be set for Object response")
96+
}
9297
}
9398

94-
if len(o.Type) == 0 {
99+
if o.Type == "" {
95100
return nil, SpecificationError("Type must be set for Object response")
96101
}
97102
var status int
@@ -109,7 +114,7 @@ func (o *Object) Prepare(r *http.Request) (*Response, SendableError) {
109114
return SpecificationError(fmt.Sprintf(
110115
"The JSON Specification does not accept '%s' requests.",
111116
r.Method,
112-
)).Prepare(r)
117+
)).prepare(r, response)
113118
}
114119

115120
return &Response{HTTPStatus: status, Data: o}, nil

object_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -106,32 +106,32 @@ func TestObject(t *testing.T) {
106106
})
107107
})
108108

109-
Convey("->Prepare()", func() {
109+
Convey("->prepare()", func() {
110110

111111
Convey("should handle a POST response correctly", func() {
112112
request.Method = "POST"
113-
resp, err := testObject.Prepare(request)
113+
resp, err := testObject.prepare(request, true)
114114
So(err, ShouldBeNil)
115115
So(resp.HTTPStatus, ShouldEqual, http.StatusCreated)
116116
})
117117

118118
Convey("should handle a GET response correctly", func() {
119119
request.Method = "GET"
120-
resp, err := testObject.Prepare(request)
120+
resp, err := testObject.prepare(request, true)
121121
So(err, ShouldBeNil)
122122
So(resp.HTTPStatus, ShouldEqual, http.StatusOK)
123123
})
124124

125125
Convey("should handle a PATCH response correctly", func() {
126126
request.Method = "PATCH"
127-
resp, err := testObject.Prepare(request)
127+
resp, err := testObject.prepare(request, true)
128128
So(err, ShouldBeNil)
129129
So(resp.HTTPStatus, ShouldEqual, http.StatusOK)
130130
})
131131

132132
Convey("should return a formatted Error for an unsupported method Type", func() {
133133
request.Method = "PUT"
134-
resp, err := testObject.Prepare(request)
134+
resp, err := testObject.prepare(request, true)
135135
So(err, ShouldBeNil)
136136
So(resp.HTTPStatus, ShouldEqual, http.StatusNotAcceptable)
137137
})

response.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const JSONAPIVersion = "1.1"
1414
// Sendable implements functions that allows different response types
1515
// to produce a sendable JSON Response format
1616
type Sendable interface {
17-
Prepare(r *http.Request) (*Response, SendableError)
17+
prepare(r *http.Request, response bool) (*Response, SendableError)
1818
}
1919

2020
// Response represents the top level json format of incoming requests
@@ -57,9 +57,9 @@ func (r *Response) Validate() SendableError {
5757
// Send fires a JSON response if the payload is prepared successfully, otherwise it
5858
// returns an Error which can also be sent.
5959
func Send(w http.ResponseWriter, r *http.Request, payload Sendable) {
60-
response, err := payload.Prepare(r)
60+
response, err := payload.prepare(r, true)
6161
if err != nil {
62-
response, err = err.Prepare(r)
62+
response, err = err.prepare(r, true)
6363

6464
// If we ever hit this, something seriously wrong has happened
6565
if err != nil {
@@ -78,7 +78,7 @@ func SendResponse(w http.ResponseWriter, r *http.Request, response *Response) {
7878

7979
err := response.Validate()
8080
if err != nil {
81-
response, err = err.Prepare(r)
81+
response, err = err.prepare(r, true)
8282

8383
// If we ever hit this, something seriously wrong has happened
8484
if err != nil {

0 commit comments

Comments
 (0)