Fix tests, add trophies endpoint for account, edit trophies struct
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
+24
@@ -12,6 +12,7 @@ type AccountService interface {
|
|||||||
Karma(ctx context.Context) ([]SubredditKarma, *Response, error)
|
Karma(ctx context.Context) ([]SubredditKarma, *Response, error)
|
||||||
Settings(ctx context.Context) (*Settings, *Response, error)
|
Settings(ctx context.Context) (*Settings, *Response, error)
|
||||||
UpdateSettings(ctx context.Context, settings *Settings) (*Settings, *Response, error)
|
UpdateSettings(ctx context.Context, settings *Settings) (*Settings, *Response, error)
|
||||||
|
Trophies(ctx context.Context) ([]Trophy, *Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountServiceOp implements the AccountService interface.
|
// AccountServiceOp implements the AccountService interface.
|
||||||
@@ -288,3 +289,26 @@ func (s *AccountServiceOp) UpdateSettings(ctx context.Context, settings *Setting
|
|||||||
|
|
||||||
return root, resp, nil
|
return root, resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trophies returns a list of your trophies.
|
||||||
|
func (s *AccountServiceOp) Trophies(ctx context.Context) ([]Trophy, *Response, error) {
|
||||||
|
path := "api/v1/me/trophies"
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(rootTrophyListing)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var trophies []Trophy
|
||||||
|
for _, trophy := range root.Data.Trophies {
|
||||||
|
trophies = append(trophies, trophy.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return trophies, resp, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -167,3 +167,19 @@ func TestAccountServiceOp_UpdateSettings(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expectedSettings, settings)
|
assert.Equal(t, expectedSettings, settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccountService_Trophies(t *testing.T) {
|
||||||
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
blob := readFileContents(t, "testdata/account/trophies.json")
|
||||||
|
|
||||||
|
mux.HandleFunc("/api/v1/me/trophies", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, http.MethodGet, r.Method)
|
||||||
|
fmt.Fprint(w, blob)
|
||||||
|
})
|
||||||
|
|
||||||
|
trophies, _, err := client.Account.Trophies(ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expectedTrophies, trophies)
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ var expectedCommentSubmitOrEdit = &Comment{
|
|||||||
ID: "test2",
|
ID: "test2",
|
||||||
FullID: "t1_test2",
|
FullID: "t1_test2",
|
||||||
ParentID: "t1_test",
|
ParentID: "t1_test",
|
||||||
Permalink: "/r/subreddit/comments/test1/some_thread/test2/",
|
Permalink: "https://www.reddit.com/r/subreddit/comments/test1/some_thread/test2/",
|
||||||
|
|
||||||
Body: "test comment",
|
Body: "test comment",
|
||||||
Author: "reddit_username",
|
Author: "reddit_username",
|
||||||
|
|||||||
+1
-1
@@ -88,7 +88,7 @@ var expectedSticky = &PostAndComments{
|
|||||||
Created: &Timestamp{time.Date(2020, 6, 20, 12, 8, 57, 0, time.UTC)},
|
Created: &Timestamp{time.Date(2020, 6, 20, 12, 8, 57, 0, time.UTC)},
|
||||||
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
||||||
|
|
||||||
Permalink: "/r/nba/comments/hcl9gq/daily_discussion_thread_freetalk_and_other/",
|
Permalink: "https://www.reddit.com/r/nba/comments/hcl9gq/daily_discussion_thread_freetalk_and_other/",
|
||||||
URL: "https://www.reddit.com/r/nba/comments/hcl9gq/daily_discussion_thread_freetalk_and_other/",
|
URL: "https://www.reddit.com/r/nba/comments/hcl9gq/daily_discussion_thread_freetalk_and_other/",
|
||||||
|
|
||||||
Title: "Daily Discussion Thread | Free-Talk and Other Updates - June 20, 2020",
|
Title: "Daily Discussion Thread | Free-Talk and Other Updates - June 20, 2020",
|
||||||
|
|||||||
Vendored
+31
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"kind": "TrophyList",
|
||||||
|
"data": {
|
||||||
|
"trophies": [
|
||||||
|
{
|
||||||
|
"kind": "t6",
|
||||||
|
"data": {
|
||||||
|
"icon_70": "https://www.redditstatic.com/awards2/3_year_club-70.png",
|
||||||
|
"name": "Three-Year Club",
|
||||||
|
"url": null,
|
||||||
|
"icon_40": "https://www.redditstatic.com/awards2/3_year_club-40.png",
|
||||||
|
"award_id": null,
|
||||||
|
"id": null,
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "t6",
|
||||||
|
"data": {
|
||||||
|
"icon_70": "https://www.redditstatic.com/awards2/verified_email-70.png",
|
||||||
|
"name": "Verified Email",
|
||||||
|
"url": null,
|
||||||
|
"icon_40": "https://www.redditstatic.com/awards2/verified_email-40.png",
|
||||||
|
"award_id": "o",
|
||||||
|
"id": "1q1tez",
|
||||||
|
"description": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,8 +13,8 @@ const (
|
|||||||
kindSubreddit = "t5"
|
kindSubreddit = "t5"
|
||||||
kindAward = "t6"
|
kindAward = "t6"
|
||||||
kindListing = "Listing"
|
kindListing = "Listing"
|
||||||
kingKarmaList = "KarmaList"
|
kindKarmaList = "KarmaList"
|
||||||
kingTrophyList = "TrophyList"
|
kindTrophyList = "TrophyList"
|
||||||
kindUserList = "UserList"
|
kindUserList = "UserList"
|
||||||
kindMode = "more"
|
kindMode = "more"
|
||||||
)
|
)
|
||||||
@@ -230,10 +230,10 @@ type Comment struct {
|
|||||||
PostID string `json:"link_id,omitempty"`
|
PostID string `json:"link_id,omitempty"`
|
||||||
|
|
||||||
// These don't appear when submitting a comment
|
// These don't appear when submitting a comment
|
||||||
PostTitle string `json:"link_title,omitempty"`
|
PostTitle string `json:"link_title,omitempty"`
|
||||||
PostPermalink Permalink `json:"link_permalink,omitempty"`
|
PostPermalink string `json:"link_permalink,omitempty"`
|
||||||
PostAuthor string `json:"link_author,omitempty"`
|
PostAuthor string `json:"link_author,omitempty"`
|
||||||
PostNumComments int `json:"num_comments"`
|
PostNumComments int `json:"num_comments"`
|
||||||
|
|
||||||
IsSubmitter bool `json:"is_submitter"`
|
IsSubmitter bool `json:"is_submitter"`
|
||||||
ScoreHidden bool `json:"score_hidden"`
|
ScoreHidden bool `json:"score_hidden"`
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package geddit
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -42,8 +40,8 @@ type UserService interface {
|
|||||||
Unblock(ctx context.Context, username string) (*Response, error)
|
Unblock(ctx context.Context, username string) (*Response, error)
|
||||||
// UnblockByID(ctx context.Context, id string) (*Response, error)
|
// UnblockByID(ctx context.Context, id string) (*Response, error)
|
||||||
|
|
||||||
Trophies(ctx context.Context) (Trophies, *Response, error)
|
Trophies(ctx context.Context) ([]Trophy, *Response, error)
|
||||||
TrophiesOf(ctx context.Context, username string) (Trophies, *Response, error)
|
TrophiesOf(ctx context.Context, username string) ([]Trophy, *Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserServiceOp implements the UserService interface.
|
// UserServiceOp implements the UserService interface.
|
||||||
@@ -98,63 +96,22 @@ type Blocked struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type rootTrophyListing struct {
|
type rootTrophyListing struct {
|
||||||
Kind string `json:"kind,omitempty"`
|
Kind string `json:"kind,omitempty"`
|
||||||
Trophies Trophies `json:"data"`
|
Data struct {
|
||||||
|
Trophies []rootTrophy `json:"trophies"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type rootTrophy struct {
|
||||||
|
Kind string `json:"kind,omitempty"`
|
||||||
|
Data Trophy `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trophy is a Reddit award.
|
// Trophy is a Reddit award.
|
||||||
type Trophy struct {
|
type Trophy struct {
|
||||||
Name string `json:"name"`
|
ID string `json:"id"`
|
||||||
}
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
// Trophies is a list of trophies.
|
|
||||||
type Trophies []Trophy
|
|
||||||
|
|
||||||
// todo: we don't really need this. just make a rootTrophyListingData struct or something and use the default unmarshaler for that
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
|
||||||
func (t *Trophies) UnmarshalJSON(b []byte) error {
|
|
||||||
var data map[string]interface{}
|
|
||||||
if err := json.Unmarshal(b, &data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
trophies, ok := data["trophies"]
|
|
||||||
if !ok {
|
|
||||||
return errors.New("data does not contain trophies")
|
|
||||||
}
|
|
||||||
|
|
||||||
trophyList, ok := trophies.([]interface{})
|
|
||||||
if !ok {
|
|
||||||
return errors.New("unexpected type for list of trophies")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, trophyData := range trophyList {
|
|
||||||
trophyInfo, ok := trophyData.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
info, ok := trophyInfo["data"]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
infoBytes, err := json.Marshal(info)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var trophy Trophy
|
|
||||||
err = json.Unmarshal(infoBytes, &trophy)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = append(*t, trophy)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns information about the user.
|
// Get returns information about the user.
|
||||||
@@ -549,12 +506,12 @@ func (s *UserServiceOp) Unblock(ctx context.Context, username string) (*Response
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Trophies returns a list of your trophies.
|
// Trophies returns a list of your trophies.
|
||||||
func (s *UserServiceOp) Trophies(ctx context.Context) (Trophies, *Response, error) {
|
func (s *UserServiceOp) Trophies(ctx context.Context) ([]Trophy, *Response, error) {
|
||||||
return s.TrophiesOf(ctx, s.client.Username)
|
return s.TrophiesOf(ctx, s.client.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrophiesOf returns a list of the specified user's trophies.
|
// TrophiesOf returns a list of the specified user's trophies.
|
||||||
func (s *UserServiceOp) TrophiesOf(ctx context.Context, username string) (Trophies, *Response, error) {
|
func (s *UserServiceOp) TrophiesOf(ctx context.Context, username string) ([]Trophy, *Response, error) {
|
||||||
path := fmt.Sprintf("api/v1/user/%s/trophies", username)
|
path := fmt.Sprintf("api/v1/user/%s/trophies", username)
|
||||||
|
|
||||||
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||||
@@ -568,5 +525,10 @@ func (s *UserServiceOp) TrophiesOf(ctx context.Context, username string) (Trophi
|
|||||||
return nil, resp, err
|
return nil, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return root.Trophies, resp, nil
|
var trophies []Trophy
|
||||||
|
for _, trophy := range root.Data.Trophies {
|
||||||
|
trophies = append(trophies, trophy.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return trophies, resp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-5
@@ -52,7 +52,7 @@ var expectedPost = Post{
|
|||||||
Created: &Timestamp{time.Date(2020, 5, 3, 22, 46, 25, 0, time.UTC)},
|
Created: &Timestamp{time.Date(2020, 5, 3, 22, 46, 25, 0, time.UTC)},
|
||||||
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
||||||
|
|
||||||
Permalink: "/r/redditdev/comments/gczwql/get_userusernamegilded_does_it_return_other_users/",
|
Permalink: "https://www.reddit.com/r/redditdev/comments/gczwql/get_userusernamegilded_does_it_return_other_users/",
|
||||||
URL: "https://www.reddit.com/r/redditdev/comments/gczwql/get_userusernamegilded_does_it_return_other_users/",
|
URL: "https://www.reddit.com/r/redditdev/comments/gczwql/get_userusernamegilded_does_it_return_other_users/",
|
||||||
|
|
||||||
Title: "GET /user/{username}/gilded: does it return other user's things you've gilded, or your things that have been gilded? Does it return both comments and posts?",
|
Title: "GET /user/{username}/gilded: does it return other user's things you've gilded, or your things that have been gilded? Does it return both comments and posts?",
|
||||||
@@ -81,7 +81,7 @@ var expectedComment = Comment{
|
|||||||
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
||||||
|
|
||||||
ParentID: "t3_d7ejpn",
|
ParentID: "t3_d7ejpn",
|
||||||
Permalink: "/r/apple/comments/d7ejpn/im_giving_away_an_iphone_11_pro_to_a_commenter_at/f0zsa37/",
|
Permalink: "https://www.reddit.com/r/apple/comments/d7ejpn/im_giving_away_an_iphone_11_pro_to_a_commenter_at/f0zsa37/",
|
||||||
|
|
||||||
Body: "Thank you!",
|
Body: "Thank you!",
|
||||||
Author: "v_95",
|
Author: "v_95",
|
||||||
@@ -116,9 +116,17 @@ var expectedBlocked = &Blocked{
|
|||||||
Created: &Timestamp{time.Date(2020, 6, 16, 16, 49, 50, 0, time.UTC)},
|
Created: &Timestamp{time.Date(2020, 6, 16, 16, 49, 50, 0, time.UTC)},
|
||||||
}
|
}
|
||||||
|
|
||||||
var expectedTrophies = Trophies{
|
var expectedTrophies = []Trophy{
|
||||||
{Name: "Three-Year Club"},
|
{
|
||||||
{Name: "Verified Email"},
|
ID: "",
|
||||||
|
Name: "Three-Year Club",
|
||||||
|
Description: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "1q1tez",
|
||||||
|
Name: "Verified Email",
|
||||||
|
Description: "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUserService_Get(t *testing.T) {
|
func TestUserService_Get(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user