This commit is contained in:
gutmet 2022-11-20 16:52:14 +01:00
parent ce14c49bcc
commit cf574831cc
17 changed files with 0 additions and 3849 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: mattn # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -1,27 +0,0 @@
name: test
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
test:
strategy:
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
go: ["1.15", "1.16", "1.17"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go }}
- run: go generate ./...
- run: git diff --cached --exit-code
- run: go test ./... -v -cover -coverprofile coverage.out
- run: go test -bench . -benchmem
- uses: codecov/codecov-action@v1

1
.gitignore vendored
View File

@ -1 +0,0 @@
*.exe

View File

@ -1,699 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestGetAccount(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"username": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccount(context.Background(), "1")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
a, err := client.GetAccount(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if a.Username != "zzz" {
t.Fatalf("want %q but %q", "zzz", a.Username)
}
}
func TestGetAccountCurrentUser(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"username": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountCurrentUser(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
a, err := client.GetAccountCurrentUser(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if a.Username != "zzz" {
t.Fatalf("want %q but %q", "zzz", a.Username)
}
}
func TestAccountUpdate(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"username": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountUpdate(context.Background(), &Profile{})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
tbool := true
fields := []Field{{"foo", "bar", time.Time{}}, {"dum", "baz", time.Time{}}}
source := AccountSource{Language: String("de"), Privacy: String("public"), Sensitive: &tbool}
a, err := client.AccountUpdate(context.Background(), &Profile{
DisplayName: String("display_name"),
Note: String("note"),
Locked: &tbool,
Fields: &fields,
Source: &source,
Avatar: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADrCAYAAAA...",
Header: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADrCAYAAAA...",
})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if a.Username != "zzz" {
t.Fatalf("want %q but %q", "zzz", a.Username)
}
}
func TestGetAccountStatuses(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/statuses" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"content": "foo"}, {"content": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountStatuses(context.Background(), "123", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
ss, err := client.GetAccountStatuses(context.Background(), "1234567", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if ss[0].Content != "foo" {
t.Fatalf("want %q but %q", "foo", ss[0].Content)
}
if ss[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", ss[1].Content)
}
}
func TestGetAccountPinnedStatuses(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/statuses" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
pinned := r.URL.Query().Get("pinned")
if pinned != "true" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"content": "foo"}, {"content": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountPinnedStatuses(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
ss, err := client.GetAccountPinnedStatuses(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if ss[0].Content != "foo" {
t.Fatalf("want %q but %q", "foo", ss[0].Content)
}
if ss[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", ss[1].Content)
}
}
func TestGetAccountFollowers(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/followers" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountFollowers(context.Background(), "123", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
fl, err := client.GetAccountFollowers(context.Background(), "1234567", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(fl) != 2 {
t.Fatalf("result should be two: %d", len(fl))
}
if fl[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", fl[0].Username)
}
if fl[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", fl[1].Username)
}
}
func TestGetAccountFollowing(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/following" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountFollowing(context.Background(), "123", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
fl, err := client.GetAccountFollowing(context.Background(), "1234567", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(fl) != 2 {
t.Fatalf("result should be two: %d", len(fl))
}
if fl[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", fl[0].Username)
}
if fl[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", fl[1].Username)
}
}
func TestGetBlocks(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetBlocks(context.Background(), nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
bl, err := client.GetBlocks(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(bl) != 2 {
t.Fatalf("result should be two: %d", len(bl))
}
if bl[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", bl[0].Username)
}
if bl[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", bl[1].Username)
}
}
func TestAccountFollow(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/follow" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id":1234567,"following":true}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountFollow(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rel, err := client.AccountFollow(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rel.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rel.ID)
}
if !rel.Following {
t.Fatalf("want %t but %t", true, rel.Following)
}
}
func TestAccountUnfollow(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/unfollow" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id":1234567,"following":false}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountUnfollow(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rel, err := client.AccountUnfollow(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rel.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rel.ID)
}
if rel.Following {
t.Fatalf("want %t but %t", false, rel.Following)
}
}
func TestAccountBlock(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/block" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id":1234567,"blocking":true}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountBlock(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rel, err := client.AccountBlock(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rel.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rel.ID)
}
if !rel.Blocking {
t.Fatalf("want %t but %t", true, rel.Blocking)
}
}
func TestAccountUnblock(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/unblock" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id":1234567,"blocking":false}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountUnblock(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rel, err := client.AccountUnblock(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rel.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rel.ID)
}
if rel.Blocking {
t.Fatalf("want %t but %t", false, rel.Blocking)
}
}
func TestAccountMute(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/mute" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id":1234567,"muting":true}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountMute(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rel, err := client.AccountMute(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rel.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rel.ID)
}
if !rel.Muting {
t.Fatalf("want %t but %t", true, rel.Muting)
}
}
func TestAccountUnmute(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1234567/unmute" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id":1234567,"muting":false}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountUnmute(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rel, err := client.AccountUnmute(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rel.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rel.ID)
}
if rel.Muting {
t.Fatalf("want %t but %t", false, rel.Muting)
}
}
func TestGetAccountRelationship(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ids := r.URL.Query()["id[]"]
if ids[0] == "1234567" && ids[1] == "8901234" {
fmt.Fprintln(w, `[{"id":1234567},{"id":8901234}]`)
return
}
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountRelationships(context.Background(), []string{"123", "456"})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rels, err := client.GetAccountRelationships(context.Background(), []string{"1234567", "8901234"})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rels[0].ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", rels[0].ID)
}
if rels[1].ID != "8901234" {
t.Fatalf("want %q but %q", "8901234", rels[1].ID)
}
}
func TestAccountsSearch(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query()["q"][0] != "foo" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[{"username": "foobar"}, {"username": "barfoo"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.AccountsSearch(context.Background(), "zzz", 2)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
res, err := client.AccountsSearch(context.Background(), "foo", 2)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(res) != 2 {
t.Fatalf("result should be two: %d", len(res))
}
if res[0].Username != "foobar" {
t.Fatalf("want %q but %q", "foobar", res[0].Username)
}
if res[1].Username != "barfoo" {
t.Fatalf("want %q but %q", "barfoo", res[1].Username)
}
}
func TestFollowRemoteUser(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.PostFormValue("uri") != "foo@success.social" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"username": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.FollowRemoteUser(context.Background(), "foo@fail.social")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
ru, err := client.FollowRemoteUser(context.Background(), "foo@success.social")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if ru.Username != "zzz" {
t.Fatalf("want %q but %q", "zzz", ru.Username)
}
}
func TestGetFollowRequests(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetFollowRequests(context.Background(), nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
fReqs, err := client.GetFollowRequests(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(fReqs) != 2 {
t.Fatalf("result should be two: %d", len(fReqs))
}
if fReqs[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", fReqs[0].Username)
}
if fReqs[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", fReqs[1].Username)
}
}
func TestFollowRequestAuthorize(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/follow_requests/1234567/authorize" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.FollowRequestAuthorize(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
err = client.FollowRequestAuthorize(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestFollowRequestReject(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/follow_requests/1234567/reject" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.FollowRequestReject(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
err = client.FollowRequestReject(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestGetMutes(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetMutes(context.Background(), nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
mutes, err := client.GetMutes(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(mutes) != 2 {
t.Fatalf("result should be two: %d", len(mutes))
}
if mutes[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", mutes[0].Username)
}
if mutes[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", mutes[1].Username)
}
}

View File

@ -1,142 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestRegisterApp(t *testing.T) {
isNotJSON := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
} else if r.URL.Path != "/api/v1/apps" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
} else if r.FormValue("redirect_uris") != "urn:ietf:wg:oauth:2.0:oob" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
} else if isNotJSON {
isNotJSON = false
fmt.Fprintln(w, `<html><head><title>Apps</title></head></html>`)
return
}
fmt.Fprintln(w, `{"id": 123, "client_id": "foo", "client_secret": "bar"}`)
}))
defer ts.Close()
// Status not ok.
_, err := RegisterApp(context.Background(), &AppConfig{
Server: ts.URL,
RedirectURIs: "/",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
// Error in url.Parse
_, err = RegisterApp(context.Background(), &AppConfig{
Server: ":",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
// Error in json.NewDecoder
_, err = RegisterApp(context.Background(), &AppConfig{
Server: ts.URL,
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
// Success.
app, err := RegisterApp(context.Background(), &AppConfig{
Server: ts.URL,
Scopes: "read write follow",
})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if string(app.ID) != "123" {
t.Fatalf("want %q but %q", "bar", app.ClientSecret)
}
if app.ClientID != "foo" {
t.Fatalf("want %q but %q", "foo", app.ClientID)
}
if app.ClientSecret != "bar" {
t.Fatalf("want %q but %q", "bar", app.ClientSecret)
}
}
func TestRegisterAppWithCancel(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(3 * time.Second)
fmt.Fprintln(w, `{"client_id": "foo", "client_secret": "bar"}`)
}))
defer ts.Close()
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := RegisterApp(ctx, &AppConfig{
Server: ts.URL,
Scopes: "read write follow",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
if want := fmt.Sprintf("Post %q: context canceled", ts.URL+"/api/v1/apps"); want != err.Error() {
t.Fatalf("want %q but %q", want, err.Error())
}
}
func TestVerifyAppCredentials(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer zoo" {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
if r.URL.Path != "/api/v1/apps/verify_credentials" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"name":"zzz","website":"yyy","vapid_key":"xxx"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zip",
})
_, err := client.VerifyAppCredentials(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
a, err := client.VerifyAppCredentials(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if a.Name != "zzz" {
t.Fatalf("want %q but %q", "zzz", a.Name)
}
if a.Website != "yyy" {
t.Fatalf("want %q but %q", "yyy", a.Name)
}
if a.VapidKey != "xxx" {
t.Fatalf("want %q but %q", "xxx", a.Name)
}
}

View File

@ -1,342 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"sort"
"strings"
"testing"
"time"
)
func TestGetFilters(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `[{"id": "6191", "phrase": "rust", "context": ["home"], "whole_word": true, "expires_at": "2019-05-21T13:47:31.333Z", "irreversible": false}, {"id": "5580", "phrase": "@twitter.com", "context": ["home", "notifications", "public", "thread"], "whole_word": false, "expires_at": null, "irreversible": true}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
d, err := time.Parse(time.RFC3339Nano, "2019-05-21T13:47:31.333Z")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
tf := []Filter{
{
ID: ID("6191"),
Phrase: "rust",
Context: []string{"home"},
WholeWord: true,
ExpiresAt: d,
Irreversible: false,
},
{
ID: ID("5580"),
Phrase: "@twitter.com",
Context: []string{"notifications", "home", "thread", "public"},
WholeWord: false,
ExpiresAt: time.Time{},
Irreversible: true,
},
}
filters, err := client.GetFilters(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(filters) != 2 {
t.Fatalf("result should be two: %d", len(filters))
}
for i, f := range tf {
if filters[i].ID != f.ID {
t.Fatalf("want %q but %q", string(f.ID), filters[i].ID)
}
if filters[i].Phrase != f.Phrase {
t.Fatalf("want %q but %q", f.Phrase, filters[i].Phrase)
}
sort.Strings(filters[i].Context)
sort.Strings(f.Context)
if strings.Join(filters[i].Context, ", ") != strings.Join(f.Context, ", ") {
t.Fatalf("want %q but %q", f.Context, filters[i].Context)
}
if filters[i].ExpiresAt != f.ExpiresAt {
t.Fatalf("want %q but %q", f.ExpiresAt, filters[i].ExpiresAt)
}
if filters[i].WholeWord != f.WholeWord {
t.Fatalf("want %t but %t", f.WholeWord, filters[i].WholeWord)
}
if filters[i].Irreversible != f.Irreversible {
t.Fatalf("want %t but %t", f.Irreversible, filters[i].Irreversible)
}
}
}
func TestGetFilter(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/filters/1" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id": "1", "phrase": "rust", "context": ["home"], "whole_word": true, "expires_at": "2019-05-21T13:47:31.333Z", "irreversible": false}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetFilter(context.Background(), "2")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
d, err := time.Parse(time.RFC3339Nano, "2019-05-21T13:47:31.333Z")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
tf := Filter{
ID: ID("1"),
Phrase: "rust",
Context: []string{"home"},
WholeWord: true,
ExpiresAt: d,
Irreversible: false,
}
filter, err := client.GetFilter(context.Background(), "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if filter.ID != tf.ID {
t.Fatalf("want %q but %q", string(tf.ID), filter.ID)
}
if filter.Phrase != tf.Phrase {
t.Fatalf("want %q but %q", tf.Phrase, filter.Phrase)
}
sort.Strings(filter.Context)
sort.Strings(tf.Context)
if strings.Join(filter.Context, ", ") != strings.Join(tf.Context, ", ") {
t.Fatalf("want %q but %q", tf.Context, filter.Context)
}
if filter.ExpiresAt != tf.ExpiresAt {
t.Fatalf("want %q but %q", tf.ExpiresAt, filter.ExpiresAt)
}
if filter.WholeWord != tf.WholeWord {
t.Fatalf("want %t but %t", tf.WholeWord, filter.WholeWord)
}
if filter.Irreversible != tf.Irreversible {
t.Fatalf("want %t but %t", tf.Irreversible, filter.Irreversible)
}
}
func TestCreateFilter(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.PostFormValue("phrase") != "rust" && r.PostFormValue("phrase") != "@twitter.com" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
if r.PostFormValue("phrase") == "rust" {
fmt.Fprintln(w, `{"id": "1", "phrase": "rust", "context": ["home"], "whole_word": true, "expires_at": "2019-05-21T13:47:31.333Z", "irreversible": true}`)
return
} else {
fmt.Fprintln(w, `{"id": "2", "phrase": "@twitter.com", "context": ["home", "notifications", "public", "thread"], "whole_word": false, "expires_at": null, "irreversible": false}`)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.CreateFilter(context.Background(), nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.CreateFilter(context.Background(), &Filter{Context: []string{"home"}})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.CreateFilter(context.Background(), &Filter{Phrase: "rust"})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.CreateFilter(context.Background(), &Filter{Phrase: "Test", Context: []string{"home"}})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
d, err := time.Parse(time.RFC3339Nano, "2019-05-21T13:47:31.333Z")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
tf := []Filter{
{
ID: ID("1"),
Phrase: "rust",
Context: []string{"home"},
WholeWord: true,
ExpiresAt: d,
Irreversible: true,
},
{
ID: ID("2"),
Phrase: "@twitter.com",
Context: []string{"notifications", "home", "thread", "public"},
WholeWord: false,
ExpiresAt: time.Time{},
Irreversible: false,
},
}
for _, f := range tf {
filter, err := client.CreateFilter(context.Background(), &f)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if filter.ID != f.ID {
t.Fatalf("want %q but %q", string(f.ID), filter.ID)
}
if filter.Phrase != f.Phrase {
t.Fatalf("want %q but %q", f.Phrase, filter.Phrase)
}
sort.Strings(filter.Context)
sort.Strings(f.Context)
if strings.Join(filter.Context, ", ") != strings.Join(f.Context, ", ") {
t.Fatalf("want %q but %q", f.Context, filter.Context)
}
if filter.ExpiresAt != f.ExpiresAt {
t.Fatalf("want %q but %q", f.ExpiresAt, filter.ExpiresAt)
}
if filter.WholeWord != f.WholeWord {
t.Fatalf("want %t but %t", f.WholeWord, filter.WholeWord)
}
if filter.Irreversible != f.Irreversible {
t.Fatalf("want %t but %t", f.Irreversible, filter.Irreversible)
}
}
}
func TestUpdateFilter(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/api/v1/filters/1" {
fmt.Fprintln(w, `{"id": "1", "phrase": "rust", "context": ["home"], "whole_word": true, "expires_at": "2019-05-21T13:47:31.333Z", "irreversible": true}`)
return
} else if r.URL.Path == "/api/v1/filters/2" {
fmt.Fprintln(w, `{"id": "2", "phrase": "@twitter.com", "context": ["home", "notifications", "public", "thread"], "whole_word": false, "expires_at": null, "irreversible": false}`)
return
} else {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.UpdateFilter(context.Background(), ID("1"), nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.UpdateFilter(context.Background(), ID(""), &Filter{Phrase: ""})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.UpdateFilter(context.Background(), ID("2"), &Filter{Phrase: ""})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.UpdateFilter(context.Background(), ID("2"), &Filter{Phrase: "rust"})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = client.UpdateFilter(context.Background(), ID("3"), &Filter{Phrase: "rust", Context: []string{"home"}})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
d, err := time.Parse(time.RFC3339Nano, "2019-05-21T13:47:31.333Z")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
tf := []Filter{
{
ID: ID("1"),
Phrase: "rust",
Context: []string{"home"},
WholeWord: true,
ExpiresAt: d,
Irreversible: true,
},
{
ID: ID("2"),
Phrase: "@twitter.com",
Context: []string{"notifications", "home", "thread", "public"},
WholeWord: false,
ExpiresAt: time.Time{},
Irreversible: false,
},
}
for _, f := range tf {
filter, err := client.UpdateFilter(context.Background(), f.ID, &f)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if filter.ID != f.ID {
t.Fatalf("want %q but %q", string(f.ID), filter.ID)
}
if filter.Phrase != f.Phrase {
t.Fatalf("want %q but %q", f.Phrase, filter.Phrase)
}
sort.Strings(filter.Context)
sort.Strings(f.Context)
if strings.Join(filter.Context, ", ") != strings.Join(f.Context, ", ") {
t.Fatalf("want %q but %q", f.Context, filter.Context)
}
if filter.ExpiresAt != f.ExpiresAt {
t.Fatalf("want %q but %q", f.ExpiresAt, filter.ExpiresAt)
}
if filter.WholeWord != f.WholeWord {
t.Fatalf("want %t but %t", f.WholeWord, filter.WholeWord)
}
if filter.Irreversible != f.Irreversible {
t.Fatalf("want %t but %t", f.Irreversible, filter.Irreversible)
}
}
}
func TestDeleteFilter(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/filters/1" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.DeleteFilter(context.Background(), "2")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
err = client.DeleteFilter(context.Background(), "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}

View File

@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -e
echo "" > coverage.txt
for d in $(go list ./... | grep -v vendor); do
go test -coverprofile=profile.out -covermode=atomic "$d"
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
fi
done

View File

@ -1,89 +0,0 @@
package mastodon
import (
"io/ioutil"
"net/http"
"os"
"strings"
"testing"
)
const wantBase64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABxCAYAAADifkzQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAXoSURBVHhe7Zxbcts4EEWtWUp2MM5fqryDLMNVWdNMObuYHdiVP2d24O/sQsNL8WbacIMPkWh0QzgpFCVGfLiPugFIpE7ngbtOaG5C4ul0mh6tI1pImpYo5b1u+DM/T9tFCU2zEilwizwJRRLPYWpO4rXZN4f3zGxS4lHyUiDTY7j+mJZNUFIgkZnuhSYkIrAWArl/byKbKKcWAlM8lVbXmcgMY9PIrbeg5rElYTIxDRhPG+uts1DiYeQapk9EkNgA5HnIhNef9XMgbJ+oCayVkbWzMbTE89s/07MLp09fp0f/YyW25kAnpERNYA4ptqjQfweR93VEhpLIErpWoETLUnCo2Eoiw41OrxE4R04u2Cy4S5xnSwk9glTuKqGDRGAtMoRELQtlkEvL5bHG6cSf40OdLlFnTRnNlcRSpTcrs0vUObKMUsKe/WEf7yb4lDkJBF2ioMRgRsvarfuX+9A+sekSBRaDmT1SczK7xIkSWbgWytkis0tMqCmQbM1Qvh4yu8QBizJ6DVLsh/P7dVmcvkxZ3CX6lDjLJBFApGVYm7pQ6lbpEg/GOgtBl7gXlFFRSmvQJTZAl7gTlE+2WvTR6VEMJZUie58YmPOPOm+8LrEB3ErUPvbKseW1LeL6A/At/SJFmvelFT+pIc2UU8hDq5WVtQQCtxIRkGuEWGYiz6+mQOC2nBK3042pjNYWCProtAHcZyJANgIXGelgIJMSIhMRKLTqUwmHAkEvp2txKhCEKKcSllZgVl4dCwThJBIpExwmVAhL8SgQhJUoOUTogjzgNVRNSJSkQsEHqTPCUrwLBGYSteCWRP5ZHzJ15isjSiMR3uOmEksf6uXlZVw+PDx8ONZ4/J+vd6f7z9OaPBHESW5qiiEFQlSuReMmJLKc4m5fNqxLy2xUzCUyeLJxvVyC3Lq0rSG9XXvV7dtBMJcoS9Zc+aKcdAm4XW5bIiXzB4NapFompo9TIXyeWy6B/cryqWUe1vH4kXGbiWBJGATkXqNJa5WqAxuZiUCTkhM1J3AR3F8/NdxPKM8hItUkQgAb0aTkROXWLyJ+IIFEF1k1EzvH4FIisoLNkqjZ6E4iAslSieXhgc38IpT84YRouJIoBRJLkVHpfWIDuJLIrJMZqWXnITSUjcUlUspaIExKKyIwQ9SpRlGJYxa9Xe6R6JTDrJxKkcxOtq1cs80WSu//aKr0iSyZWqmUAbxW8h4iTjWKSoSk33cOLVy9LYVxKUWnMq3leqZ4JkqRKRBBSVwC+TjHuN8Zken3h2u/T8SP60XDpJxqUqRAkj7Ha9i0fWjrxoukpsEUxLGt/Wqql9MNaAKAXI/HbJLctimLI+NG5orVJHaOozmJz8/P9W+BM8b04mEE2AL0i5K5/nDsL5N+0PqXg/fS7GX8FKcNarCOaAOZLtEIvCnWjjilNPBuO+VyjWgSb2JgA2mytUYfnTZAl9gAoSWmfd1mGugPQViJCDTa1SIVgcR6JL2XJsrpZpEzAkHPRENkxuwurYEJPU98Oj9Nzy48nh63TSGSjOTXUNFCElKiJpBApGRJqsxg7JPbRwpLcxIlqdAcWkaDKKEJJ3GtwL1AZJdYgJICH4d/7xiqbJTQhBmdWmWgBMeMQBPzxCIE6mRCSKyRhZFwLzFKSauJe4kYXKCtnS7cImFGpzIjTUao0+EihCeERArkNaTa1WxHiP0tcThckPf2SBiJsxcBD0DsXpGjxEAZSJqYYkAggo5+c1ffiQycrhqPNKByn4lLWUiBEmzDrJRSc5nK18jjaPv1SmiJc4FmJsn/5zopEwKv2b8nwkrcE2DKTDn6OFaE7BP3Bhbbag37jYgLicgM2TrbcJOJT3+dxwZqiYyajW76RIijRPD47b1I9lcWfZR8E+GccC5OwqTiamCTipRQqsXpaufhWaSrgQ2ClGagxGsQa+NudLok0gLtHJCZtfrqJVxOMTyIjITryX76zrc81Uj9ovtPbGrBNxBFehUIusQZvv99WXoWCLrEGZiNvkN0d/cfoIFu0rP2f7IAAAAASUVORK5CYII="
func TestBase64EncodeFileName(t *testing.T) {
// Error in os.Open.
_, err := Base64EncodeFileName("fail")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
// Success.
uri, err := Base64EncodeFileName("testdata/logo.png")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if uri != wantBase64 {
t.Fatalf("want %q but %q", wantBase64, uri)
}
}
func TestBase64Encode(t *testing.T) {
// Error in file.Stat.
_, err := Base64Encode(nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
// Error in file.Read.
logo, err := os.Open("testdata/logo.png")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
_, err = ioutil.ReadAll(logo)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
_, err = Base64Encode(logo)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
// Success.
logo, err = os.Open("testdata/logo.png")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
uri, err := Base64Encode(logo)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if uri != wantBase64 {
t.Fatalf("want %q but %q", wantBase64, uri)
}
}
func TestString(t *testing.T) {
s := "test"
sp := String(s)
if *sp != s {
t.Fatalf("want %q but %q", s, *sp)
}
}
func TestParseAPIError(t *testing.T) {
// No api error.
r := ioutil.NopCloser(strings.NewReader(`<html><head><title>404</title></head></html>`))
err := parseAPIError("bad request", &http.Response{Status: "404 Not Found", Body: r})
want := "bad request: 404 Not Found"
if err.Error() != want {
t.Fatalf("want %q but %q", want, err.Error())
}
// With api error.
r = ioutil.NopCloser(strings.NewReader(`{"error":"Record not found"}`))
err = parseAPIError("bad request", &http.Response{Status: "404 Not Found", Body: r})
want = "bad request: 404 Not Found: Record not found"
if err.Error() != want {
t.Fatalf("want %q but %q", want, err.Error())
}
}

View File

@ -1,179 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestGetInstance(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"title": "mastodon", "uri": "http://mstdn.example.com", "description": "test mastodon", "email": "mstdn@mstdn.example.com", "contact_account": {"username": "mattn"}}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetInstance(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
ins, err := client.GetInstance(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if ins.Title != "mastodon" {
t.Fatalf("want %q but %q", "mastodon", ins.Title)
}
if ins.URI != "http://mstdn.example.com" {
t.Fatalf("want %q but %q", "http://mstdn.example.com", ins.URI)
}
if ins.Description != "test mastodon" {
t.Fatalf("want %q but %q", "test mastodon", ins.Description)
}
if ins.EMail != "mstdn@mstdn.example.com" {
t.Fatalf("want %q but %q", "mstdn@mstdn.example.com", ins.EMail)
}
if ins.ContactAccount.Username != "mattn" {
t.Fatalf("want %q but %q", "mattn", ins.ContactAccount.Username)
}
}
func TestGetInstanceMore(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"title": "mastodon", "uri": "http://mstdn.example.com", "description": "test mastodon", "email": "mstdn@mstdn.example.com", "version": "0.0.1", "urls":{"foo":"http://stream1.example.com", "bar": "http://stream2.example.com"}, "thumbnail": "http://mstdn.example.com/logo.png", "stats":{"user_count":1, "status_count":2, "domain_count":3}}}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetInstance(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
ins, err := client.GetInstance(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if ins.Title != "mastodon" {
t.Fatalf("want %q but %q", "mastodon", ins.Title)
}
if ins.URI != "http://mstdn.example.com" {
t.Fatalf("want %q but %q", "mastodon", ins.URI)
}
if ins.Description != "test mastodon" {
t.Fatalf("want %q but %q", "test mastodon", ins.Description)
}
if ins.EMail != "mstdn@mstdn.example.com" {
t.Fatalf("want %q but %q", "mstdn@mstdn.example.com", ins.EMail)
}
if ins.Version != "0.0.1" {
t.Fatalf("want %q but %q", "0.0.1", ins.Version)
}
if ins.URLs["foo"] != "http://stream1.example.com" {
t.Fatalf("want %q but %q", "http://stream1.example.com", ins.Version)
}
if ins.URLs["bar"] != "http://stream2.example.com" {
t.Fatalf("want %q but %q", "http://stream2.example.com", ins.Version)
}
if ins.Thumbnail != "http://mstdn.example.com/logo.png" {
t.Fatalf("want %q but %q", "http://mstdn.example.com/logo.png", ins.Thumbnail)
}
if ins.Stats == nil {
t.Fatal("status should be nil")
}
if ins.Stats.UserCount != 1 {
t.Fatalf("want %v but %v", 1, ins.Stats.UserCount)
}
if ins.Stats.StatusCount != 2 {
t.Fatalf("want %v but %v", 2, ins.Stats.StatusCount)
}
if ins.Stats.DomainCount != 3 {
t.Fatalf("want %v but %v", 3, ins.Stats.DomainCount)
}
}
func TestGetInstanceActivity(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[{"week":"1516579200","statuses":"1","logins":"1","registrations":"0"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
})
_, err := client.GetInstanceActivity(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
activity, err := client.GetInstanceActivity(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if activity[0].Week != Unixtime(time.Unix(1516579200, 0)) {
t.Fatalf("want %v but %v", Unixtime(time.Unix(1516579200, 0)), activity[0].Week)
}
if activity[0].Logins != 1 {
t.Fatalf("want %q but %q", 1, activity[0].Logins)
}
}
func TestGetInstancePeers(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `["mastodon.social","mstdn.jp"]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
})
_, err := client.GetInstancePeers(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
peers, err := client.GetInstancePeers(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if peers[0] != "mastodon.social" {
t.Fatalf("want %q but %q", "mastodon.social", peers[0])
}
if peers[1] != "mstdn.jp" {
t.Fatalf("want %q but %q", "mstdn.jp", peers[1])
}
}

View File

@ -1,280 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetLists(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"id": "1", "title": "foo"}, {"id": "2", "title": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
lists, err := client.GetLists(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(lists) != 2 {
t.Fatalf("result should be two: %d", len(lists))
}
if lists[0].Title != "foo" {
t.Fatalf("want %q but %q", "foo", lists[0].Title)
}
if lists[1].Title != "bar" {
t.Fatalf("want %q but %q", "bar", lists[1].Title)
}
}
func TestGetAccountLists(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/accounts/1/lists" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"id": "1", "title": "foo"}, {"id": "2", "title": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetAccountLists(context.Background(), "2")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
lists, err := client.GetAccountLists(context.Background(), "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(lists) != 2 {
t.Fatalf("result should be two: %d", len(lists))
}
if lists[0].Title != "foo" {
t.Fatalf("want %q but %q", "foo", lists[0].Title)
}
if lists[1].Title != "bar" {
t.Fatalf("want %q but %q", "bar", lists[1].Title)
}
}
func TestGetListAccounts(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists/1/accounts" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetListAccounts(context.Background(), "2")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
accounts, err := client.GetListAccounts(context.Background(), "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(accounts) != 2 {
t.Fatalf("result should be two: %d", len(accounts))
}
if accounts[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", accounts[0].Username)
}
if accounts[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", accounts[1].Username)
}
}
func TestGetList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists/1" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id": "1", "title": "foo"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetList(context.Background(), "2")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
list, err := client.GetList(context.Background(), "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if list.Title != "foo" {
t.Fatalf("want %q but %q", "foo", list.Title)
}
}
func TestCreateList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.PostFormValue("title") != "foo" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"id": "1", "title": "foo"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.CreateList(context.Background(), "")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
list, err := client.CreateList(context.Background(), "foo")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if list.Title != "foo" {
t.Fatalf("want %q but %q", "foo", list.Title)
}
}
func TestRenameList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists/1" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.PostFormValue("title") != "bar" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `{"id": "1", "title": "bar"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.RenameList(context.Background(), "2", "bar")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
list, err := client.RenameList(context.Background(), "1", "bar")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if list.Title != "bar" {
t.Fatalf("want %q but %q", "bar", list.Title)
}
}
func TestDeleteList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists/1" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "DELETE" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusMethodNotAllowed)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.DeleteList(context.Background(), "2")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
err = client.DeleteList(context.Background(), "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestAddToList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists/1/accounts" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.PostFormValue("account_ids") != "1" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.AddToList(context.Background(), "1", "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestRemoveFromList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/lists/1/accounts" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "DELETE" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusMethodNotAllowed)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.RemoveFromList(context.Background(), "1", "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}

View File

@ -1,516 +0,0 @@
package mastodon
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
)
func TestDoAPI(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("max_id") == "999" {
w.Header().Set("Link", `<:>; rel="next"`)
} else {
w.Header().Set("Link", `<http://example.com?max_id=234>; rel="next", <http://example.com?since_id=890>; rel="prev"`)
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
c := NewClient(&Config{Server: ts.URL})
var accounts []Account
err := c.doAPI(context.Background(), http.MethodGet, "/", nil, &accounts, &Pagination{
MaxID: "999",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
pg := &Pagination{
MaxID: "123",
SinceID: "789",
Limit: 10,
}
err = c.doAPI(context.Background(), http.MethodGet, "/", url.Values{}, &accounts, pg)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if pg.MaxID != "234" {
t.Fatalf("want %q but %q", "234", pg.MaxID)
}
if pg.SinceID != "890" {
t.Fatalf("want %q but %q", "890", pg.SinceID)
}
if accounts[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", accounts[0].Username)
}
if accounts[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", accounts[1].Username)
}
pg = &Pagination{
MaxID: "123",
SinceID: "789",
Limit: 10,
}
err = c.doAPI(context.Background(), http.MethodGet, "/", nil, &accounts, pg)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if pg.MaxID != "234" {
t.Fatalf("want %q but %q", "234", pg.MaxID)
}
if pg.SinceID != "890" {
t.Fatalf("want %q but %q", "890", pg.SinceID)
}
if accounts[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", accounts[0].Username)
}
if accounts[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", accounts[1].Username)
}
// *Pagination is nil
err = c.doAPI(context.Background(), http.MethodGet, "/", nil, &accounts, nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if accounts[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", accounts[0].Username)
}
if accounts[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", accounts[1].Username)
}
}
func TestAuthenticate(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.FormValue("username") != "valid" || r.FormValue("password") != "user" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
fmt.Fprintln(w, `{"access_token": "zoo"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
err := client.Authenticate(context.Background(), "invalid", "user")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
err = client.Authenticate(context.Background(), "valid", "user")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestAuthenticateWithCancel(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(3 * time.Second)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
ctx, cancel := context.WithCancel(context.Background())
cancel()
err := client.Authenticate(ctx, "invalid", "user")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
if want := fmt.Sprintf("Post %q: context canceled", ts.URL+"/oauth/token"); want != err.Error() {
t.Fatalf("want %q but %q", want, err.Error())
}
}
func TestAuthenticateApp(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.FormValue("client_id") != "foo" || r.FormValue("client_secret") != "bar" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
fmt.Fprintln(w, `{"name":"zzz","website":"yyy","vapid_key":"xxx"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bat",
})
err := client.AuthenticateApp(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
err = client.AuthenticateApp(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestPostStatus(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer zoo" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
fmt.Fprintln(w, `{"access_token": "zoo"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
_, err := client.PostStatus(context.Background(), &Toot{
Status: "foobar",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err = client.PostStatus(context.Background(), &Toot{
Status: "foobar",
})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestPostStatusWithCancel(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(3 * time.Second)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := client.PostStatus(ctx, &Toot{
Status: "foobar",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
if want := fmt.Sprintf("Post %q: context canceled", ts.URL+"/api/v1/statuses"); want != err.Error() {
t.Fatalf("want %q but %q", want, err.Error())
}
}
func TestPostStatusParams(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
r.ParseForm()
if r.FormValue("media_ids[]") != "" && r.FormValue("poll[options][]") != "" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
}
s := Status{
ID: ID("1"),
Content: fmt.Sprintf("<p>%s</p>", r.FormValue("status")),
}
if r.FormValue("in_reply_to_id") != "" {
s.InReplyToID = ID(r.FormValue("in_reply_to_id"))
}
if r.FormValue("visibility") != "" {
s.Visibility = (r.FormValue("visibility"))
}
if r.FormValue("language") != "" {
s.Language = (r.FormValue("language"))
}
if r.FormValue("sensitive") == "true" {
s.Sensitive = true
s.SpoilerText = fmt.Sprintf("<p>%s</p>", r.FormValue("spoiler_text"))
}
if r.FormValue("media_ids[]") != "" {
for _, id := range r.Form["media_ids[]"] {
s.MediaAttachments = append(s.MediaAttachments,
Attachment{ID: ID(id)})
}
}
if r.FormValue("poll[options][]") != "" {
p := Poll{}
for _, opt := range r.Form["poll[options][]"] {
p.Options = append(p.Options, PollOption{
Title: opt,
VotesCount: 0,
})
}
if r.FormValue("poll[multiple]") == "true" {
p.Multiple = true
}
s.Poll = &p
}
json.NewEncoder(w).Encode(s)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
s, err := client.PostStatus(context.Background(), &Toot{
Status: "foobar",
InReplyToID: ID("2"),
Visibility: "unlisted",
Language: "sv",
Sensitive: true,
SpoilerText: "bar",
MediaIDs: []ID{"1", "2"},
Poll: &TootPoll{
Options: []string{"A", "B"},
},
})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(s.MediaAttachments) > 0 && s.Poll != nil {
t.Fatal("should not fail, can't have both Media and Poll")
}
if s.Content != "<p>foobar</p>" {
t.Fatalf("want %q but %q", "<p>foobar</p>", s.Content)
}
if s.InReplyToID != "2" {
t.Fatalf("want %q but %q", "2", s.InReplyToID)
}
if s.Visibility != "unlisted" {
t.Fatalf("want %q but %q", "unlisted", s.Visibility)
}
if s.Language != "sv" {
t.Fatalf("want %q but %q", "sv", s.Language)
}
if s.Sensitive != true {
t.Fatalf("want %t but %t", true, s.Sensitive)
}
if s.SpoilerText != "<p>bar</p>" {
t.Fatalf("want %q but %q", "<p>bar</p>", s.SpoilerText)
}
s, err = client.PostStatus(context.Background(), &Toot{
Status: "foobar",
Poll: &TootPoll{
Multiple: true,
Options: []string{"A", "B"},
},
})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if s.Poll == nil {
t.Fatalf("poll should not be %v", s.Poll)
}
if len(s.Poll.Options) != 2 {
t.Fatalf("want %q but %q", 2, len(s.Poll.Options))
}
if s.Poll.Options[0].Title != "A" {
t.Fatalf("want %q but %q", "A", s.Poll.Options[0].Title)
}
if s.Poll.Options[1].Title != "B" {
t.Fatalf("want %q but %q", "B", s.Poll.Options[1].Title)
}
if s.Poll.Multiple != true {
t.Fatalf("want %t but %t", true, s.Poll.Multiple)
}
}
func TestGetTimelineHome(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `[{"content": "foo"}, {"content": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
_, err := client.PostStatus(context.Background(), &Toot{
Status: "foobar",
})
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
tl, err := client.GetTimelineHome(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(tl) != 2 {
t.Fatalf("result should be two: %d", len(tl))
}
if tl[0].Content != "foo" {
t.Fatalf("want %q but %q", "foo", tl[0].Content)
}
if tl[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", tl[1].Content)
}
}
func TestGetTimelineHomeWithCancel(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(3 * time.Second)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := client.GetTimelineHome(ctx, nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
if want := fmt.Sprintf("Get %q: context canceled", ts.URL+"/api/v1/timelines/home"); want != err.Error() {
t.Fatalf("want %q but %q", want, err.Error())
}
}
func TestForTheCoverages(t *testing.T) {
(*UpdateEvent)(nil).event()
(*NotificationEvent)(nil).event()
(*DeleteEvent)(nil).event()
(*ErrorEvent)(nil).event()
_ = (&ErrorEvent{io.EOF}).Error()
}
func TestNewPagination(t *testing.T) {
_, err := newPagination("")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = newPagination(`<:>; rel="next"`)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = newPagination(`<:>; rel="prev"`)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = newPagination(`<http://example.com?min_id=abc>; rel="prev"`)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
pg, err := newPagination(`<http://example.com?max_id=123>; rel="next", <http://example.com?since_id=789>; rel="prev"`)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if pg.MaxID != "123" {
t.Fatalf("want %q but %q", "123", pg.MaxID)
}
if pg.SinceID != "789" {
t.Fatalf("want %q but %q", "789", pg.SinceID)
}
}
func TestGetPaginationID(t *testing.T) {
_, err := getPaginationID(":", "max_id")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
_, err = getPaginationID("http://example.com?max_id=abc", "max_id")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
id, err := getPaginationID("http://example.com?max_id=123", "max_id")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if id != "123" {
t.Fatalf("want %q but %q", "123", id)
}
}
func TestPaginationSetValues(t *testing.T) {
p := &Pagination{
MaxID: "123",
SinceID: "456",
MinID: "789",
Limit: 10,
}
before := url.Values{"key": {"value"}}
after := p.setValues(before)
if after.Get("key") != "value" {
t.Fatalf("want %q but %q", "value", after.Get("key"))
}
if after.Get("max_id") != "123" {
t.Fatalf("want %q but %q", "123", after.Get("max_id"))
}
if after.Get("since_id") != "456" {
t.Fatalf("want %q but %q", "456", after.Get("since_id"))
}
if after.Get("min_id") != "789" {
t.Fatalf("want %q but %q", "789", after.Get("min_id"))
}
if after.Get("limit") != "10" {
t.Fatalf("want %q but %q", "10", after.Get("limit"))
}
p = &Pagination{
MaxID: "",
SinceID: "789",
}
before = url.Values{}
after = p.setValues(before)
if after.Get("max_id") != "" {
t.Fatalf("result should be empty string: %q", after.Get("max_id"))
}
if after.Get("since_id") != "789" {
t.Fatalf("want %q but %q", "789", after.Get("since_id"))
}
if after.Get("min_id") != "" {
t.Fatalf("result should be empty string: %q", after.Get("min_id"))
}
}

View File

@ -1,143 +0,0 @@
package mastodon
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetNotifications(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/notifications":
fmt.Fprintln(w, `[{"id": 122, "action_taken": false}, {"id": 123, "action_taken": true}]`)
return
case "/api/v1/notifications/123":
fmt.Fprintln(w, `{"id": 123, "action_taken": true}`)
return
case "/api/v1/notifications/clear":
fmt.Fprintln(w, `{}`)
return
case "/api/v1/notifications/123/dismiss":
fmt.Fprintln(w, `{}`)
return
}
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
ns, err := client.GetNotifications(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(ns) != 2 {
t.Fatalf("result should be two: %d", len(ns))
}
if ns[0].ID != "122" {
t.Fatalf("want %v but %v", "122", ns[0].ID)
}
if ns[1].ID != "123" {
t.Fatalf("want %v but %v", "123", ns[1].ID)
}
n, err := client.GetNotification(context.Background(), "123")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if n.ID != "123" {
t.Fatalf("want %v but %v", "123", n.ID)
}
err = client.ClearNotifications(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
err = client.DismissNotification(context.Background(), "123")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestPushSubscription(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/push/subscription":
fmt.Fprintln(w, ` {"id":1,"endpoint":"https://example.org","alerts":{"follow":true,"favourite":"true","reblog":"true","mention":"true"},"server_key":"foobar"}`)
return
}
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
enabled := new(Sbool)
*enabled = true
alerts := PushAlerts{Follow: enabled, Favourite: enabled, Reblog: enabled, Mention: enabled}
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
shared := make([]byte, 16)
_, err = rand.Read(shared)
if err != nil {
t.Fatal(err)
}
testSub := func(sub *PushSubscription, err error) {
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if sub.ID != "1" {
t.Fatalf("want %v but %v", "1", sub.ID)
}
if sub.Endpoint != "https://example.org" {
t.Fatalf("want %v but %v", "https://example.org", sub.Endpoint)
}
if sub.ServerKey != "foobar" {
t.Fatalf("want %v but %v", "foobar", sub.ServerKey)
}
if *sub.Alerts.Favourite != true {
t.Fatalf("want %v but %v", true, *sub.Alerts.Favourite)
}
if *sub.Alerts.Mention != true {
t.Fatalf("want %v but %v", true, *sub.Alerts.Mention)
}
if *sub.Alerts.Reblog != true {
t.Fatalf("want %v but %v", true, *sub.Alerts.Reblog)
}
if *sub.Alerts.Follow != true {
t.Fatalf("want %v but %v", true, *sub.Alerts.Follow)
}
}
sub, err := client.AddPushSubscription(context.Background(), "http://example.org", priv.PublicKey, shared, alerts)
testSub(sub, err)
sub, err = client.GetPushSubscription(context.Background())
testSub(sub, err)
sub, err = client.UpdatePushSubscription(context.Background(), &alerts)
testSub(sub, err)
err = client.RemovePushSubscription(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}

View File

@ -1,145 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetPoll(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/polls/1234567" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id": "1234567", "expires_at": "2019-12-05T04:05:08.302Z", "expired": true, "multiple": false, "votes_count": 10, "voters_count": null, "voted": true, "own_votes": [1], "options": [{"title": "accept", "votes_count": 6}, {"title": "deny", "votes_count": 4}], "emojis":[{"shortcode":"💩", "url":"http://example.com", "static_url": "http://example.com/static"}]}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetPoll(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
poll, err := client.GetPoll(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if poll.Expired != true {
t.Fatalf("want %t but %t", true, poll.Expired)
}
if poll.Multiple != false {
t.Fatalf("want %t but %t", true, poll.Multiple)
}
if poll.VotesCount != 10 {
t.Fatalf("want %d but %d", 10, poll.VotesCount)
}
if poll.VotersCount != 0 {
t.Fatalf("want %d but %d", 0, poll.VotersCount)
}
if poll.Voted != true {
t.Fatalf("want %t but %t", true, poll.Voted)
}
if len(poll.OwnVotes) != 1 {
t.Fatalf("should have own votes")
}
if poll.OwnVotes[0] != 1 {
t.Fatalf("want %d but %d", 1, poll.OwnVotes[0])
}
if len(poll.Options) != 2 {
t.Fatalf("should have 2 options")
}
if poll.Options[0].Title != "accept" {
t.Fatalf("want %q but %q", "accept", poll.Options[0].Title)
}
if poll.Options[0].VotesCount != 6 {
t.Fatalf("want %q but %q", 6, poll.Options[0].VotesCount)
}
if poll.Options[1].Title != "deny" {
t.Fatalf("want %q but %q", "deny", poll.Options[1].Title)
}
if poll.Options[1].VotesCount != 4 {
t.Fatalf("want %q but %q", 4, poll.Options[1].VotesCount)
}
if len(poll.Emojis) != 1 {
t.Fatal("should have emojis")
}
if poll.Emojis[0].ShortCode != "💩" {
t.Fatalf("want %q but %q", "💩", poll.Emojis[0].ShortCode)
}
if poll.Emojis[0].URL != "http://example.com" {
t.Fatalf("want %q but %q", "https://example.com", poll.Emojis[0].URL)
}
if poll.Emojis[0].StaticURL != "http://example.com/static" {
t.Fatalf("want %q but %q", "https://example.com/static", poll.Emojis[0].StaticURL)
}
}
func TestPollVote(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/polls/1234567/votes" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "POST" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusMethodNotAllowed)
return
}
fmt.Fprintln(w, `{"id": "1234567", "expires_at": "2019-12-05T04:05:08.302Z", "expired": false, "multiple": false, "votes_count": 10, "voters_count": null, "voted": true, "own_votes": [1], "options": [{"title": "accept", "votes_count": 6}, {"title": "deny", "votes_count": 4}], "emojis":[]}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
poll, err := client.PollVote(context.Background(), ID("1234567"), 1)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if poll.Expired != false {
t.Fatalf("want %t but %t", false, poll.Expired)
}
if poll.Multiple != false {
t.Fatalf("want %t but %t", true, poll.Multiple)
}
if poll.VotesCount != 10 {
t.Fatalf("want %d but %d", 10, poll.VotesCount)
}
if poll.VotersCount != 0 {
t.Fatalf("want %d but %d", 0, poll.VotersCount)
}
if poll.Voted != true {
t.Fatalf("want %t but %t", true, poll.Voted)
}
if len(poll.OwnVotes) != 1 {
t.Fatalf("should have own votes")
}
if poll.OwnVotes[0] != 1 {
t.Fatalf("want %d but %d", 1, poll.OwnVotes[0])
}
if len(poll.Options) != 2 {
t.Fatalf("should have 2 options")
}
if poll.Options[0].Title != "accept" {
t.Fatalf("want %q but %q", "accept", poll.Options[0].Title)
}
if poll.Options[0].VotesCount != 6 {
t.Fatalf("want %q but %q", 6, poll.Options[0].VotesCount)
}
if poll.Options[1].Title != "deny" {
t.Fatalf("want %q but %q", "deny", poll.Options[1].Title)
}
if poll.Options[1].VotesCount != 4 {
t.Fatalf("want %q but %q", 4, poll.Options[1].VotesCount)
}
}

View File

@ -1,90 +0,0 @@
package mastodon
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetReports(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/reports" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"id": 122, "action_taken": false}, {"id": 123, "action_taken": true}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
rs, err := client.GetReports(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(rs) != 2 {
t.Fatalf("result should be two: %d", len(rs))
}
if rs[0].ID != 122 {
t.Fatalf("want %v but %v", 122, rs[0].ID)
}
if rs[1].ID != 123 {
t.Fatalf("want %v but %v", 123, rs[1].ID)
}
}
func TestReport(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/reports" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.FormValue("account_id") != "122" && r.FormValue("account_id") != "123" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.FormValue("account_id") == "122" {
fmt.Fprintln(w, `{"id": 1234, "action_taken": false}`)
} else {
fmt.Fprintln(w, `{"id": 1234, "action_taken": true}`)
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Report(context.Background(), "121", nil, "")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rp, err := client.Report(context.Background(), "122", nil, "")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rp.ID != 1234 {
t.Fatalf("want %q but %q", "1234", rp.ID)
}
if rp.ActionTaken {
t.Fatalf("want %v but %v", true, rp.ActionTaken)
}
rp, err = client.Report(context.Background(), "123", []ID{"567"}, "")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if rp.ID != 1234 {
t.Fatalf("want %q but %q", "1234", rp.ID)
}
if !rp.ActionTaken {
t.Fatalf("want %v but %v", false, rp.ActionTaken)
}
}

View File

@ -1,788 +0,0 @@
package mastodon
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"testing"
)
func TestGetFavourites(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `[{"content": "foo"}, {"content": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
favs, err := client.GetFavourites(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(favs) != 2 {
t.Fatalf("result should be two: %d", len(favs))
}
if favs[0].Content != "foo" {
t.Fatalf("want %q but %q", "foo", favs[0].Content)
}
if favs[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", favs[1].Content)
}
}
func TestGetBookmarks(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `[{"content": "foo"}, {"content": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
books, err := client.GetBookmarks(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(books) != 2 {
t.Fatalf("result should be two: %d", len(books))
}
if books[0].Content != "foo" {
t.Fatalf("want %q but %q", "foo", books[0].Content)
}
if books[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", books[1].Content)
}
}
func TestGetStatus(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz", "emojis":[{"shortcode":"💩", "url":"http://example.com", "static_url": "http://example.com/static"}]}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetStatus(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.GetStatus(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
if len(status.Emojis) != 1 {
t.Fatal("should have emojis")
}
if status.Emojis[0].ShortCode != "💩" {
t.Fatalf("want %q but %q", "💩", status.Emojis[0].ShortCode)
}
if status.Emojis[0].URL != "http://example.com" {
t.Fatalf("want %q but %q", "https://example.com", status.Emojis[0].URL)
}
if status.Emojis[0].StaticURL != "http://example.com/static" {
t.Fatalf("want %q but %q", "https://example.com/static", status.Emojis[0].StaticURL)
}
}
func TestGetStatusCard(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/card" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"title": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetStatusCard(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
card, err := client.GetStatusCard(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if card.Title != "zzz" {
t.Fatalf("want %q but %q", "zzz", card.Title)
}
}
func TestGetStatusContext(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/context" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"ancestors": [{"content": "zzz"},{"content": "bbb"}]}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetStatusContext(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
context, err := client.GetStatusContext(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(context.Ancestors) != 2 {
t.Fatalf("Ancestors should have 2 entries but %q", len(context.Ancestors))
}
if context.Ancestors[0].Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", context.Ancestors[0].Content)
}
if context.Ancestors[1].Content != "bbb" {
t.Fatalf("want %q but %q", "bbb", context.Ancestors[1].Content)
}
if len(context.Descendants) > 0 {
t.Fatalf("Descendants should not be included")
}
}
func TestGetRebloggedBy(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/reblogged_by" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetRebloggedBy(context.Background(), "123", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
rbs, err := client.GetRebloggedBy(context.Background(), "1234567", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(rbs) != 2 {
t.Fatalf("result should be two: %d", len(rbs))
}
if rbs[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", rbs[0].Username)
}
if rbs[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", rbs[1].Username)
}
}
func TestGetFavouritedBy(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/favourited_by" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"username": "foo"}, {"username": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetFavouritedBy(context.Background(), "123", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
fbs, err := client.GetFavouritedBy(context.Background(), "1234567", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(fbs) != 2 {
t.Fatalf("result should be two: %d", len(fbs))
}
if fbs[0].Username != "foo" {
t.Fatalf("want %q but %q", "foo", fbs[0].Username)
}
if fbs[1].Username != "bar" {
t.Fatalf("want %q but %q", "bar", fbs[1].Username)
}
}
func TestReblog(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/reblog" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Reblog(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.Reblog(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
}
func TestUnreblog(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/unreblog" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Unreblog(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.Unreblog(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
}
func TestFavourite(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/favourite" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Favourite(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.Favourite(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
}
func TestUnfavourite(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/unfavourite" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Unfavourite(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.Unfavourite(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
}
func TestBookmark(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/bookmark" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Bookmark(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.Bookmark(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
}
func TestUnbookmark(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567/unbookmark" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"content": "zzz"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.Unbookmark(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
status, err := client.Unbookmark(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if status.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", status.Content)
}
}
func TestGetTimelinePublic(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("local") == "" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[{"content": "foo"}, {"content": "bar"}]`)
}))
defer ts.Close()
client := NewClient(&Config{Server: ts.URL})
_, err := client.GetTimelinePublic(context.Background(), false, nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
tl, err := client.GetTimelinePublic(context.Background(), true, nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(tl) != 2 {
t.Fatalf("result should be two: %d", len(tl))
}
if tl[0].Content != "foo" {
t.Fatalf("want %q but %q", "foo", tl[0].Content)
}
if tl[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", tl[1].Content)
}
}
func TestGetTimelineDirect(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `[{"id": "4", "unread":false, "last_status" : {"content": "zzz"}}, {"id": "3", "unread":true, "last_status" : {"content": "bar"}}]`)
}))
defer ts.Close()
client := NewClient(&Config{Server: ts.URL})
tl, err := client.GetTimelineDirect(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(tl) != 2 {
t.Fatalf("result should be two: %d", len(tl))
}
if tl[0].Content != "zzz" {
t.Fatalf("want %q but %q", "foo", tl[0].Content)
}
if tl[1].Content != "bar" {
t.Fatalf("want %q but %q", "bar", tl[1].Content)
}
}
func TestGetTimelineHashtag(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/timelines/tag/zzz" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"content": "zzz"},{"content": "yyy"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetTimelineHashtag(context.Background(), "notfound", false, nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
tags, err := client.GetTimelineHashtag(context.Background(), "zzz", true, nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(tags) != 2 {
t.Fatalf("should have %q entries but %q", "2", len(tags))
}
if tags[0].Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", tags[0].Content)
}
if tags[1].Content != "yyy" {
t.Fatalf("want %q but %q", "zzz", tags[1].Content)
}
}
func TestGetTimelineList(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/timelines/list/1" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"content": "zzz"},{"content": "yyy"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetTimelineList(context.Background(), "notfound", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
tags, err := client.GetTimelineList(context.Background(), "1", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(tags) != 2 {
t.Fatalf("should have %q entries but %q", "2", len(tags))
}
if tags[0].Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", tags[0].Content)
}
if tags[1].Content != "yyy" {
t.Fatalf("want %q but %q", "zzz", tags[1].Content)
}
}
func TestGetTimelineMedia(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("local") == "" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `[{"content": "zzz"},{"content": "yyy"}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetTimelineMedia(context.Background(), false, nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
tags, err := client.GetTimelineMedia(context.Background(), true, nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(tags) != 2 {
t.Fatalf("should have %q entries but %q", "2", len(tags))
}
if tags[0].Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", tags[0].Content)
}
if tags[1].Content != "yyy" {
t.Fatalf("want %q but %q", "zzz", tags[1].Content)
}
}
func TestDeleteStatus(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/statuses/1234567" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "DELETE" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusMethodNotAllowed)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.DeleteStatus(context.Background(), "123")
if err == nil {
t.Fatalf("should be fail: %v", err)
}
err = client.DeleteStatus(context.Background(), "1234567")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestSearch(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v2/search" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.RequestURI != "/api/v2/search?q=q&resolve=false" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusBadRequest)
return
}
fmt.Fprintln(w, `
{"accounts":[{"username": "zzz"},{"username": "yyy"}],
"statuses":[{"content": "aaa"}],
"hashtags":[{"name": "tag"},{"name": "tag2"},{"name": "tag3"}]
}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
ret, err := client.Search(context.Background(), "q", false)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(ret.Accounts) != 2 {
t.Fatalf("Accounts have %q entries, but %q", "2", len(ret.Accounts))
}
if ret.Accounts[0].Username != "zzz" {
t.Fatalf("Accounts Username should %q , but %q", "zzz", ret.Accounts[0].Username)
}
if len(ret.Statuses) != 1 {
t.Fatalf("Statuses have %q entries, but %q", "1", len(ret.Statuses))
}
if ret.Statuses[0].Content != "aaa" {
t.Fatalf("Statuses Content should %q , but %q", "aaa", ret.Statuses[0].Content)
}
if len(ret.Hashtags) != 3 {
t.Fatalf("Hashtags have %q entries, but %q", "3", len(ret.Hashtags))
}
if ret.Hashtags[2].Name != "tag3" {
t.Fatalf("Hashtags[2] should %q , but %q", "tag3", ret.Hashtags[2])
}
}
func TestUploadMedia(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/media" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "POST" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"id": 123}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
attachment, err := client.UploadMedia(context.Background(), "testdata/logo.png")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if attachment.ID != "123" {
t.Fatalf("want %q but %q", "123", attachment.ID)
}
file, err := os.Open("testdata/logo.png")
if err != nil {
t.Fatalf("could not open file: %v", err)
}
defer file.Close()
writerAttachment, err := client.UploadMediaFromReader(context.Background(), file)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if writerAttachment.ID != "123" {
t.Fatalf("want %q but %q", "123", attachment.ID)
}
bytes, err := ioutil.ReadFile("testdata/logo.png")
if err != nil {
t.Fatalf("could not open file: %v", err)
}
byteAttachment, err := client.UploadMediaFromBytes(context.Background(), bytes)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if byteAttachment.ID != "123" {
t.Fatalf("want %q but got %q", "123", attachment.ID)
}
}
func TestGetConversations(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/conversations" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}
fmt.Fprintln(w, `[{"id": "4", "unread":false, "last_status" : {"content": "zzz"}}, {"id": "3", "unread":true, "last_status" : {"content": "bar"}}]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
convs, err := client.GetConversations(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(convs) != 2 {
t.Fatalf("result should be 2: %d", len(convs))
}
if convs[0].ID != "4" {
t.Fatalf("want %q but %q", "4", convs[0].ID)
}
if convs[0].LastStatus.Content != "zzz" {
t.Fatalf("want %q but %q", "zzz", convs[0].LastStatus.Content)
}
if convs[1].Unread != true {
t.Fatalf("unread should be true: %t", convs[1].Unread)
}
}
func TestDeleteConversation(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/conversations/12345678" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "DELETE" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusMethodNotAllowed)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "hoge",
})
err := client.DeleteConversation(context.Background(), "12345678")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestMarkConversationsAsRead(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/conversations/111111/read" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
if r.Method != "POST" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
err := client.MarkConversationAsRead(context.Background(), "111111")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}

View File

@ -1,384 +0,0 @@
package mastodon
import (
"bufio"
"context"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
func TestHandleReader(t *testing.T) {
large := "large"
largeContent := strings.Repeat(large, 2*(bufio.MaxScanTokenSize/len(large)))
q := make(chan Event)
r := strings.NewReader(fmt.Sprintf(`
event: update
data: {content: error}
event: update
data: {"content": "foo"}
event: update
data: {"content": "%s"}
event: notification
data: {"type": "mention"}
event: delete
data: 1234567
:thump
`, largeContent))
go func() {
defer close(q)
err := handleReader(q, r)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}()
var passUpdate, passUpdateLarge, passNotification, passDelete, passError bool
for e := range q {
switch event := e.(type) {
case *UpdateEvent:
if event.Status.Content == "foo" {
passUpdate = true
} else if event.Status.Content == largeContent {
passUpdateLarge = true
} else {
t.Fatalf("bad update content: %q", event.Status.Content)
}
case *NotificationEvent:
passNotification = true
if event.Notification.Type != "mention" {
t.Fatalf("want %q but %q", "mention", event.Notification.Type)
}
case *DeleteEvent:
passDelete = true
if event.ID != "1234567" {
t.Fatalf("want %q but %q", "1234567", event.ID)
}
case *ErrorEvent:
passError = true
if event.err == nil {
t.Fatalf("should be fail: %v", event.err)
}
}
}
if !passUpdate || !passUpdateLarge || !passNotification || !passDelete || !passError {
t.Fatalf("have not passed through somewhere: "+
"update: %t, update (large): %t, notification: %t, delete: %t, error: %t",
passUpdate, passUpdateLarge, passNotification, passDelete, passError)
}
}
func TestStreaming(t *testing.T) {
var isEnd bool
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isEnd {
return
} else if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
f := w.(http.Flusher)
fmt.Fprintln(w, `
event: update
data: {"content": "foo"}
`)
f.Flush()
isEnd = true
}))
defer ts.Close()
c := NewClient(&Config{Server: ":"})
_, err := c.streaming(context.Background(), "", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
c = NewClient(&Config{Server: ts.URL})
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(time.Second, cancel)
q, err := c.streaming(ctx, "", nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
var cnt int
var passError, passUpdate bool
for e := range q {
switch event := e.(type) {
case *ErrorEvent:
passError = true
if event.err == nil {
t.Fatalf("should be fail: %v", event.err)
}
case *UpdateEvent:
cnt++
passUpdate = true
if event.Status.Content != "foo" {
t.Fatalf("want %q but %q", "foo", event.Status.Content)
}
}
}
if cnt != 1 {
t.Fatalf("result should be one: %d", cnt)
}
if !passError || !passUpdate {
t.Fatalf("have not passed through somewhere: error %t, update %t", passError, passUpdate)
}
}
func TestDoStreaming(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.(http.Flusher).Flush()
time.Sleep(time.Second)
}))
defer ts.Close()
c := NewClient(&Config{Server: ts.URL})
req, err := http.NewRequest(http.MethodGet, ts.URL, nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(time.Millisecond, cancel)
req = req.WithContext(ctx)
q := make(chan Event)
go func() {
defer close(q)
c.doStreaming(req, q)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}()
var passError bool
for e := range q {
if event, ok := e.(*ErrorEvent); ok {
passError = true
if event.err == nil {
t.Fatalf("should be fail: %v", event.err)
}
}
}
if !passError {
t.Fatalf("have not passed through: error %t", passError)
}
}
func TestStreamingUser(t *testing.T) {
var isEnd bool
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isEnd {
return
} else if r.URL.Path != "/api/v1/streaming/user" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
f, _ := w.(http.Flusher)
fmt.Fprintln(w, `
event: update
data: {"content": "foo"}
`)
f.Flush()
isEnd = true
}))
defer ts.Close()
c := NewClient(&Config{Server: ts.URL})
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(time.Second, cancel)
q, err := c.StreamingUser(ctx)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
events := []Event{}
for e := range q {
if _, ok := e.(*ErrorEvent); !ok {
events = append(events, e)
}
}
if len(events) != 1 {
t.Fatalf("result should be one: %d", len(events))
}
if events[0].(*UpdateEvent).Status.Content != "foo" {
t.Fatalf("want %q but %q", "foo", events[0].(*UpdateEvent).Status.Content)
}
}
func TestStreamingPublic(t *testing.T) {
var isEnd bool
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isEnd {
return
} else if r.URL.Path != "/api/v1/streaming/public/local" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
f, _ := w.(http.Flusher)
fmt.Fprintln(w, `
event: update
data: {"content": "foo"}
`)
f.Flush()
fmt.Fprintln(w, `
event: update
data: {"content": "bar"}
`)
f.Flush()
isEnd = true
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
ctx, cancel := context.WithCancel(context.Background())
q, err := client.StreamingPublic(ctx, true)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
time.AfterFunc(time.Second, cancel)
events := []Event{}
for e := range q {
if _, ok := e.(*ErrorEvent); !ok {
events = append(events, e)
}
}
if len(events) != 2 {
t.Fatalf("result should be two: %d", len(events))
}
if events[0].(*UpdateEvent).Status.Content != "foo" {
t.Fatalf("want %q but %q", "foo", events[0].(*UpdateEvent).Status.Content)
}
if events[1].(*UpdateEvent).Status.Content != "bar" {
t.Fatalf("want %q but %q", "bar", events[1].(*UpdateEvent).Status.Content)
}
}
func TestStreamingHashtag(t *testing.T) {
var isEnd bool
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isEnd {
return
} else if r.URL.Path != "/api/v1/streaming/hashtag/local" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
f, _ := w.(http.Flusher)
fmt.Fprintln(w, `
event: update
data: {"content": "foo"}
`)
f.Flush()
isEnd = true
}))
defer ts.Close()
client := NewClient(&Config{Server: ts.URL})
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(time.Second, cancel)
q, err := client.StreamingHashtag(ctx, "hashtag", true)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
events := []Event{}
for e := range q {
if _, ok := e.(*ErrorEvent); !ok {
events = append(events, e)
}
}
if len(events) != 1 {
t.Fatalf("result should be one: %d", len(events))
}
if events[0].(*UpdateEvent).Status.Content != "foo" {
t.Fatalf("want %q but %q", "foo", events[0].(*UpdateEvent).Status.Content)
}
}
func TestStreamingList(t *testing.T) {
var isEnd bool
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isEnd {
return
} else if r.URL.Path != "/api/v1/streaming/list" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
f, _ := w.(http.Flusher)
fmt.Fprintln(w, `
event: update
data: {"content": "foo"}
`)
f.Flush()
isEnd = true
}))
defer ts.Close()
client := NewClient(&Config{Server: ts.URL})
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(time.Second, cancel)
q, err := client.StreamingList(ctx, "1")
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
events := []Event{}
for e := range q {
if _, ok := e.(*ErrorEvent); !ok {
events = append(events, e)
}
}
if len(events) != 1 {
t.Fatalf("result should be one: %d", len(events))
}
if events[0].(*UpdateEvent).Status.Content != "foo" {
t.Fatalf("want %q but %q", "foo", events[0].(*UpdateEvent).Status.Content)
}
}
func TestStreamingDirect(t *testing.T) {
var isEnd bool
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isEnd {
return
} else if r.URL.Path != "/api/v1/streaming/direct" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
f, _ := w.(http.Flusher)
fmt.Fprintln(w, `
event: update
data: {"content": "foo"}
`)
f.Flush()
isEnd = true
}))
defer ts.Close()
client := NewClient(&Config{Server: ts.URL})
ctx, cancel := context.WithCancel(context.Background())
time.AfterFunc(time.Second, cancel)
q, err := client.StreamingDirect(ctx)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
events := []Event{}
for e := range q {
if _, ok := e.(*ErrorEvent); !ok {
events = append(events, e)
}
}
if len(events) != 1 {
t.Fatalf("result should be one: %d", len(events))
}
if events[0].(*UpdateEvent).Status.Content != "foo" {
t.Fatalf("want %q but %q", "foo", events[0].(*UpdateEvent).Status.Content)
}
}

BIN
testdata/logo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB