Replace references to "link" by "post"

Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
Vartan Benohanian
2020-06-22 21:52:34 -04:00
parent b70253ec48
commit f649216b9d
15 changed files with 191 additions and 221 deletions
+12 -15
View File
@@ -8,7 +8,7 @@ import (
) )
// CommentService handles communication with the comment // CommentService handles communication with the comment
// related methods of the Reddit API // related methods of the Reddit API.
type CommentService interface { type CommentService interface {
Submit(ctx context.Context, id string, text string) (*Comment, *Response, error) Submit(ctx context.Context, id string, text string) (*Comment, *Response, error)
Edit(ctx context.Context, id string, text string) (*Comment, *Response, error) Edit(ctx context.Context, id string, text string) (*Comment, *Response, error)
@@ -18,7 +18,7 @@ type CommentService interface {
Unsave(ctx context.Context, id string) (*Response, error) Unsave(ctx context.Context, id string) (*Response, error)
} }
// CommentServiceOp implements the CommentService interface // CommentServiceOp implements the CommentService interface.
type CommentServiceOp struct { type CommentServiceOp struct {
client *Client client *Client
} }
@@ -29,7 +29,7 @@ func (s *CommentServiceOp) isCommentID(id string) bool {
return strings.HasPrefix(id, kindComment+"_") return strings.HasPrefix(id, kindComment+"_")
} }
// Submit submits a comment as a reply to a link or to another comment // Submit submits a comment as a reply to a post or to another comment.
func (s *CommentServiceOp) Submit(ctx context.Context, id string, text string) (*Comment, *Response, error) { func (s *CommentServiceOp) Submit(ctx context.Context, id string, text string) (*Comment, *Response, error) {
path := "api/comment" path := "api/comment"
@@ -53,11 +53,11 @@ func (s *CommentServiceOp) Submit(ctx context.Context, id string, text string) (
return root, resp, nil return root, resp, nil
} }
// Edit edits the comment with the id provided // Edit edits the comment with the id provided.
// todo: don't forget to do this for links (i.e. posts) // todo: don't forget to do this for posts
func (s *CommentServiceOp) Edit(ctx context.Context, id string, text string) (*Comment, *Response, error) { func (s *CommentServiceOp) Edit(ctx context.Context, id string, text string) (*Comment, *Response, error) {
if !s.isCommentID(id) { if !s.isCommentID(id) {
return nil, nil, fmt.Errorf("must provide comment id (starting with t1_); id provided: %q", id) return nil, nil, fmt.Errorf("must provide comment id (starting with %s_); id provided: %q", kindComment, id)
} }
path := "api/editusertext" path := "api/editusertext"
@@ -82,12 +82,11 @@ func (s *CommentServiceOp) Edit(ctx context.Context, id string, text string) (*C
return root, resp, nil return root, resp, nil
} }
// Delete deletes a comment via the id // Delete deletes a comment via the id.
// todo: don't forget to do this for links (i.e. posts) // todo: don't forget to do this for posts.
// Seems like this always returns {} as a response, no matter if an id is even provided
func (s *CommentServiceOp) Delete(ctx context.Context, id string) (*Response, error) { func (s *CommentServiceOp) Delete(ctx context.Context, id string) (*Response, error) {
if !s.isCommentID(id) { if !s.isCommentID(id) {
return nil, fmt.Errorf("must provide comment id (starting with t1_); id provided: %q", id) return nil, fmt.Errorf("must provide comment id (starting with %s_); id provided: %q", kindComment, id)
} }
path := "api/del" path := "api/del"
@@ -108,11 +107,10 @@ func (s *CommentServiceOp) Delete(ctx context.Context, id string) (*Response, er
return resp, nil return resp, nil
} }
// Save saves a comment // Save saves a comment.
// Seems like this just returns {} on success
func (s *CommentServiceOp) Save(ctx context.Context, id string) (*Response, error) { func (s *CommentServiceOp) Save(ctx context.Context, id string) (*Response, error) {
if !s.isCommentID(id) { if !s.isCommentID(id) {
return nil, fmt.Errorf("must provide comment id (starting with t1_); id provided: %q", id) return nil, fmt.Errorf("must provide comment id (starting with %s_); id provided: %q", kindComment, id)
} }
path := "api/save" path := "api/save"
@@ -133,8 +131,7 @@ func (s *CommentServiceOp) Save(ctx context.Context, id string) (*Response, erro
return resp, nil return resp, nil
} }
// Unsave unsaves a comment // Unsave unsaves a comment.
// Seems like this just returns {} on success
func (s *CommentServiceOp) Unsave(ctx context.Context, id string) (*Response, error) { func (s *CommentServiceOp) Unsave(ctx context.Context, id string) (*Response, error) {
if !s.isCommentID(id) { if !s.isCommentID(id) {
return nil, fmt.Errorf("must provide comment id (starting with t1_); id provided: %q", id) return nil, fmt.Errorf("must provide comment id (starting with t1_); id provided: %q", id)
+3 -2
View File
@@ -32,9 +32,10 @@ var expectedCommentSubmitOrEdit = &Comment{
Controversiality: 0, Controversiality: 0,
Created: &Timestamp{time.Date(2020, 4, 29, 0, 9, 47, 0, time.UTC)}, Created: &Timestamp{time.Date(2020, 4, 29, 0, 9, 47, 0, time.UTC)},
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)}, // todo: this should just be nil
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
LinkID: "t3_link1", PostID: "t3_link1",
} }
func TestCommentServiceOp_Submit(t *testing.T) { func TestCommentServiceOp_Submit(t *testing.T) {
+2 -2
View File
@@ -93,8 +93,8 @@ type Client struct {
Comment CommentService Comment CommentService
Flair FlairService Flair FlairService
Link LinkService
Listings ListingsService Listings ListingsService
Post PostService
Search SearchService Search SearchService
Subreddit SubredditService Subreddit SubredditService
User UserService User UserService
@@ -122,8 +122,8 @@ func newClient(httpClient *http.Client) *Client {
c.Comment = &CommentServiceOp{client: c} c.Comment = &CommentServiceOp{client: c}
c.Flair = &FlairServiceOp{client: c} c.Flair = &FlairServiceOp{client: c}
c.Link = &LinkServiceOp{client: c}
c.Listings = &ListingsServiceOp{client: c} c.Listings = &ListingsServiceOp{client: c}
c.Post = &PostServiceOp{client: c}
c.Search = &SearchServiceOp{client: c} c.Search = &SearchServiceOp{client: c}
c.Subreddit = &SubredditServiceOp{client: c} c.Subreddit = &SubredditServiceOp{client: c}
c.User = &UserServiceOp{client: c} c.User = &UserServiceOp{client: c}
+1 -1
View File
@@ -68,8 +68,8 @@ func testClientServices(t *testing.T, c *Client) {
services := []string{ services := []string{
"Comment", "Comment",
"Flair", "Flair",
"Link",
"Listings", "Listings",
"Post",
"Subreddit", "Subreddit",
"User", "User",
"Vote", "Vote",
+16 -16
View File
@@ -8,23 +8,23 @@ import (
"strings" "strings"
) )
// ListingsService handles communication with the link (post) // ListingsService handles communication with the post
// related methods of the Reddit API // related methods of the Reddit API.
type ListingsService interface { type ListingsService interface {
Get(ctx context.Context, ids ...string) ([]Comment, []Link, []Subreddit, *Response, error) Get(ctx context.Context, ids ...string) ([]Post, []Comment, []Subreddit, *Response, error)
GetLinks(ctx context.Context, ids ...string) ([]Link, *Response, error) GetPosts(ctx context.Context, ids ...string) ([]Post, *Response, error)
GetLink(ctx context.Context, id string) (*LinkAndComments, *Response, error) GetPost(ctx context.Context, id string) (*PostAndComments, *Response, error)
} }
// ListingsServiceOp implements the Vote interface // ListingsServiceOp implements the Vote interface.
type ListingsServiceOp struct { type ListingsServiceOp struct {
client *Client client *Client
} }
var _ ListingsService = &ListingsServiceOp{} var _ ListingsService = &ListingsServiceOp{}
// Get returns comments, links, and subreddits from their IDs // Get returns posts, comments, and subreddits from their IDs.
func (s *ListingsServiceOp) Get(ctx context.Context, ids ...string) ([]Comment, []Link, []Subreddit, *Response, error) { func (s *ListingsServiceOp) Get(ctx context.Context, ids ...string) ([]Post, []Comment, []Subreddit, *Response, error) {
type query struct { type query struct {
IDs []string `url:"id,comma"` IDs []string `url:"id,comma"`
} }
@@ -46,15 +46,15 @@ func (s *ListingsServiceOp) Get(ctx context.Context, ids ...string) ([]Comment,
return nil, nil, nil, resp, err return nil, nil, nil, resp, err
} }
posts := root.getPosts().Posts
comments := root.getComments().Comments comments := root.getComments().Comments
links := root.getLinks().Links
subreddits := root.getSubreddits().Subreddits subreddits := root.getSubreddits().Subreddits
return comments, links, subreddits, resp, nil return posts, comments, subreddits, resp, nil
} }
// GetLinks returns links from their full IDs // GetPosts returns posts from their full IDs.
func (s *ListingsServiceOp) GetLinks(ctx context.Context, ids ...string) ([]Link, *Response, error) { func (s *ListingsServiceOp) GetPosts(ctx context.Context, ids ...string) ([]Post, *Response, error) {
if len(ids) == 0 { if len(ids) == 0 {
return nil, nil, errors.New("must provide at least 1 id") return nil, nil, errors.New("must provide at least 1 id")
} }
@@ -71,18 +71,18 @@ func (s *ListingsServiceOp) GetLinks(ctx context.Context, ids ...string) ([]Link
return nil, resp, err return nil, resp, err
} }
return root.getLinks().Links, resp, nil return root.getPosts().Posts, resp, nil
} }
// GetLink returns a link with its comments // GetPost returns a post with its comments.
func (s *ListingsServiceOp) GetLink(ctx context.Context, id string) (*LinkAndComments, *Response, error) { func (s *ListingsServiceOp) GetPost(ctx context.Context, id string) (*PostAndComments, *Response, error) {
path := fmt.Sprintf("comments/%s", id) path := fmt.Sprintf("comments/%s", id)
req, err := s.client.NewRequest(http.MethodGet, path, nil) req, err := s.client.NewRequest(http.MethodGet, path, nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
root := new(LinkAndComments) root := new(PostAndComments)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
+30 -38
View File
@@ -9,9 +9,9 @@ import (
"github.com/google/go-querystring/query" "github.com/google/go-querystring/query"
) )
// LinkService handles communication with the link (post) // PostService handles communication with the link (post)
// related methods of the Reddit API // related methods of the Reddit API.
type LinkService interface { type PostService interface {
SubmitSelf(ctx context.Context, opts SubmitSelfOptions) (*Submitted, *Response, error) SubmitSelf(ctx context.Context, opts SubmitSelfOptions) (*Submitted, *Response, error)
SubmitURL(ctx context.Context, opts SubmitURLOptions) (*Submitted, *Response, error) SubmitURL(ctx context.Context, opts SubmitURLOptions) (*Submitted, *Response, error)
@@ -28,12 +28,12 @@ type LinkService interface {
Unhide(ctx context.Context, ids ...string) (*Response, error) Unhide(ctx context.Context, ids ...string) (*Response, error)
} }
// LinkServiceOp implements the LinkService interface // PostServiceOp implements the PostService interface.
type LinkServiceOp struct { type PostServiceOp struct {
client *Client client *Client
} }
var _ LinkService = &LinkServiceOp{} var _ PostService = &PostServiceOp{}
type submittedLinkRoot struct { type submittedLinkRoot struct {
JSON struct { JSON struct {
@@ -41,14 +41,14 @@ type submittedLinkRoot struct {
} `json:"json"` } `json:"json"`
} }
// Submitted is a newly submitted post on Reddit // Submitted is a newly submitted post on Reddit.
type Submitted struct { type Submitted struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"` FullID string `json:"name,omitempty"`
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
} }
// SubmitSelfOptions are options used for selftext posts // SubmitSelfOptions are options used for selftext posts.
type SubmitSelfOptions struct { type SubmitSelfOptions struct {
Subreddit string `url:"sr,omitempty"` Subreddit string `url:"sr,omitempty"`
Title string `url:"title,omitempty"` Title string `url:"title,omitempty"`
@@ -62,7 +62,7 @@ type SubmitSelfOptions struct {
Spoiler bool `url:"spoiler,omitempty"` Spoiler bool `url:"spoiler,omitempty"`
} }
// SubmitURLOptions are options used for link posts // SubmitURLOptions are options used for link posts.
type SubmitURLOptions struct { type SubmitURLOptions struct {
Subreddit string `url:"sr,omitempty"` Subreddit string `url:"sr,omitempty"`
Title string `url:"title,omitempty"` Title string `url:"title,omitempty"`
@@ -77,8 +77,8 @@ type SubmitURLOptions struct {
Spoiler bool `url:"spoiler,omitempty"` Spoiler bool `url:"spoiler,omitempty"`
} }
// SubmitSelf submits a self text post // SubmitSelf submits a self text post.
func (s *LinkServiceOp) SubmitSelf(ctx context.Context, opts SubmitSelfOptions) (*Submitted, *Response, error) { func (s *PostServiceOp) SubmitSelf(ctx context.Context, opts SubmitSelfOptions) (*Submitted, *Response, error) {
type submit struct { type submit struct {
SubmitSelfOptions SubmitSelfOptions
Kind string `url:"kind,omitempty"` Kind string `url:"kind,omitempty"`
@@ -86,8 +86,8 @@ func (s *LinkServiceOp) SubmitSelf(ctx context.Context, opts SubmitSelfOptions)
return s.submit(ctx, &submit{opts, "self"}) return s.submit(ctx, &submit{opts, "self"})
} }
// SubmitURL submits a link post // SubmitURL submits a link post.
func (s *LinkServiceOp) SubmitURL(ctx context.Context, opts SubmitURLOptions) (*Submitted, *Response, error) { func (s *PostServiceOp) SubmitURL(ctx context.Context, opts SubmitURLOptions) (*Submitted, *Response, error) {
type submit struct { type submit struct {
SubmitURLOptions SubmitURLOptions
Kind string `url:"kind,omitempty"` Kind string `url:"kind,omitempty"`
@@ -95,7 +95,7 @@ func (s *LinkServiceOp) SubmitURL(ctx context.Context, opts SubmitURLOptions) (*
return s.submit(ctx, &submit{opts, "link"}) return s.submit(ctx, &submit{opts, "link"})
} }
func (s *LinkServiceOp) submit(ctx context.Context, v interface{}) (*Submitted, *Response, error) { func (s *PostServiceOp) submit(ctx context.Context, v interface{}) (*Submitted, *Response, error) {
path := "api/submit" path := "api/submit"
form, err := query.Values(v) form, err := query.Values(v)
@@ -118,9 +118,8 @@ func (s *LinkServiceOp) submit(ctx context.Context, v interface{}) (*Submitted,
return root.JSON.Data, resp, nil return root.JSON.Data, resp, nil
} }
// EnableReplies enables inbox replies for a thing created by the client // EnableReplies enables inbox replies for a thing created by the client.
// Always returns {} func (s *PostServiceOp) EnableReplies(ctx context.Context, id string) (*Response, error) {
func (s *LinkServiceOp) EnableReplies(ctx context.Context, id string) (*Response, error) {
path := "api/sendreplies" path := "api/sendreplies"
form := url.Values{} form := url.Values{}
@@ -135,9 +134,8 @@ func (s *LinkServiceOp) EnableReplies(ctx context.Context, id string) (*Response
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// DisableReplies dsables inbox replies for a thing created by the client // DisableReplies dsables inbox replies for a thing created by the client.
// Always returns {} func (s *PostServiceOp) DisableReplies(ctx context.Context, id string) (*Response, error) {
func (s *LinkServiceOp) DisableReplies(ctx context.Context, id string) (*Response, error) {
path := "api/sendreplies" path := "api/sendreplies"
form := url.Values{} form := url.Values{}
@@ -152,9 +150,8 @@ func (s *LinkServiceOp) DisableReplies(ctx context.Context, id string) (*Respons
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// MarkNSFW marks a post as NSFW // MarkNSFW marks a post as NSFW.
// {} on success func (s *PostServiceOp) MarkNSFW(ctx context.Context, id string) (*Response, error) {
func (s *LinkServiceOp) MarkNSFW(ctx context.Context, id string) (*Response, error) {
path := "api/marknsfw" path := "api/marknsfw"
form := url.Values{} form := url.Values{}
@@ -168,9 +165,8 @@ func (s *LinkServiceOp) MarkNSFW(ctx context.Context, id string) (*Response, err
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// UnmarkNSFW unmarks a post as NSFW // UnmarkNSFW unmarks a post as NSFW.
// {} on success func (s *PostServiceOp) UnmarkNSFW(ctx context.Context, id string) (*Response, error) {
func (s *LinkServiceOp) UnmarkNSFW(ctx context.Context, id string) (*Response, error) {
path := "api/unmarknsfw" path := "api/unmarknsfw"
form := url.Values{} form := url.Values{}
@@ -184,9 +180,8 @@ func (s *LinkServiceOp) UnmarkNSFW(ctx context.Context, id string) (*Response, e
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// Spoiler marks a post as a spoiler // Spoiler marks a post as a spoiler.
// {} on success func (s *PostServiceOp) Spoiler(ctx context.Context, id string) (*Response, error) {
func (s *LinkServiceOp) Spoiler(ctx context.Context, id string) (*Response, error) {
path := "api/spoiler" path := "api/spoiler"
form := url.Values{} form := url.Values{}
@@ -200,9 +195,8 @@ func (s *LinkServiceOp) Spoiler(ctx context.Context, id string) (*Response, erro
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// Unspoiler unmarks a post as a spoiler // Unspoiler unmarks a post as a spoiler.
// {} on success func (s *PostServiceOp) Unspoiler(ctx context.Context, id string) (*Response, error) {
func (s *LinkServiceOp) Unspoiler(ctx context.Context, id string) (*Response, error) {
path := "api/unspoiler" path := "api/unspoiler"
form := url.Values{} form := url.Values{}
@@ -216,9 +210,8 @@ func (s *LinkServiceOp) Unspoiler(ctx context.Context, id string) (*Response, er
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// Hide hides links with the specified ids // Hide hides links with the specified ids.
// On successful calls, it just returns {} func (s *PostServiceOp) Hide(ctx context.Context, ids ...string) (*Response, error) {
func (s *LinkServiceOp) Hide(ctx context.Context, ids ...string) (*Response, error) {
if len(ids) == 0 { if len(ids) == 0 {
return nil, errors.New("must provide at least 1 id") return nil, errors.New("must provide at least 1 id")
} }
@@ -236,9 +229,8 @@ func (s *LinkServiceOp) Hide(ctx context.Context, ids ...string) (*Response, err
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// Unhide unhides links with the specified ids // Unhide unhides links with the specified ids.
// On successful calls, it just returns {} func (s *PostServiceOp) Unhide(ctx context.Context, ids ...string) (*Response, error) {
func (s *LinkServiceOp) Unhide(ctx context.Context, ids ...string) (*Response, error) {
if len(ids) == 0 { if len(ids) == 0 {
return nil, errors.New("must provide at least 1 id") return nil, errors.New("must provide at least 1 id")
} }
+6 -6
View File
@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestLinkServiceOp_Hide(t *testing.T) { func TestPostServiceOp_Hide(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
@@ -26,15 +26,15 @@ func TestLinkServiceOp_Hide(t *testing.T) {
fmt.Fprint(w, `{}`) fmt.Fprint(w, `{}`)
}) })
_, err := client.Link.Hide(ctx) _, err := client.Post.Hide(ctx)
assert.EqualError(t, err, "must provide at least 1 id") assert.EqualError(t, err, "must provide at least 1 id")
res, err := client.Link.Hide(ctx, "1", "2", "3") res, err := client.Post.Hide(ctx, "1", "2", "3")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode) assert.Equal(t, http.StatusOK, res.StatusCode)
} }
func TestLinkServiceOp_Unhide(t *testing.T) { func TestPostServiceOp_Unhide(t *testing.T) {
setup() setup()
defer teardown() defer teardown()
@@ -51,10 +51,10 @@ func TestLinkServiceOp_Unhide(t *testing.T) {
fmt.Fprint(w, `{}`) fmt.Fprint(w, `{}`)
}) })
_, err := client.Link.Unhide(ctx) _, err := client.Post.Unhide(ctx)
assert.EqualError(t, err, "must provide at least 1 id") assert.EqualError(t, err, "must provide at least 1 id")
res, err := client.Link.Unhide(ctx, "1", "2", "3") res, err := client.Post.Unhide(ctx, "1", "2", "3")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode) assert.Equal(t, http.StatusOK, res.StatusCode)
} }
+3 -3
View File
@@ -16,7 +16,7 @@ import (
// Note: The "limit" parameter in searches is prone to inconsistent // Note: The "limit" parameter in searches is prone to inconsistent
// behaviour. // behaviour.
type SearchService interface { type SearchService interface {
Posts(ctx context.Context, query string, subreddits []string, opts ...SearchOptionSetter) (*Links, *Response, error) Posts(ctx context.Context, query string, subreddits []string, opts ...SearchOptionSetter) (*Posts, *Response, error)
Subreddits(ctx context.Context, query string, opts ...SearchOptionSetter) (*Subreddits, *Response, error) Subreddits(ctx context.Context, query string, opts ...SearchOptionSetter) (*Subreddits, *Response, error)
Users(ctx context.Context, query string, opts ...SearchOptionSetter) (*Users, *Response, error) Users(ctx context.Context, query string, opts ...SearchOptionSetter) (*Users, *Response, error)
} }
@@ -99,7 +99,7 @@ func setRestrict(opts SearchOptions) {
// Posts searches for posts. // Posts searches for posts.
// If the list of subreddits is empty, the search is run against r/all. // If the list of subreddits is empty, the search is run against r/all.
func (s *SearchServiceOp) Posts(ctx context.Context, query string, subreddits []string, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *SearchServiceOp) Posts(ctx context.Context, query string, subreddits []string, opts ...SearchOptionSetter) (*Posts, *Response, error) {
opts = append(opts, setType("link"), setQuery(query)) opts = append(opts, setType("link"), setQuery(query))
path := "search" path := "search"
@@ -122,7 +122,7 @@ func (s *SearchServiceOp) Posts(ctx context.Context, query string, subreddits []
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
// Subreddits searches for subreddits. // Subreddits searches for subreddits.
+8 -12
View File
@@ -25,8 +25,8 @@ type SubredditService interface {
GetApproved(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) GetApproved(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetModerated(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error) GetModerated(ctx context.Context, opts *ListOptions) (*Subreddits, *Response, error)
GetSticky1(ctx context.Context, subreddit string) (*LinkAndComments, *Response, error) GetSticky1(ctx context.Context, subreddit string) (*PostAndComments, *Response, error)
GetSticky2(ctx context.Context, subreddit string) (*LinkAndComments, *Response, error) GetSticky2(ctx context.Context, subreddit string) (*PostAndComments, *Response, error)
Subscribe(ctx context.Context, subreddits ...string) (*Response, error) Subscribe(ctx context.Context, subreddits ...string) (*Response, error)
SubscribeByID(ctx context.Context, ids ...string) (*Response, error) SubscribeByID(ctx context.Context, ids ...string) (*Response, error)
@@ -126,17 +126,16 @@ func (s *SubredditServiceOp) GetModerated(ctx context.Context, opts *ListOptions
} }
// GetSticky1 returns the first stickied post on a subreddit (if it exists). // GetSticky1 returns the first stickied post on a subreddit (if it exists).
func (s *SubredditServiceOp) GetSticky1(ctx context.Context, name string) (*LinkAndComments, *Response, error) { func (s *SubredditServiceOp) GetSticky1(ctx context.Context, name string) (*PostAndComments, *Response, error) {
return s.getSticky(ctx, name, sticky1) return s.getSticky(ctx, name, sticky1)
} }
// GetSticky2 returns the second stickied post on a subreddit (if it exists). // GetSticky2 returns the second stickied post on a subreddit (if it exists).
func (s *SubredditServiceOp) GetSticky2(ctx context.Context, name string) (*LinkAndComments, *Response, error) { func (s *SubredditServiceOp) GetSticky2(ctx context.Context, name string) (*PostAndComments, *Response, error) {
return s.getSticky(ctx, name, sticky2) return s.getSticky(ctx, name, sticky2)
} }
// Subscribe subscribes to subreddits based on their names. // Subscribe subscribes to subreddits based on their names.
// Returns {} on success.
func (s *SubredditServiceOp) Subscribe(ctx context.Context, subreddits ...string) (*Response, error) { func (s *SubredditServiceOp) Subscribe(ctx context.Context, subreddits ...string) (*Response, error) {
form := url.Values{} form := url.Values{}
form.Set("action", "sub") form.Set("action", "sub")
@@ -145,7 +144,6 @@ func (s *SubredditServiceOp) Subscribe(ctx context.Context, subreddits ...string
} }
// SubscribeByID subscribes to subreddits based on their id. // SubscribeByID subscribes to subreddits based on their id.
// Returns {} on success.
func (s *SubredditServiceOp) SubscribeByID(ctx context.Context, ids ...string) (*Response, error) { func (s *SubredditServiceOp) SubscribeByID(ctx context.Context, ids ...string) (*Response, error) {
form := url.Values{} form := url.Values{}
form.Set("action", "sub") form.Set("action", "sub")
@@ -154,7 +152,6 @@ func (s *SubredditServiceOp) SubscribeByID(ctx context.Context, ids ...string) (
} }
// Unsubscribe unsubscribes from subreddits based on their names. // Unsubscribe unsubscribes from subreddits based on their names.
// Returns {} on success.
func (s *SubredditServiceOp) Unsubscribe(ctx context.Context, subreddits ...string) (*Response, error) { func (s *SubredditServiceOp) Unsubscribe(ctx context.Context, subreddits ...string) (*Response, error) {
form := url.Values{} form := url.Values{}
form.Set("action", "unsub") form.Set("action", "unsub")
@@ -163,7 +160,6 @@ func (s *SubredditServiceOp) Unsubscribe(ctx context.Context, subreddits ...stri
} }
// UnsubscribeByID unsubscribes from subreddits based on their id. // UnsubscribeByID unsubscribes from subreddits based on their id.
// Returns {} on success.
func (s *SubredditServiceOp) UnsubscribeByID(ctx context.Context, ids ...string) (*Response, error) { func (s *SubredditServiceOp) UnsubscribeByID(ctx context.Context, ids ...string) (*Response, error) {
form := url.Values{} form := url.Values{}
form.Set("action", "unsub") form.Set("action", "unsub")
@@ -255,7 +251,7 @@ func (s *SubredditServiceOp) getSubreddits(ctx context.Context, path string, opt
// Num should be equal to 1 or 2, depending on which one you want. // Num should be equal to 1 or 2, depending on which one you want.
// If it's <= 1, it's 1. // If it's <= 1, it's 1.
// If it's >= 2, it's 2. // If it's >= 2, it's 2.
func (s *SubredditServiceOp) getSticky(ctx context.Context, subreddit string, num sticky) (*LinkAndComments, *Response, error) { func (s *SubredditServiceOp) getSticky(ctx context.Context, subreddit string, num sticky) (*PostAndComments, *Response, error) {
type query struct { type query struct {
Num sticky `url:"num"` Num sticky `url:"num"`
} }
@@ -271,7 +267,7 @@ func (s *SubredditServiceOp) getSticky(ctx context.Context, subreddit string, nu
return nil, nil, err return nil, nil, err
} }
root := new(LinkAndComments) root := new(PostAndComments)
resp, err := s.client.Do(ctx, req, root) resp, err := s.client.Do(ctx, req, root)
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
@@ -337,7 +333,7 @@ func (f *PostFinder) Timespan(timespan Timespan) *PostFinder {
} }
// Do conducts the search. // Do conducts the search.
func (f *PostFinder) Do(ctx context.Context) (*Links, *Response, error) { func (f *PostFinder) Do(ctx context.Context) (*Posts, *Response, error) {
path := f.sort path := f.sort
if len(f.subreddits) > 0 { if len(f.subreddits) > 0 {
path = fmt.Sprintf("r/%s/%s", strings.Join(f.subreddits, "+"), f.sort) path = fmt.Sprintf("r/%s/%s", strings.Join(f.subreddits, "+"), f.sort)
@@ -359,5 +355,5 @@ func (f *PostFinder) Do(ctx context.Context) (*Links, *Response, error) {
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
+5 -5
View File
@@ -81,8 +81,8 @@ var expectedSubreddits = &Subreddits{
}, },
} }
var expectedStickyPost = &LinkAndComments{ var expectedSticky = &PostAndComments{
Link: Link{ Post: Post{
ID: "hcl9gq", ID: "hcl9gq",
FullID: "t3_hcl9gq", FullID: "t3_hcl9gq",
Created: &Timestamp{time.Date(2020, 6, 20, 12, 8, 57, 0, time.UTC)}, Created: &Timestamp{time.Date(2020, 6, 20, 12, 8, 57, 0, time.UTC)},
@@ -255,9 +255,9 @@ func TestSubredditServiceOp_GetSticky1(t *testing.T) {
fmt.Fprint(w, blob) fmt.Fprint(w, blob)
}) })
post, _, err := client.Subreddit.GetSticky1(ctx, "nba") sticky, _, err := client.Subreddit.GetSticky1(ctx, "nba")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, expectedStickyPost.Link, post.Link) assert.Equal(t, expectedSticky.Post, sticky.Post)
// b, _ := json.MarshalIndent(post.Comments, "", " ") // b, _ := json.MarshalIndent(sticky.Comments, "", " ")
// fmt.Println(string(b)) // fmt.Println(string(b))
} }
+33 -48
View File
@@ -8,7 +8,7 @@ import (
const ( const (
kindComment = "t1" kindComment = "t1"
kindAccount = "t2" kindAccount = "t2"
kindLink = "t3" kindLink = "t3" // a link is a post
kindMessage = "t4" kindMessage = "t4"
kindSubreddit = "t5" kindSubreddit = "t5"
kindAward = "t6" kindAward = "t6"
@@ -108,11 +108,11 @@ type Listing struct {
Before string `json:"before"` Before string `json:"before"`
} }
// Things are stuff! // Things are objects/entities coming from the Reddit API.
type Things struct { type Things struct {
Comments []Comment `json:"comments,omitempty"` Comments []Comment `json:"comments,omitempty"`
Users []User `json:"users,omitempty"` Users []User `json:"users,omitempty"`
Links []Link `json:"links,omitempty"` Posts []Post `json:"posts,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"` Subreddits []Subreddit `json:"subreddits,omitempty"`
// todo: add the other kinds of things // todo: add the other kinds of things
} }
@@ -127,9 +127,9 @@ type userRoot struct {
Data *User `json:"data,omitempty"` Data *User `json:"data,omitempty"`
} }
type linkRoot struct { type postRoot struct {
Kind string `json:"kind,omitempty"` Kind string `json:"kind,omitempty"`
Data *Link `json:"data,omitempty"` Data *Post `json:"data,omitempty"`
} }
type subredditRoot struct { type subredditRoot struct {
@@ -138,7 +138,7 @@ type subredditRoot struct {
} }
// UnmarshalJSON implements the json.Unmarshaler interface. // UnmarshalJSON implements the json.Unmarshaler interface.
func (l *Things) UnmarshalJSON(b []byte) error { func (t *Things) UnmarshalJSON(b []byte) error {
var children []map[string]interface{} var children []map[string]interface{}
if err := json.Unmarshal(b, &children); err != nil { if err := json.Unmarshal(b, &children); err != nil {
return err return err
@@ -151,23 +151,23 @@ func (l *Things) UnmarshalJSON(b []byte) error {
case kindComment: case kindComment:
root := new(commentRoot) root := new(commentRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil { if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Comments = append(l.Comments, *root.Data) t.Comments = append(t.Comments, *root.Data)
} }
case kindAccount: case kindAccount:
root := new(userRoot) root := new(userRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil { if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Users = append(l.Users, *root.Data) t.Users = append(t.Users, *root.Data)
} }
case kindLink: case kindLink:
root := new(linkRoot) root := new(postRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil { if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Links = append(l.Links, *root.Data) t.Posts = append(t.Posts, *root.Data)
} }
case kindMessage: case kindMessage:
case kindSubreddit: case kindSubreddit:
root := new(subredditRoot) root := new(subredditRoot)
if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil { if err := json.Unmarshal(byteValue, root); err == nil && root.Data != nil {
l.Subreddits = append(l.Subreddits, *root.Data) t.Subreddits = append(t.Subreddits, *root.Data)
} }
case kindAward: case kindAward:
} }
@@ -203,13 +203,13 @@ type Comment struct {
Score int `json:"score"` Score int `json:"score"`
Controversiality int `json:"controversiality"` Controversiality int `json:"controversiality"`
LinkID string `json:"link_id,omitempty"` PostID string `json:"link_id,omitempty"`
// These don't appear when submitting a comment // These don't appear when submitting a comment
LinkTitle string `json:"link_title,omitempty"` PostTitle string `json:"link_title,omitempty"`
LinkPermalink string `json:"link_permalink,omitempty"` PostPermalink string `json:"link_permalink,omitempty"`
LinkAuthor string `json:"link_author,omitempty"` PostAuthor string `json:"link_author,omitempty"`
LinkNumComments int `json:"num_comments"` PostNumComments int `json:"num_comments"`
IsSubmitter bool `json:"is_submitter"` IsSubmitter bool `json:"is_submitter"`
ScoreHidden bool `json:"score_hidden"` ScoreHidden bool `json:"score_hidden"`
@@ -242,8 +242,8 @@ func (r *Replies) UnmarshalJSON(data []byte) error {
return nil return nil
} }
// Link is a submitted post on Reddit // Post is a submitted post on Reddit.
type Link struct { type Post struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
FullID string `json:"name,omitempty"` FullID string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"` Created *Timestamp `json:"created_utc,omitempty"`
@@ -332,10 +332,10 @@ func (rl *rootListing) getUsers() *Users {
return v return v
} }
func (rl *rootListing) getLinks() *Links { func (rl *rootListing) getPosts() *Posts {
v := new(Links) v := new(Posts)
if rl != nil && rl.Data != nil { if rl != nil && rl.Data != nil {
v.Links = rl.Data.Things.Links v.Posts = rl.Data.Things.Posts
v.After = rl.Data.After v.After = rl.Data.After
v.Before = rl.Data.Before v.Before = rl.Data.Before
} }
@@ -373,31 +373,16 @@ type Subreddits struct {
Before string `json:"before"` Before string `json:"before"`
} }
// Links is a list of links // Posts is a list of posts.
type Links struct { type Posts struct {
Links []Link `json:"submissions,omitempty"` Posts []Post `json:"submissions,omitempty"`
After string `json:"after"` After string `json:"after"`
Before string `json:"before"` Before string `json:"before"`
} }
// CommentsLinks is a list of comments and links // PostAndComments is a post and its comments
type CommentsLinks struct { type PostAndComments struct {
Comments []Comment `json:"comments,omitempty"` Post Post `json:"post,omitempty"`
Links []Link `json:"links,omitempty"`
After string `json:"after"`
Before string `json:"before"`
}
// CommentsLinksSubreddits is a list of comments, links, and subreddits
type CommentsLinksSubreddits struct {
Comments []Comment `json:"comments,omitempty"`
Links []Link `json:"links,omitempty"`
Subreddits []Subreddit `json:"subreddits,omitempty"`
}
// LinkAndComments is a link and its comments
type LinkAndComments struct {
Link Link `json:"link,omitempty"`
Comments []Comment `json:"comments,omitempty"` Comments []Comment `json:"comments,omitempty"`
} }
@@ -405,7 +390,7 @@ type LinkAndComments struct {
// When getting a sticky post, you get an array of 2 Listings // When getting a sticky post, you get an array of 2 Listings
// The 1st one contains the single post in its children array // The 1st one contains the single post in its children array
// The 2nd one contains the comments to the post // The 2nd one contains the comments to the post
func (rl *LinkAndComments) UnmarshalJSON(data []byte) error { func (pc *PostAndComments) UnmarshalJSON(data []byte) error {
var l []rootListing var l []rootListing
err := json.Unmarshal(data, &l) err := json.Unmarshal(data, &l)
@@ -414,14 +399,14 @@ func (rl *LinkAndComments) UnmarshalJSON(data []byte) error {
} }
if len(l) < 2 { if len(l) < 2 {
return errors.New("unexpected json response when getting link") return errors.New("unexpected json response when getting post")
} }
stickyLink := l[0].getLinks().Links[0] post := l[0].getPosts().Posts[0]
stickyComments := l[1].getComments().Comments comments := l[1].getComments().Comments
rl.Link = stickyLink pc.Post = post
rl.Comments = stickyComments pc.Comments = comments
return nil return nil
} }
+1 -1
View File
@@ -26,7 +26,7 @@ func (t *Timestamp) MarshalJSON() ([]byte, error) {
func (t *Timestamp) UnmarshalJSON(data []byte) (err error) { func (t *Timestamp) UnmarshalJSON(data []byte) (err error) {
str := string(data) str := string(data)
// "edited" for comments and links is either false, or a timestamp // "edited" for posts and comments is either false, or a timestamp.
if str == "false" { if str == "false" {
return return
} }
+38 -39
View File
@@ -10,26 +10,26 @@ import (
) )
// UserService handles communication with the user // UserService handles communication with the user
// related methods of the Reddit API // related methods of the Reddit API.
type UserService interface { type UserService interface {
Get(ctx context.Context, username string) (*User, *Response, error) Get(ctx context.Context, username string) (*User, *Response, error)
GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserShort, *Response, error) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserShort, *Response, error)
UsernameAvailable(ctx context.Context, username string) (bool, *Response, error) UsernameAvailable(ctx context.Context, username string) (bool, *Response, error)
Overview(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Comments, *Response, error) Overview(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Comments, *Response, error)
OverviewOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Links, *Comments, *Response, error) OverviewOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Posts, *Comments, *Response, error)
Posts(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) Posts(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error)
PostsOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Links, *Response, error) PostsOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Posts, *Response, error)
Comments(ctx context.Context, opts ...SearchOptionSetter) (*Comments, *Response, error) Comments(ctx context.Context, opts ...SearchOptionSetter) (*Comments, *Response, error)
CommentsOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Comments, *Response, error) CommentsOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Comments, *Response, error)
Saved(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Comments, *Response, error) Saved(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Comments, *Response, error)
Upvoted(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) Upvoted(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error)
Downvoted(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) Downvoted(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error)
Hidden(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) Hidden(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error)
Gilded(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) Gilded(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error)
GetFriendship(ctx context.Context, username string) (*Friendship, *Response, error) GetFriendship(ctx context.Context, username string) (*Friendship, *Response, error)
Friend(ctx context.Context, username string) (*Friendship, *Response, error) Friend(ctx context.Context, username string) (*Friendship, *Response, error)
@@ -44,21 +44,21 @@ type UserService interface {
TrophiesOf(ctx context.Context, username string) (Trophies, *Response, error) TrophiesOf(ctx context.Context, username string) (Trophies, *Response, error)
} }
// UserServiceOp implements the UserService interface // UserServiceOp implements the UserService interface.
type UserServiceOp struct { type UserServiceOp struct {
client *Client client *Client
} }
var _ UserService = &UserServiceOp{} var _ UserService = &UserServiceOp{}
// User represents a Reddit user // User represents a Reddit user.
type User struct { type User struct {
// this is not the full ID, watch out // this is not the full ID, watch out.
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"` Created *Timestamp `json:"created_utc,omitempty"`
LinkKarma int `json:"link_karma"` PostKarma int `json:"link_karma"`
CommentKarma int `json:"comment_karma"` CommentKarma int `json:"comment_karma"`
IsFriend bool `json:"is_friend"` IsFriend bool `json:"is_friend"`
@@ -68,13 +68,13 @@ type User struct {
IsSuspended bool `json:"is_suspended"` IsSuspended bool `json:"is_suspended"`
} }
// UserShort represents a Reddit user, but contains fewer pieces of information // UserShort represents a Reddit user, but
// It is returned from the GET /api/user_data_by_account_ids endpoint // contains fewer pieces of information.
type UserShort struct { type UserShort struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Created *Timestamp `json:"created_utc,omitempty"` Created *Timestamp `json:"created_utc,omitempty"`
LinkKarma int `json:"link_karma"` PostKarma int `json:"link_karma"`
CommentKarma int `json:"comment_karma"` CommentKarma int `json:"comment_karma"`
NSFW bool `json:"profile_over_18"` NSFW bool `json:"profile_over_18"`
@@ -153,7 +153,7 @@ func (t *Trophies) UnmarshalJSON(b []byte) error {
return nil return nil
} }
// Get returns information about the user // Get returns information about the user.
func (s *UserServiceOp) Get(ctx context.Context, username string) (*User, *Response, error) { func (s *UserServiceOp) Get(ctx context.Context, username string) (*User, *Response, error) {
path := fmt.Sprintf("user/%s/about", username) path := fmt.Sprintf("user/%s/about", username)
req, err := s.client.NewRequest(http.MethodGet, path, nil) req, err := s.client.NewRequest(http.MethodGet, path, nil)
@@ -170,7 +170,7 @@ func (s *UserServiceOp) Get(ctx context.Context, username string) (*User, *Respo
return root.Data, resp, nil return root.Data, resp, nil
} }
// GetMultipleByID returns multiple users from their full IDs // GetMultipleByID returns multiple users from their full IDs.
// The response body is a map where the keys are the IDs (if they exist), and the value is the user // The response body is a map where the keys are the IDs (if they exist), and the value is the user
func (s *UserServiceOp) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserShort, *Response, error) { func (s *UserServiceOp) GetMultipleByID(ctx context.Context, ids ...string) (map[string]*UserShort, *Response, error) {
type query struct { type query struct {
@@ -197,8 +197,7 @@ func (s *UserServiceOp) GetMultipleByID(ctx context.Context, ids ...string) (map
return *root, resp, nil return *root, resp, nil
} }
// UsernameAvailable checks whether a username is available for registration // UsernameAvailable checks whether a username is available for registration.
// If a valid username is provided, this endpoint returns a body with just "true" or "false"
func (s *UserServiceOp) UsernameAvailable(ctx context.Context, username string) (bool, *Response, error) { func (s *UserServiceOp) UsernameAvailable(ctx context.Context, username string) (bool, *Response, error) {
type query struct { type query struct {
User string `url:"user,omitempty"` User string `url:"user,omitempty"`
@@ -224,13 +223,13 @@ func (s *UserServiceOp) UsernameAvailable(ctx context.Context, username string)
return *root, resp, nil return *root, resp, nil
} }
// Overview returns a list of the client's comments and links // Overview returns a list of the client's posts and comments.
func (s *UserServiceOp) Overview(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Comments, *Response, error) { func (s *UserServiceOp) Overview(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Comments, *Response, error) {
return s.OverviewOf(ctx, s.client.Username, opts...) return s.OverviewOf(ctx, s.client.Username, opts...)
} }
// OverviewOf returns a list of the user's comments and links // OverviewOf returns a list of the user's posts and comments.
func (s *UserServiceOp) OverviewOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Links, *Comments, *Response, error) { func (s *UserServiceOp) OverviewOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Posts, *Comments, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/overview", username) path := fmt.Sprintf("user/%s/overview", username)
@@ -247,16 +246,16 @@ func (s *UserServiceOp) OverviewOf(ctx context.Context, username string, opts ..
return nil, nil, resp, err return nil, nil, resp, err
} }
return root.getLinks(), root.getComments(), resp, nil return root.getPosts(), root.getComments(), resp, nil
} }
// Posts returns a list of the client's posts. // Posts returns a list of the client's posts.
func (s *UserServiceOp) Posts(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *UserServiceOp) Posts(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error) {
return s.PostsOf(ctx, s.client.Username, opts...) return s.PostsOf(ctx, s.client.Username, opts...)
} }
// PostsOf returns a list of the user's posts. // PostsOf returns a list of the user's posts.
func (s *UserServiceOp) PostsOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *UserServiceOp) PostsOf(ctx context.Context, username string, opts ...SearchOptionSetter) (*Posts, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/submitted", username) path := fmt.Sprintf("user/%s/submitted", username)
@@ -273,7 +272,7 @@ func (s *UserServiceOp) PostsOf(ctx context.Context, username string, opts ...Se
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
// Comments returns a list of the client's comments. // Comments returns a list of the client's comments.
@@ -303,7 +302,7 @@ func (s *UserServiceOp) CommentsOf(ctx context.Context, username string, opts ..
} }
// Saved returns a list of the user's saved posts and comments. // Saved returns a list of the user's saved posts and comments.
func (s *UserServiceOp) Saved(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Comments, *Response, error) { func (s *UserServiceOp) Saved(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Comments, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/saved", s.client.Username) path := fmt.Sprintf("user/%s/saved", s.client.Username)
@@ -320,11 +319,11 @@ func (s *UserServiceOp) Saved(ctx context.Context, opts ...SearchOptionSetter) (
return nil, nil, resp, err return nil, nil, resp, err
} }
return root.getLinks(), root.getComments(), resp, nil return root.getPosts(), root.getComments(), resp, nil
} }
// Upvoted returns a list of the user's upvoted posts. // Upvoted returns a list of the user's upvoted posts.
func (s *UserServiceOp) Upvoted(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *UserServiceOp) Upvoted(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/upvoted", s.client.Username) path := fmt.Sprintf("user/%s/upvoted", s.client.Username)
@@ -341,11 +340,11 @@ func (s *UserServiceOp) Upvoted(ctx context.Context, opts ...SearchOptionSetter)
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
// Downvoted returns a list of the user's downvoted posts. // Downvoted returns a list of the user's downvoted posts.
func (s *UserServiceOp) Downvoted(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *UserServiceOp) Downvoted(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/downvoted", s.client.Username) path := fmt.Sprintf("user/%s/downvoted", s.client.Username)
@@ -362,11 +361,11 @@ func (s *UserServiceOp) Downvoted(ctx context.Context, opts ...SearchOptionSette
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
// Hidden returns a list of the user's hidden posts. // Hidden returns a list of the user's hidden posts.
func (s *UserServiceOp) Hidden(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *UserServiceOp) Hidden(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/hidden", s.client.Username) path := fmt.Sprintf("user/%s/hidden", s.client.Username)
@@ -383,11 +382,11 @@ func (s *UserServiceOp) Hidden(ctx context.Context, opts ...SearchOptionSetter)
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
// Gilded returns a list of the user's gilded posts. // Gilded returns a list of the user's gilded posts.
func (s *UserServiceOp) Gilded(ctx context.Context, opts ...SearchOptionSetter) (*Links, *Response, error) { func (s *UserServiceOp) Gilded(ctx context.Context, opts ...SearchOptionSetter) (*Posts, *Response, error) {
form := newSearchOptions(opts...) form := newSearchOptions(opts...)
path := fmt.Sprintf("user/%s/gilded", s.client.Username) path := fmt.Sprintf("user/%s/gilded", s.client.Username)
@@ -404,7 +403,7 @@ func (s *UserServiceOp) Gilded(ctx context.Context, opts ...SearchOptionSetter)
return nil, resp, err return nil, resp, err
} }
return root.getLinks(), resp, nil return root.getPosts(), resp, nil
} }
// GetFriendship returns friendship details with the specified user. // GetFriendship returns friendship details with the specified user.
+28 -28
View File
@@ -16,7 +16,7 @@ var expectedUser = &User{
Name: "Test_User", Name: "Test_User",
Created: &Timestamp{time.Date(2012, 10, 18, 10, 11, 11, 0, time.UTC)}, Created: &Timestamp{time.Date(2012, 10, 18, 10, 11, 11, 0, time.UTC)},
LinkKarma: 8239, PostKarma: 8239,
CommentKarma: 130514, CommentKarma: 130514,
HasVerifiedEmail: true, HasVerifiedEmail: true,
@@ -26,27 +26,27 @@ var expectedUsers = map[string]*UserShort{
"t2_1": { "t2_1": {
Name: "test_user_1", Name: "test_user_1",
Created: &Timestamp{time.Date(2017, 3, 12, 2, 1, 47, 0, time.UTC)}, Created: &Timestamp{time.Date(2017, 3, 12, 2, 1, 47, 0, time.UTC)},
LinkKarma: 488, PostKarma: 488,
CommentKarma: 22223, CommentKarma: 22223,
NSFW: false, NSFW: false,
}, },
"t2_2": { "t2_2": {
Name: "test_user_2", Name: "test_user_2",
Created: &Timestamp{time.Date(2015, 12, 20, 18, 12, 51, 0, time.UTC)}, Created: &Timestamp{time.Date(2015, 12, 20, 18, 12, 51, 0, time.UTC)},
LinkKarma: 8277, PostKarma: 8277,
CommentKarma: 131948, CommentKarma: 131948,
NSFW: false, NSFW: false,
}, },
"t2_3": { "t2_3": {
Name: "test_user_3", Name: "test_user_3",
Created: &Timestamp{time.Date(2013, 3, 4, 15, 46, 31, 0, time.UTC)}, Created: &Timestamp{time.Date(2013, 3, 4, 15, 46, 31, 0, time.UTC)},
LinkKarma: 126887, PostKarma: 126887,
CommentKarma: 81918, CommentKarma: 81918,
NSFW: true, NSFW: true,
}, },
} }
var expectedPost = Link{ var expectedPost = Post{
ID: "gczwql", ID: "gczwql",
FullID: "t3_gczwql", FullID: "t3_gczwql",
Created: &Timestamp{time.Date(2020, 5, 3, 22, 46, 25, 0, time.UTC)}, Created: &Timestamp{time.Date(2020, 5, 3, 22, 46, 25, 0, time.UTC)},
@@ -96,11 +96,11 @@ var expectedComment = Comment{
Score: 1, Score: 1,
Controversiality: 0, Controversiality: 0,
LinkID: "t3_d7ejpn", PostID: "t3_d7ejpn",
LinkTitle: "I'm giving away an iPhone 11 Pro to a commenter at random to celebrate Apollo for Reddit's new iOS 13 update and as a thank you to the community! Just leave a comment on this post and the winner will be selected randomly and announced tomorrow at 8 PM GMT. Details inside, and good luck!", PostTitle: "I'm giving away an iPhone 11 Pro to a commenter at random to celebrate Apollo for Reddit's new iOS 13 update and as a thank you to the community! Just leave a comment on this post and the winner will be selected randomly and announced tomorrow at 8 PM GMT. Details inside, and good luck!",
LinkPermalink: "https://www.reddit.com/r/apple/comments/d7ejpn/im_giving_away_an_iphone_11_pro_to_a_commenter_at/", PostPermalink: "https://www.reddit.com/r/apple/comments/d7ejpn/im_giving_away_an_iphone_11_pro_to_a_commenter_at/",
LinkAuthor: "iamthatis", PostAuthor: "iamthatis",
LinkNumComments: 89751, PostNumComments: 89751,
} }
var expectedFriendship = &Friendship{ var expectedFriendship = &Friendship{
@@ -200,8 +200,8 @@ func TestUserService_Overview(t *testing.T) {
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.NotNil(t, comments) assert.NotNil(t, comments)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t1_f0zsa37", posts.After) assert.Equal(t, "t1_f0zsa37", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
@@ -227,8 +227,8 @@ func TestUserService_OverviewOf(t *testing.T) {
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.NotNil(t, comments) assert.NotNil(t, comments)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t1_f0zsa37", posts.After) assert.Equal(t, "t1_f0zsa37", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
@@ -278,8 +278,8 @@ func TestUserService_Posts(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t3_gczwql", posts.After) assert.Equal(t, "t3_gczwql", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
} }
@@ -299,8 +299,8 @@ func TestUserService_PostsOf(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t3_gczwql", posts.After) assert.Equal(t, "t3_gczwql", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
} }
@@ -412,8 +412,8 @@ func TestUserService_Saved(t *testing.T) {
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.NotNil(t, comments) assert.NotNil(t, comments)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t1_f0zsa37", posts.After) assert.Equal(t, "t1_f0zsa37", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
@@ -463,8 +463,8 @@ func TestUserService_Upvoted(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t3_gczwql", posts.After) assert.Equal(t, "t3_gczwql", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
} }
@@ -509,8 +509,8 @@ func TestUserService_Downvoted(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t3_gczwql", posts.After) assert.Equal(t, "t3_gczwql", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
} }
@@ -556,8 +556,8 @@ func TestUserService_Hidden(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t3_gczwql", posts.After) assert.Equal(t, "t3_gczwql", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
} }
@@ -578,8 +578,8 @@ func TestUserService_Gilded(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, posts) assert.NotNil(t, posts)
assert.Len(t, posts.Links, 1) assert.Len(t, posts.Posts, 1)
assert.Equal(t, expectedPost, posts.Links[0]) assert.Equal(t, expectedPost, posts.Posts[0])
assert.Equal(t, "t3_gczwql", posts.After) assert.Equal(t, "t3_gczwql", posts.After)
assert.Equal(t, "", posts.Before) assert.Equal(t, "", posts.Before)
} }
+5 -5
View File
@@ -7,14 +7,14 @@ import (
) )
// VoteService handles communication with the upvote/downvote // VoteService handles communication with the upvote/downvote
// related methods of the Reddit API // related methods of the Reddit API.
type VoteService interface { type VoteService interface {
Up(ctx context.Context, id string) (*Response, error) Up(ctx context.Context, id string) (*Response, error)
Down(ctx context.Context, id string) (*Response, error) Down(ctx context.Context, id string) (*Response, error)
Remove(ctx context.Context, id string) (*Response, error) Remove(ctx context.Context, id string) (*Response, error)
} }
// VoteServiceOp implements the Vote interface // VoteServiceOp implements the Vote interface.
type VoteServiceOp struct { type VoteServiceOp struct {
client *Client client *Client
} }
@@ -46,17 +46,17 @@ func (s *VoteServiceOp) vote(ctx context.Context, id string, vote vote) (*Respon
return s.client.Do(ctx, req, nil) return s.client.Do(ctx, req, nil)
} }
// Up upvotes a link or a comment // Up upvotes a post or a comment.
func (s *VoteServiceOp) Up(ctx context.Context, id string) (*Response, error) { func (s *VoteServiceOp) Up(ctx context.Context, id string) (*Response, error) {
return s.vote(ctx, id, upvote) return s.vote(ctx, id, upvote)
} }
// Down downvotes a link or a comment // Down downvotes a post or a comment.
func (s *VoteServiceOp) Down(ctx context.Context, id string) (*Response, error) { func (s *VoteServiceOp) Down(ctx context.Context, id string) (*Response, error) {
return s.vote(ctx, id, downvote) return s.vote(ctx, id, downvote)
} }
// Remove removes the user's vote on a link or a comment // Remove removes the user's vote on a post or a comment.
func (s *VoteServiceOp) Remove(ctx context.Context, id string) (*Response, error) { func (s *VoteServiceOp) Remove(ctx context.Context, id string) (*Response, error) {
return s.vote(ctx, id, novote) return s.vote(ctx, id, novote)
} }