Add more methods to moderation service

Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
Vartan Benohanian 2020-07-13 19:52:39 -04:00
parent a0b06ed651
commit 838db037b9
3 changed files with 255 additions and 7 deletions

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"net/url"
)
// ModerationService handles communication with the moderation
@ -37,6 +38,7 @@ type ModAction struct {
}
// GetActions gets a list of moderator actions on a subreddit.
// By default, the limit parameter is 25; max is 500.
func (s *ModerationService) GetActions(ctx context.Context, subreddit string, opts ...SearchOptionSetter) (*ModActions, *Response, error) {
form := newSearchOptions(opts...)
@ -57,11 +59,110 @@ func (s *ModerationService) GetActions(ctx context.Context, subreddit string, op
return root.getModeratorActions(), resp, nil
}
/*
type rootTrophyListing struct {
Kind string `json:"kind,omitempty"`
Data struct {
Trophies []rootTrophy `json:"trophies"`
} `json:"data"`
// GetActionsByType gets a list of moderator actions of the specified type on a subreddit.
// By default, the limit parameter is 25; max is 500.
// The type should be one of: banuser, unbanuser, spamlink, removelink, approvelink, spamcomment,
// removecomment, approvecomment, addmoderator, showcomment, invitemoderator, uninvitemoderator,
// acceptmoderatorinvite, removemoderator, addcontributor, removecontributor, editsettings, editflair,
// distinguish, marknsfw, wikibanned, wikicontributor, wikiunbanned, wikipagelisted, removewikicontributor,
// wikirevise, wikipermlevel, ignorereports, unignorereports, setpermissions, setsuggestedsort, sticky,
// unsticky, setcontestmode, unsetcontestmode, lock, unlock, muteuser, unmuteuser, createrule, editrule,
// reorderrules, deleterule, spoiler, unspoiler, modmail_enrollment, community_styling, community_widgets,
// markoriginalcontent, collections, events, hidden_award, add_community_topics, remove_community_topics,
// create_scheduled_post, edit_scheduled_post, delete_scheduled_post, submit_scheduled_post, edit_post_requirements
func (s *ModerationService) GetActionsByType(ctx context.Context, subreddit string, actionType string, opts ...SearchOptionSetter) (*ModActions, *Response, error) {
opts = append(opts, setType(actionType))
return s.GetActions(ctx, subreddit, opts...)
}
// AcceptInvite accepts a pending invite to moderate the specified subreddit.
func (s *ModerationService) AcceptInvite(ctx context.Context, subreddit string) (*Response, error) {
path := fmt.Sprintf("r/%s/api/accept_moderator_invite", subreddit)
form := url.Values{}
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)
}
// Approve approves a post or comment via its full ID.
func (s *ModerationService) Approve(ctx context.Context, id string) (*Response, error) {
path := "api/approve"
form := url.Values{}
form.Set("id", id)
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// Remove removes a post, comment or modmail message via its full ID.
func (s *ModerationService) Remove(ctx context.Context, id string) (*Response, error) {
path := "api/remove"
form := url.Values{}
form.Set("id", id)
form.Set("spam", "false")
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// RemoveSpam removes a post, comment or modmail message via its full ID and marks it as spam.
func (s *ModerationService) RemoveSpam(ctx context.Context, id string) (*Response, error) {
path := "api/remove"
form := url.Values{}
form.Set("id", id)
form.Set("spam", "true")
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// Leave abdicates your moderator status in a subreddit via its full ID.
func (s *ModerationService) Leave(ctx context.Context, subredditID string) (*Response, error) {
path := "api/leavemoderator"
form := url.Values{}
form.Set("id", subredditID)
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// LeaveContributor abdicates your approved user status in a subreddit via its full ID.
func (s *ModerationService) LeaveContributor(ctx context.Context, subredditID string) (*Response, error) {
path := "api/leavecontributor"
form := url.Values{}
form.Set("id", subredditID)
req, err := s.client.NewRequestWithForm(http.MethodPost, path, form)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
*/

View file

@ -3,6 +3,7 @@ package reddit
import (
"fmt"
"net/http"
"net/url"
"testing"
"time"
@ -63,3 +64,147 @@ func TestModerationService_GetActions(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, expectedModActionsResult, result)
}
func TestModerationService_GetActionsByType(t *testing.T) {
setup()
defer teardown()
blob := readFileContents(t, "testdata/moderation/actions.json")
mux.HandleFunc("/r/testsubreddit/about/log", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method)
form := url.Values{}
form.Set("type", "testtype")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
fmt.Fprint(w, blob)
})
result, _, err := client.Moderation.GetActionsByType(ctx, "testsubreddit", "testtype")
assert.NoError(t, err)
assert.Equal(t, expectedModActionsResult, result)
}
func TestModerationService_AcceptInvite(t *testing.T) {
setup()
defer teardown()
blob := readFileContents(t, "testdata/moderation/actions.json")
mux.HandleFunc("/r/testsubreddit/api/accept_moderator_invite", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
form := url.Values{}
form.Set("api_type", "json")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
fmt.Fprint(w, blob)
})
_, err := client.Moderation.AcceptInvite(ctx, "testsubreddit")
assert.NoError(t, err)
}
func TestModerationService_Approve(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/api/approve", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
form := url.Values{}
form.Set("id", "t3_test")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
})
_, err := client.Moderation.Approve(ctx, "t3_test")
assert.NoError(t, err)
}
func TestModerationService_Remove(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/api/remove", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
form := url.Values{}
form.Set("id", "t3_test")
form.Set("spam", "false")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
})
_, err := client.Moderation.Remove(ctx, "t3_test")
assert.NoError(t, err)
}
func TestModerationService_RemoveSpam(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/api/remove", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
form := url.Values{}
form.Set("id", "t3_test")
form.Set("spam", "true")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
})
_, err := client.Moderation.RemoveSpam(ctx, "t3_test")
assert.NoError(t, err)
}
func TestModerationService_Leave(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/api/leavemoderator", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
form := url.Values{}
form.Set("id", "t5_test")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
})
_, err := client.Moderation.Leave(ctx, "t5_test")
assert.NoError(t, err)
}
func TestModerationService_LeaveContributor(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/api/leavecontributor", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
form := url.Values{}
form.Set("id", "t5_test")
err := r.ParseForm()
assert.NoError(t, err)
assert.Equal(t, form, r.Form)
})
_, err := client.Moderation.LeaveContributor(ctx, "t5_test")
assert.NoError(t, err)
}

View file

@ -68,6 +68,8 @@ func SetTimespan(v Timespan) SearchOptionSetter {
}
// setType sets the type option.
// It could be user, link, sr (subreddit).
// For mod actions, it's for the type of action (e.g. "banuser", "spamcomment").
func setType(v string) SearchOptionSetter {
return func(opts url.Values) {
opts.Set("type", v)