Skip to content

Commit

Permalink
Add Location endpoint. (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
orian authored and dbertouille committed Nov 27, 2018
1 parent 9c5a83f commit 4f26131
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 0 deletions.
21 changes: 21 additions & 0 deletions fixtures/location.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"location": {
"id": 4688969785,
"name": "Bajkowa",
"address1": "Bajkowa",
"address2": "",
"city": "Olsztyn",
"zip": "10-001",
"province": null,
"country": "PL",
"phone": "12312312",
"created_at": "2018-02-19T16:18:59-05:00",
"updated_at": "2018-02-19T16:19:00-05:00",
"country_code": "PL",
"country_name": "Poland",
"province_code": null,
"legacy": false,
"active": true,
"admin_graphql_api_id": "gid:\/\/shopify\/Location\/4688969785"
}
}
23 changes: 23 additions & 0 deletions fixtures/locations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"locations": [
{
"id": 4688969785,
"name": "Bajkowa",
"address1": "Bajkowa",
"address2": "",
"city": "Olsztyn",
"zip": "10-001",
"province": null,
"country": "PL",
"phone": "12312312",
"created_at": "2018-02-19T16:18:59-05:00",
"updated_at": "2018-02-19T16:19:00-05:00",
"country_code": "PL",
"country_name": "Poland",
"province_code": null,
"legacy": false,
"active": true,
"admin_graphql_api_id": "gid:\/\/shopify\/Location\/4688969785"
}
]
}
2 changes: 2 additions & 0 deletions goshopify.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type Client struct {
Page PageService
StorefrontAccessToken StorefrontAccessTokenService
Collect CollectService
Location LocationService
}

// A general response error that follows a similar layout to Shopify's response
Expand Down Expand Up @@ -209,6 +210,7 @@ func NewClient(app App, shopName, token string) *Client {
c.StorefrontAccessToken = &StorefrontAccessTokenServiceOp{client: c}
c.UsageCharge = &UsageChargeServiceOp{client: c}
c.Collect = &CollectServiceOp{client: c}
c.Location = &LocationServiceOp{client: c}

return c
}
Expand Down
110 changes: 110 additions & 0 deletions location.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package goshopify

import (
"fmt"
"time"
)

const locationsBasePath = "admin/locations"

// LocationService is an interface for interfacing with the location endpoints
// of the Shopify API.
// See: https://help.shopify.com/en/api/reference/inventory/location
type LocationService interface {
// Retrieves a list of locations
List(options interface{}) ([]Location, error)
// Retrieves a single location by its ID
Get(ID int, options interface{}) (*Location, error)
// Retrieves a count of locations
Count(options interface{}) (int, error)
}

type Location struct {
// Whether the location is active.If true, then the location can be used to sell products,
// stock inventory, and fulfill orders.Merchants can deactivate locations from the Shopify admin.
// Deactivated locations don't contribute to the shop's location limit.
Active bool `json:"active"`

// The first line of the address.
Address1 string `json:"address1"`

// The second line of the address.
Address2 string `json:"address2"`

// The city the location is in.
City string `json:"city"`

// The country the location is in.
Country string `json:"country"`

// The two-letter code (ISO 3166-1 alpha-2 format) corresponding to country the location is in.
CountryCode string `json:"country_code"`

CountryName string `json:"country_name"`

// The date and time (ISO 8601 format) when the location was created.
CreatedAt time.Time `json:"created_at"`

// The ID for the location.
ID int `json:"id"`

// Whether this is a fulfillment service location.
// If true, then the location is a fulfillment service location.
// If false, then the location was created by the merchant and isn't tied to a fulfillment service.
Legacy bool `json:"legacy"`

// The name of the location.
Name string `json:"name"`

// The phone number of the location.This value can contain special characters like - and +.
Phone string `json:"phone"`

// The province the location is in.
Province string `json:"province"`

// The two-letter code corresponding to province or state the location is in.
ProvinceCode string `json:"province_code"`

// The date and time (ISO 8601 format) when the location was last updated.
UpdatedAt time.Time `json:"updated_at"`

// The zip or postal code.
Zip string `json:"zip"`

AdminGraphqlAPIID string `json:"admin_graphql_api_id"`
}

