Skip to content

Commit

Permalink
Add [POST] /v1/oauth/token endpoint (#35)
Browse files Browse the repository at this point in the history
* Add [POST] /v1/oauth/token endpoint

* Add timeout tests...

* Add docs for OAuth

* Rename sample board to prevent race condition
  • Loading branch information
BrandonRomano authored Jan 18, 2017
1 parent a0f8353 commit 5220f3e
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 5 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@ if pinterestError, ok := err.(*models.PinterestError); ok {
}
```

## OAuth Endpoints

### Generate Access Token

`[POST] /v1/oauth/token`

```go
accessToken, err := client.OAuth.Token.Create(
"client-id",
"client-secret",
"access-code"
)
```

## Boards Endpoints

### Create a Board
Expand Down
20 changes: 20 additions & 0 deletions controllers/oauth_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package controllers

import (
"github.com/BrandonRomano/wrecker"
)

// OAuthController is the controller that is responsible
// for all /v1/oauth endpoints in the Pinterest API.
type OAuthController struct {
wreckerClient *wrecker.Wrecker
Token *OAuthTokenController
}

// NewOAuthController instantiates a new OAuthController
func NewOAuthController(wc *wrecker.Wrecker) *OAuthController {
return &OAuthController{
wreckerClient: wc,
Token: newOAuthTokenController(wc),
}
}
47 changes: 47 additions & 0 deletions controllers/oauth_token_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package controllers

import (
"github.com/BrandonRomano/wrecker"
"github.com/carrot/go-pinterest/models"
)

// OAuthTokenController is the controller that is responsible
// for all /v1/oauth/token endpoints in the Pinterest API.
type OAuthTokenController struct {
wreckerClient *wrecker.Wrecker
}

// newOAuthTokenController instantiates a new OAuthTokenController
func newOAuthTokenController(wc *wrecker.Wrecker) *OAuthTokenController {
return &OAuthTokenController{
wreckerClient: wc,
}
}

// Create generates an access token
// Endpoint: [POST] /v1/oauth/token
func (otc *OAuthTokenController) Create(clientId, clientSecret, accessCode string) (*models.AccessToken, error) {
// Build + execute request
accessToken := new(models.AccessToken)
httpResp, err := otc.wreckerClient.Post("/oauth/token").
URLParam("grant_type", "authorization_code").
URLParam("client_id", clientId).
URLParam("client_secret", clientSecret).
URLParam("code", accessCode).
Into(accessToken).
Execute()

if err != nil {
return nil, err
}

if !(httpResp.StatusCode >= 200 && httpResp.StatusCode < 300) {
return nil, &models.PinterestError{
StatusCode: httpResp.StatusCode,
Message: accessToken.Error,
}
}

// OK
return accessToken, nil
}
11 changes: 11 additions & 0 deletions models/access_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models

// AccessToken is a struct that represents a Access Token
// response from the Pinterest API.
type AccessToken struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
Scope []string `json:"scope"`
ErrorDescription string `json:"error_description"`
Error string `json:"error"`
}
2 changes: 2 additions & 0 deletions pinterest.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
// For more information about the Pinterest API,
// check out https://developers.pinterest.com/
type Client struct {
OAuth *controllers.OAuthController
Users *controllers.UsersController
Boards *controllers.BoardsController
Pins *controllers.PinsController
Expand All @@ -40,6 +41,7 @@ func NewClient() *Client {
// Build Pinterest client
return &Client{
wreckerClient: wc,
OAuth: controllers.NewOAuthController(wc),
Users: controllers.NewUsersController(wc),
Boards: controllers.NewBoardsController(wc),
Pins: controllers.NewPinsController(wc),
Expand Down
39 changes: 34 additions & 5 deletions pinterest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,18 +357,18 @@ func (suite *ClientTestSuite) TestSuccessfulBoardCUD() {
// Updating the Board
board, err = suite.client.Boards.Update("brandonrromano/go-pinterest-test",
&controllers.BoardUpdateOptionals{
Name: "Go Pinterest Test2",
Description: "Go Pinterest Test2!",
Name: "Go Pinterest Test3",
Description: "Go Pinterest Test3!",
},
)

// Assume there is no error / test result
assert.Equal(suite.T(), nil, err)
assert.Equal(suite.T(), board.Name, "Go Pinterest Test2")
assert.Equal(suite.T(), board.Description, "Go Pinterest Test2!")
assert.Equal(suite.T(), board.Name, "Go Pinterest Test3")
assert.Equal(suite.T(), board.Description, "Go Pinterest Test3!")

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

Expand Down Expand Up @@ -1432,3 +1432,32 @@ func (suite *ClientTestSuite) TestUnauthorizedMeSearchPinsFetch() {
assert.Equal(suite.T(), true, false)
}
}

// ========================================
// ========== OAuth.Token.Create ==========
// ========================================

// TestTimeoutOAuthTokenCreate tests that an error is appropriately thrown
// when a network timeout occurs
func (suite *ClientTestSuite) TestTimeoutOAuthTokenCreate() {
_, err := suite.timeoutClient.OAuth.Token.Create("", "", "")
assert.NotEqual(suite.T(), nil, err)
}

// TestUnauthorizedOAuthTokenCreate tests that an error is appropriately thrown
// when the user makes an unauthorized request
func (suite *ClientTestSuite) TestUnauthorizedOAuthTokenCreate() {
_, err := suite.client.OAuth.Token.Create("", "", "")

// There should be an error
assert.NotEqual(suite.T(), nil, err)

// Check error type
if pinterestError, ok := err.(*models.PinterestError); ok {
// Should be a 401
assert.Equal(suite.T(), http.StatusUnauthorized, pinterestError.StatusCode)
} else {
// Make this error out, should always be a PinterestError
assert.Equal(suite.T(), true, false)
}
}

0 comments on commit 5220f3e

Please sign in to comment.