Permalink
Browse files

Allow filtering orders by payment_state and fulfillment_state

  • Loading branch information...
mraerino committed Oct 26, 2018
1 parent 0fe53d4 commit 7d46f178208b3173521f5d08e757cdb001941fc9
Showing with 150 additions and 0 deletions.
  1. +103 −0 api/order_test.go
  2. +33 −0 api/params.go
  3. +14 −0 models/order.go
@@ -19,6 +19,18 @@ import (
"github.com/stretchr/testify/require"
)
func createOrder(test *RouteTest, email, currency string) (*models.Order, func()) {
t := test.T
order := models.NewOrder("", "session1", email, currency)
result := test.DB.Create(order)
assert.NoError(t, result.Error, fmt.Sprintf("inserting the test order failed: %+v", result.Error))
return order, func() {
test.DB.Unscoped().Delete(&order)
}
}
// ------------------------------------------------------------------------------------------------
// CREATE
// ------------------------------------------------------------------------------------------------
@@ -328,6 +340,97 @@ func TestUserOrdersList(t *testing.T) {
assert.Len(t, orders, 2)
validateAllOrders(t, orders, test.Data)
})
t.Run("AllOrdersFilter", func(t *testing.T) {
t.Run("PaymentStatePending", func(t *testing.T) {
test := NewRouteTest(t)
pendingOrder, rollback := createOrder(test, "fanboy@wayneindustries.com", "USD")
defer rollback()
pendingOrder.PaymentState = models.PendingState
test.DB.Save(&pendingOrder)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?payment_state=pending", nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 1)
singleOrder := orders[0]
assert.Equal(t, pendingOrder.ID, singleOrder.ID)
assert.Equal(t, "fanboy@wayneindustries.com", singleOrder.Email)
})
t.Run("PaymentStatePaid", func(t *testing.T) {
test := NewRouteTest(t)
pendingOrder, rollback := createOrder(test, "fanboy@wayneindustries.com", "USD")
defer rollback()
pendingOrder.PaymentState = models.PendingState
test.DB.Save(&pendingOrder)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?payment_state=paid", nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 2)
validateAllOrders(t, orders, test.Data)
})
t.Run("PaymentStateFailed", func(t *testing.T) {
test := NewRouteTest(t)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?payment_state=failed", nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 0)
})
t.Run("PaymentStateInvalid", func(t *testing.T) {
test := NewRouteTest(t)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?payment_state=stolen", nil, token)
validateError(t, http.StatusBadRequest, recorder)
})
t.Run("FulfillmentStatePending", func(t *testing.T) {
test := NewRouteTest(t)
shippedOrder, rollback := createOrder(test, "fanboy@wayneindustries.com", "USD")
defer rollback()
shippedOrder.FulfillmentState = models.ShippedState
test.DB.Save(&shippedOrder)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?fulfillment_state=pending", nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 2)
validateAllOrders(t, orders, test.Data)
})
t.Run("FulfillmentStateShipped", func(t *testing.T) {
test := NewRouteTest(t)
shippedOrder, rollback := createOrder(test, "fanboy@wayneindustries.com", "USD")
defer rollback()
shippedOrder.FulfillmentState = models.ShippedState
test.DB.Save(&shippedOrder)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?fulfillment_state=shipped", nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 1)
singleOrder := orders[0]
assert.Equal(t, shippedOrder.ID, singleOrder.ID)
assert.Equal(t, "fanboy@wayneindustries.com", singleOrder.Email)
})
t.Run("FulfillmentStateInvalid", func(t *testing.T) {
test := NewRouteTest(t)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?fulfillment_state=sunken", nil, token)
validateError(t, http.StatusBadRequest, recorder)
})
})
t.Run("NotWithAdminRights", func(t *testing.T) {
test := NewRouteTest(t)
token := testToken("stranger", "stranger-danger@wayneindustries.com")
@@ -155,6 +155,15 @@ func parseOrderParams(query *gorm.DB, params url.Values) (*gorm.DB, error) {
query = query.Joins(statement, "%"+itemType+"%")
}
query, err := addFilterChoices(query, orderTable, params, "payment_state", models.PaymentStates)
if err != nil {
return nil, err
}
query, err = addFilterChoices(query, orderTable, params, "fulfillment_state", models.FulfillmentStates)
if err != nil {
return nil, err
}
query = addFilters(query, orderTable, params, []string{
"invoice_number",
})
@@ -231,3 +240,27 @@ func addLikeFilters(query *gorm.DB, table string, params url.Values, availableFi
}
return query
}
func addFilterChoices(query *gorm.DB, table string, params url.Values, filterField string, choices []string) (*gorm.DB, error) {
values, exists := params[filterField]
if !exists {
return query, nil
}
filterValues := []string{}
for _, q := range values {
filterValue := ""
for _, v := range choices {
if q == v {
filterValue = v
break
}
}
if filterValue == "" {
return query, fmt.Errorf("Value for %s is not supported: %s", filterField, q)
}
filterValues = append(filterValues, filterValue)
}
return query.Where(fmt.Sprintf("%s.%s IN (?)", table, filterField), filterValues), nil
}
@@ -24,6 +24,20 @@ const ShippedState = "shipped"
// FailedState is the failed state of an Order
const FailedState = "failed"
// PaymentState are the possible values for the PaymentState field
var PaymentStates = []string{
PendingState,
PaidState,
FailedState,
}
// FulfillmentStates are the possible values for the FulfillmentState field
var FulfillmentStates = []string{
PendingState,
ShippedState,
FailedState,
}
// NumberType | StringType | BoolType are the different types supported in custom data for orders
const (
NumberType = iota

0 comments on commit 7d46f17

Please sign in to comment.