Repository: Shopify/themekit
Pull request #755 (2020-08-19 15:12:12)

Use unstable API version for checksums support
We expect checksums to be part of the 2020-10 release. Until then, we'll need to point to the unstable version of the API.

### Warn Checklist
- [ ] This changes the interface and requires a Major/Minor version change.
- [x] I have :tophat:'d these changes by using the commands I changed by hand.
- [ ] I have added a dependancy to the project.



Patch:
diff --git a/src/shopify/theme_client.go b/src/shopify/theme_client.go
index f37b3f6..c3eb685 100644
--- a/src/shopify/theme_client.go
+++ b/src/shopify/theme_client.go
@@ -17,6 +17,9 @@ import (
 	"github.com/Shopify/themekit/src/httpify"
 )
 
+// APIPath is the version of the Admin REST API to use
+const APIPath = "/admin/api/unstable/"
+
 var (
 	// ErrCriticalFile will be returned when trying to remove a critical file
 	ErrCriticalFile = errors.New("this file is critical and removing it would cause your theme to become non-functional")
@@ -143,7 +146,7 @@ func (c Client) GetShop() (Shop, error) {
 
 // Themes will return all the available themes on a domain.
 func (c Client) Themes() ([]Theme, error) {
-	resp, err := c.http.Get("/admin/themes.json", nil)
+	resp, err := c.http.Get(APIPath + "themes.json", nil)
 	if err != nil {
 		return []Theme{}, err
 	}
@@ -163,7 +166,7 @@ func (c *Client) CreateNewTheme(name string) (theme Theme, err error) {
 		return Theme{}, ErrThemeNameRequired
 	}
 
-	resp, err := c.http.Post("/admin/themes.json", map[string]interface{}{"theme": Theme{Name: name}}, nil)
+	resp, err := c.http.Post(APIPath + "themes.json", map[string]interface{}{"theme": Theme{Name: name}}, nil)
 	if err != nil {
 		return Theme{}, err
 	}
@@ -187,7 +190,7 @@ func (c Client) GetInfo() (Theme, error) {
 		return Theme{}, ErrInfoWithoutThemeID
 	}
 
-	resp, err := c.http.Get(fmt.Sprintf("/admin/themes/%s.json", c.themeID), nil)
+	resp, err := c.http.Get(fmt.Sprintf(APIPath + "themes/%s.json", c.themeID), nil)
 	if err != nil {
 		return Theme{}, err
 	} else if resp.StatusCode == 404 {
@@ -209,7 +212,7 @@ func (c Client) PublishTheme() error {
 	}
 
 	resp, err := c.http.Put(
-		fmt.Sprintf("/admin/themes/%s.json", c.themeID),
+		fmt.Sprintf(APIPath + "themes/%s.json", c.themeID),
 		map[string]Theme{"theme": {Role: "main"}},
 		nil,
 	)
@@ -342,9 +345,9 @@ func (c Client) DeleteAsset(asset Asset) error {
 }
 
 func (c Client) assetPath(query map[string]string) string {
-	formatted := "/admin/assets.json"
+	formatted := APIPath + "assets.json"
 	if c.themeID != "" {
-		formatted = fmt.Sprintf("/admin/themes/%s/assets.json", c.themeID)
+		formatted = fmt.Sprintf(APIPath + "themes/%s/assets.json", c.themeID)
 	}
 
 	if len(query) > 0 {


Test patch:
diff --git a/src/shopify/theme_client_test.go b/src/shopify/theme_client_test.go
index a52de06..5fd07de 100644
--- a/src/shopify/theme_client_test.go
+++ b/src/shopify/theme_client_test.go
@@ -16,6 +16,8 @@ import (
 
 var NoHeaders = map[string]string(nil)
 
+// APIPath is the version of the Admin REST API to use
+
 func TestNewThemeClient(t *testing.T) {
 	testcases := []struct {
 		e   *env.Env
@@ -92,7 +94,7 @@ func TestThemeClient_Themes(t *testing.T) {
 		client, _ := NewClient(&env.Env{})
 		client.http = m
 
-		expectation := m.On("Get", "/admin/themes.json", NoHeaders)
+		expectation := m.On("Get", APIPath + "themes.json", NoHeaders)
 		if testcase.resperr != "" {
 			expectation.Return(nil, errors.New(testcase.resperr))
 		} else {
@@ -133,9 +135,9 @@ func TestThemeClient_CreateNewTheme(t *testing.T) {
 		query := map[string]interface{}{"theme": Theme{Name: testcase.in}}
 
 		if testcase.resp != "" {
-			m.On("Post", "/admin/themes.json", query, NoHeaders).Return(jsonResponse(testcase.resp, 200), nil)
+			m.On("Post", APIPath + "themes.json", query, NoHeaders).Return(jsonResponse(testcase.resp, 200), nil)
 		} else if testcase.resperr != "" {
-			m.On("Post", "/admin/themes.json", query, NoHeaders).Return(nil, errors.New(testcase.resperr))
+			m.On("Post", APIPath + "themes.json", query, NoHeaders).Return(nil, errors.New(testcase.resperr))
 		}
 
 		theme, err := client.CreateNewTheme(testcase.in)
@@ -171,7 +173,7 @@ func TestThemeClient_GetInfo(t *testing.T) {
 		client, _ := NewClient(&env.Env{ThemeID: testcase.themeID})
 		client.http = m
 
-		expectation := m.On("Get", fmt.Sprintf("/admin/themes/%s.json", testcase.themeID), NoHeaders)
+		expectation := m.On("Get", fmt.Sprintf(APIPath + "themes/%s.json", testcase.themeID), NoHeaders)
 		if testcase.resperr != "" {
 			expectation.Return(nil, errors.New(testcase.resperr))
 		} else {
@@ -214,7 +216,7 @@ func TestThemeClient_PublishTheme(t *testing.T) {
 
 		expectation := m.On(
 			"Put",
-			fmt.Sprintf("/admin/themes/%s.json", testcase.themeID),
+			fmt.Sprintf(APIPath + "themes/%s.json", testcase.themeID),
 			map[string]Theme{"theme": {Role: "main"}},
 			NoHeaders,
 		)
@@ -254,7 +256,7 @@ func TestThemeClient_GetAllAssets(t *testing.T) {
 		client, _ := NewClient(&env.Env{ThemeID: "123"})
 		client.http = m
 
-		expectation := m.On("Get", "/admin/themes/123/assets.json?fields=key%2Cchecksum", NoHeaders)
+		expectation := m.On("Get", APIPath + "themes/123/assets.json?fields=key%2Cchecksum", NoHeaders)
 		if testcase.resperr != "" {
 			expectation.Return(nil, errors.New(testcase.resperr))
 		} else {
@@ -297,7 +299,7 @@ func TestThemeClient_GetAllAssets(t *testing.T) {
 		m := new(mocks.HttpAdapter)
 		client, _ := NewClient(&env.Env{ThemeID: "123", IgnoredFiles: testcase.ignore})
 		client.http = m
-		m.On("Get", "/admin/themes/123/assets.json?fields=key%2Cchecksum", NoHeaders).Return(jsonResponse(testcase.input, 200), nil)
+		m.On("Get", APIPath + "themes/123/assets.json?fields=key%2Cchecksum", NoHeaders).Return(jsonResponse(testcase.input, 200), nil)
 		assets, err := client.GetAllAssets()
 		assert.Nil(t, err)
 		assert.Equal(t, testcase.expected, assets)
@@ -320,7 +322,7 @@ func TestThemeClient_GetAsset(t *testing.T) {
 		client, _ := NewClient(&env.Env{ThemeID: "123"})
 		client.http = m
 
-		expectation := m.On("Get", "/admin/themes/123/assets.json?asset%5Bkey%5D=filename.txt", NoHeaders)
+		expectation := m.On("Get", APIPath + "themes/123/assets.json?asset%5Bkey%5D=filename.txt", NoHeaders)
 		if testcase.resperr != "" {
 			expectation.Return(nil, errors.New(testcase.resperr))
 		} else if testcase.code != 0 {
@@ -356,7 +358,7 @@ func TestThemeClient_UpdateAsset(t *testing.T) {
 		client, _ := NewClient(&env.Env{ThemeID: "123"})
 		client.http = m
 
-		expectation := m.On("Put", "/admin/themes/123/assets.json", map[string]Asset{"asset": {Key: "filename.txt"}}, NoHeaders)
+		expectation := m.On("Put", APIPath + "themes/123/assets.json", map[string]Asset{"asset": {Key: "filename.txt"}}, NoHeaders)
 		if testcase.resperr != "" {
 			expectation.Return(nil, errors.New(testcase.resperr))
 		} else if testcase.code != 0 {
@@ -398,13 +400,13 @@ func TestThemeClient_UpdateAsset(t *testing.T) {
 
 	m.On(
 		"Delete",
-		"/admin/themes/123/assets.json?asset%5Bkey%5D=filename.txt.liquid",
+		APIPath + "themes/123/assets.json?asset%5Bkey%5D=filename.txt.liquid",
 		NoHeaders,
 	).Return(jsonResponse("{}", 200), nil)
 
 	m.On(
 		"Put",
-		"/admin/themes/123/assets.json",
+		APIPath + "themes/123/assets.json",
 		map[string]Asset{"asset": asset},
 		NoHeaders,
 	).Return(jsonResponse(`{"asset":{"key":"assets/hello.txt"}}`, 200), nil)
@@ -429,7 +431,7 @@ func TestThemeClient_DeleteAsset(t *testing.T) {
 		client, _ := NewClient(&env.Env{ThemeID: "123"})
 		client.http = m
 
-		expectation := m.On("Delete", "/admin/themes/123/assets.json?asset%5Bkey%5D=filename.txt", NoHeaders)
+		expectation := m.On("Delete", APIPath + "themes/123/assets.json?asset%5Bkey%5D=filename.txt", NoHeaders)
 		if testcase.resperr != "" {
 			expectation.Return(nil, errors.New(testcase.resperr))
 		} else {
@@ -453,10 +455,10 @@ func TestThemeClient_assetPath(t *testing.T) {
 		query         map[string]string
 		themeID, path string
 	}{
-		{themeID: "123", path: "/admin/themes/123/assets.json?asset%5Bkey%5D=layout%2Ftheme.liquid", query: map[string]string{"asset[key]": "layout/theme.liquid"}},
-		{path: "/admin/assets.json?asset%5Bkey%5D=layout%2Ftheme.liquid", query: map[string]string{"asset[key]": "layout/theme.liquid"}},
-		{themeID: "123", path: "/admin/themes/123/assets.json"},
-		{path: "/admin/assets.json"},
+		{themeID: "123", path: APIPath + "themes/123/assets.json?asset%5Bkey%5D=layout%2Ftheme.liquid", query: map[string]string{"asset[key]": "layout/theme.liquid"}},
+		{path: "/admin/api/unstable/assets.json?asset%5Bkey%5D=layout%2Ftheme.liquid", query: map[string]string{"asset[key]": "layout/theme.liquid"}},
+		{themeID: "123", path: APIPath + "themes/123/assets.json"},
+		{path: "/admin/api/unstable/assets.json"},
 	}
 
 	for _, testcase := range testcases {