diff --git a/testdata/user/list.json b/testdata/user/list.json new file mode 100644 index 0000000..b6c6ba6 --- /dev/null +++ b/testdata/user/list.json @@ -0,0 +1,137 @@ +{ + "kind": "Listing", + "data": { + "modhash": null, + "dist": 2, + "children": [ + { + "kind": "t2", + "data": { + "is_employee": false, + "icon_img": "https://styles.redditmedia.com/t5_3kdh5/styles/profileIcon_0ws73gmqq8t21.png?width=256&height=256&crop=256:256,smart&s=a4d69298f5514b44cfa28a428c0953ebe0d5f6a1", + "pref_show_snoovatar": false, + "name": "washingtonpost", + "is_friend": false, + "created": 1492752238.0, + "has_subscribed": true, + "hide_from_robots": false, + "verified": true, + "created_utc": 1492723438.0, + "subreddit": { + "default_set": true, + "banner_img": "https://b.thumbs.redditmedia.com/6pvP62O65Lnam35DjverknB9sW10mFuVaZago5Ksovo.png", + "restrict_posting": true, + "user_is_banned": false, + "free_form_reports": true, + "community_icon": null, + "show_media": true, + "description": "Test text. Test text. Refer to [Reddit's site-wide rules](https://www.reddit.com/help/contentpolicy).", + "user_is_muted": false, + "display_name": "u_washingtonpost", + "header_img": null, + "title": "Washington Post", + "previous_names": [], + "user_is_moderator": false, + "over_18": false, + "icon_size": [256, 256], + "primary_color": "", + "icon_img": "https://styles.redditmedia.com/t5_3kdh5/styles/profileIcon_0ws73gmqq8t21.png?width=256&height=256&crop=256:256,smart&s=a4d69298f5514b44cfa28a428c0953ebe0d5f6a1", + "icon_color": "", + "submit_link_label": null, + "header_size": null, + "restrict_commenting": false, + "subscribers": 0, + "submit_text_label": null, + "is_default_icon": false, + "link_flair_position": "right", + "display_name_prefixed": "u/washingtonpost", + "key_color": "", + "name": "t5_3kdh5", + "is_default_banner": false, + "url": "/user/washingtonpost/", + "banner_size": [1280, 384], + "user_is_contributor": false, + "public_description": "Democracy Dies in Dankness. Official account.\n\nOur award-winning journalists have covered Washington and the world since 1877. Modded by /u/GenePark.", + "link_flair_enabled": true, + "disable_contributor_requests": false, + "subreddit_type": "user", + "user_is_subscriber": false + }, + "comment_karma": 339569, + "is_gold": true, + "is_mod": true, + "accept_chats": false, + "link_karma": 1075227, + "has_verified_email": true, + "id": "179965", + "accept_pms": true + } + }, + { + "kind": "t2", + "data": { + "is_employee": false, + "icon_img": "https://styles.redditmedia.com/t5_i4xj7/styles/profileIcon_mlsb0hlsebs01.jpg?width=256&height=256&crop=256:256,smart&s=7cb6c6fcf5079cd5514ea626e73398429f3b4b54", + "pref_show_snoovatar": false, + "name": "reuters", + "is_friend": false, + "created": 1521107404.0, + "has_subscribed": false, + "hide_from_robots": false, + "verified": true, + "created_utc": 1521078604.0, + "subreddit": { + "default_set": true, + "banner_img": "https://styles.redditmedia.com/t5_i4xj7/styles/profileBanner_lzxtifo1fbs01.jpg?width=1280&height=384&crop=1280:384,smart&s=b423e44cd122c0d06c91b445abdb73c214ec8c4c", + "restrict_posting": true, + "user_is_banned": false, + "free_form_reports": true, + "community_icon": null, + "show_media": true, + "description": "", + "user_is_muted": false, + "display_name": "u_reuters", + "header_img": null, + "title": "Reuters ", + "previous_names": [], + "user_is_moderator": false, + "over_18": false, + "icon_size": [256, 256], + "primary_color": "", + "icon_img": "https://styles.redditmedia.com/t5_i4xj7/styles/profileIcon_mlsb0hlsebs01.jpg?width=256&height=256&crop=256:256,smart&s=7cb6c6fcf5079cd5514ea626e73398429f3b4b54", + "icon_color": "", + "submit_link_label": "", + "header_size": null, + "restrict_commenting": false, + "subscribers": 0, + "submit_text_label": "", + "is_default_icon": false, + "link_flair_position": "right", + "display_name_prefixed": "u/reuters", + "key_color": "", + "name": "t5_i4xj7", + "is_default_banner": false, + "url": "/user/reuters/", + "banner_size": [1280, 384], + "user_is_contributor": false, + "public_description": "", + "link_flair_enabled": true, + "disable_contributor_requests": false, + "subreddit_type": "user", + "user_is_subscriber": false + }, + "comment_karma": 42717, + "is_gold": true, + "is_mod": false, + "accept_chats": false, + "link_karma": 76744, + "has_verified_email": true, + "id": "11kowl2w", + "accept_pms": true + } + } + ], + "after": "t2_11kowl2w", + "before": null + } +} diff --git a/user.go b/user.go index 62be962..56a0402 100644 --- a/user.go +++ b/user.go @@ -37,9 +37,9 @@ type User struct { IsSuspended bool `json:"is_suspended"` } -// UserShort represents a Reddit user, but +// UserSummary represents a Reddit user, but // contains fewer pieces of information. -type UserShort struct { +type UserSummary struct { Name string `json:"name,omitempty"` Created *Timestamp `json:"created_utc,omitempty"` @@ -101,8 +101,8 @@ func (s *UserService) Get(ctx context.Context, username string) (*User, *Respons } // GetMultipleByID returns multiple users from their full IDs. -// The response body is a map where the keys are the IDs (if they exist), and the value is the user -func (s *UserService) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserShort, *Response, error) { +// The response body is a map where the keys are the IDs (if they exist), and the value is the user. +func (s *UserService) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserSummary, *Response, error) { type query struct { IDs []string `url:"ids,omitempty,comma"` } @@ -118,13 +118,13 @@ func (s *UserService) GetMultipleByID(ctx context.Context, ids ...string) (map[s return nil, nil, err } - root := new(map[string]*UserShort) - resp, err := s.client.Do(ctx, req, root) + root := make(map[string]*UserSummary) + resp, err := s.client.Do(ctx, req, &root) if err != nil { return nil, resp, err } - return *root, resp, nil + return root, resp, nil } // UsernameAvailable checks whether a username is available for registration. @@ -553,3 +553,24 @@ func (s *UserService) New(ctx context.Context, opts ...SearchOptionSetter) (*Sub return root.getSubreddits(), resp, nil } + +// Search searches for users. +func (s *UserService) Search(ctx context.Context, query string, opts ...SearchOptionSetter) (*Users, *Response, error) { + opts = append(opts, setQuery(query)) + form := newSearchOptions(opts...) + + path := addQuery("users/search", form) + + req, err := s.client.NewRequest(http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(rootListing) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.getUsers(), resp, nil +} diff --git a/user_test.go b/user_test.go index c596150..a674189 100644 --- a/user_test.go +++ b/user_test.go @@ -22,7 +22,7 @@ var expectedUser = &User{ HasVerifiedEmail: true, } -var expectedUsers = map[string]*UserShort{ +var expectedUsers = map[string]*UserSummary{ "t2_1": { Name: "test_user_1", Created: &Timestamp{time.Date(2017, 3, 12, 2, 1, 47, 0, time.UTC)}, @@ -160,6 +160,32 @@ var expectedUserSubreddits = &Subreddits{ After: "t5_3knn1", } +var expectedSearchUsers2 = &Users{ + Users: []*User{ + { + ID: "179965", + Name: "washingtonpost", + Created: &Timestamp{time.Date(2017, 4, 20, 21, 23, 58, 0, time.UTC)}, + + PostKarma: 1075227, + CommentKarma: 339569, + + HasVerifiedEmail: true, + }, + { + ID: "11kowl2w", + Name: "reuters", + Created: &Timestamp{time.Date(2018, 3, 15, 1, 50, 4, 0, time.UTC)}, + + PostKarma: 76744, + CommentKarma: 42717, + + HasVerifiedEmail: true, + }, + }, + After: "t2_11kowl2w", +} + func TestUserService_Get(t *testing.T) { setup() defer teardown() @@ -894,3 +920,28 @@ func TestUserService_New(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expectedUserSubreddits, userSubreddits) } + +func TestUserService_Search(t *testing.T) { + setup() + defer teardown() + + blob, err := readFileContents("testdata/user/list.json") + assert.NoError(t, err) + + mux.HandleFunc("/users/search", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method) + + form := url.Values{} + form.Set("q", "test") + + err := r.ParseForm() + assert.NoError(t, err) + assert.Equal(t, form, r.Form) + + fmt.Fprint(w, blob) + }) + + users, _, err := client.User.Search(ctx, "test") + assert.NoError(t, err) + assert.Equal(t, expectedSearchUsers2, users) +}