From 519a448ff9e3e14bceef2ba158bd356d30cdca65 Mon Sep 17 00:00:00 2001 From: Vartan Benohanian Date: Thu, 10 Sep 2020 00:39:50 -0400 Subject: [PATCH] Get flair choices Signed-off-by: Vartan Benohanian --- reddit/flair.go | 63 ++++++++++++++++ reddit/flair_test.go | 142 ++++++++++++++++++++++++++++++++++++ testdata/flair/choices.json | 38 ++++++++++ 3 files changed, 243 insertions(+) create mode 100644 testdata/flair/choices.json diff --git a/reddit/flair.go b/reddit/flair.go index f427a44..9691fa9 100644 --- a/reddit/flair.go +++ b/reddit/flair.go @@ -39,6 +39,15 @@ type FlairSummary struct { CSSClass string `json:"flair_css_class,omitempty"` } +// FlairChoice is a choice of flair when selecting one for yourself or for a post. +type FlairChoice struct { + TemplateID string `json:"flair_template_id"` + Text string `json:"flair_text"` + Editable bool `json:"flair_text_editable"` + Position string `json:"flair_position"` + CSSClass string `json:"flair_css_class"` +} + // ConfigureFlairRequest represents a request to configure a subreddit's flair settings. // Not setting an attribute can have unexpected side effects, so assign every one just in case. type ConfigureFlairRequest struct { @@ -337,6 +346,7 @@ func (s *FlairService) DeleteAllPostTemplates(ctx context.Context, subreddit str } // ReorderUserTemplates reorders the user flair templates in the order provided in the slice. +// The order should contain every single flair id of this flair type; omitting any id will result in an error. func (s *FlairService) ReorderUserTemplates(ctx context.Context, subreddit string, ids []string) (*Response, error) { path := fmt.Sprintf("api/v1/%s/flair_template_order/USER_FLAIR", subreddit) req, err := s.client.NewJSONRequest(http.MethodPatch, path, ids) @@ -347,6 +357,7 @@ func (s *FlairService) ReorderUserTemplates(ctx context.Context, subreddit strin } // ReorderPostTemplates reorders the post flair templates in the order provided in the slice. +// The order should contain every single flair id of this flair type; omitting any id will result in an error. func (s *FlairService) ReorderPostTemplates(ctx context.Context, subreddit string, ids []string) (*Response, error) { path := fmt.Sprintf("api/v1/%s/flair_template_order/LINK_FLAIR", subreddit) req, err := s.client.NewJSONRequest(http.MethodPatch, path, ids) @@ -355,3 +366,55 @@ func (s *FlairService) ReorderPostTemplates(ctx context.Context, subreddit strin } return s.client.Do(ctx, req, nil) } + +// Choices returns a list of flairs you can assign to yourself in the subreddit, and your current one. +func (s *FlairService) Choices(ctx context.Context, subreddit string) ([]*FlairChoice, *FlairChoice, *Response, error) { + return s.ChoicesOf(ctx, subreddit, s.client.Username) +} + +// ChoicesOf returns a list of flairs the user can assign to themself in the subreddit, and their current one. +// Unless the user is you, this only works if you're a moderator of the subreddit. +func (s *FlairService) ChoicesOf(ctx context.Context, subreddit, username string) ([]*FlairChoice, *FlairChoice, *Response, error) { + path := fmt.Sprintf("r/%s/api/flairselector", subreddit) + form := url.Values{} + form.Set("name", username) + return s.choices(ctx, path, form) +} + +// ChoicesForPost returns a list of flairs you can assign to an existing post, and the current one assigned to it. +// If the post isn't yours, this only works if you're the moderator of the subreddit it's in. +func (s *FlairService) ChoicesForPost(ctx context.Context, postID string) ([]*FlairChoice, *FlairChoice, *Response, error) { + path := "api/flairselector" + form := url.Values{} + form.Set("link", postID) + return s.choices(ctx, path, form) +} + +// ChoicesForNewPost returns a list of flairs you can assign to a new post in a subreddit. +func (s *FlairService) ChoicesForNewPost(ctx context.Context, subreddit string) ([]*FlairChoice, *Response, error) { + path := fmt.Sprintf("r/%s/api/flairselector", subreddit) + + form := url.Values{} + form.Set("is_newlink", "true") + + choices, _, resp, err := s.choices(ctx, path, form) + return choices, resp, err +} + +func (s *FlairService) choices(ctx context.Context, path string, form url.Values) ([]*FlairChoice, *FlairChoice, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, path, form) + if err != nil { + return nil, nil, nil, err + } + + root := new(struct { + Choices []*FlairChoice `json:"choices"` + Current *FlairChoice `json:"current"` + }) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, nil, resp, err + } + + return root.Choices, root.Current, resp, nil +} diff --git a/reddit/flair_test.go b/reddit/flair_test.go index cdb96c9..0cd3224 100644 --- a/reddit/flair_test.go +++ b/reddit/flair_test.go @@ -83,6 +83,45 @@ var expectedFlairTemplate = &FlairTemplate{ CSSClass: "", } +var expectedFlairChoices = []*FlairChoice{ + { + TemplateID: "c4edd5ce-40e8-11e7-b814-0ef91bd65558", + Text: "Reddit API", + Editable: false, + Position: "left", + CSSClass: "", + }, + { + TemplateID: "49bb3d06-0dad-11e7-b897-0e42c2400b7a", + Text: "PRAW", + Editable: false, + Position: "left", + CSSClass: "", + }, + { + TemplateID: "f1905376-40e9-11e7-a0dc-0e2f53ef3712", + Text: "snoowrap", + Editable: false, + Position: "left", + CSSClass: "", + }, + { + TemplateID: "03dc6ea8-40e9-11e7-8abb-0eb85aed0bce", + Text: "Other API Wrapper", + Editable: false, + Position: "left", + CSSClass: "", + }, +} + +var expectedFlairChoice = &FlairChoice{ + TemplateID: "03dc6ea8-40e9-11e7-8abb-0eb85aed0bce", + Text: "Other API Wrapper", + Editable: false, + Position: "left", + CSSClass: "", +} + func TestFlairService_GetUserFlairs(t *testing.T) { client, mux, teardown := setup() defer teardown() @@ -412,3 +451,106 @@ func TestFlairService_ReorderPostTemplates(t *testing.T) { _, err := client.Flair.ReorderPostTemplates(ctx, "testsubreddit", []string{"test1", "test2", "test3", "test4"}) require.NoError(t, err) } + +func TestFlairService_Choices(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + blob, err := readFileContents("../testdata/flair/choices.json") + require.NoError(t, err) + + mux.HandleFunc("/r/testsubreddit/api/flairselector", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("name", "user1") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + + fmt.Fprint(w, blob) + }) + + choices, current, _, err := client.Flair.Choices(ctx, "testsubreddit") + require.NoError(t, err) + require.Equal(t, expectedFlairChoices, choices) + require.Equal(t, expectedFlairChoice, current) +} + +func TestFlairService_ChoicesOf(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + blob, err := readFileContents("../testdata/flair/choices.json") + require.NoError(t, err) + + mux.HandleFunc("/r/testsubreddit/api/flairselector", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("name", "testuser") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + + fmt.Fprint(w, blob) + }) + + choices, current, _, err := client.Flair.ChoicesOf(ctx, "testsubreddit", "testuser") + require.NoError(t, err) + require.Equal(t, expectedFlairChoices, choices) + require.Equal(t, expectedFlairChoice, current) +} + +func TestFlairService_ChoicesForPost(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + blob, err := readFileContents("../testdata/flair/choices.json") + require.NoError(t, err) + + mux.HandleFunc("/api/flairselector", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("link", "t3_123") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + + fmt.Fprint(w, blob) + }) + + choices, current, _, err := client.Flair.ChoicesForPost(ctx, "t3_123") + require.NoError(t, err) + require.Equal(t, expectedFlairChoices, choices) + require.Equal(t, expectedFlairChoice, current) +} + +func TestFlairService_ChoicesForNewPost(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + blob, err := readFileContents("../testdata/flair/choices.json") + require.NoError(t, err) + + mux.HandleFunc("/r/testsubreddit/api/flairselector", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("is_newlink", "true") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + + fmt.Fprint(w, blob) + }) + + choices, _, err := client.Flair.ChoicesForNewPost(ctx, "testsubreddit") + require.NoError(t, err) + require.Equal(t, expectedFlairChoices, choices) +} diff --git a/testdata/flair/choices.json b/testdata/flair/choices.json new file mode 100644 index 0000000..7295aab --- /dev/null +++ b/testdata/flair/choices.json @@ -0,0 +1,38 @@ +{ + "current": { + "flair_css_class": "", + "flair_template_id": "03dc6ea8-40e9-11e7-8abb-0eb85aed0bce", + "flair_text": "Other API Wrapper", + "flair_position": "left" + }, + "choices": [ + { + "flair_css_class": "", + "flair_template_id": "c4edd5ce-40e8-11e7-b814-0ef91bd65558", + "flair_text_editable": false, + "flair_position": "left", + "flair_text": "Reddit API" + }, + { + "flair_css_class": "", + "flair_template_id": "49bb3d06-0dad-11e7-b897-0e42c2400b7a", + "flair_text_editable": false, + "flair_position": "left", + "flair_text": "PRAW" + }, + { + "flair_css_class": "", + "flair_template_id": "f1905376-40e9-11e7-a0dc-0e2f53ef3712", + "flair_text_editable": false, + "flair_position": "left", + "flair_text": "snoowrap" + }, + { + "flair_css_class": "", + "flair_template_id": "03dc6ea8-40e9-11e7-8abb-0eb85aed0bce", + "flair_text_editable": false, + "flair_position": "left", + "flair_text": "Other API Wrapper" + } + ] +}