From 73db8f30d8711a3b5c336c75d4882fa56f4f6b3b Mon Sep 17 00:00:00 2001 From: Vartan Benohanian Date: Sat, 8 Aug 2020 01:27:53 -0400 Subject: [PATCH] Add EmojiService Signed-off-by: Vartan Benohanian --- emoji.go | 84 ++++++++++++++++++++++++++++++++++++++ emoji_test.go | 57 ++++++++++++++++++++++++++ reddit.go | 2 + reddit_test.go | 1 + testdata/emoji/emojis.json | 27 ++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 emoji.go create mode 100644 emoji_test.go create mode 100644 testdata/emoji/emojis.json diff --git a/emoji.go b/emoji.go new file mode 100644 index 0000000..2781ed8 --- /dev/null +++ b/emoji.go @@ -0,0 +1,84 @@ +package reddit + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" +) + +// EmojiService handles communication with the emoji +// related methods of the Reddit API. +// +// Reddit API docs: https://www.reddit.com/dev/api/#section_collections +type EmojiService struct { + client *Client +} + +// Emoji is a graphic element you can include in a post flair or user flair. +type Emoji struct { + Name string `json:"name,omitempty"` + URL string `json:"url,omitempty"` + UserFlairAllowed bool `json:"user_flair_allowed,omitempty"` + PostFlairAllowed bool `json:"post_flair_allowed,omitempty"` + ModFlairOnly bool `json:"mod_flair_only,omitempty"` + // ID of the user who created this emoji. + CreatedBy string `json:"created_by,omitempty"` +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// func (e *Emoji) UnmarshalJSON(data []byte) (err error) { +// fmt.Println("===", string(data)) +// return nil +// } + +type emojis []*Emoji + +func (e *emojis) UnmarshalJSON(data []byte) (err error) { + emojiMap := make(map[string]json.RawMessage) + err = json.Unmarshal(data, &emojiMap) + if err != nil { + return + } + + for emojiName, emojiValue := range emojiMap { + emoji := new(Emoji) + err = json.Unmarshal(emojiValue, emoji) + if err != nil { + return + } + emoji.Name = emojiName + *e = append(*e, emoji) + } + + return +} + +// Get returns the default set of Reddit emojis, and those of the subreddit, respectively. +func (s *EmojiService) Get(ctx context.Context, subreddit string) ([]*Emoji, []*Emoji, *Response, error) { + path := fmt.Sprintf("api/v1/%s/emojis/all", subreddit) + + req, err := s.client.NewRequest(http.MethodGet, path, nil) + if err != nil { + return nil, nil, nil, err + } + + root := make(map[string]emojis) + resp, err := s.client.Do(ctx, req, &root) + if err != nil { + return nil, nil, resp, err + } + + defaultEmojis := root["snoomojis"] + var subredditEmojis []*Emoji + + for k := range root { + if strings.HasPrefix(k, kindSubreddit) { + subredditEmojis = root[k] + break + } + } + + return defaultEmojis, subredditEmojis, resp, nil +} diff --git a/emoji_test.go b/emoji_test.go new file mode 100644 index 0000000..918d06b --- /dev/null +++ b/emoji_test.go @@ -0,0 +1,57 @@ +package reddit + +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +var expectedDefaultEmojis = []*Emoji{ + { + Name: "cake", + URL: "https://emoji.redditmedia.com/46kel8lf1guz_t5_3nqvj/cake", + UserFlairAllowed: true, + PostFlairAllowed: true, + ModFlairOnly: false, + CreatedBy: "t2_6zfp6ii", + }, + { + Name: "cat_blep", + URL: "https://emoji.redditmedia.com/p9sxc1zh1guz_t5_3nqvj/cat_blep", + UserFlairAllowed: true, + PostFlairAllowed: true, + ModFlairOnly: false, + CreatedBy: "t2_6zfp6ii", + }, +} + +var expectedSubredditEmojis = []*Emoji{ + { + Name: "TestEmoji", + URL: "https://emoji.redditmedia.com/fxe5a674hpf51_t5_2uquw1/TestEmoji", + UserFlairAllowed: true, + PostFlairAllowed: true, + ModFlairOnly: false, + CreatedBy: "t2_164ab8", + }, +} + +func TestEmojiService_Get(t *testing.T) { + setup() + defer teardown() + + blob, err := readFileContents("./testdata/emoji/emojis.json") + assert.NoError(t, err) + + mux.HandleFunc("/api/v1/test/emojis/all", func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method) + fmt.Fprint(w, blob) + }) + + defaultEmojis, subredditEmojis, _, err := client.Emoji.Get(ctx, "test") + assert.NoError(t, err) + assert.Equal(t, expectedDefaultEmojis, defaultEmojis) + assert.Equal(t, expectedSubredditEmojis, subredditEmojis) +} diff --git a/reddit.go b/reddit.go index 73f0654..5eff123 100644 --- a/reddit.go +++ b/reddit.go @@ -94,6 +94,7 @@ type Client struct { Account *AccountService Collection *CollectionService Comment *CommentService + Emoji *EmojiService Flair *FlairService Listings *ListingsService Moderation *ModerationService @@ -141,6 +142,7 @@ func newClient(httpClient *http.Client) *Client { c.Account = &AccountService{client: c} c.Collection = &CollectionService{client: c} + c.Emoji = &EmojiService{client: c} c.Flair = &FlairService{client: c} c.Listings = &ListingsService{client: c} c.Moderation = &ModerationService{client: c} diff --git a/reddit_test.go b/reddit_test.go index 29e548b..17b12b8 100644 --- a/reddit_test.go +++ b/reddit_test.go @@ -69,6 +69,7 @@ func testClientServices(t *testing.T, c *Client) { "Account", "Collection", "Comment", + "Emoji", "Flair", "Listings", "Moderation", diff --git a/testdata/emoji/emojis.json b/testdata/emoji/emojis.json new file mode 100644 index 0000000..0898f6e --- /dev/null +++ b/testdata/emoji/emojis.json @@ -0,0 +1,27 @@ +{ + "snoomojis": { + "cake": { + "url": "https://emoji.redditmedia.com/46kel8lf1guz_t5_3nqvj/cake", + "user_flair_allowed": true, + "post_flair_allowed": true, + "mod_flair_only": false, + "created_by": "t2_6zfp6ii" + }, + "cat_blep": { + "url": "https://emoji.redditmedia.com/p9sxc1zh1guz_t5_3nqvj/cat_blep", + "user_flair_allowed": true, + "post_flair_allowed": true, + "mod_flair_only": false, + "created_by": "t2_6zfp6ii" + } + }, + "t5_2uquw1": { + "TestEmoji": { + "url": "https://emoji.redditmedia.com/fxe5a674hpf51_t5_2uquw1/TestEmoji", + "user_flair_allowed": true, + "post_flair_allowed": true, + "mod_flair_only": false, + "created_by": "t2_164ab8" + } + } +}