Files
zeekay 1943f1c093 Hanzo Commerce
Multi-tenant commerce and billing: orders, subscriptions, invoices, plans,
usage metering and a credit ledger. One Go binary. MIT OR Apache-2.0.

Claude-Session: https://claude.ai/code/session_01SAtaDFm8VDiWrhYHNNtxMw
2026-09-23 21:52:16 -07:00

169 lines
3.8 KiB
Go

package test
import (
"testing"
"github.com/hanzoai/commerce/datastore"
"github.com/hanzoai/commerce/models/fixtures"
"github.com/hanzoai/commerce/models/lineitem"
"github.com/hanzoai/commerce/models/order"
"github.com/hanzoai/commerce/models/product"
"github.com/hanzoai/commerce/models/shippingrates"
"github.com/hanzoai/commerce/models/store"
"github.com/hanzoai/commerce/models/taxrates"
"github.com/hanzoai/commerce/models/types/currency"
"github.com/hanzoai/commerce/models/types/georate"
"github.com/hanzoai/commerce/util/test/ae"
"github.com/hanzoai/commerce/util/zipctx"
"github.com/hanzoai/decimal"
. "github.com/hanzoai/commerce/types"
. "github.com/hanzoai/commerce/util/test/ginkgo"
)
// The rates the store fixture below is configured with, expressed exactly. The tests used
// to re-derive tax and shipping with currency.Cents(float64(base)*0.0885), which duplicated
// the production formula INCLUDING the truncation it has now dropped — so it agreed with a
// bug, and past 2^53 cents it did not even agree with itself. Stating the rate once, in the
// same exact form the order model applies it, is the only thing a tally test should assert.
var (
taxRate = decimal.New(885, 4) // 0.0885 — the KS rate on the fixture store
shipRate = decimal.New(1, 1) // 0.1
)
func Test(t *testing.T) {
Setup("models/order", t)
}
var (
ctx ae.Context
db *datastore.Datastore
ord *order.Order
stor *store.Store
stor2 *store.Store
stor3 *store.Store
subProd *product.Product
)
// Setup test context
var _ = BeforeSuite(func() {
ctx = ae.NewContext()
db = datastore.New(ctx)
// Mock gin context that we can use with fixtures
c := zipctx.New(ctx)
ord = fixtures.Order(c).(*order.Order)
// Add a subscription item
subProd = product.Fake(ord.Datastore())
subProd.IsSubscribeable = true
subProd.Interval = Monthly
subProd.IntervalCount = 1
subProd.TrialPeriodDays = 1
subProd.MustPut()
ord.Items = append(ord.Items, lineitem.LineItem{
ProductId: subProd.Id(),
Quantity: 1,
})
stor = store.New(ord.Datastore())
stor.MustCreate()
stor2 = store.New(ord.Datastore())
stor2.MustCreate()
sr, err := stor.GetShippingRates()
Expect(err).NotTo(HaveOccurred())
sr.GeoRates = append(sr.GeoRates, shippingrates.GeoRate{
GeoRate: georate.New(
"",
"",
"",
"",
currency.Cents(0),
currency.Cents(0),
0.1,
currency.Cents(499),
),
ShippingName: "SHIPPING",
})
sr.MustUpdate()
tr, err := stor.GetTaxRates()
Expect(err).NotTo(HaveOccurred())
tr.GeoRates = append(tr.GeoRates, taxrates.GeoRate{
GeoRate: georate.New(
"US",
"KS",
"",
"66212",
currency.Cents(0),
currency.Cents(0),
0.0885,
currency.Cents(1),
),
TaxShipping: false,
TaxName: "TEST TAX",
})
tr.GeoRates = append(tr.GeoRates, taxrates.GeoRate{
GeoRate: georate.New(
"US",
"KS",
"",
"",
currency.Cents(0),
currency.Cents(0),
0.0885,
currency.Cents(1),
),
TaxShipping: false,
TaxName: "TEST TAX",
})
tr.GeoRates = append(tr.GeoRates, taxrates.GeoRate{
GeoRate: georate.New(
"GB",
"",
"",
"",
currency.Cents(0),
currency.Cents(0),
0.20,
currency.Cents(0),
),
TaxShipping: false,
TaxName: "VAT",
})
tr.MustUpdate()
fixtures.Coupon(c)
stor2 = store.New(ord.Datastore())
stor2.MustCreate()
sr2, err := stor2.GetShippingRates()
Expect(err).NotTo(HaveOccurred())
sr2.MustDelete()
tr2, err := stor2.GetTaxRates()
Expect(err).NotTo(HaveOccurred())
stor3 = store.New(ord.Datastore())
stor3.MustCreate()
stor3.Currency = currency.ETH
price := currency.Cents(1234)
stor3.Listings = make(map[string]store.Listing)
stor3.Listings[ord.Items[0].ProductId] = store.Listing{Price: &price}
tr2.MustDelete()
})
// Tear-down test context
var _ = AfterSuite(func() {
ctx.Close()
})