Finish LiveThreadService
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
+177
-1
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
@@ -42,6 +43,19 @@ type LiveThread struct {
|
||||
NSFW bool `json:"nsfw"`
|
||||
}
|
||||
|
||||
// LiveThreadUpdate is an update in a live thread.
|
||||
type LiveThreadUpdate struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
FullID string `json:"name,omitempty"`
|
||||
Author string `json:"author,omitempty"`
|
||||
Created *Timestamp `json:"created_utc,omitempty"`
|
||||
|
||||
Body string `json:"body,omitempty"`
|
||||
// todo: add "embeds" field?
|
||||
|
||||
Stricken bool `json:"stricken"`
|
||||
}
|
||||
|
||||
// LiveThreadCreateOrUpdateRequest represents a request to create/update a live thread.
|
||||
type LiveThreadCreateOrUpdateRequest struct {
|
||||
// No longer than 120 characters.
|
||||
@@ -133,7 +147,8 @@ type LiveThreadPermissions struct {
|
||||
Edit bool `permission:"edit"`
|
||||
Manage bool `permission:"manage"`
|
||||
Settings bool `permission:"settings"`
|
||||
Update bool `permission:"update"`
|
||||
// Posting updates to the thread.
|
||||
Update bool `permission:"update"`
|
||||
}
|
||||
|
||||
func (p *LiveThreadPermissions) String() (s string) {
|
||||
@@ -168,6 +183,28 @@ func (p *LiveThreadPermissions) String() (s string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Now gets information about the currently featured live thread.
|
||||
// This returns an empty 204 response if no thread is currently featured.
|
||||
func (s *LiveThreadService) Now(ctx context.Context) (*LiveThread, *Response, error) {
|
||||
path := "api/live/happening_now"
|
||||
req, err := s.client.NewRequest(http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(thing)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
if err == io.EOF && resp != nil && resp.StatusCode == http.StatusNoContent {
|
||||
return nil, resp, nil
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
t, _ := root.LiveThread()
|
||||
return t, resp, nil
|
||||
}
|
||||
|
||||
// Get information about a live thread.
|
||||
func (s *LiveThreadService) Get(ctx context.Context, id string) (*LiveThread, *Response, error) {
|
||||
path := fmt.Sprintf("live/%s/about", id)
|
||||
@@ -199,6 +236,94 @@ func (s *LiveThreadService) GetMultiple(ctx context.Context, ids ...string) ([]*
|
||||
return l.LiveThreads(), resp, nil
|
||||
}
|
||||
|
||||
// Update the live thread by posting an update to it.
|
||||
// Requires the "update" permission.
|
||||
func (s *LiveThreadService) Update(ctx context.Context, id, text string) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("body", text)
|
||||
|
||||
path := fmt.Sprintf("/api/live/%s/update", id)
|
||||
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// Updates gets a list of updates posted in the live thread.
|
||||
func (s *LiveThreadService) Updates(ctx context.Context, id string, opts *ListOptions) ([]*LiveThreadUpdate, *Response, error) {
|
||||
path := fmt.Sprintf("live/%s", id)
|
||||
l, resp, err := s.client.getListing(ctx, path, opts)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return l.LiveThreadUpdates(), resp, nil
|
||||
}
|
||||
|
||||
// UpdateByID gets a specific update in the live thread by its id.
|
||||
// The ID of the update is the "short" one, i.e. the one that doesn't start with "LiveUpdate_".
|
||||
func (s *LiveThreadService) UpdateByID(ctx context.Context, threadID, updateID string) (*LiveThreadUpdate, *Response, error) {
|
||||
path := fmt.Sprintf("live/%s/updates/%s", threadID, updateID)
|
||||
|
||||
// this endpoint returns a listing
|
||||
l, resp, err := s.client.getListing(ctx, path, nil)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
var update *LiveThreadUpdate
|
||||
updates := l.LiveThreadUpdates()
|
||||
if len(updates) > 0 {
|
||||
update = updates[0]
|
||||
}
|
||||
|
||||
return update, resp, nil
|
||||
}
|
||||
|
||||
// Discussions gets a list of discussions (posts) about the live thread.
|
||||
func (s *LiveThreadService) Discussions(ctx context.Context, id string, opts *ListOptions) ([]*Post, *Response, error) {
|
||||
path := fmt.Sprintf("live/%s/discussions", id)
|
||||
l, resp, err := s.client.getListing(ctx, path, opts)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return l.Posts(), resp, nil
|
||||
}
|
||||
|
||||
// Strike (mark incorrect and cross out) the content of an update.
|
||||
// You must either be the author of the update or have the "edit" permission.
|
||||
func (s *LiveThreadService) Strike(ctx context.Context, threadID, updateID string) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("id", updateID)
|
||||
|
||||
path := fmt.Sprintf("api/live/%s/strike_update", threadID)
|
||||
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// Delete an update from the live thread.
|
||||
// You must either be the author of the update or have the "edit" permission.
|
||||
func (s *LiveThreadService) Delete(ctx context.Context, threadID, updateID string) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("id", updateID)
|
||||
|
||||
path := fmt.Sprintf("api/live/%s/delete_update", threadID)
|
||||
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// Create a live thread and get its id.
|
||||
func (s *LiveThreadService) Create(ctx context.Context, request *LiveThreadCreateOrUpdateRequest) (string, *Response, error) {
|
||||
if request == nil {
|
||||
@@ -360,6 +485,25 @@ func (s *LiveThreadService) Uninvite(ctx context.Context, threadID, userID strin
|
||||
// If permissions is nil, all permissions will be granted.
|
||||
// Requires the "manage" permission.
|
||||
func (s *LiveThreadService) SetPermissions(ctx context.Context, id, username string, permissions *LiveThreadPermissions) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("name", username)
|
||||
form.Set("type", "liveupdate_contributor")
|
||||
form.Set("permissions", permissions.String())
|
||||
|
||||
path := fmt.Sprintf("/api/live/%s/set_contributor_permissions", id)
|
||||
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// SetPermissionsForInvite sets the permissions for a contributor who's yet to accept/refuse their invite.
|
||||
// If permissions is nil, all permissions will be granted.
|
||||
// Requires the "manage" permission.
|
||||
func (s *LiveThreadService) SetPermissionsForInvite(ctx context.Context, id, username string, permissions *LiveThreadPermissions) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("name", username)
|
||||
@@ -391,6 +535,38 @@ func (s *LiveThreadService) Revoke(ctx context.Context, threadID, userID string)
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// HideDiscussion hides a linked post from the live thread's discussion sidebar.
|
||||
// The postID should be the base36 ID of the post, i.e. not its full id.
|
||||
func (s *LiveThreadService) HideDiscussion(ctx context.Context, threadID, postID string) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("link", postID)
|
||||
|
||||
path := fmt.Sprintf("/api/live/%s/hide_discussion", threadID)
|
||||
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// UnhideDiscussion unhides a linked post from the live thread's discussion sidebar.
|
||||
// The postID should be the base36 ID of the post, i.e. not its full id.
|
||||
func (s *LiveThreadService) UnhideDiscussion(ctx context.Context, threadID, postID string) (*Response, error) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("link", postID)
|
||||
|
||||
path := fmt.Sprintf("/api/live/%s/unhide_discussion", threadID)
|
||||
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// Report the live thread.
|
||||
// The reason should be one of:
|
||||
// spam, vote-manipulation, personal-information, sexualizing-minors, site-breaking
|
||||
|
||||
+288
-1
@@ -68,6 +68,89 @@ var expectedLiveThreads = []*LiveThread{
|
||||
},
|
||||
}
|
||||
|
||||
var expectedLiveThreadUpdates = []*LiveThreadUpdate{
|
||||
{
|
||||
ID: "5e46cd94-f968-11ea-9a6a-0e1933241e7d",
|
||||
FullID: "LiveUpdate_5e46cd94-f968-11ea-9a6a-0e1933241e7d",
|
||||
Author: "testuser1",
|
||||
Created: &Timestamp{time.Date(2020, 9, 18, 4, 35, 24, 0, time.UTC)},
|
||||
|
||||
Body: "test 2",
|
||||
|
||||
Stricken: true,
|
||||
},
|
||||
{
|
||||
ID: "fc44f204-f964-11ea-b148-0e2e56a0425f",
|
||||
FullID: "LiveUpdate_fc44f204-f964-11ea-b148-0e2e56a0425f",
|
||||
Author: "testuser1",
|
||||
Created: &Timestamp{time.Date(2020, 9, 18, 4, 11, 11, 0, time.UTC)},
|
||||
|
||||
Body: "test 1",
|
||||
|
||||
Stricken: true,
|
||||
},
|
||||
}
|
||||
|
||||
var expectedLiveThreadUpdate = &LiveThreadUpdate{
|
||||
ID: "fc44f204-f964-11ea-b148-0e2e56a0425f",
|
||||
FullID: "LiveUpdate_fc44f204-f964-11ea-b148-0e2e56a0425f",
|
||||
Author: "testuser1",
|
||||
Created: &Timestamp{time.Date(2020, 9, 18, 4, 11, 11, 0, time.UTC)},
|
||||
|
||||
Body: "test 1",
|
||||
|
||||
Stricken: true,
|
||||
}
|
||||
|
||||
var expectedLiveThreadDiscussions = []*Post{
|
||||
{
|
||||
ID: "test1",
|
||||
FullID: "t3_test1",
|
||||
Created: &Timestamp{time.Date(2020, 9, 16, 12, 37, 31, 0, time.UTC)},
|
||||
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
||||
|
||||
Permalink: "/r/live/comments/test1/test_title/",
|
||||
URL: "https://www.reddit.com/live/15nfp4mtfbo14/",
|
||||
|
||||
Title: "test title",
|
||||
|
||||
Score: 22,
|
||||
UpvoteRatio: 0.9,
|
||||
NumberOfComments: 1,
|
||||
|
||||
SubredditName: "live",
|
||||
SubredditNamePrefixed: "r/live",
|
||||
SubredditID: "t5_32o7w",
|
||||
SubredditSubscribers: 24501,
|
||||
|
||||
Author: "TestUser",
|
||||
AuthorID: "t2_test1",
|
||||
},
|
||||
{
|
||||
ID: "test2",
|
||||
FullID: "t3_test2",
|
||||
Created: &Timestamp{time.Date(2020, 9, 16, 12, 37, 1, 0, time.UTC)},
|
||||
Edited: &Timestamp{time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)},
|
||||
|
||||
Permalink: "/r/live/comments/test2/test_title/",
|
||||
URL: "https://www.reddit.com/live/15nfp4mtfbo14/",
|
||||
|
||||
Title: "test title",
|
||||
|
||||
Score: 71,
|
||||
UpvoteRatio: 0.97,
|
||||
NumberOfComments: 34,
|
||||
|
||||
SubredditName: "live",
|
||||
SubredditNamePrefixed: "r/live",
|
||||
SubredditID: "t5_32o7w",
|
||||
SubredditSubscribers: 24501,
|
||||
|
||||
Author: "TestUser",
|
||||
AuthorID: "t2_test1",
|
||||
},
|
||||
}
|
||||
|
||||
var expectedLiveThreadContributors = &LiveThreadContributors{
|
||||
Current: []*LiveThreadContributor{
|
||||
{ID: "t2_test1", Name: "test1", Permissions: []string{"all"}},
|
||||
@@ -103,6 +186,37 @@ func TestLiveThreadService_Get(t *testing.T) {
|
||||
require.Equal(t, expectedLiveThread, liveThread)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Now(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
blob, err := readFileContents("../testdata/live-thread/live-thread.json")
|
||||
require.NoError(t, err)
|
||||
|
||||
mux.HandleFunc("/api/live/happening_now", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
fmt.Fprint(w, blob)
|
||||
})
|
||||
|
||||
liveThread, _, err := client.LiveThread.Now(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedLiveThread, liveThread)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Now_NoContent(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/happening_now", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
w.WriteHeader(204)
|
||||
})
|
||||
|
||||
liveThread, _, err := client.LiveThread.Now(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, liveThread)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_GetMultiple(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
@@ -123,6 +237,117 @@ func TestLiveThreadService_GetMultiple(t *testing.T) {
|
||||
require.Equal(t, expectedLiveThreads, liveThreads)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Update(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/id123/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("body", "test")
|
||||
|
||||
err := r.ParseForm()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, form, r.PostForm)
|
||||
})
|
||||
|
||||
_, err := client.LiveThread.Update(ctx, "id123", "test")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Updates(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
blob, err := readFileContents("../testdata/live-thread/updates.json")
|
||||
require.NoError(t, err)
|
||||
|
||||
mux.HandleFunc("/live/id123", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
fmt.Fprint(w, blob)
|
||||
})
|
||||
|
||||
liveThreadUpdates, _, err := client.LiveThread.Updates(ctx, "id123", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedLiveThreadUpdates, liveThreadUpdates)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_UpdateByID(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
blob, err := readFileContents("../testdata/live-thread/update.json")
|
||||
require.NoError(t, err)
|
||||
|
||||
mux.HandleFunc("/live/id123/updates/update123", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
fmt.Fprint(w, blob)
|
||||
})
|
||||
|
||||
liveThreadUpdate, _, err := client.LiveThread.UpdateByID(ctx, "id123", "update123")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedLiveThreadUpdate, liveThreadUpdate)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Discussions(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
blob, err := readFileContents("../testdata/live-thread/discussions.json")
|
||||
require.NoError(t, err)
|
||||
|
||||
mux.HandleFunc("/live/id123/discussions", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
fmt.Fprint(w, blob)
|
||||
})
|
||||
|
||||
liveThreadDiscussions, _, err := client.LiveThread.Discussions(ctx, "id123", nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedLiveThreadDiscussions, liveThreadDiscussions)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Strike(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/id123/strike_update", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("id", "update123")
|
||||
|
||||
err := r.ParseForm()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, form, r.PostForm)
|
||||
})
|
||||
|
||||
_, err := client.LiveThread.Strike(ctx, "id123", "update123")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Delete(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/id123/delete_update", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("id", "update123")
|
||||
|
||||
err := r.ParseForm()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, form, r.PostForm)
|
||||
})
|
||||
|
||||
_, err := client.LiveThread.Delete(ctx, "id123", "update123")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Create(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
@@ -369,7 +594,7 @@ func TestLiveThreadService_SetPermissions(t *testing.T) {
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("name", "testuser")
|
||||
form.Set("type", "liveupdate_contributor_invite")
|
||||
form.Set("type", "liveupdate_contributor")
|
||||
form.Set("permissions", "-all,-close,+discussions,+edit,-manage,+settings,-update")
|
||||
|
||||
err := r.ParseForm()
|
||||
@@ -381,6 +606,28 @@ func TestLiveThreadService_SetPermissions(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_SetPermissionsForInvite(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/id123/set_contributor_permissions", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("name", "testuser")
|
||||
form.Set("type", "liveupdate_contributor_invite")
|
||||
form.Set("permissions", "-all,-close,+discussions,+edit,-manage,+settings,-update")
|
||||
|
||||
err := r.ParseForm()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, form, r.PostForm)
|
||||
})
|
||||
|
||||
_, err := client.LiveThread.SetPermissionsForInvite(ctx, "id123", "testuser", &LiveThreadPermissions{Discussions: true, Edit: true, Settings: true})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Revoke(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
@@ -401,6 +648,46 @@ func TestLiveThreadService_Revoke(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_HideDiscussion(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/id123/hide_discussion", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("link", "t3_test")
|
||||
|
||||
err := r.ParseForm()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, form, r.PostForm)
|
||||
})
|
||||
|
||||
_, err := client.LiveThread.HideDiscussion(ctx, "id123", "t3_test")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_UnhideDiscussion(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/api/live/id123/unhide_discussion", func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPost, r.Method)
|
||||
|
||||
form := url.Values{}
|
||||
form.Set("api_type", "json")
|
||||
form.Set("link", "t3_test")
|
||||
|
||||
err := r.ParseForm()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, form, r.PostForm)
|
||||
})
|
||||
|
||||
_, err := client.LiveThread.UnhideDiscussion(ctx, "id123", "t3_test")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveThreadService_Report(t *testing.T) {
|
||||
client, mux, teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
+2
-2
@@ -322,12 +322,12 @@ func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Res
|
||||
if w, ok := v.(io.Writer); ok {
|
||||
_, err = io.Copy(w, response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return response, err
|
||||
}
|
||||
} else {
|
||||
err = json.NewDecoder(response.Body).Decode(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return response, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-8
@@ -18,6 +18,7 @@ const (
|
||||
kindUserList = "UserList"
|
||||
kindMore = "more"
|
||||
kindLiveThread = "LiveUpdateEvent"
|
||||
kindLiveThreadUpdate = "LiveUpdate"
|
||||
kindModAction = "modaction"
|
||||
kindMulti = "LabeledMulti"
|
||||
kindMultiDescription = "LabeledMultiDescription"
|
||||
@@ -92,6 +93,8 @@ func (t *thing) UnmarshalJSON(b []byte) error {
|
||||
v = new(Subreddit)
|
||||
case kindLiveThread:
|
||||
v = new(LiveThread)
|
||||
case kindLiveThreadUpdate:
|
||||
v = new(LiveThreadUpdate)
|
||||
case kindModAction:
|
||||
v = new(ModAction)
|
||||
case kindMulti:
|
||||
@@ -160,6 +163,11 @@ func (t *thing) LiveThread() (v *LiveThread, ok bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func (t *thing) LiveThreadUpdate() (v *LiveThreadUpdate, ok bool) {
|
||||
v, ok = t.Data.(*LiveThreadUpdate)
|
||||
return
|
||||
}
|
||||
|
||||
func (t *thing) ModAction() (v *ModAction, ok bool) {
|
||||
v, ok = t.Data.(*ModAction)
|
||||
return
|
||||
@@ -314,15 +322,23 @@ func (l *listing) LiveThreads() []*LiveThread {
|
||||
return l.things.LiveThreads
|
||||
}
|
||||
|
||||
func (l *listing) LiveThreadUpdates() []*LiveThreadUpdate {
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
return l.things.LiveThreadUpdates
|
||||
}
|
||||
|
||||
type things struct {
|
||||
Comments []*Comment
|
||||
Mores []*More
|
||||
Users []*User
|
||||
Posts []*Post
|
||||
Subreddits []*Subreddit
|
||||
ModActions []*ModAction
|
||||
Multis []*Multi
|
||||
LiveThreads []*LiveThread
|
||||
Comments []*Comment
|
||||
Mores []*More
|
||||
Users []*User
|
||||
Posts []*Post
|
||||
Subreddits []*Subreddit
|
||||
ModActions []*ModAction
|
||||
Multis []*Multi
|
||||
LiveThreads []*LiveThread
|
||||
LiveThreadUpdates []*LiveThreadUpdate
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
@@ -355,6 +371,8 @@ func (t *things) add(things ...thing) {
|
||||
t.Multis = append(t.Multis, v)
|
||||
case *LiveThread:
|
||||
t.LiveThreads = append(t.LiveThreads, v)
|
||||
case *LiveThreadUpdate:
|
||||
t.LiveThreadUpdates = append(t.LiveThreadUpdates, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
{
|
||||
"kind": "Listing",
|
||||
"data": {
|
||||
"modhash": null,
|
||||
"dist": 2,
|
||||
"children": [
|
||||
{
|
||||
"kind": "t3",
|
||||
"data": {
|
||||
"approved_at_utc": null,
|
||||
"subreddit": "live",
|
||||
"selftext": "",
|
||||
"author_fullname": "t2_test1",
|
||||
"saved": false,
|
||||
"mod_reason_title": null,
|
||||
"gilded": 0,
|
||||
"clicked": false,
|
||||
"title": "test title",
|
||||
"link_flair_richtext": [],
|
||||
"subreddit_name_prefixed": "r/live",
|
||||
"hidden": false,
|
||||
"pwls": 6,
|
||||
"link_flair_css_class": null,
|
||||
"downs": 0,
|
||||
"thumbnail_height": 140,
|
||||
"top_awarded_type": null,
|
||||
"hide_score": false,
|
||||
"name": "t3_test1",
|
||||
"quarantine": false,
|
||||
"link_flair_text_color": "dark",
|
||||
"upvote_ratio": 0.9,
|
||||
"author_flair_background_color": null,
|
||||
"subreddit_type": "public",
|
||||
"ups": 22,
|
||||
"total_awards_received": 0,
|
||||
"media_embed": {
|
||||
"content": "\n<div class=\"psuedo-selftext\">\n <iframe src=\"//www.redditmedia.com/live/15nfp4mtfbo14/embed\" height=\"500\"></iframe>\n</div>\n",
|
||||
"width": 710,
|
||||
"scrolling": false,
|
||||
"height": 500
|
||||
},
|
||||
"thumbnail_width": 140,
|
||||
"author_flair_template_id": null,
|
||||
"is_original_content": false,
|
||||
"user_reports": [],
|
||||
"secure_media": {
|
||||
"event_id": "15nfp4mtfbo14",
|
||||
"type": "liveupdate"
|
||||
},
|
||||
"is_reddit_media_domain": false,
|
||||
"is_meta": false,
|
||||
"category": null,
|
||||
"secure_media_embed": {
|
||||
"content": "\n<div class=\"psuedo-selftext\">\n <iframe src=\"//www.redditmedia.com/live/15nfp4mtfbo14/embed\" height=\"500\"></iframe>\n</div>\n",
|
||||
"width": 710,
|
||||
"scrolling": false,
|
||||
"media_domain_url": "https://www.redditmedia.com/mediaembed/test1",
|
||||
"height": 500
|
||||
},
|
||||
"link_flair_text": "LIVE THREAD",
|
||||
"can_mod_post": false,
|
||||
"score": 22,
|
||||
"approved_by": null,
|
||||
"author_premium": true,
|
||||
"thumbnail": "default",
|
||||
"edited": false,
|
||||
"author_flair_css_class": null,
|
||||
"author_flair_richtext": [],
|
||||
"gildings": {},
|
||||
"content_categories": null,
|
||||
"is_self": false,
|
||||
"mod_note": null,
|
||||
"created": 1600288651.0,
|
||||
"link_flair_type": "text",
|
||||
"wls": 6,
|
||||
"removed_by_category": null,
|
||||
"banned_by": null,
|
||||
"author_flair_type": "text",
|
||||
"domain": "reddit.com",
|
||||
"allow_live_comments": false,
|
||||
"selftext_html": null,
|
||||
"likes": null,
|
||||
"suggested_sort": null,
|
||||
"banned_at_utc": null,
|
||||
"url_overridden_by_dest": "https://www.reddit.com/live/15nfp4mtfbo14/",
|
||||
"view_count": null,
|
||||
"archived": false,
|
||||
"no_follow": false,
|
||||
"is_crosspostable": true,
|
||||
"pinned": false,
|
||||
"over_18": false,
|
||||
"all_awardings": [],
|
||||
"awarders": [],
|
||||
"media_only": false,
|
||||
"can_gild": true,
|
||||
"spoiler": false,
|
||||
"locked": false,
|
||||
"author_flair_text": null,
|
||||
"treatment_tags": [],
|
||||
"visited": false,
|
||||
"removed_by": null,
|
||||
"num_reports": null,
|
||||
"distinguished": null,
|
||||
"subreddit_id": "t5_32o7w",
|
||||
"mod_reason_by": null,
|
||||
"removal_reason": null,
|
||||
"link_flair_background_color": "",
|
||||
"id": "test1",
|
||||
"is_robot_indexable": true,
|
||||
"report_reasons": null,
|
||||
"author": "TestUser",
|
||||
"discussion_type": null,
|
||||
"num_comments": 1,
|
||||
"send_replies": true,
|
||||
"whitelist_status": "all_ads",
|
||||
"contest_mode": false,
|
||||
"mod_reports": [],
|
||||
"author_patreon_flair": false,
|
||||
"author_flair_text_color": null,
|
||||
"permalink": "/r/live/comments/test1/test_title/",
|
||||
"parent_whitelist_status": "all_ads",
|
||||
"stickied": false,
|
||||
"url": "https://www.reddit.com/live/15nfp4mtfbo14/",
|
||||
"subreddit_subscribers": 24501,
|
||||
"created_utc": 1600259851.0,
|
||||
"num_crossposts": 0,
|
||||
"media": {
|
||||
"event_id": "15nfp4mtfbo14",
|
||||
"type": "liveupdate"
|
||||
},
|
||||
"is_video": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "t3",
|
||||
"data": {
|
||||
"approved_at_utc": null,
|
||||
"subreddit": "live",
|
||||
"selftext": "",
|
||||
"author_fullname": "t2_test1",
|
||||
"saved": false,
|
||||
"mod_reason_title": null,
|
||||
"gilded": 0,
|
||||
"clicked": false,
|
||||
"title": "test title",
|
||||
"link_flair_richtext": [
|
||||
{
|
||||
"e": "text",
|
||||
"t": "LIVE THREAD CLOSED | No further updates."
|
||||
}
|
||||
],
|
||||
"subreddit_name_prefixed": "r/live",
|
||||
"hidden": false,
|
||||
"pwls": 6,
|
||||
"link_flair_css_class": "diss",
|
||||
"downs": 0,
|
||||
"thumbnail_height": 140,
|
||||
"top_awarded_type": null,
|
||||
"hide_score": false,
|
||||
"name": "t3_test2",
|
||||
"quarantine": false,
|
||||
"link_flair_text_color": "dark",
|
||||
"upvote_ratio": 0.97,
|
||||
"author_flair_background_color": null,
|
||||
"subreddit_type": "public",
|
||||
"ups": 71,
|
||||
"total_awards_received": 0,
|
||||
"media_embed": {
|
||||
"content": "\n<div class=\"psuedo-selftext\">\n <iframe src=\"//www.redditmedia.com/live/15nfp4mtfbo14/embed\" height=\"500\"></iframe>\n</div>\n",
|
||||
"width": 710,
|
||||
"scrolling": false,
|
||||
"height": 500
|
||||
},
|
||||
"thumbnail_width": 140,
|
||||
"author_flair_template_id": null,
|
||||
"is_original_content": false,
|
||||
"user_reports": [],
|
||||
"secure_media": {
|
||||
"event_id": "15nfp4mtfbo14",
|
||||
"type": "liveupdate"
|
||||
},
|
||||
"is_reddit_media_domain": false,
|
||||
"is_meta": false,
|
||||
"category": null,
|
||||
"secure_media_embed": {
|
||||
"content": "\n<div class=\"psuedo-selftext\">\n <iframe src=\"//www.redditmedia.com/live/15nfp4mtfbo14/embed\" height=\"500\"></iframe>\n</div>\n",
|
||||
"width": 710,
|
||||
"scrolling": false,
|
||||
"media_domain_url": "https://www.redditmedia.com/mediaembed/itulo6",
|
||||
"height": 500
|
||||
},
|
||||
"link_flair_text": "LIVE THREAD CLOSED | No further updates.",
|
||||
"can_mod_post": false,
|
||||
"score": 71,
|
||||
"approved_by": null,
|
||||
"author_premium": true,
|
||||
"thumbnail": "https://b.thumbs.redditmedia.com/rZKNaYfha47BqSqVTn2S7WGm5-ydloMOqz3Oqli87aU.jpg",
|
||||
"edited": false,
|
||||
"author_flair_css_class": null,
|
||||
"author_flair_richtext": [],
|
||||
"gildings": {},
|
||||
"content_categories": null,
|
||||
"is_self": false,
|
||||
"mod_note": null,
|
||||
"created": 1600288621.0,
|
||||
"link_flair_type": "richtext",
|
||||
"wls": 6,
|
||||
"removed_by_category": null,
|
||||
"banned_by": null,
|
||||
"author_flair_type": "text",
|
||||
"domain": "reddit.com",
|
||||
"allow_live_comments": true,
|
||||
"selftext_html": null,
|
||||
"likes": null,
|
||||
"suggested_sort": "new",
|
||||
"banned_at_utc": null,
|
||||
"url_overridden_by_dest": "https://www.reddit.com/live/15nfp4mtfbo14/",
|
||||
"view_count": null,
|
||||
"archived": false,
|
||||
"no_follow": false,
|
||||
"is_crosspostable": true,
|
||||
"pinned": false,
|
||||
"over_18": false,
|
||||
"all_awardings": [],
|
||||
"awarders": [],
|
||||
"media_only": false,
|
||||
"link_flair_template_id": "9b12fc60-ff01-11e3-b179-12313b0a9e38",
|
||||
"can_gild": true,
|
||||
"spoiler": false,
|
||||
"locked": false,
|
||||
"author_flair_text": null,
|
||||
"treatment_tags": [],
|
||||
"visited": false,
|
||||
"removed_by": null,
|
||||
"num_reports": null,
|
||||
"distinguished": null,
|
||||
"subreddit_id": "t5_32o7w",
|
||||
"mod_reason_by": null,
|
||||
"removal_reason": null,
|
||||
"link_flair_background_color": "#f5f5f5",
|
||||
"id": "test2",
|
||||
"is_robot_indexable": true,
|
||||
"report_reasons": null,
|
||||
"author": "TestUser",
|
||||
"discussion_type": null,
|
||||
"num_comments": 34,
|
||||
"send_replies": true,
|
||||
"whitelist_status": "all_ads",
|
||||
"contest_mode": false,
|
||||
"mod_reports": [],
|
||||
"author_patreon_flair": false,
|
||||
"author_flair_text_color": null,
|
||||
"permalink": "/r/live/comments/test2/test_title/",
|
||||
"parent_whitelist_status": "all_ads",
|
||||
"stickied": false,
|
||||
"url": "https://www.reddit.com/live/15nfp4mtfbo14/",
|
||||
"subreddit_subscribers": 24501,
|
||||
"created_utc": 1600259821.0,
|
||||
"num_crossposts": 0,
|
||||
"media": {
|
||||
"event_id": "15nfp4mtfbo14",
|
||||
"type": "liveupdate"
|
||||
},
|
||||
"is_video": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"after": null,
|
||||
"before": null
|
||||
}
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"kind": "Listing",
|
||||
"data": {
|
||||
"modhash": null,
|
||||
"dist": null,
|
||||
"children": [
|
||||
{
|
||||
"kind": "LiveUpdate",
|
||||
"data": {
|
||||
"body": "test 1",
|
||||
"name": "LiveUpdate_fc44f204-f964-11ea-b148-0e2e56a0425f",
|
||||
"mobile_embeds": [],
|
||||
"author": "testuser1",
|
||||
"embeds": [],
|
||||
"created": 1600431071.0,
|
||||
"created_utc": 1600402271.0,
|
||||
"body_html": "<div class=\"md\"><p>test 1</p>\n</div>",
|
||||
"stricken": true,
|
||||
"id": "fc44f204-f964-11ea-b148-0e2e56a0425f"
|
||||
}
|
||||
}
|
||||
],
|
||||
"after": null,
|
||||
"before": null
|
||||
}
|
||||
}
|
||||
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"kind": "Listing",
|
||||
"data": {
|
||||
"modhash": null,
|
||||
"dist": null,
|
||||
"children": [
|
||||
{
|
||||
"kind": "LiveUpdate",
|
||||
"data": {
|
||||
"body": "test 2",
|
||||
"name": "LiveUpdate_5e46cd94-f968-11ea-9a6a-0e1933241e7d",
|
||||
"mobile_embeds": [],
|
||||
"author": "testuser1",
|
||||
"embeds": [],
|
||||
"created": 1600432524.0,
|
||||
"created_utc": 1600403724.0,
|
||||
"body_html": "<div class=\"md\"><p>test 2</p>\n</div>",
|
||||
"stricken": true,
|
||||
"id": "5e46cd94-f968-11ea-9a6a-0e1933241e7d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "LiveUpdate",
|
||||
"data": {
|
||||
"body": "test 1",
|
||||
"name": "LiveUpdate_fc44f204-f964-11ea-b148-0e2e56a0425f",
|
||||
"mobile_embeds": [],
|
||||
"author": "testuser1",
|
||||
"embeds": [],
|
||||
"created": 1600431071.0,
|
||||
"created_utc": 1600402271.0,
|
||||
"body_html": "<div class=\"md\"><p>test 1</p>\n</div>",
|
||||
"stricken": true,
|
||||
"id": "fc44f204-f964-11ea-b148-0e2e56a0425f"
|
||||
}
|
||||
}
|
||||
],
|
||||
"after": null,
|
||||
"before": null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user