Skip to content

Commit 6921a44

Browse files
committed
Minor improvements + improve test coverage
1 parent 62f955e commit 6921a44

File tree

2 files changed

+184
-24
lines changed

2 files changed

+184
-24
lines changed

pastebin.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ func (c *Client) doPastebinRequest(apiUrl string, fields url.Values, reAuthentic
211211
// You may want to use GetPasteContentUsingScrapingAPI instead.
212212
func GetPasteContent(pasteKey string) (string, error) {
213213
client := getHTTPClient()
214-
request, err := http.NewRequest("GET", fmt.Sprintf("%s/%s", RawUrlPrefix, pasteKey), nil)
214+
request, err := http.NewRequest("GET", RawUrlPrefix+"/"+pasteKey, nil)
215215
if err != nil {
216216
return "", err
217217
}
@@ -237,7 +237,7 @@ func GetPasteContent(pasteKey string) (string, error) {
237237
// See https://pastebin.com/doc_scraping_api
238238
func GetPasteContentUsingScrapingAPI(pasteKey string) (string, error) {
239239
client := getHTTPClient()
240-
request, err := http.NewRequest("GET", fmt.Sprintf("%s?%s", ScrapeItemApiUrl, url.Values{"i": {pasteKey}}.Encode()), nil)
240+
request, err := http.NewRequest("GET", ScrapeItemApiUrl+"?"+url.Values{"i": {pasteKey}}.Encode(), nil)
241241
if err != nil {
242242
return "", err
243243
}
@@ -263,7 +263,7 @@ func GetPasteContentUsingScrapingAPI(pasteKey string) (string, error) {
263263
// See https://pastebin.com/doc_scraping_api
264264
func GetPasteUsingScrapingAPI(pasteKey string) (*Paste, error) {
265265
client := getHTTPClient()
266-
request, err := http.NewRequest("GET", fmt.Sprintf("%s?%s", ScrapeItemMetadataApiUrl, url.Values{"i": {pasteKey}}.Encode()), nil)
266+
request, err := http.NewRequest("GET", ScrapeItemMetadataApiUrl+"?"+url.Values{"i": {pasteKey}}.Encode(), nil)
267267
if err != nil {
268268
return nil, err
269269
}
@@ -295,7 +295,7 @@ func GetPasteUsingScrapingAPI(pasteKey string) (*Paste, error) {
295295
// See https://pastebin.com/doc_scraping_api
296296
func GetRecentPastesUsingScrapingAPI(syntax string, limit int) ([]*Paste, error) {
297297
client := getHTTPClient()
298-
request, err := http.NewRequest("POST", fmt.Sprintf("%s?%s", ScrapingApiUrl, url.Values{"lang": {syntax}, "limit": {strconv.Itoa(limit)}}.Encode()), nil)
298+
request, err := http.NewRequest("POST", ScrapingApiUrl+"?"+url.Values{"lang": {syntax}, "limit": {strconv.Itoa(limit)}}.Encode(), nil)
299299
if err != nil {
300300
return nil, err
301301
}
@@ -313,6 +313,7 @@ func GetRecentPastesUsingScrapingAPI(syntax string, limit int) ([]*Paste, error)
313313
return nil, errors.New(string(body))
314314
}
315315
var jsonPastes jsonPastes
316+
// the output isn't formatted properly, so we'll cheat a bit
316317
err = json.Unmarshal([]byte(fmt.Sprintf("{\"pastes\":%s}", string(body))), &jsonPastes)
317318
if err != nil {
318319
return nil, err

pastebin_test.go

Lines changed: 179 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,86 @@ func init() {
2727
}
2828

2929
func TestNewClient(t *testing.T) {
30+
client = &mockClient{
31+
DoFunc: func(request *http.Request) (*http.Response, error) {
32+
body, _ := ioutil.ReadAll(request.Body)
33+
defer request.Body.Close()
34+
if request.URL.String() == LoginApiUrl && string(body) == "api_dev_key=token&api_user_name=username&api_user_password=password" {
35+
return &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBufferString("session-key"))}, nil
36+
}
37+
return &http.Response{
38+
StatusCode: 403,
39+
Body: ioutil.NopCloser(bytes.NewBufferString("forbidden")),
40+
}, nil
41+
},
42+
}
43+
client, _ := NewClient("username", "password", "token")
44+
if client.sessionKey != "session-key" {
45+
t.Errorf("expected %s, got %s", "session-key", client.sessionKey)
46+
}
47+
}
48+
49+
func TestNewClientWithoutUsernameAndPassword(t *testing.T) {
3050
client, err := NewClient("", "", "token")
3151
if err != nil {
32-
t.Fatal("Shouldn't have returned an error, because the only reason an error could be returned is if client.login() was called, but the username was not specified therefore client.login() shouldn't have returned an error")
52+
t.Fatal("shouldn't have returned an error, because the only reason an error could be returned is if client.login() was called, but the username was not specified therefore client.login() shouldn't have returned an error")
3353
}
3454
if client.developerApiKey != "token" {
3555
t.Errorf("expected %s, got %s", "token", client.developerApiKey)
3656
}
3757
}
3858

3959
func TestClient_DeletePaste(t *testing.T) {
60+
client = &mockClient{
61+
DoFunc: func(request *http.Request) (*http.Response, error) {
62+
body, _ := ioutil.ReadAll(request.Body)
63+
defer request.Body.Close()
64+
if request.URL.String() == LoginApiUrl && string(body) == "api_dev_key=token&api_user_name=username&api_user_password=password" {
65+
return &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBufferString("session-key"))}, nil
66+
}
67+
if request.URL.String() == RawApiUrl && string(body) == "api_dev_key=token&api_option=delete&api_paste_key=paste-key&api_user_key=session-key" {
68+
return &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewBufferString("deleted"))}, nil
69+
}
70+
return &http.Response{
71+
StatusCode: 400,
72+
Body: ioutil.NopCloser(bytes.NewBufferString("bad request")),
73+
}, nil
74+
},
75+
}
76+
client, _ := NewClient("username", "password", "token")
77+
err := client.DeletePaste("paste-key")
78+
if err != nil {
79+
t.Fatal("shouldn't have returned an error, got", err.Error())
80+
}
81+
}
82+
83+
func TestClient_DeletePasteWhenNotAuthenticated(t *testing.T) {
4084
client, _ := NewClient("", "", "token")
4185
err := client.DeletePaste("paste-key")
4286
if err != ErrNotAuthenticated {
43-
t.Error("DeletePaste should've instantly returned ErrNotAuthenticated, because only a client configured with a username and password can delete a paste")
87+
t.Error("DeletePaste should've returned ErrNotAuthenticated, because only a client configured with a username and password can delete a paste")
4488
}
4589
}
4690

4791
func TestClient_CreatePaste(t *testing.T) {
4892
client = &mockClient{
4993
DoFunc: func(request *http.Request) (*http.Response, error) {
94+
if request.URL.String() == LoginApiUrl {
95+
return &http.Response{
96+
StatusCode: 200,
97+
Body: ioutil.NopCloser(bytes.NewBufferString("session-key")),
98+
}, nil
99+
}
50100
return &http.Response{
51101
StatusCode: 200,
52102
Body: ioutil.NopCloser(bytes.NewBufferString("https://pastebin.com/abcdefgh")),
53103
}, nil
54104
},
55105
}
56106
client, _ := NewClient("username", "password", "token")
57-
pasteKey, err := client.CreatePaste(NewCreatePasteRequest("", "", ExpirationTenMinutes, VisibilityPrivate, ""))
107+
pasteKey, err := client.CreatePaste(NewCreatePasteRequest("", "", ExpirationTenMinutes, VisibilityPublic, ""))
58108
if err != nil {
59-
t.Error("Shouldn't have returned an error")
109+
t.Error("shouldn't have returned an error")
60110
}
61111
if pasteKey != "abcdefgh" {
62112
t.Errorf("expected %s, got %s", "abcdefgh", pasteKey)
@@ -71,6 +121,90 @@ func TestClient_CreatePasteWithPrivateVisibility(t *testing.T) {
71121
}
72122
}
73123

124+
func TestClient_CreatePasteWhenHTTPRequestReturnsError(t *testing.T) {
125+
client = &mockClient{
126+
DoFunc: func(request *http.Request) (*http.Response, error) {
127+
if request.URL.String() == LoginApiUrl {
128+
return &http.Response{
129+
StatusCode: 200,
130+
Body: ioutil.NopCloser(bytes.NewBufferString("session-key")),
131+
}, nil
132+
}
133+
return &http.Response{
134+
StatusCode: 403,
135+
Body: ioutil.NopCloser(bytes.NewBufferString("error")),
136+
}, nil
137+
},
138+
}
139+
client, _ := NewClient("username", "password", "token")
140+
_, err := client.CreatePaste(NewCreatePasteRequest("", "", ExpirationTenMinutes, VisibilityPublic, ""))
141+
if err == nil {
142+
t.Error("should've returned an error")
143+
}
144+
}
145+
146+
func TestClient_CreatePasteWhenSessionKeyExpired(t *testing.T) {
147+
numberOfCallsToLoginApiUrl := 0
148+
client = &mockClient{
149+
DoFunc: func(request *http.Request) (*http.Response, error) {
150+
if request.URL.String() == LoginApiUrl {
151+
numberOfCallsToLoginApiUrl++
152+
return &http.Response{
153+
StatusCode: 200,
154+
Body: ioutil.NopCloser(bytes.NewBufferString("session-key")),
155+
}, nil
156+
}
157+
// Mock the behavior of an expired sessionKey, which should trigger an automatic re-login
158+
if numberOfCallsToLoginApiUrl == 1 {
159+
return &http.Response{
160+
StatusCode: 200,
161+
Body: ioutil.NopCloser(bytes.NewBufferString("Bad API request, invalid api_user_key")),
162+
}, nil
163+
}
164+
return &http.Response{
165+
StatusCode: 200,
166+
Body: ioutil.NopCloser(bytes.NewBufferString("https://pastebin.com/abcdefgh")),
167+
}, nil
168+
},
169+
}
170+
client, _ := NewClient("username", "password", "token")
171+
pasteKey, err := client.CreatePaste(NewCreatePasteRequest("", "", ExpirationTenMinutes, VisibilityPublic, ""))
172+
if err != nil {
173+
t.Fatal("shouldn't have returned an error")
174+
}
175+
if pasteKey != "abcdefgh" {
176+
t.Errorf("expected %s, got %s", "abcdefgh", pasteKey)
177+
}
178+
if numberOfCallsToLoginApiUrl != 2 {
179+
t.Errorf("expected %d calls to LoginApiUrl, got %s", 2, pasteKey)
180+
}
181+
}
182+
183+
func TestClient_GetUserPasteContent(t *testing.T) {
184+
client = &mockClient{
185+
DoFunc: func(request *http.Request) (*http.Response, error) {
186+
if request.URL.String() == LoginApiUrl {
187+
return &http.Response{
188+
StatusCode: 200,
189+
Body: ioutil.NopCloser(bytes.NewBufferString("session-key")),
190+
}, nil
191+
}
192+
return &http.Response{
193+
StatusCode: 200,
194+
Body: ioutil.NopCloser(bytes.NewBufferString("content")),
195+
}, nil
196+
},
197+
}
198+
client, _ := NewClient("username", "password", "token")
199+
content, err := client.GetUserPasteContent("does-not-matter-because-client-is-mocked")
200+
if err != nil {
201+
t.Error("shouldn't have returned an error")
202+
}
203+
if content != "content" {
204+
t.Errorf("expected %s, got %s", "content", content)
205+
}
206+
}
207+
74208
func TestClient_GetAllUserPastes(t *testing.T) {
75209
client = &mockClient{
76210
DoFunc: func(request *http.Request) (*http.Response, error) {
@@ -94,42 +228,42 @@ func TestClient_GetAllUserPastes(t *testing.T) {
94228
client, _ := NewClient("username", "password", "token")
95229
pastes, err := client.GetAllUserPastes()
96230
if err != nil {
97-
t.Error("Shouldn't have returned an error")
231+
t.Error("shouldn't have returned an error")
98232
}
99233
if len(pastes) != 1 {
100-
t.Error("Should've returned 1 paste, but returned", len(pastes))
234+
t.Error("should've returned 1 paste, but returned", len(pastes))
101235
}
102236
if ExpectedUser := "username"; pastes[0].User != ExpectedUser {
103-
t.Errorf("Expected User to be '%s', got '%s'", ExpectedUser, pastes[0].User)
237+
t.Errorf("expected User to be '%s', got '%s'", ExpectedUser, pastes[0].User)
104238
}
105239
if ExpectedKey := "fakefake"; pastes[0].Key != ExpectedKey {
106-
t.Errorf("Expected Key to be '%s', got '%s'", ExpectedKey, pastes[0].Key)
240+
t.Errorf("expected Key to be '%s', got '%s'", ExpectedKey, pastes[0].Key)
107241
}
108242
if ExpectedTitle := "Fake Paste"; pastes[0].Title != ExpectedTitle {
109-
t.Errorf("Expected Title to be '%s', got '%s'", ExpectedTitle, pastes[0].Title)
243+
t.Errorf("expected Title to be '%s', got '%s'", ExpectedTitle, pastes[0].Title)
110244
}
111245
if ExpectedSyntax := "go"; pastes[0].Syntax != ExpectedSyntax {
112-
t.Errorf("Expected Syntax to be '%s', got '%s'", ExpectedSyntax, pastes[0].Syntax)
246+
t.Errorf("expected Syntax to be '%s', got '%s'", ExpectedSyntax, pastes[0].Syntax)
113247
}
114248
if ExpectedSize := 5555; pastes[0].Size != ExpectedSize {
115-
t.Errorf("Expected Size to be '%d', got '%d'", ExpectedSize, pastes[0].Size)
249+
t.Errorf("expected Size to be '%d', got '%d'", ExpectedSize, pastes[0].Size)
116250
}
117251
if ExpectedHits := 9999; pastes[0].Hits != ExpectedHits {
118-
t.Errorf("Expected Hits to be '%d', got '%d'", ExpectedHits, pastes[0].Hits)
252+
t.Errorf("expected Hits to be '%d', got '%d'", ExpectedHits, pastes[0].Hits)
119253
}
120254
if ExpectedVisibility := VisibilityUnlisted; pastes[0].Visibility != ExpectedVisibility {
121-
t.Errorf("Expected Visibility to be '%d', got '%d'", ExpectedVisibility, pastes[0].Visibility)
255+
t.Errorf("expected Visibility to be '%d', got '%d'", ExpectedVisibility, pastes[0].Visibility)
122256
}
123257
if ExpectedDate := int64(1338651885); pastes[0].Date.Unix() != ExpectedDate {
124-
t.Errorf("Expected Date to be '%d', got '%d'", ExpectedDate, pastes[0].Date.Unix())
258+
t.Errorf("expected Date to be '%d', got '%d'", ExpectedDate, pastes[0].Date.Unix())
125259
}
126260
}
127261

128262
func TestClient_GetAllUserPastesWithoutCredentials(t *testing.T) {
129263
client, _ := NewClient("", "", "token")
130264
_, err := client.GetAllUserPastes()
131265
if err != ErrNotAuthenticated {
132-
t.Error("Should've returned ErrNotAuthenticated, but returned", err)
266+
t.Error("should've returned ErrNotAuthenticated, but returned", err)
133267
}
134268
}
135269

@@ -144,10 +278,10 @@ func TestGetPasteContent(t *testing.T) {
144278
}
145279
pasteContent, err := GetPasteContent("abcdefgh")
146280
if err != nil {
147-
t.Fatal("Shouldn't have returned an error, but returned", err)
281+
t.Fatal("shouldn't have returned an error, but returned", err)
148282
}
149283
if pasteContent != "this is code" {
150-
t.Errorf("Expected '%s', got '%s'", "this is code", pasteContent)
284+
t.Errorf("expected '%s', got '%s'", "this is code", pasteContent)
151285
}
152286
}
153287

@@ -162,7 +296,7 @@ func TestGetPasteUsingScrapingAPIWhenPasteKeyInvalid(t *testing.T) {
162296
}
163297
_, err := GetPasteUsingScrapingAPI("")
164298
if ExpectedError := "Error, we cannot find this paste."; err == nil || err.Error() != ExpectedError {
165-
t.Errorf("Error should've been '%s', but was '%s'", ExpectedError, err)
299+
t.Errorf("error should've been '%s', but was '%s'", ExpectedError, err)
166300
}
167301
}
168302

@@ -177,7 +311,7 @@ func TestGetPasteContentUsingScrapingAPIWhenPasteKeyInvalid(t *testing.T) {
177311
}
178312
_, err := GetPasteContentUsingScrapingAPI("")
179313
if ExpectedError := "Error, paste key is not valid."; err == nil || err.Error() != ExpectedError {
180-
t.Errorf("Error should've been '%s', but was '%s'", ExpectedError, err)
314+
t.Errorf("error should've been '%s', but was '%s'", ExpectedError, err)
181315
}
182316
}
183317

@@ -192,6 +326,31 @@ func TestGetPasteContentUsingScrapingAPIWhenIpBlocked(t *testing.T) {
192326
}
193327
_, err := GetPasteContentUsingScrapingAPI("abcdefgh")
194328
if err == nil {
195-
t.Error("Should've returned an error")
329+
t.Error("should've returned an error")
330+
}
331+
}
332+
333+
func TestGetRecentPastesUsingScrapingAPI(t *testing.T) {
334+
client = &mockClient{
335+
DoFunc: func(request *http.Request) (*http.Response, error) {
336+
if request.URL.String() == ScrapingApiUrl+"?lang=go&limit=1" {
337+
return &http.Response{
338+
StatusCode: 200,
339+
Body: ioutil.NopCloser(bytes.NewBufferString(`[{"title":"title"}]`)),
340+
}, nil
341+
}
342+
t.Error(request)
343+
return &http.Response{
344+
StatusCode: 400,
345+
Body: ioutil.NopCloser(bytes.NewBufferString("bad request")),
346+
}, nil
347+
},
348+
}
349+
pastes, err := GetRecentPastesUsingScrapingAPI("go", 1)
350+
if err != nil {
351+
t.Fatal("shouldn't have returned an error, got", err.Error())
352+
}
353+
if len(pastes) != 1 {
354+
t.Error("expected 1 paste to be returned")
196355
}
197356
}

0 commit comments

Comments
 (0)