diff --git a/reddit/flair.go b/reddit/flair.go index 3bfbc57..560385b 100644 --- a/reddit/flair.go +++ b/reddit/flair.go @@ -2,8 +2,12 @@ package reddit import ( "context" + "errors" "fmt" "net/http" + "net/url" + + "github.com/google/go-querystring/query" ) // FlairService handles communication with the flair @@ -35,6 +39,21 @@ type FlairSummary struct { CSSClass string `json:"flair_css_class,omitempty"` } +// ConfigureFlairRequest represents a request to configure a subreddit's flair settings. +// Not setting an attribute can have unexpected side effects. +type ConfigureFlairRequest struct { + // Enable user flair in the subreddit. + UserFlairEnabled *bool `url:"flair_enabled,omitempty"` + // One of: left, right. + UserFlairPosition string `url:"flair_position,omitempty"` + // Allow users to assign their own flair. + UserFlairSelfAssignEnabled *bool `url:"flair_self_assign_enabled,omitempty"` + // One of: none, left, right. + PostFlairPosition string `url:"link_flair_position,omitempty"` + // Allow submitters to assign their own post flair. + PostFlairSelfAssignEnabled *bool `url:"link_flair_self_assign_enabled,omitempty"` +} + // GetUserFlairs returns the user flairs from the subreddit. func (s *FlairService) GetUserFlairs(ctx context.Context, subreddit string) ([]*Flair, *Response, error) { path := fmt.Sprintf("r/%s/api/user_flair_v2", subreddit) @@ -80,13 +99,67 @@ func (s *FlairService) ListUserFlairs(ctx context.Context, subreddit string) ([] return nil, nil, err } - var root struct { + root := new(struct { UserFlairs []*FlairSummary `json:"users"` - } - resp, err := s.client.Do(ctx, req, &root) + }) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } return root.UserFlairs, resp, nil } + +// Configure the subreddit's flair settings. +func (s *FlairService) Configure(ctx context.Context, subreddit string, request *ConfigureFlairRequest) (*Response, error) { + if request == nil { + return nil, errors.New("request: cannot be nil") + } + + path := fmt.Sprintf("r/%s/api/flairconfig", subreddit) + + form, err := query.Values(request) + if err != nil { + return nil, err + } + form.Set("api_type", "json") + + req, err := s.client.NewRequestWithForm(http.MethodPost, path, form) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// Enable your flair in the subreddit. +func (s *FlairService) Enable(ctx context.Context, subreddit string) (*Response, error) { + path := fmt.Sprintf("r/%s/api/setflairenabled", subreddit) + + form := url.Values{} + form.Set("api_type", "json") + form.Set("flair_enabled", "true") + + req, err := s.client.NewRequestWithForm(http.MethodPost, path, form) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} + +// Disable your flair in the subreddit. +func (s *FlairService) Disable(ctx context.Context, subreddit string) (*Response, error) { + path := fmt.Sprintf("r/%s/api/setflairenabled", subreddit) + + form := url.Values{} + form.Set("api_type", "json") + form.Set("flair_enabled", "false") + + req, err := s.client.NewRequestWithForm(http.MethodPost, path, form) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/reddit/flair_test.go b/reddit/flair_test.go index d0fbfe7..337b494 100644 --- a/reddit/flair_test.go +++ b/reddit/flair_test.go @@ -3,6 +3,7 @@ package reddit import ( "fmt" "net/http" + "net/url" "testing" "github.com/stretchr/testify/require" @@ -111,3 +112,76 @@ func TestFlairService_ListUserFlairs(t *testing.T) { require.NoError(t, err) require.Equal(t, expectedListUserFlairs, userFlairs) } + +func TestFlairService_Configure(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/r/testsubreddit/api/flairconfig", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("api_type", "json") + form.Set("flair_enabled", "true") + form.Set("flair_position", "right") + form.Set("flair_self_assign_enabled", "false") + form.Set("link_flair_position", "left") + form.Set("link_flair_self_assign_enabled", "false") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + }) + + _, err := client.Flair.Configure(ctx, "testsubreddit", nil) + require.EqualError(t, err, "request: cannot be nil") + + _, err = client.Flair.Configure(ctx, "testsubreddit", &ConfigureFlairRequest{ + UserFlairEnabled: Bool(true), + UserFlairPosition: "right", + UserFlairSelfAssignEnabled: Bool(false), + PostFlairPosition: "left", + PostFlairSelfAssignEnabled: Bool(false), + }) + require.NoError(t, err) +} + +func TestFlairService_Enable(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/r/testsubreddit/api/setflairenabled", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("api_type", "json") + form.Set("flair_enabled", "true") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + }) + + _, err := client.Flair.Enable(ctx, "testsubreddit") + require.NoError(t, err) +} + +func TestFlairService_Disable(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + mux.HandleFunc("/r/testsubreddit/api/setflairenabled", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPost, r.Method) + + form := url.Values{} + form.Set("api_type", "json") + form.Set("flair_enabled", "false") + + err := r.ParseForm() + require.NoError(t, err) + require.Equal(t, form, r.PostForm) + }) + + _, err := client.Flair.Disable(ctx, "testsubreddit") + require.NoError(t, err) +} diff --git a/reddit/reddit.go b/reddit/reddit.go index 5d546a9..5e603d4 100644 --- a/reddit/reddit.go +++ b/reddit/reddit.go @@ -218,7 +218,7 @@ func (c *Client) UserAgent() string { } // NewRequest creates an API request with a JSON body. -// The path is the relative URL which will be resolves to the BaseURL of the Client. +// The path is the relative URL which will be resolved to the BaseURL of the Client. // It should always be specified without a preceding slash. func (c *Client) NewRequest(method string, path string, body interface{}) (*http.Request, error) { u, err := c.BaseURL.Parse(path)