// LocationServiceOp handles communication with the location related methods of
// the Shopify API.
type LocationServiceOp struct {
client *Client
}

func (s *LocationServiceOp) List(options interface{}) ([]Location, error) {
path := fmt.Sprintf("%s.json", locationsBasePath)
resource := new(LocationsResource)
err := s.client.Get(path, resource, options)
return resource.Locations, err
}

func (s *LocationServiceOp) Get(ID int, options interface{}) (*Location, error) {
path := fmt.Sprintf("%s/%d.json", locationsBasePath, ID)
resource := new(LocationResource)
err := s.client.Get(path, resource, options)
return resource.Location, err
}

func (s *LocationServiceOp) Count(options interface{}) (int, error) {
path := fmt.Sprintf("%s/count.json", locationsBasePath)
return s.client.Count(path, options)
}

// Represents the result from the locations/X.json endpoint
type LocationResource struct {
Location *Location `json:"location"`
}

// Represents the result from the locations.json endpoint
type LocationsResource struct {
Locations []Location `json:"locations"`
}
103 changes: 103 additions & 0 deletions location_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package goshopify

import (
"reflect"
"testing"
"time"

"gopkg.in/jarcoal/httpmock.v1"
)

func TestLocationServiceOp_List(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/locations.json",
httpmock.NewBytesResponder(200, loadFixture("locations.json")))

products, err := client.Location.List(nil)
if err != nil {
t.Errorf("Location.List returned error: %v", err)
}

created, _ := time.Parse(time.RFC3339, "2018-02-19T16:18:59-05:00")
updated, _ := time.Parse(time.RFC3339, "2018-02-19T16:19:00-05:00")

expected := []Location{{
ID: 4688969785,
Name: "Bajkowa",
Address1: "Bajkowa",
Address2: "",
City: "Olsztyn",
Zip: "10-001",
Country: "PL",
Phone: "12312312",
CreatedAt: created,
UpdatedAt: updated,
CountryCode: "PL",
CountryName: "Poland",
Legacy: false,
Active: true,
AdminGraphqlAPIID: "gid://shopify/Location/4688969785",
}}

if !reflect.DeepEqual(products, expected) {
t.Errorf("Location.List returned %+v, expected %+v", products, expected)
}
}

func TestLocationServiceOp_Get(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/locations/4688969785.json",
httpmock.NewBytesResponder(200, loadFixture("location.json")))

product, err := client.Location.Get(4688969785, nil)
if err != nil {
t.Errorf("Location.Get returned error: %v", err)
}

created, _ := time.Parse(time.RFC3339, "2018-02-19T16:18:59-05:00")
updated, _ := time.Parse(time.RFC3339, "2018-02-19T16:19:00-05:00")

expected := &Location{
ID: 4688969785,
Name: "Bajkowa",
Address1: "Bajkowa",
Address2: "",
City: "Olsztyn",
Zip: "10-001",
Country: "PL",
Phone: "12312312",
CreatedAt: created,
UpdatedAt: updated,
CountryCode: "PL",
CountryName: "Poland",
Legacy: false,
Active: true,
AdminGraphqlAPIID: "gid://shopify/Location/4688969785",
}

if !reflect.DeepEqual(product, expected) {
t.Errorf("Location.Get returned %+v, expected %+v", product, expected)
}
}

func TestLocationServiceOp_Count(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/locations/count.json",
httpmock.NewStringResponder(200, `{"count": 3}`))

cnt, err := client.Location.Count(nil)
if err != nil {
t.Errorf("Location.Count returned error: %v", err)
}

expected := 3
if cnt != expected {
t.Errorf("Location.Count returned %d, expected %d", cnt, expected)
}
}

0 comments on commit 4f26131

Please sign in to comment.