Skip to content

Commit

Permalink
Mention that Do/Receive won't decode for status code 204 (#56)
Browse files Browse the repository at this point in the history
* Improve the godoc for `Do` and add no content tests
  • Loading branch information
wangyuehong authored and dghubble committed Aug 31, 2019
1 parent 8dde57b commit 449393a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion sling.go
Expand Up @@ -359,6 +359,7 @@ func (s *Sling) ReceiveSuccess(successV interface{}) (*http.Response, error) {
// Receive creates a new HTTP request and returns the response. Success
// responses (2XX) are JSON decoded into the value pointed to by successV and
// other responses are JSON decoded into the value pointed to by failureV.
// If the status code of response is 204(no content), decoding is skipped.
// Any error creating the request, sending it, or decoding the response is
// returned.
// Receive is shorthand for calling Request and Do.
Expand All @@ -373,6 +374,7 @@ func (s *Sling) Receive(successV, failureV interface{}) (*http.Response, error)
// Do sends an HTTP request and returns the response. Success responses (2XX)
// are JSON decoded into the value pointed to by successV and other responses
// are JSON decoded into the value pointed to by failureV.
// If the status code of response is 204(no content), decoding is skipped.
// Any error sending the request or decoding the response is returned.
func (s *Sling) Do(req *http.Request, successV, failureV interface{}) (*http.Response, error) {
resp, err := s.httpClient.Do(req)
Expand All @@ -383,7 +385,7 @@ func (s *Sling) Do(req *http.Request, successV, failureV interface{}) (*http.Res
defer resp.Body.Close()

// Don't try to decode on 204s
if resp.StatusCode == 204 {
if resp.StatusCode == http.StatusNoContent {
return resp, nil
}

Expand Down
49 changes: 49 additions & 0 deletions sling_test.go
Expand Up @@ -665,6 +665,36 @@ func TestDo_onSuccessWithNilValue(t *testing.T) {
}
}

func TestDo_noContent(t *testing.T) {
client, mux, server := testServer()
defer server.Close()
mux.HandleFunc("/nocontent", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(204)
})

sling := New().Client(client)
req, _ := http.NewRequest("DELETE", "http://example.com/nocontent", nil)

model := new(FakeModel)
apiError := new(APIError)
resp, err := sling.Do(req, model, apiError)

if err != nil {
t.Errorf("expected nil, got %v", err)
}
if resp.StatusCode != 204 {
t.Errorf("expected %d, got %d", 204, resp.StatusCode)
}
expectedModel := &FakeModel{}
if !reflect.DeepEqual(expectedModel, model) {
t.Errorf("successV should not be populated, exepcted %v, got %v", expectedModel, model)
}
expectedAPIError := &APIError{}
if !reflect.DeepEqual(expectedAPIError, apiError) {
t.Errorf("failureV should not be populated, exepcted %v, got %v", expectedAPIError, apiError)
}
}

func TestDo_onFailure(t *testing.T) {
const expectedMessage = "Invalid argument"
const expectedCode int = 215
Expand Down Expand Up @@ -830,6 +860,25 @@ func TestReceive_failure(t *testing.T) {
}
}

func TestReceive_noContent(t *testing.T) {
client, mux, server := testServer()
defer server.Close()
mux.HandleFunc("/foo/submit", func(w http.ResponseWriter, r *http.Request) {
assertMethod(t, "HEAD", r)
w.WriteHeader(204)
})

endpoint := New().Client(client).Base("http://example.com/").Path("foo/").Head("submit")
resp, err := endpoint.New().Receive(nil, nil)

if err != nil {
t.Errorf("expected nil, got %v", err)
}
if resp.StatusCode != 204 {
t.Errorf("expected %d, got %d", 204, resp.StatusCode)
}
}

func TestReceive_errorCreatingRequest(t *testing.T) {
expectedErr := errors.New("json: unsupported value: +Inf")
resp, err := New().BodyJSON(FakeModel{Temperature: math.Inf(1)}).Receive(nil, nil)
Expand Down

0 comments on commit 449393a

Please sign in to comment.