Skip to content

Commit 5220f3e

Browse files
Add [POST] /v1/oauth/token endpoint (#35)
* Add [POST] /v1/oauth/token endpoint * Add timeout tests... * Add docs for OAuth * Rename sample board to prevent race condition
1 parent a0f8353 commit 5220f3e

6 files changed

+128
-5
lines changed

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ if pinterestError, ok := err.(*models.PinterestError); ok {
9595
}
9696
```
9797

98+
## OAuth Endpoints
99+
100+
### Generate Access Token
101+
102+
`[POST] /v1/oauth/token`
103+
104+
```go
105+
accessToken, err := client.OAuth.Token.Create(
106+
"client-id",
107+
"client-secret",
108+
"access-code"
109+
)
110+
```
111+
98112
## Boards Endpoints
99113

100114
### Create a Board

controllers/oauth_controller.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package controllers
2+
3+
import (
4+
"github.com/BrandonRomano/wrecker"
5+
)
6+
7+
// OAuthController is the controller that is responsible
8+
// for all /v1/oauth endpoints in the Pinterest API.
9+
type OAuthController struct {
10+
wreckerClient *wrecker.Wrecker
11+
Token *OAuthTokenController
12+
}
13+
14+
// NewOAuthController instantiates a new OAuthController
15+
func NewOAuthController(wc *wrecker.Wrecker) *OAuthController {
16+
return &OAuthController{
17+
wreckerClient: wc,
18+
Token: newOAuthTokenController(wc),
19+
}
20+
}

controllers/oauth_token_controller.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package controllers
2+
3+
import (
4+
"github.com/BrandonRomano/wrecker"
5+
"github.com/carrot/go-pinterest/models"
6+
)
7+
8+
// OAuthTokenController is the controller that is responsible
9+
// for all /v1/oauth/token endpoints in the Pinterest API.
10+
type OAuthTokenController struct {
11+
wreckerClient *wrecker.Wrecker
12+
}
13+
14+
// newOAuthTokenController instantiates a new OAuthTokenController
15+
func newOAuthTokenController(wc *wrecker.Wrecker) *OAuthTokenController {
16+
return &OAuthTokenController{
17+
wreckerClient: wc,
18+
}
19+
}
20+
21+
// Create generates an access token
22+
// Endpoint: [POST] /v1/oauth/token
23+
func (otc *OAuthTokenController) Create(clientId, clientSecret, accessCode string) (*models.AccessToken, error) {
24+
// Build + execute request
25+
accessToken := new(models.AccessToken)
26+
httpResp, err := otc.wreckerClient.Post("/oauth/token").
27+
URLParam("grant_type", "authorization_code").
28+
URLParam("client_id", clientId).
29+
URLParam("client_secret", clientSecret).
30+
URLParam("code", accessCode).
31+
Into(accessToken).
32+
Execute()
33+
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
if !(httpResp.StatusCode >= 200 && httpResp.StatusCode < 300) {
39+
return nil, &models.PinterestError{
40+
StatusCode: httpResp.StatusCode,
41+
Message: accessToken.Error,
42+
}
43+
}
44+
45+
// OK
46+
return accessToken, nil
47+
}

models/access_token.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package models
2+
3+
// AccessToken is a struct that represents a Access Token
4+
// response from the Pinterest API.
5+
type AccessToken struct {
6+
AccessToken string `json:"access_token"`
7+
TokenType string `json:"token_type"`
8+
Scope []string `json:"scope"`
9+
ErrorDescription string `json:"error_description"`
10+
Error string `json:"error"`
11+
}

pinterest.go

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
// For more information about the Pinterest API,
1818
// check out https://developers.pinterest.com/
1919
type Client struct {
20+
OAuth *controllers.OAuthController
2021
Users *controllers.UsersController
2122
Boards *controllers.BoardsController
2223
Pins *controllers.PinsController
@@ -40,6 +41,7 @@ func NewClient() *Client {
4041
// Build Pinterest client
4142
return &Client{
4243
wreckerClient: wc,
44+
OAuth: controllers.NewOAuthController(wc),
4345
Users: controllers.NewUsersController(wc),
4446
Boards: controllers.NewBoardsController(wc),
4547
Pins: controllers.NewPinsController(wc),

pinterest_test.go

+34-5
Original file line numberDiff line numberDiff line change
@@ -357,18 +357,18 @@ func (suite *ClientTestSuite) TestSuccessfulBoardCUD() {
357357
// Updating the Board
358358
board, err = suite.client.Boards.Update("brandonrromano/go-pinterest-test",
359359
&controllers.BoardUpdateOptionals{
360-
Name: "Go Pinterest Test2",
361-
Description: "Go Pinterest Test2!",
360+
Name: "Go Pinterest Test3",
361+
Description: "Go Pinterest Test3!",
362362
},
363363
)
364364

365365
// Assume there is no error / test result
366366
assert.Equal(suite.T(), nil, err)
367-
assert.Equal(suite.T(), board.Name, "Go Pinterest Test2")
368-
assert.Equal(suite.T(), board.Description, "Go Pinterest Test2!")
367+
assert.Equal(suite.T(), board.Name, "Go Pinterest Test3")
368+
assert.Equal(suite.T(), board.Description, "Go Pinterest Test3!")
369369

370370
// Deleting the board
371-
err = suite.client.Boards.Delete("brandonrromano/go-pinterest-test2")
371+
err = suite.client.Boards.Delete("brandonrromano/go-pinterest-test3")
372372
assert.Equal(suite.T(), nil, err)
373373
}
374374

@@ -1432,3 +1432,32 @@ func (suite *ClientTestSuite) TestUnauthorizedMeSearchPinsFetch() {
14321432
assert.Equal(suite.T(), true, false)
14331433
}
14341434
}
1435+
1436+
// ========================================
1437+
// ========== OAuth.Token.Create ==========
1438+
// ========================================
1439+
1440+
// TestTimeoutOAuthTokenCreate tests that an error is appropriately thrown
1441+
// when a network timeout occurs
1442+
func (suite *ClientTestSuite) TestTimeoutOAuthTokenCreate() {
1443+
_, err := suite.timeoutClient.OAuth.Token.Create("", "", "")
1444+
assert.NotEqual(suite.T(), nil, err)
1445+
}
1446+
1447+
// TestUnauthorizedOAuthTokenCreate tests that an error is appropriately thrown
1448+
// when the user makes an unauthorized request
1449+
func (suite *ClientTestSuite) TestUnauthorizedOAuthTokenCreate() {
1450+
_, err := suite.client.OAuth.Token.Create("", "", "")
1451+
1452+
// There should be an error
1453+
assert.NotEqual(suite.T(), nil, err)
1454+
1455+
// Check error type
1456+
if pinterestError, ok := err.(*models.PinterestError); ok {
1457+
// Should be a 401
1458+
assert.Equal(suite.T(), http.StatusUnauthorized, pinterestError.StatusCode)
1459+
} else {
1460+
// Make this error out, should always be a PinterestError
1461+
assert.Equal(suite.T(), true, false)
1462+
}
1463+
}

0 commit comments

Comments
 (0)