Permalink
Browse files

Merge pull request #152 from mraerino/feature/order-country-negative-…

…filter

Allow negative filtering on order list for shipping / billing country
  • Loading branch information...
bcomnes committed Nov 1, 2018
2 parents 3ba1a93 + 5c0379e commit dc2dccc6e86df73cebf738d9bf988a5a1b31bcb0
Showing with 107 additions and 0 deletions.
  1. +87 −0 api/order_test.go
  2. +20 −0 api/params.go
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
@@ -21,6 +22,27 @@ import (
func createOrder(test *RouteTest, email, currency string) *models.Order {
order := models.NewOrder("", "session1", email, currency)
order.ShippingAddress = models.Address{
AddressRequest: models.AddressRequest{
Name: "Test User",
Address1: "Hohe Str. 10",
City: "Cologne",
State: "NRW",
Zip: "50667",
Country: "Germany",
},
}
order.BillingAddress = models.Address{
AddressRequest: models.AddressRequest{
Name: "Big Corp",
Address1: "Hohe Str. 10",
City: "Cologne",
State: "NRW",
Zip: "50667",
Country: "Germany",
},
}
result := test.DB.Create(order)
assert.NoError(test.T, result.Error, fmt.Sprintf("inserting the test order failed: %+v", result.Error))
@@ -422,6 +444,71 @@ func TestUserOrdersList(t *testing.T) {
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?fulfillment_state=sunken", nil, token)
validateError(t, http.StatusBadRequest, recorder)
})
var createExampleCountryOrders = func(test *RouteTest) {
orderDe := createOrder(test, "heinrich@zemo.org", "EUR")
orderDe.ShippingAddress.Country = "Germany"
orderDe.BillingAddress.Country = "Germany"
assert.NoError(t, test.DB.Save(orderDe).Error)
orderDk := createOrder(test, "antboy@hasselbalch.dk", "DKR")
orderDk.ShippingAddress.Country = "Denmark"
orderDk.BillingAddress.Country = "Denmark"
assert.NoError(t, test.DB.Save(orderDk).Error)
}
var euCountries = []string{
"Austria", "Italy", "Belgium", "Latvia", "Bulgaria", "Lithuania", "Croatia", "Luxembourg", "Cyprus",
"Malta", "Czechia", "Netherlands", "Denmark", "Poland", "Estonia", "Portugal", "Finland", "Romania",
"France", "Slovakia", "Germany", "Slovenia", "Greece", "Spain", "Hungary", "Sweden", "Ireland", "United Kingdom",
}
t.Run("ShippingCountrySingle", func(t *testing.T) {
test := NewRouteTest(t)
createExampleCountryOrders(test)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
recorder := test.TestEndpoint(http.MethodGet, "/users/all/orders?shipping_countries=Denmark", nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 1)
singleOrder := orders[0]
assert.Equal(t, singleOrder.Email, "antboy@hasselbalch.dk")
})
t.Run("ShippingCountryEU", func(t *testing.T) {
test := NewRouteTest(t)
createExampleCountryOrders(test)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
url := "/users/all/orders?shipping_countries=" + url.QueryEscape(strings.Join(euCountries, ","))
recorder := test.TestEndpoint(http.MethodGet, url, nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 2)
for _, o := range orders {
switch o.Email {
case "heinrich@zemo.org":
assert.Equal(t, "EUR", o.Currency)
assert.Equal(t, "Germany", o.ShippingAddress.Country)
case "antboy@hasselbalch.dk":
assert.Equal(t, "DKR", o.Currency)
assert.Equal(t, "Denmark", o.ShippingAddress.Country)
default:
assert.Fail(t, "Invalid order: $+v", o)
}
}
})
t.Run("ShippingCountryNonEU", func(t *testing.T) {
test := NewRouteTest(t)
createExampleCountryOrders(test)
token := testAdminToken("admin-yo", "admin@wayneindustries.com")
url := "/users/all/orders?shipping_countries!=" + url.QueryEscape(strings.Join(euCountries, ","))
recorder := test.TestEndpoint(http.MethodGet, url, nil, token)
orders := []models.Order{}
extractPayload(t, http.StatusOK, recorder, &orders)
assert.Len(t, orders, 2)
validateAllOrders(t, orders, test.Data)
})
})
t.Run("NotWithAdminRights", func(t *testing.T) {
test := NewRouteTest(t)
@@ -103,6 +103,25 @@ func addAddressFilter(query *gorm.DB, params url.Values, queryField string, dbFi
return query
}
// addNegativeAddressFilter allows filtering with a negative query arg like "?shipping_countries!=Germany"
func addNegativeAddressFilter(query *gorm.DB, params url.Values, queryField string, dbField string) *gorm.DB {
addressTable := query.NewScope(models.Address{}).QuotedTableName()
orderTable := query.NewScope(models.Order{}).QuotedTableName()
if billingField := params.Get("billing_" + queryField + "!"); billingField != "" {
statement := "JOIN " + addressTable + " as billing_address on billing_address.id = " +
orderTable + ".billing_address_id AND " + "billing_address." + dbField + " not in (?)"
query = query.Joins(statement, strings.Split(billingField, ","))
}
if shippingField := params.Get("shipping_" + queryField + "!"); shippingField != "" {
statement := "JOIN " + addressTable + " as shipping_address on shipping_address.id = " +
orderTable + ".shipping_address_id AND " + "shipping_address." + dbField + " not in (?)"
query = query.Joins(statement, strings.Split(shippingField, ","))
}
return query
}
func parseOrderParams(query *gorm.DB, params url.Values) (*gorm.DB, error) {
if tax := params.Get("tax"); tax != "" {
if tax == "yes" || tax == "true" {
@@ -113,6 +132,7 @@ func parseOrderParams(query *gorm.DB, params url.Values) (*gorm.DB, error) {
}
query = addAddressFilter(query, params, "countries", "country")
query = addNegativeAddressFilter(query, params, "countries", "country")
query = addAddressFilter(query, params, "name", "name")
if values, exists := params["sort"]; exists {

0 comments on commit dc2dccc

Please sign in to comment.