Skip to content

Commit

Permalink
Shopify API versioning support (#48)
Browse files Browse the repository at this point in the history
* Build an Options function struct to optionally pass into the NewClient function in order to optionally prefix all API calls made with that function with a version. This is to adhere to the new Shopify API versioning changes, without making this a breaking change.
  • Loading branch information
dougyss4 authored and rickywiens committed Apr 25, 2019
1 parent ba45604 commit f0085a4
Show file tree
Hide file tree
Showing 68 changed files with 527 additions and 441 deletions.
12 changes: 6 additions & 6 deletions applicationcharge.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/shopspring/decimal"
)

const applicationChargesBasePath = "admin/application_charges"
const applicationChargesBasePath = "application_charges"

// ApplicationChargeService is an interface for interacting with the
// ApplicationCharge endpoints of the Shopify API.
Expand All @@ -26,7 +26,7 @@ type ApplicationChargeServiceOp struct {
type ApplicationCharge struct {
ID int64 `json:"id"`
Name string `json:"name"`
APIClientID int64 `json:"api_client_id"`
APIClientID int64 `json:"api_client_id"`
Price *decimal.Decimal `json:"price"`
Status string `json:"status"`
ReturnURL string `json:"return_url"`
Expand All @@ -52,28 +52,28 @@ type ApplicationChargesResource struct {

// Create creates new application charge.
func (a ApplicationChargeServiceOp) Create(charge ApplicationCharge) (*ApplicationCharge, error) {
path := fmt.Sprintf("%s.json", applicationChargesBasePath)
path := fmt.Sprintf("%s/%s.json", globalApiPathPrefix, applicationChargesBasePath)
resource := &ApplicationChargeResource{}
return resource.Charge, a.client.Post(path, ApplicationChargeResource{Charge: &charge}, resource)
}

// Get gets individual application charge.
func (a ApplicationChargeServiceOp) Get(chargeID int64, options interface{}) (*ApplicationCharge, error) {
path := fmt.Sprintf("%s/%d.json", applicationChargesBasePath, chargeID)
path := fmt.Sprintf("%s/%s/%d.json", globalApiPathPrefix, applicationChargesBasePath, chargeID)
resource := &ApplicationChargeResource{}
return resource.Charge, a.client.Get(path, resource, options)
}

// List gets all application charges.
func (a ApplicationChargeServiceOp) List(options interface{}) ([]ApplicationCharge, error) {
path := fmt.Sprintf("%s.json", applicationChargesBasePath)
path := fmt.Sprintf("%s/%s.json", globalApiPathPrefix, applicationChargesBasePath)
resource := &ApplicationChargesResource{}
return resource.Charges, a.client.Get(path, resource, options)
}

// Activate activates application charge.
func (a ApplicationChargeServiceOp) Activate(charge ApplicationCharge) (*ApplicationCharge, error) {
path := fmt.Sprintf("%s/%d/activate.json", applicationChargesBasePath, charge.ID)
path := fmt.Sprintf("%s/%s/%d/activate.json", globalApiPathPrefix, applicationChargesBasePath, charge.ID)
resource := &ApplicationChargeResource{}
return resource.Charge, a.client.Post(path, ApplicationChargeResource{Charge: &charge}, resource)
}
12 changes: 6 additions & 6 deletions applicationcharge_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package goshopify

import (
"fmt"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -33,8 +34,7 @@ func applicationChargeTests(t *testing.T, charge ApplicationCharge) {
},
{
"ConfirmationURL",
"https://apple.myshopify.com/admin/charges/1017262355/confirm_application_charge?sign" +
"ature=BAhpBBMxojw%3D--1139a82a3433b1a6771786e03f02300440e11883",
fmt.Sprintf("https://apple.myshopify.com/%s/charges/1017262355/confirm_application_charge?signature=BAhpBBMxojw%%3D--1139a82a3433b1a6771786e03f02300440e11883", globalApiPathPrefix),
charge.ConfirmationURL,
},
}
Expand All @@ -52,7 +52,7 @@ func TestApplicationChargeServiceOp_Create(t *testing.T) {

httpmock.RegisterResponder(
"POST",
"https://fooshop.myshopify.com/admin/application_charges.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/application_charges.json", globalApiPathPrefix),
httpmock.NewBytesResponder(200, loadFixture("applicationcharge.json")),
)

Expand All @@ -77,7 +77,7 @@ func TestApplicationChargeServiceOp_Get(t *testing.T) {

httpmock.RegisterResponder(
"GET",
"https://fooshop.myshopify.com/admin/application_charges/1.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/application_charges/1.json", globalApiPathPrefix),
httpmock.NewStringResponder(200, `{"application_charge": {"id":1}}`),
)

Expand All @@ -98,7 +98,7 @@ func TestApplicationChargeServiceOp_List(t *testing.T) {

httpmock.RegisterResponder(
"GET",
"https://fooshop.myshopify.com/admin/application_charges.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/application_charges.json", globalApiPathPrefix),
httpmock.NewStringResponder(200, `{"application_charges": [{"id":1},{"id":2}]}`),
)

Expand All @@ -119,7 +119,7 @@ func TestApplicationChargeServiceOp_Activate(t *testing.T) {

httpmock.RegisterResponder(
"POST",
"https://fooshop.myshopify.com/admin/application_charges/455696195/activate.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/application_charges/455696195/activate.json", globalApiPathPrefix),
httpmock.NewStringResponder(
200,
`{"application_charge":{"id":455696195,"status":"active"}}`,
Expand Down
10 changes: 5 additions & 5 deletions asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"time"
)

const assetsBasePath = "admin/themes"
const assetsBasePath = "themes"

// AssetService is an interface for interfacing with the asset endpoints
// of the Shopify API.
Expand Down Expand Up @@ -55,15 +55,15 @@ type assetGetOptions struct {

// List the metadata for all assets in the given theme
func (s *AssetServiceOp) List(themeID int64, options interface{}) ([]Asset, error) {
path := fmt.Sprintf("%s/%d/assets.json", assetsBasePath, themeID)
path := fmt.Sprintf("%s/%s/%d/assets.json", globalApiPathPrefix, assetsBasePath, themeID)
resource := new(AssetsResource)
err := s.client.Get(path, resource, options)
return resource.Assets, err
}

// Get an asset by key from the given theme
func (s *AssetServiceOp) Get(themeID int64, key string) (*Asset, error) {
path := fmt.Sprintf("%s/%d/assets.json", assetsBasePath, themeID)
path := fmt.Sprintf("%s/%s/%d/assets.json", globalApiPathPrefix, assetsBasePath, themeID)
options := assetGetOptions{
Key: key,
ThemeID: themeID,
Expand All @@ -75,7 +75,7 @@ func (s *AssetServiceOp) Get(themeID int64, key string) (*Asset, error) {

// Update an asset
func (s *AssetServiceOp) Update(themeID int64, asset Asset) (*Asset, error) {
path := fmt.Sprintf("%s/%d/assets.json", assetsBasePath, themeID)
path := fmt.Sprintf("%s/%s/%d/assets.json", globalApiPathPrefix, assetsBasePath, themeID)
wrappedData := AssetResource{Asset: &asset}
resource := new(AssetResource)
err := s.client.Put(path, wrappedData, resource)
Expand All @@ -84,6 +84,6 @@ func (s *AssetServiceOp) Update(themeID int64, asset Asset) (*Asset, error) {

// Delete an asset
func (s *AssetServiceOp) Delete(themeID int64, key string) error {
path := fmt.Sprintf("%s/%d/assets.json?asset[key]=%s", assetsBasePath, themeID, key)
path := fmt.Sprintf("%s/%s/%d/assets.json?asset[key]=%s", globalApiPathPrefix, assetsBasePath, themeID, key)
return s.client.Delete(path)
}
9 changes: 5 additions & 4 deletions asset_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package goshopify

import (
"fmt"
"reflect"
"testing"

Expand All @@ -20,7 +21,7 @@ func TestAssetList(t *testing.T) {

httpmock.RegisterResponder(
"GET",
"https://fooshop.myshopify.com/admin/themes/1/assets.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/themes/1/assets.json", globalApiPathPrefix),
httpmock.NewStringResponder(
200,
`{"assets": [{"key":"assets\/1.liquid"},{"key":"assets\/2.liquid"}]}`,
Expand All @@ -47,7 +48,7 @@ func TestAssetGet(t *testing.T) {
}
httpmock.RegisterResponderWithQuery(
"GET",
"https://fooshop.myshopify.com/admin/themes/1/assets.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/themes/1/assets.json", globalApiPathPrefix),
params,
httpmock.NewStringResponder(
200,
Expand All @@ -72,7 +73,7 @@ func TestAssetUpdate(t *testing.T) {

httpmock.RegisterResponder(
"PUT",
"https://fooshop.myshopify.com/admin/themes/1/assets.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/themes/1/assets.json", globalApiPathPrefix),
httpmock.NewBytesResponder(
200,
loadFixture("asset.json"),
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestAssetDelete(t *testing.T) {
params := map[string]string{"asset[key]": "foo/bar.liquid"}
httpmock.RegisterResponderWithQuery(
"DELETE",
"https://fooshop.myshopify.com/admin/themes/1/assets.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/themes/1/assets.json", globalApiPathPrefix),
params,
httpmock.NewStringResponder(200, "{}"),
)
Expand Down
14 changes: 7 additions & 7 deletions blog.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"time"
)

const blogsBasePath = "admin/blogs"
const blogsBasePath = "blogs"

// BlogService is an interface for interfacing with the blogs endpoints
// of the Shopify API.
Expand Down Expand Up @@ -52,29 +52,29 @@ type BlogResource struct {

// List all blogs
func (s *BlogServiceOp) List(options interface{}) ([]Blog, error) {
path := fmt.Sprintf("%s.json", blogsBasePath)
path := fmt.Sprintf("%s/%s.json", globalApiPathPrefix, blogsBasePath)
resource := new(BlogsResource)
err := s.client.Get(path, resource, options)
return resource.Blogs, err
}

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

// Get single blog
func (s *BlogServiceOp) Get(blogId int64, options interface{}) (*Blog, error) {
path := fmt.Sprintf("%s/%d.json", blogsBasePath, blogId)
path := fmt.Sprintf("%s/%s/%d.json", globalApiPathPrefix, blogsBasePath, blogId)
resource := new(BlogResource)
err := s.client.Get(path, resource, options)
return resource.Blog, err
}

// Create a new blog
func (s *BlogServiceOp) Create(blog Blog) (*Blog, error) {
path := fmt.Sprintf("%s.json", blogsBasePath)
path := fmt.Sprintf("%s/%s.json", globalApiPathPrefix, blogsBasePath)
wrappedData := BlogResource{Blog: &blog}
resource := new(BlogResource)
err := s.client.Post(path, wrappedData, resource)
Expand All @@ -83,7 +83,7 @@ func (s *BlogServiceOp) Create(blog Blog) (*Blog, error) {

// Update an existing blog
func (s *BlogServiceOp) Update(blog Blog) (*Blog, error) {
path := fmt.Sprintf("%s/%d.json", blogsBasePath, blog.ID)
path := fmt.Sprintf("%s/%s/%d.json", globalApiPathPrefix, blogsBasePath, blog.ID)
wrappedData := BlogResource{Blog: &blog}
resource := new(BlogResource)
err := s.client.Put(path, wrappedData, resource)
Expand All @@ -92,5 +92,5 @@ func (s *BlogServiceOp) Update(blog Blog) (*Blog, error) {

// Delete an blog
func (s *BlogServiceOp) Delete(blogId int64) error {
return s.client.Delete(fmt.Sprintf("%s/%d.json", blogsBasePath, blogId))
return s.client.Delete(fmt.Sprintf("%s/%s/%d.json", globalApiPathPrefix, blogsBasePath, blogId))
}
13 changes: 7 additions & 6 deletions blog_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package goshopify

import (
"fmt"
"reflect"
"testing"

Expand All @@ -13,7 +14,7 @@ func TestBlogList(t *testing.T) {

httpmock.RegisterResponder(
"GET",
"https://fooshop.myshopify.com/admin/blogs.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/blogs.json", globalApiPathPrefix),
httpmock.NewStringResponder(
200,
`{"blogs": [{"id":1},{"id":2}]}`,
Expand All @@ -38,7 +39,7 @@ func TestBlogCount(t *testing.T) {

httpmock.RegisterResponder(
"GET",
"https://fooshop.myshopify.com/admin/blogs/count.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/blogs/count.json", globalApiPathPrefix),
httpmock.NewStringResponder(
200,
`{"count": 5}`,
Expand All @@ -63,7 +64,7 @@ func TestBlogGet(t *testing.T) {

httpmock.RegisterResponder(
"GET",
"https://fooshop.myshopify.com/admin/blogs/1.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/blogs/1.json", globalApiPathPrefix),
httpmock.NewStringResponder(
200,
`{"blog": {"id":1}}`,
Expand All @@ -88,7 +89,7 @@ func TestBlogCreate(t *testing.T) {

httpmock.RegisterResponder(
"POST",
"https://fooshop.myshopify.com/admin/blogs.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/blogs.json", globalApiPathPrefix),
httpmock.NewBytesResponder(
200,
loadFixture("blog.json"),
Expand Down Expand Up @@ -117,7 +118,7 @@ func TestBlogUpdate(t *testing.T) {

httpmock.RegisterResponder(
"PUT",
"https://fooshop.myshopify.com/admin/blogs/1.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/blogs/1.json", globalApiPathPrefix),
httpmock.NewBytesResponder(
200,
loadFixture("blog.json"),
Expand All @@ -144,7 +145,7 @@ func TestBlogDelete(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("DELETE", "https://fooshop.myshopify.com/admin/blogs/1.json",
httpmock.RegisterResponder("DELETE", fmt.Sprintf("https://fooshop.myshopify.com/%s/blogs/1.json", globalApiPathPrefix),
httpmock.NewStringResponder(200, "{}"))

err := client.Blog.Delete(1)
Expand Down
6 changes: 3 additions & 3 deletions collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"time"
)

const collectsBasePath = "admin/collects"
const collectsBasePath = "collects"

// CollectService is an interface for interfacing with the collect endpoints
// of the Shopify API.
Expand Down Expand Up @@ -45,14 +45,14 @@ type CollectsResource struct {

// List collects
func (s *CollectServiceOp) List(options interface{}) ([]Collect, error) {
path := fmt.Sprintf("%s.json", collectsBasePath)
path := fmt.Sprintf("%s/%s.json", globalApiPathPrefix, collectsBasePath)
resource := new(CollectsResource)
err := s.client.Get(path, resource, options)
return resource.Collects, err
}

// Count collects
func (s *CollectServiceOp) Count(options interface{}) (int, error) {
path := fmt.Sprintf("%s/count.json", collectsBasePath)
path := fmt.Sprintf("%s/%s/count.json", globalApiPathPrefix, collectsBasePath)
return s.client.Count(path, options)
}
9 changes: 5 additions & 4 deletions collect_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package goshopify

import (
"fmt"
"reflect"
"testing"

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

func collectTests(t *testing.T, collect Collect) {
Expand Down Expand Up @@ -33,7 +34,7 @@ func TestCollectList(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/collects.json",
httpmock.RegisterResponder("GET", fmt.Sprintf("https://fooshop.myshopify.com/%s/collects.json", globalApiPathPrefix),
httpmock.NewStringResponder(200, `{"collects": [{"id":1},{"id":2}]}`))

collects, err := client.Collect.List(nil)
Expand All @@ -51,12 +52,12 @@ func TestCollectCount(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/collects/count.json",
httpmock.RegisterResponder("GET", fmt.Sprintf("https://fooshop.myshopify.com/%s/collects/count.json", globalApiPathPrefix),
httpmock.NewStringResponder(200, `{"count": 5}`))

params := map[string]string{"since_id": "123"}
httpmock.RegisterResponderWithQuery("GET",
"https://fooshop.myshopify.com/admin/collects/count.json",
fmt.Sprintf("https://fooshop.myshopify.com/%s/collects/count.json", globalApiPathPrefix),
params,
httpmock.NewStringResponder(200, `{"count": 2}`))

Expand Down
Loading

0 comments on commit f0085a4

Please sign in to comment.