Skip to content

Commit

Permalink
Add customer and order counts (bold-commerce#3)
Browse files Browse the repository at this point in the history
* Singularize naming of Product service

* Add customer and order count
  • Loading branch information
dlebech committed May 12, 2016
1 parent 994346c commit 638d37e
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 23 deletions.
42 changes: 42 additions & 0 deletions customer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package goshopify

import (
"fmt"
)

const customersBasePath = "admin/customers"

// CustomerService is an interface for interfacing with the customers endpoints
// of the Shopify API.
// See: https://help.shopify.com/api/reference/customer
type CustomerService interface {
Count() (int, error)
}

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

type customerCountRoot struct {
Count int `json:"count"`
}

// Count customers
func (s *CustomerServiceOp) Count() (int, error) {
path := fmt.Sprintf("%s/count.json", customersBasePath)

req, err := s.client.NewRequest("GET", path, nil)
if err != nil {
return 0, err
}

root := new(customerCountRoot)
err = s.client.Do(req, root)
if err != nil {
return 0, err
}

return root.Count, err
}
25 changes: 25 additions & 0 deletions customer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package goshopify

import (
"testing"

"github.com/jarcoal/httpmock"
)

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

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

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

expected := 5
if cnt != expected {
t.Errorf("Customer.Count returned %d, expected %d", cnt, expected)
}
}
8 changes: 6 additions & 2 deletions goshopify.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ type Client struct {
token string

// Services used for communicating with the API
Products ProductsService
Product ProductService
Customer CustomerService
Order OrderService
}

// Creates an API request. A relative URL can be provided in urlStr, which will
Expand Down Expand Up @@ -85,7 +87,9 @@ func NewClient(app App, shopName string, token string) *Client {
baseURL, _ := url.Parse(ShopBaseUrl(shopName))

c := &Client{client: httpClient, app: app, baseURL: baseURL, token: token}
c.Products = &ProductsServiceOp{client: c}
c.Product = &ProductServiceOp{client: c}
c.Customer = &CustomerServiceOp{client: c}
c.Order = &OrderServiceOp{client: c}

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

import (
"fmt"
)

const ordersBasePath = "admin/orders"

// OrderService is an interface for interfacing with the orders endpoints of
// the Shopify API.
// See: https://help.shopify.com/api/reference/order
type OrderService interface {
Count() (int, error)
}

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

type orderCountRoot struct {
Count int `json:"count"`
}

// Count orders
func (s *OrderServiceOp) Count() (int, error) {
path := fmt.Sprintf("%s/count.json", ordersBasePath)

req, err := s.client.NewRequest("GET", path, nil)
if err != nil {
return 0, err
}

root := new(orderCountRoot)
err = s.client.Do(req, root)
if err != nil {
return 0, err
}

return root.Count, err
}
25 changes: 25 additions & 0 deletions order_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package goshopify

import (
"testing"

"github.com/jarcoal/httpmock"
)

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

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

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

expected := 7
if cnt != expected {
t.Errorf("Order.Count returned %d, expected %d", cnt, expected)
}
}
18 changes: 9 additions & 9 deletions products.go → product.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import (

const productsBasePath = "admin/products"

// ProductsService is an interface for interfacing with the product endpoints
// ProductService is an interface for interfacing with the product endpoints
// of the Shopify API.
// See: https://help.shopify.com/api/reference/product
type ProductsService interface {
type ProductService interface {
List() ([]Product, error)
Count() (int, error)
Get(int) (*Product, error)
}

// ProductsServiceOp handles communication with the product related methods of
// ProductServiceOp handles communication with the product related methods of
// the Shopify API.
type ProductsServiceOp struct {
type ProductServiceOp struct {
client *Client
}

Expand All @@ -36,12 +36,12 @@ type productsRoot struct {
Products []Product `json:"products"`
}

type countRoot struct {
type productCountRoot struct {
Count int `json:"count"`
}

// Performs a list request given a path
func (s *ProductsServiceOp) List() ([]Product, error) {
func (s *ProductServiceOp) List() ([]Product, error) {
path := fmt.Sprintf("%s.json", productsBasePath)
req, err := s.client.NewRequest("GET", path, nil)
if err != nil {
Expand All @@ -58,15 +58,15 @@ func (s *ProductsServiceOp) List() ([]Product, error) {
}

// Count products
func (s *ProductsServiceOp) Count() (int, error) {
func (s *ProductServiceOp) Count() (int, error) {
path := fmt.Sprintf("%s/count.json", productsBasePath)

req, err := s.client.NewRequest("GET", path, nil)
if err != nil {
return 0, err
}

root := new(countRoot)
root := new(productCountRoot)
err = s.client.Do(req, root)
if err != nil {
return 0, err
Expand All @@ -76,7 +76,7 @@ func (s *ProductsServiceOp) Count() (int, error) {
}

// Get individual product
func (s *ProductsServiceOp) Get(productID int) (*Product, error) {
func (s *ProductServiceOp) Get(productID int) (*Product, error) {
path := fmt.Sprintf("%s/%d.json", productsBasePath, productID)

req, err := s.client.NewRequest("GET", path, nil)
Expand Down
24 changes: 12 additions & 12 deletions products_test.go → product_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,56 @@ import (
"github.com/jarcoal/httpmock"
)

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

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/products.json",
httpmock.NewStringResponder(200, `{"products": [{"id":1},{"id":2}]}`))

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

expected := []Product{{ID: 1}, {ID: 2}}
if !reflect.DeepEqual(products, expected) {
t.Errorf("Products.List returned %+v, expected %+v", products, expected)
t.Errorf("Product.List returned %+v, expected %+v", products, expected)
}
}

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

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

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

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

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

httpmock.RegisterResponder("GET", "https://fooshop.myshopify.com/admin/products/1.json",
httpmock.NewStringResponder(200, `{"product": {"id":1}}`))

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

expected := &Product{ID: 1}
if !reflect.DeepEqual(product, expected) {
t.Errorf("Products.Get returned %+v, expected %+v", product, expected)
t.Errorf("Product.Get returned %+v, expected %+v", product, expected)
}
}

0 comments on commit 638d37e

Please sign in to comment.