Create, update, and reorder flair templates
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
parent
d72022d252
commit
34c2559707
3 changed files with 296 additions and 1 deletions
130
reddit/flair.go
130
reddit/flair.go
|
@ -40,7 +40,7 @@ type FlairSummary struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigureFlairRequest represents a request to configure a subreddit's flair settings.
|
// ConfigureFlairRequest represents a request to configure a subreddit's flair settings.
|
||||||
// Not setting an attribute can have unexpected side effects.
|
// Not setting an attribute can have unexpected side effects, so assign every one just in case.
|
||||||
type ConfigureFlairRequest struct {
|
type ConfigureFlairRequest struct {
|
||||||
// Enable user flair in the subreddit.
|
// Enable user flair in the subreddit.
|
||||||
UserFlairEnabled *bool `url:"flair_enabled,omitempty"`
|
UserFlairEnabled *bool `url:"flair_enabled,omitempty"`
|
||||||
|
@ -48,12 +48,60 @@ type ConfigureFlairRequest struct {
|
||||||
UserFlairPosition string `url:"flair_position,omitempty"`
|
UserFlairPosition string `url:"flair_position,omitempty"`
|
||||||
// Allow users to assign their own flair.
|
// Allow users to assign their own flair.
|
||||||
UserFlairSelfAssignEnabled *bool `url:"flair_self_assign_enabled,omitempty"`
|
UserFlairSelfAssignEnabled *bool `url:"flair_self_assign_enabled,omitempty"`
|
||||||
|
|
||||||
// One of: none, left, right.
|
// One of: none, left, right.
|
||||||
PostFlairPosition string `url:"link_flair_position,omitempty"`
|
PostFlairPosition string `url:"link_flair_position,omitempty"`
|
||||||
// Allow submitters to assign their own post flair.
|
// Allow submitters to assign their own post flair.
|
||||||
PostFlairSelfAssignEnabled *bool `url:"link_flair_self_assign_enabled,omitempty"`
|
PostFlairSelfAssignEnabled *bool `url:"link_flair_self_assign_enabled,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FlairTemplateCreateOrUpdateRequest represents a request to create/update a flair template.
|
||||||
|
// Not setting an attribute can have unexpected side effects, so assign every one just in case.
|
||||||
|
type FlairTemplateCreateOrUpdateRequest struct {
|
||||||
|
// The id of the template. Only provide this if it's an update request.
|
||||||
|
// If provided and it's not a valid id, the template will be created.
|
||||||
|
ID string `url:"flair_template_id,omitempty"`
|
||||||
|
|
||||||
|
// One of: all, emoji, text.
|
||||||
|
AllowableContent string `url:"allowable_content,omitempty"`
|
||||||
|
// No longer than 64 characters.
|
||||||
|
Text string `url:"text,omitempty"`
|
||||||
|
// One of: light, dark.
|
||||||
|
TextColor string `url:"text_color,omitempty"`
|
||||||
|
// Allow user to edit the text of the flair.
|
||||||
|
TextEditable *bool `url:"text_editable,omitempty"`
|
||||||
|
|
||||||
|
ModOnly *bool `url:"mod_only,omitempty"`
|
||||||
|
|
||||||
|
// Between 1 and 10 (inclusive). Default: 10.
|
||||||
|
MaxEmojis *int `url:"max_emojis,omitempty"`
|
||||||
|
|
||||||
|
// One of: none, transparent, 6-digit rgb hex color, e.g. #AABBCC.
|
||||||
|
BackgroundColor string `url:"background_color,omitempty"`
|
||||||
|
CSSClass string `url:"css_class,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlairTemplate is a generic flair structure that can users can use next to their username
|
||||||
|
// or posts in a subreddit.
|
||||||
|
type FlairTemplate struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
// USER_FLAIR (for users) or LINK_FLAIR (for posts).
|
||||||
|
Type string `json:"flairType"`
|
||||||
|
ModOnly bool `json:"modOnly"`
|
||||||
|
|
||||||
|
AllowableContent string `json:"allowableContent"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
TextType string `json:"type"`
|
||||||
|
TextColor string `json:"textColor"`
|
||||||
|
TextEditable bool `json:"textEditable"`
|
||||||
|
RichText []map[string]string `json:"richtext"`
|
||||||
|
|
||||||
|
OverrideCSS bool `json:"overrideCss"`
|
||||||
|
MaxEmojis int `json:"maxEmojis"`
|
||||||
|
BackgroundColor string `json:"backgroundColor"`
|
||||||
|
CSSClass string `json:"cssClass"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserFlairs returns the user flairs from the subreddit.
|
// GetUserFlairs returns the user flairs from the subreddit.
|
||||||
func (s *FlairService) GetUserFlairs(ctx context.Context, subreddit string) ([]*Flair, *Response, error) {
|
func (s *FlairService) GetUserFlairs(ctx context.Context, subreddit string) ([]*Flair, *Response, error) {
|
||||||
path := fmt.Sprintf("r/%s/api/user_flair_v2", subreddit)
|
path := fmt.Sprintf("r/%s/api/user_flair_v2", subreddit)
|
||||||
|
@ -164,6 +212,66 @@ func (s *FlairService) Disable(ctx context.Context, subreddit string) (*Response
|
||||||
return s.client.Do(ctx, req, nil)
|
return s.client.Do(ctx, req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpsertUserTemplate creates a user flair template, or updates it if the request.ID is valid.
|
||||||
|
// It returns the created/updated flair template.
|
||||||
|
func (s *FlairService) UpsertUserTemplate(ctx context.Context, subreddit string, request *FlairTemplateCreateOrUpdateRequest) (*FlairTemplate, *Response, error) {
|
||||||
|
if request == nil {
|
||||||
|
return nil, nil, errors.New("request: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("r/%s/api/flairtemplate_v2", subreddit)
|
||||||
|
|
||||||
|
form, err := query.Values(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
form.Set("api_type", "json")
|
||||||
|
form.Set("flair_type", "USER_FLAIR")
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(FlairTemplate)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return root, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpsertPostTemplate creates a post flair template, or updates it if the request.ID is valid.
|
||||||
|
// It returns the created/updated flair template.
|
||||||
|
func (s *FlairService) UpsertPostTemplate(ctx context.Context, subreddit string, request *FlairTemplateCreateOrUpdateRequest) (*FlairTemplate, *Response, error) {
|
||||||
|
if request == nil {
|
||||||
|
return nil, nil, errors.New("request: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("r/%s/api/flairtemplate_v2", subreddit)
|
||||||
|
|
||||||
|
form, err := query.Values(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
form.Set("api_type", "json")
|
||||||
|
form.Set("flair_type", "LINK_FLAIR")
|
||||||
|
|
||||||
|
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := new(FlairTemplate)
|
||||||
|
resp, err := s.client.Do(ctx, req, root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return root, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the flair of the user.
|
// Delete the flair of the user.
|
||||||
func (s *FlairService) Delete(ctx context.Context, subreddit, username string) (*Response, error) {
|
func (s *FlairService) Delete(ctx context.Context, subreddit, username string) (*Response, error) {
|
||||||
path := fmt.Sprintf("r/%s/api/deleteflair", subreddit)
|
path := fmt.Sprintf("r/%s/api/deleteflair", subreddit)
|
||||||
|
@ -227,3 +335,23 @@ func (s *FlairService) DeleteAllPostTemplates(ctx context.Context, subreddit str
|
||||||
|
|
||||||
return s.client.Do(ctx, req, nil)
|
return s.client.Do(ctx, req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReorderUserTemplates reorders the user flair templates in the order provided in the slice.
|
||||||
|
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.NewRequest(http.MethodPatch, path, ids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReorderPostTemplates reorders the post flair templates in the order provided in the slice.
|
||||||
|
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.NewRequest(http.MethodPatch, path, ids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package reddit
|
package reddit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -62,6 +63,26 @@ var expectedListUserFlairs = []*FlairSummary{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var expectedFlairTemplate = &FlairTemplate{
|
||||||
|
ID: "be0a6110-f23c-11ea-862f-0e08890d7323",
|
||||||
|
Type: "LINK_FLAIR",
|
||||||
|
ModOnly: false,
|
||||||
|
|
||||||
|
AllowableContent: "all",
|
||||||
|
Text: "lol",
|
||||||
|
TextType: "richtext",
|
||||||
|
TextColor: "dark",
|
||||||
|
TextEditable: false,
|
||||||
|
RichText: []map[string]string{
|
||||||
|
{"e": "text", "t": "lol"},
|
||||||
|
},
|
||||||
|
|
||||||
|
OverrideCSS: false,
|
||||||
|
MaxEmojis: 1,
|
||||||
|
BackgroundColor: "#fafafa",
|
||||||
|
CSSClass: "",
|
||||||
|
}
|
||||||
|
|
||||||
func TestFlairService_GetUserFlairs(t *testing.T) {
|
func TestFlairService_GetUserFlairs(t *testing.T) {
|
||||||
client, mux, teardown := setup()
|
client, mux, teardown := setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
@ -186,6 +207,98 @@ func TestFlairService_Disable(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlairService_UpsertUserTemplate(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
blob, err := readFileContents("../testdata/flair/flair-template.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/api/flairtemplate_v2", 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_type", "USER_FLAIR")
|
||||||
|
form.Set("allowable_content", "all")
|
||||||
|
form.Set("text", "testtext")
|
||||||
|
form.Set("text_color", "dark")
|
||||||
|
form.Set("text_editable", "false")
|
||||||
|
form.Set("mod_only", "true")
|
||||||
|
form.Set("max_emojis", "5")
|
||||||
|
form.Set("background_color", "transparent")
|
||||||
|
form.Set("css_class", "testclass")
|
||||||
|
|
||||||
|
err := r.ParseForm()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, form, r.PostForm)
|
||||||
|
|
||||||
|
fmt.Fprint(w, blob)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, _, err = client.Flair.UpsertUserTemplate(ctx, "testsubreddit", nil)
|
||||||
|
require.EqualError(t, err, "request: cannot be nil")
|
||||||
|
|
||||||
|
flairTemplate, _, err := client.Flair.UpsertUserTemplate(ctx, "testsubreddit", &FlairTemplateCreateOrUpdateRequest{
|
||||||
|
AllowableContent: "all",
|
||||||
|
ModOnly: Bool(true),
|
||||||
|
Text: "testtext",
|
||||||
|
TextColor: "dark",
|
||||||
|
TextEditable: Bool(false),
|
||||||
|
MaxEmojis: Int(5),
|
||||||
|
BackgroundColor: "transparent",
|
||||||
|
CSSClass: "testclass",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expectedFlairTemplate, flairTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFlairService_UpsertPostTemplate(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
blob, err := readFileContents("../testdata/flair/flair-template.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/api/flairtemplate_v2", 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_type", "LINK_FLAIR")
|
||||||
|
form.Set("flair_template_id", "testid")
|
||||||
|
form.Set("allowable_content", "text")
|
||||||
|
form.Set("text", "testtext")
|
||||||
|
form.Set("text_color", "light")
|
||||||
|
form.Set("text_editable", "true")
|
||||||
|
form.Set("mod_only", "false")
|
||||||
|
form.Set("background_color", "#fafafa")
|
||||||
|
form.Set("css_class", "testclass")
|
||||||
|
|
||||||
|
err := r.ParseForm()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, form, r.PostForm)
|
||||||
|
|
||||||
|
fmt.Fprint(w, blob)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, _, err = client.Flair.UpsertPostTemplate(ctx, "testsubreddit", nil)
|
||||||
|
require.EqualError(t, err, "request: cannot be nil")
|
||||||
|
|
||||||
|
flairTemplate, _, err := client.Flair.UpsertPostTemplate(ctx, "testsubreddit", &FlairTemplateCreateOrUpdateRequest{
|
||||||
|
ID: "testid",
|
||||||
|
AllowableContent: "text",
|
||||||
|
ModOnly: Bool(false),
|
||||||
|
Text: "testtext",
|
||||||
|
TextColor: "light",
|
||||||
|
TextEditable: Bool(true),
|
||||||
|
BackgroundColor: "#fafafa",
|
||||||
|
CSSClass: "testclass",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expectedFlairTemplate, flairTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFlairService_Delete(t *testing.T) {
|
func TestFlairService_Delete(t *testing.T) {
|
||||||
client, mux, teardown := setup()
|
client, mux, teardown := setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
@ -265,3 +378,37 @@ func TestFlairService_DeleteAllPostTemplates(t *testing.T) {
|
||||||
_, err := client.Flair.DeleteAllPostTemplates(ctx, "testsubreddit")
|
_, err := client.Flair.DeleteAllPostTemplates(ctx, "testsubreddit")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlairService_ReorderUserTemplates(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/api/v1/testsubreddit/flair_template_order/USER_FLAIR", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodPatch, r.Method)
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
err := json.NewDecoder(r.Body).Decode(&ids)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, []string{"test1", "test2", "test3", "test4"}, ids)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Flair.ReorderUserTemplates(ctx, "testsubreddit", []string{"test1", "test2", "test3", "test4"})
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFlairService_ReorderPostTemplates(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
mux.HandleFunc("/api/v1/testsubreddit/flair_template_order/LINK_FLAIR", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodPatch, r.Method)
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
err := json.NewDecoder(r.Body).Decode(&ids)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, []string{"test1", "test2", "test3", "test4"}, ids)
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := client.Flair.ReorderPostTemplates(ctx, "testsubreddit", []string{"test1", "test2", "test3", "test4"})
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
20
testdata/flair/flair-template.json
vendored
Normal file
20
testdata/flair/flair-template.json
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"text": "lol",
|
||||||
|
"allowableContent": "all",
|
||||||
|
"modOnly": false,
|
||||||
|
"cssClass": "",
|
||||||
|
"id": "be0a6110-f23c-11ea-862f-0e08890d7323",
|
||||||
|
"textEditable": false,
|
||||||
|
"overrideCss": false,
|
||||||
|
"richtext": [
|
||||||
|
{
|
||||||
|
"e": "text",
|
||||||
|
"t": "lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"maxEmojis": 1,
|
||||||
|
"flairType": "LINK_FLAIR",
|
||||||
|
"backgroundColor": "#fafafa",
|
||||||
|
"textColor": "dark",
|
||||||
|
"type": "richtext"
|
||||||
|
}
|
Loading…
Reference in a new issue