Test contextual location and add first integration test

This commit is contained in:
Jean-Baptiste Pinalie
2019-05-27 21:54:44 +02:00
parent 4b7e5a67c7
commit a63792e92f
7 changed files with 152 additions and 9 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
.env

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"net/url"
)
// BrowseService handles communication with the Browse API
@@ -11,24 +12,29 @@ import (
// eBay API docs: https://developer.ebay.com/api-docs/buy/browse/overview.html
type BrowseService service
// OptContextualLocation adds the header containing contextualLocation.
// OptBrowseContextualLocation adds the header containing contextualLocation.
// It is strongly recommended that you use it when submitting Browse API methods.
//
// eBay API docs: https://developer.ebay.com/api-docs/buy/static/api-browse.html#Headers
func OptContextualLocation(country, zip string) func(*http.Request) {
func OptBrowseContextualLocation(country, zip string) func(*http.Request) {
return func(req *http.Request) {
// X-EBAY-C-ENDUSERCTX: contextualLocation=country=US,zip=19406
v := req.Header.Get(headerEndUserCtx)
if len(v) > 0 {
v += ","
}
v += "contextualLocation=" + url.QueryEscape(fmt.Sprintf("country=%s,zip=%s", country, zip))
req.Header.Set(headerEndUserCtx, v)
}
}
// Item represents a eBay item.
// Item represents an eBay item.
type Item struct{}
// GetItem retrieves the details of a specific item.
//
// eBay API docs: https://developer.ebay.com/api-docs/buy/browse/resources/item/methods/getItem
func (s *BrowseService) GetItem(ctx context.Context, itemID string, opts ...Opt) (Item, error) {
u := fmt.Sprintf("item/%s", itemID)
u := fmt.Sprintf("buy/browse/v1/item/%s", itemID)
req, err := s.client.NewRequest(http.MethodGet, u, opts...)
if err != nil {
return Item{}, err

View File

@@ -8,8 +8,15 @@ import (
"github.com/stretchr/testify/assert"
)
func TestOptContextualLocation(t *testing.T) {
func TestOptBrowseContextualLocationn(t *testing.T) {
r, _ := http.NewRequest("", "", nil)
ebay.OptContextualLocation("US", "19406")(r)
assert.Equal(t, "country%3DUS%2Czip%3D19406", r.Header.Get("X-EBAY-C-ENDUSERCTX"))
ebay.OptBrowseContextualLocation("US", "19406")(r)
assert.Equal(t, "contextualLocation=country%3DUS%2Czip%3D19406", r.Header.Get("X-EBAY-C-ENDUSERCTX"))
}
func TestOptBrowseContextualLocationExistingHeader(t *testing.T) {
r, _ := http.NewRequest("", "", nil)
r.Header.Set("X-EBAY-C-ENDUSERCTX", "affiliateCampaignId=1")
ebay.OptBrowseContextualLocation("US", "19406")(r)
assert.Equal(t, "affiliateCampaignId=1,contextualLocation=country%3DUS%2Czip%3D19406", r.Header.Get("X-EBAY-C-ENDUSERCTX"))
}

View File

@@ -90,7 +90,7 @@ func (c *Client) NewRequest(method, url string, opts ...Opt) (*http.Request, err
return req, nil
}
// Do sends an API reauest and stores the JSON decoded value into v.
// Do sends an API request and stores the JSON decoded value into v.
func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) error {
resp, err := c.client.Do(req.WithContext(ctx))
if err != nil {

8
go.mod Normal file
View File

@@ -0,0 +1,8 @@
module github.com/jybp/ebay
go 1.12
require (
github.com/stretchr/testify v1.3.0
golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0
)

17
go.sum Normal file
View File

@@ -0,0 +1,17 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0 h1:xFEXbcD0oa/xhqQmMXztdZ0bWvexAWds+8c1gRN8nu0=
golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

104
integration_test.go Normal file
View File

@@ -0,0 +1,104 @@
// +build integration
package ebay_test
import (
"context"
_ "github.com/joho/godotenv/autoload"
"github.com/jybp/ebay"
"golang.org/x/oauth2"
"os"
"testing"
"net/http"
"strings"
"fmt"
"bytes"
"time"
"io/ioutil"
"encoding/json"
"net/url"
)
var client *ebay.Client
func init() {
clientID := os.Getenv("CLIENT_ID")
clientSecret := os.Getenv("CLIENT_SECRET")
if clientID == "" || clientSecret == "" {
panic("No CLIENT_ID or CLIENT_SECRET. Tests won't run.")
}
c := &http.Client{
Transport: &oauth2.Transport{
Source: oauth2.ReuseTokenSource(nil, TokenSource{
Endpoint: "https://api.sandbox.ebay.com/identity/v1/oauth2/token",
ID: clientID,
Secret: clientSecret,
Scopes: []string{"https://api.ebay.com/oauth/api_scope"},
Client: http.DefaultClient,
}),
Base: http.DefaultTransport,
},
}
client = ebay.NewSandboxClient(c)
}
type TokenSource struct {
Endpoint string
ID string
Secret string
Scopes []string
Client *http.Client
}
func (ts TokenSource) Token() (*oauth2.Token, error) {
scopes := strings.Join(ts.Scopes, " ")
req, err := http.NewRequest(http.MethodPost,
ts.Endpoint,
strings.NewReader(fmt.Sprintf("grant_type=client_credentials&scope=%s", url.PathEscape(scopes))))
if err != nil {
return nil, err
}
req.SetBasicAuth(ts.ID, ts.Secret)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := ts.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if c := resp.StatusCode; c < 200 || c >= 300 {
return nil, fmt.Errorf("%s\nStatus:\n%d", req.URL, resp.StatusCode)
}
token := struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}{}
if err = json.NewDecoder(bytes.NewReader(body)).Decode(&token); err != nil {
return nil, err
}
t := oauth2.Token{
AccessToken: token.AccessToken,
TokenType: token.TokenType,
}
if secs := token.ExpiresIn; secs > 0 {
t.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
}
print(t.TokenType)
print("\n")
print(t.AccessToken)
print("\n")
return &t, nil
}
func TestAuthorization(t *testing.T) {
// TODO user token is reauired
req, err := client.NewRequest("GET", "buy/browse/v1/item_summary/search?q=drone&limit=3")
t.Log(req, err)
into := map[string]string{}
err = client.Do(context.Background(), req, &into)
t.Log(into, err)
}