diff --git a/emoji.go b/emoji.go index 9216921..58f5844 100644 --- a/emoji.go +++ b/emoji.go @@ -113,8 +113,6 @@ func (s *EmojiService) Delete(ctx context.Context, subreddit string, emoji strin return s.client.Do(ctx, req, nil) } -//todo: fav subreddits - // SetSize sets the custom emoji size in the subreddit. // Both height and width must be between 1 and 40 (inclusive). func (s *EmojiService) SetSize(ctx context.Context, subreddit string, height, width int) (*Response, error) { diff --git a/errors.go b/errors.go index 744a762..b1acca4 100644 --- a/errors.go +++ b/errors.go @@ -6,7 +6,7 @@ import ( "net/http" ) -// APIError is an error coming from Reddit +// APIError is an error coming from Reddit. type APIError struct { Label string Reason string @@ -19,17 +19,13 @@ func (e *APIError) Error() string { // UnmarshalJSON implements the json.Unmarshaler interface. func (e *APIError) UnmarshalJSON(data []byte) error { - var info []string + var info [3]string err := json.Unmarshal(data, &info) if err != nil { return err } - if len(info) != 3 { - return fmt.Errorf("got unexpected Reddit error: %v", info) - } - e.Label = info[0] e.Reason = info[1] e.Field = info[2] @@ -37,9 +33,9 @@ func (e *APIError) UnmarshalJSON(data []byte) error { return nil } -// JSONErrorResponse is an error response that sometimes gets returned with a 200 code +// JSONErrorResponse is an error response that sometimes gets returned with a 200 code. type JSONErrorResponse struct { - // HTTP response that caused this error + // HTTP response that caused this error. Response *http.Response `json:"-"` JSON *struct { @@ -78,3 +74,5 @@ func (r *ErrorResponse) Error() string { r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message, ) } + +// todo: rate limit errors diff --git a/reddit_test.go b/reddit_test.go index 8ab41ff..3c2f200 100644 --- a/reddit_test.go +++ b/reddit_test.go @@ -111,3 +111,82 @@ func TestNewClient_Error(t *testing.T) { _, err := NewClient(nil, errorOpt) require.EqualError(t, err, "foo") } + +func TestClient_OnRequestComplemented(t *testing.T) { + setup() + defer teardown() + + var i int + cb := func(*http.Request, *http.Response) { + i++ + } + client.OnRequestCompleted(cb) + + mux.HandleFunc("/api/v1/test", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodGet, r.Method) + }) + + req, err := client.NewRequest(http.MethodGet, "api/v1/test", nil) + require.NoError(t, err) + + _, _ = client.Do(ctx, req, nil) + require.Equal(t, 1, i) + + _, _ = client.Do(ctx, req, nil) + _, _ = client.Do(ctx, req, nil) + _, _ = client.Do(ctx, req, nil) + _, _ = client.Do(ctx, req, nil) + require.Equal(t, 5, i) + + _, _ = client.Do(ctx, req, nil) + require.Equal(t, 6, i) +} + +func TestClient_JSONErrorResponse(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/api/v1/test", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodGet, r.Method) + fmt.Fprint(w, `{ + "json": { + "errors": [ + [ + "TEST_ERROR", + "this is a test error", + "test field" + ] + ] + } + }`) + }) + + req, err := client.NewRequest(http.MethodGet, "api/v1/test", nil) + require.NoError(t, err) + + resp, err := client.Do(ctx, req, nil) + require.IsType(t, &JSONErrorResponse{}, err) + require.EqualError(t, err, fmt.Sprintf(`GET %s/api/v1/test: 200 field "test field" caused TEST_ERROR: this is a test error`, server.URL)) + require.Equal(t, http.StatusOK, resp.StatusCode) +} + +func TestClient_ErrorResponse(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/api/v1/test", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodGet, r.Method) + w.WriteHeader(http.StatusForbidden) + fmt.Fprint(w, `{ + "message": "error message" + }`) + }) + + req, err := client.NewRequest(http.MethodGet, "api/v1/test", nil) + require.NoError(t, err) + + resp, err := client.Do(ctx, req, nil) + require.IsType(t, &ErrorResponse{}, err) + require.EqualError(t, err, fmt.Sprintf(`GET %s/api/v1/test: 403 error message`, server.URL)) + require.Equal(t, http.StatusForbidden, resp.StatusCode) +} diff --git a/things.go b/things.go index a40bf79..9a07ba3 100644 --- a/things.go +++ b/things.go @@ -425,17 +425,13 @@ type PostAndComments struct { // The 1st one contains the single post in its children array // The 2nd one contains the comments to the post func (pc *PostAndComments) UnmarshalJSON(data []byte) error { - var l []rootListing + var l [2]rootListing err := json.Unmarshal(data, &l) if err != nil { return err } - if len(l) < 2 { - return errors.New("unexpected json response when getting post") - } - post := l[0].getPosts().Posts[0] comments := l[1].getComments().Comments moreComments := l[1].getMoreComments()