@stacksjs/commerce 0.70.55 → 0.70.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -7
- package/src/carts/destroy.ts +0 -54
- package/src/carts/fetch.ts +0 -20
- package/src/carts/index.ts +0 -13
- package/src/carts/store.ts +0 -75
- package/src/carts/update.ts +0 -78
- package/src/coupons/destroy.ts +0 -49
- package/src/coupons/fetch.ts +0 -510
- package/src/coupons/index.ts +0 -30
- package/src/coupons/store.ts +0 -46
- package/src/coupons/update.ts +0 -147
- package/src/customers/destroy.ts +0 -62
- package/src/customers/fetch.ts +0 -20
- package/src/customers/index.ts +0 -17
- package/src/customers/store.ts +0 -45
- package/src/customers/update.ts +0 -44
- package/src/devices/destroy.ts +0 -54
- package/src/devices/export.ts +0 -98
- package/src/devices/fetch.ts +0 -125
- package/src/devices/index.ts +0 -31
- package/src/devices/store.ts +0 -82
- package/src/devices/update.ts +0 -125
- package/src/errors/destroy.ts +0 -54
- package/src/errors/fetch.ts +0 -197
- package/src/errors/index.ts +0 -28
- package/src/errors/update.ts +0 -116
- package/src/gift-cards/destroy.ts +0 -87
- package/src/gift-cards/fetch.ts +0 -431
- package/src/gift-cards/index.ts +0 -26
- package/src/gift-cards/store.ts +0 -56
- package/src/gift-cards/update.ts +0 -102
- package/src/index.ts +0 -78
- package/src/orders/destroy.ts +0 -111
- package/src/orders/events.ts +0 -121
- package/src/orders/export.ts +0 -158
- package/src/orders/fetch.ts +0 -379
- package/src/orders/guards.ts +0 -261
- package/src/orders/index.ts +0 -91
- package/src/orders/place-order.ts +0 -274
- package/src/orders/store.ts +0 -51
- package/src/orders/totals.ts +0 -190
- package/src/orders/update.ts +0 -164
- package/src/orders/webhook.ts +0 -312
- package/src/payments/destroy.ts +0 -56
- package/src/payments/fetch.ts +0 -288
- package/src/payments/index.ts +0 -16
- package/src/payments/store.ts +0 -63
- package/src/payments/update.ts +0 -52
- package/src/product.ts +0 -0
- package/src/products/categories/destroy.ts +0 -103
- package/src/products/categories/fetch.ts +0 -285
- package/src/products/categories/index.ts +0 -36
- package/src/products/categories/store.ts +0 -87
- package/src/products/categories/update.ts +0 -251
- package/src/products/index.ts +0 -35
- package/src/products/items/destroy.ts +0 -54
- package/src/products/items/fetch.ts +0 -282
- package/src/products/items/index.ts +0 -26
- package/src/products/items/store.ts +0 -84
- package/src/products/items/update.ts +0 -324
- package/src/products/manufacturers/destroy.ts +0 -56
- package/src/products/manufacturers/fetch.ts +0 -117
- package/src/products/manufacturers/index.ts +0 -24
- package/src/products/manufacturers/store.ts +0 -82
- package/src/products/manufacturers/update.ts +0 -113
- package/src/products/reviews/destroy.ts +0 -56
- package/src/products/reviews/fetch.ts +0 -63
- package/src/products/reviews/index.ts +0 -25
- package/src/products/reviews/store.ts +0 -46
- package/src/products/reviews/update.ts +0 -82
- package/src/products/units/destroy.ts +0 -56
- package/src/products/units/fetch.ts +0 -20
- package/src/products/units/index.ts +0 -13
- package/src/products/units/store.ts +0 -162
- package/src/products/units/update.ts +0 -159
- package/src/products/variants/destroy.ts +0 -56
- package/src/products/variants/fetch.ts +0 -20
- package/src/products/variants/index.ts +0 -21
- package/src/products/variants/store.ts +0 -136
- package/src/products/variants/update.ts +0 -104
- package/src/receipts/destroy.ts +0 -54
- package/src/receipts/export.ts +0 -0
- package/src/receipts/fetch.ts +0 -222
- package/src/receipts/index.ts +0 -24
- package/src/receipts/printer.ts +0 -69
- package/src/receipts/store.ts +0 -69
- package/src/receipts/update.ts +0 -124
- package/src/shippings/delivery-routes/destroy.ts +0 -54
- package/src/shippings/delivery-routes/fetch.ts +0 -42
- package/src/shippings/delivery-routes/index.ts +0 -26
- package/src/shippings/delivery-routes/store.ts +0 -69
- package/src/shippings/delivery-routes/update.ts +0 -120
- package/src/shippings/digital-deliveries/destroy.ts +0 -111
- package/src/shippings/digital-deliveries/fetch.ts +0 -20
- package/src/shippings/digital-deliveries/index.ts +0 -26
- package/src/shippings/digital-deliveries/store.ts +0 -76
- package/src/shippings/digital-deliveries/update.ts +0 -129
- package/src/shippings/drivers/destroy.ts +0 -78
- package/src/shippings/drivers/fetch.ts +0 -20
- package/src/shippings/drivers/index.ts +0 -24
- package/src/shippings/drivers/store.ts +0 -69
- package/src/shippings/drivers/update.ts +0 -117
- package/src/shippings/index.ts +0 -39
- package/src/shippings/license-keys/destroy.ts +0 -111
- package/src/shippings/license-keys/fetch.ts +0 -20
- package/src/shippings/license-keys/index.ts +0 -26
- package/src/shippings/license-keys/store.ts +0 -77
- package/src/shippings/license-keys/update.ts +0 -117
- package/src/shippings/shipping-methods/destroy.ts +0 -111
- package/src/shippings/shipping-methods/fetch.ts +0 -62
- package/src/shippings/shipping-methods/index.ts +0 -28
- package/src/shippings/shipping-methods/store.ts +0 -123
- package/src/shippings/shipping-methods/update.ts +0 -120
- package/src/shippings/shipping-rates/destroy.ts +0 -102
- package/src/shippings/shipping-rates/fetch.ts +0 -320
- package/src/shippings/shipping-rates/index.ts +0 -36
- package/src/shippings/shipping-rates/store.ts +0 -102
- package/src/shippings/shipping-rates/update.ts +0 -139
- package/src/shippings/shipping-zones/destroy.ts +0 -111
- package/src/shippings/shipping-zones/fetch.ts +0 -96
- package/src/shippings/shipping-zones/index.ts +0 -26
- package/src/shippings/shipping-zones/store.ts +0 -74
- package/src/shippings/shipping-zones/update.ts +0 -156
- package/src/tax/destroy.ts +0 -54
- package/src/tax/fetch.ts +0 -20
- package/src/tax/index.ts +0 -24
- package/src/tax/store.ts +0 -69
- package/src/tax/update.ts +0 -119
- package/src/tests/coupons.test.ts +0 -90
- package/src/tests/customers.test.ts +0 -39
- package/src/tests/device.test.ts +0 -111
- package/src/tests/digitals.test.ts +0 -31
- package/src/tests/drivers.test.ts +0 -25
- package/src/tests/gift-cards.test.ts +0 -36
- package/src/tests/license.test.ts +0 -31
- package/src/tests/manufacturers.test.ts +0 -80
- package/src/tests/orders.test.ts +0 -25
- package/src/tests/payments.test.ts +0 -75
- package/src/tests/rates.test.ts +0 -367
- package/src/tests/receipts.test.ts +0 -287
- package/src/tests/restaurant.test.ts +0 -522
- package/src/tests/reviews.test.ts +0 -165
- package/src/tests/routes.test.ts +0 -51
- package/src/tests/setup.ts +0 -149
- package/src/tests/shipping.test.ts +0 -88
- package/src/tests/tax.test.ts +0 -25
- package/src/tests/units.test.ts +0 -110
- package/src/tests/variants.test.ts +0 -133
- package/src/tests/waitlist.test.ts +0 -303
- package/src/tests/zones.test.ts +0 -86
- package/src/types.ts +0 -312
- package/src/utils/typed-stats.ts +0 -67
- package/src/waitlists/index.ts +0 -19
- package/src/waitlists/products/destroy.ts +0 -65
- package/src/waitlists/products/export.ts +0 -113
- package/src/waitlists/products/fetch.ts +0 -362
- package/src/waitlists/products/index.ts +0 -33
- package/src/waitlists/products/store.ts +0 -112
- package/src/waitlists/products/update.ts +0 -125
- package/src/waitlists/restaurant/destroy.ts +0 -65
- package/src/waitlists/restaurant/export.ts +0 -107
- package/src/waitlists/restaurant/fetch.ts +0 -538
- package/src/waitlists/restaurant/index.ts +0 -43
- package/src/waitlists/restaurant/store.ts +0 -109
- package/src/waitlists/restaurant/update.ts +0 -198
- /package/dist/{src/coupons → coupons}/destroy.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/fetch.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/index.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/store.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/update.d.ts +0 -0
- /package/dist/{src/customers → customers}/destroy.d.ts +0 -0
- /package/dist/{src/customers → customers}/fetch.d.ts +0 -0
- /package/dist/{src/customers → customers}/index.d.ts +0 -0
- /package/dist/{src/customers → customers}/store.d.ts +0 -0
- /package/dist/{src/customers → customers}/update.d.ts +0 -0
- /package/dist/{src/devices → devices}/destroy.d.ts +0 -0
- /package/dist/{src/devices → devices}/export.d.ts +0 -0
- /package/dist/{src/devices → devices}/fetch.d.ts +0 -0
- /package/dist/{src/devices → devices}/index.d.ts +0 -0
- /package/dist/{src/devices → devices}/store.d.ts +0 -0
- /package/dist/{src/devices → devices}/update.d.ts +0 -0
- /package/dist/{src/errors → errors}/destroy.d.ts +0 -0
- /package/dist/{src/errors → errors}/fetch.d.ts +0 -0
- /package/dist/{src/errors → errors}/index.d.ts +0 -0
- /package/dist/{src/errors → errors}/update.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/destroy.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/fetch.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/index.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/store.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/update.d.ts +0 -0
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
- /package/dist/{src/orders → orders}/destroy.d.ts +0 -0
- /package/dist/{src/orders → orders}/events.d.ts +0 -0
- /package/dist/{src/orders → orders}/export.d.ts +0 -0
- /package/dist/{src/orders → orders}/fetch.d.ts +0 -0
- /package/dist/{src/orders → orders}/guards.d.ts +0 -0
- /package/dist/{src/orders → orders}/index.d.ts +0 -0
- /package/dist/{src/orders → orders}/place-order.d.ts +0 -0
- /package/dist/{src/orders → orders}/store.d.ts +0 -0
- /package/dist/{src/orders → orders}/totals.d.ts +0 -0
- /package/dist/{src/orders → orders}/update.d.ts +0 -0
- /package/dist/{src/orders → orders}/webhook.d.ts +0 -0
- /package/dist/{src/payments → payments}/destroy.d.ts +0 -0
- /package/dist/{src/payments → payments}/fetch.d.ts +0 -0
- /package/dist/{src/payments → payments}/index.d.ts +0 -0
- /package/dist/{src/payments → payments}/store.d.ts +0 -0
- /package/dist/{src/payments → payments}/update.d.ts +0 -0
- /package/dist/{src/products → products}/categories/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/categories/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/categories/index.d.ts +0 -0
- /package/dist/{src/products → products}/categories/store.d.ts +0 -0
- /package/dist/{src/products → products}/categories/update.d.ts +0 -0
- /package/dist/{src/products → products}/index.d.ts +0 -0
- /package/dist/{src/products → products}/items/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/items/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/items/index.d.ts +0 -0
- /package/dist/{src/products → products}/items/store.d.ts +0 -0
- /package/dist/{src/products → products}/items/update.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/index.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/store.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/update.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/index.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/store.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/update.d.ts +0 -0
- /package/dist/{src/products → products}/units/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/units/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/units/index.d.ts +0 -0
- /package/dist/{src/products → products}/units/store.d.ts +0 -0
- /package/dist/{src/products → products}/units/update.d.ts +0 -0
- /package/dist/{src/products → products}/variants/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/variants/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/variants/index.d.ts +0 -0
- /package/dist/{src/products → products}/variants/store.d.ts +0 -0
- /package/dist/{src/products → products}/variants/update.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/destroy.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/fetch.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/index.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/store.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/update.d.ts +0 -0
- /package/dist/{src/tax → tax}/destroy.d.ts +0 -0
- /package/dist/{src/tax → tax}/fetch.d.ts +0 -0
- /package/dist/{src/tax → tax}/index.d.ts +0 -0
- /package/dist/{src/tax → tax}/store.d.ts +0 -0
- /package/dist/{src/tax → tax}/update.d.ts +0 -0
- /package/dist/{src/types.d.ts → types.d.ts} +0 -0
- /package/dist/{src/utils → utils}/typed-stats.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/index.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/destroy.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/fetch.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/index.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/store.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/update.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/destroy.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/fetch.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/index.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/store.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/update.d.ts +0 -0
package/src/tests/routes.test.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'bun:test'
|
|
2
|
-
import { refreshDatabase } from './setup'
|
|
3
|
-
import { bulkDestroy } from '../shippings/delivery-routes/destroy'
|
|
4
|
-
import { fetchByDriver } from '../shippings/delivery-routes/fetch'
|
|
5
|
-
import { store } from '../shippings/delivery-routes/store'
|
|
6
|
-
|
|
7
|
-
beforeEach(async () => {
|
|
8
|
-
await refreshDatabase()
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
describe('Delivery Route Module', () => {
|
|
12
|
-
describe('fetch', () => {
|
|
13
|
-
it('should fetch routes by driver', async () => {
|
|
14
|
-
// Create routes for the same driver
|
|
15
|
-
const driverName = 'John Doe'
|
|
16
|
-
const routes = [
|
|
17
|
-
{
|
|
18
|
-
driver: driverName,
|
|
19
|
-
vehicle: 'Truck A123',
|
|
20
|
-
stops: 5,
|
|
21
|
-
delivery_time: 120,
|
|
22
|
-
total_distance: 50,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
driver: driverName,
|
|
26
|
-
vehicle: 'Van B456',
|
|
27
|
-
stops: 3,
|
|
28
|
-
delivery_time: 60,
|
|
29
|
-
total_distance: 25,
|
|
30
|
-
},
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
// Store each route individually
|
|
34
|
-
for (const routeData of routes) {
|
|
35
|
-
await store(routeData)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const driverRoutes = await fetchByDriver(driverName)
|
|
39
|
-
expect(driverRoutes.length).toBeGreaterThanOrEqual(2)
|
|
40
|
-
expect(driverRoutes.every(route => route.driver === driverName)).toBe(true)
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
describe('destroy', () => {
|
|
45
|
-
it('should return 0 when trying to delete an empty array of routes', async () => {
|
|
46
|
-
// Try to delete with an empty array
|
|
47
|
-
const deletedCount = await bulkDestroy([])
|
|
48
|
-
expect(deletedCount).toBe(0)
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
})
|
package/src/tests/setup.ts
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Commerce package test harness.
|
|
3
|
-
*
|
|
4
|
-
* These suites used to import `refreshDatabase` from
|
|
5
|
-
* `@stacksjs/testing/database`, which (pre-existing breakage) never
|
|
6
|
-
* worked from a package directory: `bun test` run from
|
|
7
|
-
* storage/framework/core/commerce doesn't load the repo-root `.env`,
|
|
8
|
-
* so the driver fell back to mysql and the helper's dead kysely-era
|
|
9
|
-
* `sql\`...\`.execute(db)` calls threw in every `beforeEach`. Even
|
|
10
|
-
* forced to sqlite, the migration pipeline resolves `database/` and
|
|
11
|
-
* `database/migrations` off `process.cwd()` and the committed
|
|
12
|
-
* migration corpus is both unrunnable on a virgin DB and drifted from
|
|
13
|
-
* the models (missing `uuid` columns for the 28 `useUuid` commerce
|
|
14
|
-
* models).
|
|
15
|
-
*
|
|
16
|
-
* Strategy (mirrors auth/tests/password-reset-revocation.test.ts): pin
|
|
17
|
-
* env to a throwaway SQLite file BEFORE any framework module loads,
|
|
18
|
-
* then generate the schema directly from the live model definitions
|
|
19
|
-
* via bun-query-builder's loadModels → buildMigrationPlan →
|
|
20
|
-
* generateSql. Foreign-key references are stripped from the plan
|
|
21
|
-
* because the fixtures intentionally insert dangling parent ids
|
|
22
|
-
* (e.g. customer_id 1..3 with no customers row).
|
|
23
|
-
*
|
|
24
|
-
* Wired up via this package's bunfig.toml `[test] preload`, so the
|
|
25
|
-
* env pin always lands before any test file's own imports evaluate.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import { existsSync, mkdtempSync, rmSync, unlinkSync, writeFileSync } from 'node:fs'
|
|
29
|
-
import { tmpdir } from 'node:os'
|
|
30
|
-
import { join } from 'node:path'
|
|
31
|
-
import process from 'node:process'
|
|
32
|
-
|
|
33
|
-
const DB_PATH = join(tmpdir(), `stacks-commerce-${process.pid}.sqlite`)
|
|
34
|
-
process.env.DB_CONNECTION = 'sqlite'
|
|
35
|
-
process.env.DB_DATABASE_PATH = DB_PATH
|
|
36
|
-
process.env.APP_ENV = 'testing'
|
|
37
|
-
|
|
38
|
-
// Dynamic imports AFTER the env pin so the lazy `db` proxy and the
|
|
39
|
-
// config loader can't capture a different connection first.
|
|
40
|
-
const { acquireDbConfigLock, db, ensureDatabaseConfigLoaded, initializeDbConfig } = await import('@stacksjs/database')
|
|
41
|
-
const { buildMigrationPlan, generateSql, loadModels } = await import('bun-query-builder')
|
|
42
|
-
|
|
43
|
-
// Holds `initializeDbConfig`'s process-wide config mutex (stacksjs/stacks#1862)
|
|
44
|
-
// for this module's entire lifetime — no `describe`/`afterAll` boundary exists
|
|
45
|
-
// here (this is a shared fixture imported by many test files, not a test file
|
|
46
|
-
// itself), so it's released on process exit alongside the file cleanup below.
|
|
47
|
-
const releaseDbConfigLock = await acquireDbConfigLock()
|
|
48
|
-
|
|
49
|
-
// storage/framework/defaults — the framework's vendor layer where the
|
|
50
|
-
// default model definitions live. `loadModels` does not recurse, so the
|
|
51
|
-
// commerce subdirectory is loaded explicitly and merged.
|
|
52
|
-
const defaultsModelsDir = join(import.meta.dir, '../../../../defaults/app/Models')
|
|
53
|
-
const commerceModelsDir = join(defaultsModelsDir, 'commerce')
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Drain the one-shot async config reload, then force our temp SQLite
|
|
57
|
-
* config so a late-resolving override can't re-point the shared `db`
|
|
58
|
-
* proxy at a different database mid-test.
|
|
59
|
-
*/
|
|
60
|
-
async function forceConfig(): Promise<void> {
|
|
61
|
-
await ensureDatabaseConfigLoaded()
|
|
62
|
-
initializeDbConfig({
|
|
63
|
-
app: { env: 'testing' },
|
|
64
|
-
database: {
|
|
65
|
-
default: 'sqlite',
|
|
66
|
-
connections: { sqlite: { database: DB_PATH, prefix: '' } },
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Stale file from a recycled pid would otherwise leak a previous run's
|
|
72
|
-
// schema/rows into this one.
|
|
73
|
-
for (const suffix of ['', '-wal', '-shm']) {
|
|
74
|
-
if (existsSync(`${DB_PATH}${suffix}`))
|
|
75
|
-
unlinkSync(`${DB_PATH}${suffix}`)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
await forceConfig()
|
|
79
|
-
|
|
80
|
-
const models = {
|
|
81
|
-
...(await loadModels({ modelsDir: defaultsModelsDir })),
|
|
82
|
-
...(await loadModels({ modelsDir: commerceModelsDir })),
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const plan = buildMigrationPlan(models, { dialect: 'sqlite' })
|
|
86
|
-
|
|
87
|
-
// The fixtures insert dangling parent ids by design (e.g. orders with
|
|
88
|
-
// customer_id 1 and no customers row), so FK constraints would reject
|
|
89
|
-
// most of the corpus. Strip references — the suites exercise the
|
|
90
|
-
// commerce modules' query logic, not referential integrity.
|
|
91
|
-
for (const table of plan.tables) {
|
|
92
|
-
for (const column of table.columns)
|
|
93
|
-
delete column.references
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// `generateSql()` also writes one `.sql` migration file per statement
|
|
97
|
-
// into `<nearest package.json dir>/database/migrations` (resolved off
|
|
98
|
-
// `process.cwd()`) as a side effect — from this package's cwd that
|
|
99
|
-
// would litter storage/framework/core/commerce/database/. Point the
|
|
100
|
-
// side effect at a disposable temp workspace for the duration of the
|
|
101
|
-
// call. The stub package.json makes its workspace-root walk stop there.
|
|
102
|
-
const scratchDir = mkdtempSync(join(tmpdir(), 'stacks-commerce-migrations-'))
|
|
103
|
-
writeFileSync(join(scratchDir, 'package.json'), '{}')
|
|
104
|
-
const originalCwd = process.cwd()
|
|
105
|
-
let statements: string[]
|
|
106
|
-
try {
|
|
107
|
-
process.chdir(scratchDir)
|
|
108
|
-
statements = generateSql(plan)
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
process.chdir(originalCwd)
|
|
112
|
-
rmSync(scratchDir, { recursive: true, force: true })
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
for (const statement of statements) {
|
|
116
|
-
await db.unsafe(statement).execute()
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const tableNames = plan.tables.map(table => table.table)
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Wipe every model-derived table between tests. DELETE (not DROP) keeps
|
|
123
|
-
* the schema warm; with FK references stripped, order doesn't matter.
|
|
124
|
-
*/
|
|
125
|
-
export async function refreshDatabase(): Promise<void> {
|
|
126
|
-
await forceConfig()
|
|
127
|
-
for (const table of tableNames) {
|
|
128
|
-
await db.unsafe(`DELETE FROM ${table}`).execute()
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Cleanup on process exit, NOT in an `afterAll`: when this module is
|
|
133
|
-
// imported by a test file mid-run (e.g. `bun test tests/` from the
|
|
134
|
-
// repo root, where the path filter also matches these suites), an
|
|
135
|
-
// `afterAll` registered during module evaluation attaches to the FIRST
|
|
136
|
-
// importing file's scope and unlinks the shared DB while later files'
|
|
137
|
-
// connections still use it (SQLITE_IOERR_VNODE).
|
|
138
|
-
process.on('exit', () => {
|
|
139
|
-
for (const suffix of ['', '-wal', '-shm']) {
|
|
140
|
-
try {
|
|
141
|
-
if (existsSync(`${DB_PATH}${suffix}`))
|
|
142
|
-
unlinkSync(`${DB_PATH}${suffix}`)
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
// Best effort — pid-named file in tmpdir, the OS reclaims it.
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
releaseDbConfigLock()
|
|
149
|
-
})
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'bun:test'
|
|
2
|
-
import { refreshDatabase } from './setup'
|
|
3
|
-
import { bulkDestroy, bulkSoftDelete } from '../shippings/shipping-methods/destroy'
|
|
4
|
-
import { formatShippingOptions, getActiveShippingMethods, store } from '../shippings/shipping-methods/store'
|
|
5
|
-
|
|
6
|
-
beforeEach(async () => {
|
|
7
|
-
await refreshDatabase()
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
describe('Shipping Methods Module', () => {
|
|
11
|
-
describe('store', () => {
|
|
12
|
-
it('should format shipping options correctly', async () => {
|
|
13
|
-
// Create test shipping methods
|
|
14
|
-
const request1 = {
|
|
15
|
-
name: 'Standard Shipping',
|
|
16
|
-
base_rate: 500,
|
|
17
|
-
status: 'active',
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
await store(request1)
|
|
21
|
-
|
|
22
|
-
const request2 = {
|
|
23
|
-
name: 'Express Shipping',
|
|
24
|
-
base_rate: 1500,
|
|
25
|
-
zones: JSON.stringify(['North America', 'Europe']),
|
|
26
|
-
status: 'active',
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
await store(request2)
|
|
30
|
-
|
|
31
|
-
// Get formatted options
|
|
32
|
-
const options = await formatShippingOptions()
|
|
33
|
-
|
|
34
|
-
expect(options.length).toBe(2)
|
|
35
|
-
expect(options[0].name).toBeDefined()
|
|
36
|
-
expect(options[0].base_rate).toBeDefined()
|
|
37
|
-
expect(options[0].status).toBeDefined()
|
|
38
|
-
})
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
describe('destroy', () => {
|
|
42
|
-
it('should return 0 when trying to delete an empty array of shipping methods', async () => {
|
|
43
|
-
// Try to delete with an empty array
|
|
44
|
-
const deletedCount = await bulkDestroy([])
|
|
45
|
-
expect(deletedCount).toBe(0)
|
|
46
|
-
|
|
47
|
-
// Try to soft delete with an empty array
|
|
48
|
-
const softDeletedCount = await bulkSoftDelete([])
|
|
49
|
-
expect(softDeletedCount).toBe(0)
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe('fetch', () => {
|
|
54
|
-
it('should get active shipping methods only', async () => {
|
|
55
|
-
// Create an active shipping method
|
|
56
|
-
const activeRequest = {
|
|
57
|
-
name: 'Active Shipping',
|
|
58
|
-
base_rate: 1000,
|
|
59
|
-
status: 'active',
|
|
60
|
-
}
|
|
61
|
-
await store(activeRequest)
|
|
62
|
-
|
|
63
|
-
// Create an inactive shipping method
|
|
64
|
-
const inactiveRequest = {
|
|
65
|
-
name: 'Inactive Shipping',
|
|
66
|
-
base_rate: 1500,
|
|
67
|
-
status: 'inactive',
|
|
68
|
-
}
|
|
69
|
-
await store(inactiveRequest)
|
|
70
|
-
|
|
71
|
-
// Create a draft shipping method
|
|
72
|
-
const draftRequest = {
|
|
73
|
-
name: 'Draft Shipping',
|
|
74
|
-
base_rate: 2000,
|
|
75
|
-
status: 'draft',
|
|
76
|
-
}
|
|
77
|
-
await store(draftRequest)
|
|
78
|
-
|
|
79
|
-
// Get active shipping methods
|
|
80
|
-
const activeMethods = await getActiveShippingMethods()
|
|
81
|
-
|
|
82
|
-
// Should only return active methods
|
|
83
|
-
expect(activeMethods.length).toBe(1)
|
|
84
|
-
expect(activeMethods[0].name).toBe('Active Shipping')
|
|
85
|
-
expect(activeMethods[0].status).toBe('active')
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
})
|
package/src/tests/tax.test.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'bun:test'
|
|
2
|
-
import { refreshDatabase } from './setup'
|
|
3
|
-
import { bulkDestroy } from '../tax/destroy'
|
|
4
|
-
import { bulkStore } from '../tax/store'
|
|
5
|
-
|
|
6
|
-
beforeEach(async () => {
|
|
7
|
-
await refreshDatabase()
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
describe('Tax Rate Module', () => {
|
|
11
|
-
describe('store', () => {
|
|
12
|
-
it('should return 0 when trying to bulk store an empty array', async () => {
|
|
13
|
-
const count = await bulkStore([])
|
|
14
|
-
expect(count).toBe(0)
|
|
15
|
-
})
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
describe('destroy', () => {
|
|
19
|
-
it('should return 0 when trying to delete an empty array of tax rates', async () => {
|
|
20
|
-
// Try to delete with an empty array
|
|
21
|
-
const deletedCount = await bulkDestroy([])
|
|
22
|
-
expect(deletedCount).toBe(0)
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
})
|
package/src/tests/units.test.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'bun:test'
|
|
2
|
-
import { refreshDatabase } from './setup'
|
|
3
|
-
import { bulkDestroy } from '../products/units/destroy'
|
|
4
|
-
import { bulkStore, formatUnitOptions } from '../products/units/store'
|
|
5
|
-
import { bulkUpdate } from '../products/units/update'
|
|
6
|
-
|
|
7
|
-
beforeEach(async () => {
|
|
8
|
-
await refreshDatabase()
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
describe('Product Unit Module', () => {
|
|
12
|
-
describe('bulkStore', () => {
|
|
13
|
-
it('should create multiple product units at once', async () => {
|
|
14
|
-
const unitRequests = [
|
|
15
|
-
{
|
|
16
|
-
name: 'Kilogram',
|
|
17
|
-
product_id: 1,
|
|
18
|
-
abbreviation: 'kg',
|
|
19
|
-
type: 'weight',
|
|
20
|
-
description: 'Standard weight unit',
|
|
21
|
-
is_default: true,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'Liter',
|
|
25
|
-
product_id: 1,
|
|
26
|
-
abbreviation: 'L',
|
|
27
|
-
type: 'volume',
|
|
28
|
-
description: 'Standard volume unit',
|
|
29
|
-
is_default: true,
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'Piece',
|
|
33
|
-
product_id: 1,
|
|
34
|
-
abbreviation: 'pc',
|
|
35
|
-
type: 'quantity',
|
|
36
|
-
description: 'Standard quantity unit',
|
|
37
|
-
is_default: true,
|
|
38
|
-
},
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
const createdCount = await bulkStore(unitRequests)
|
|
42
|
-
expect(createdCount).toBe(3)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('should return 0 when trying to create an empty array of units', async () => {
|
|
46
|
-
const createdCount = await bulkStore([])
|
|
47
|
-
expect(createdCount).toBe(0)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
describe('formatUnitOptions and getDefaultUnit', () => {
|
|
53
|
-
it('should format unit options correctly', async () => {
|
|
54
|
-
// Create units first
|
|
55
|
-
const unitRequests = [
|
|
56
|
-
{
|
|
57
|
-
name: 'Kilogram',
|
|
58
|
-
product_id: 1,
|
|
59
|
-
abbreviation: 'kg',
|
|
60
|
-
type: 'weight',
|
|
61
|
-
is_default: true,
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: 'Gram',
|
|
65
|
-
product_id: 1,
|
|
66
|
-
abbreviation: 'g',
|
|
67
|
-
type: 'weight',
|
|
68
|
-
is_default: false,
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'Liter',
|
|
72
|
-
product_id: 1,
|
|
73
|
-
abbreviation: 'L',
|
|
74
|
-
type: 'volume',
|
|
75
|
-
is_default: true,
|
|
76
|
-
},
|
|
77
|
-
]
|
|
78
|
-
|
|
79
|
-
await bulkStore(unitRequests)
|
|
80
|
-
|
|
81
|
-
// Test formatting options for weight units
|
|
82
|
-
const weightUnits = await formatUnitOptions('weight')
|
|
83
|
-
expect(weightUnits.length).toBe(2)
|
|
84
|
-
expect(weightUnits[0].name).toBe('Gram') // Alphabetical order
|
|
85
|
-
expect(weightUnits[1].name).toBe('Kilogram')
|
|
86
|
-
expect(weightUnits[0].abbreviation).toBe('g')
|
|
87
|
-
expect(weightUnits[1].abbreviation).toBe('kg')
|
|
88
|
-
expect(Boolean(weightUnits[0].is_default)).toBe(false)
|
|
89
|
-
expect(Boolean(weightUnits[1].is_default)).toBe(true)
|
|
90
|
-
|
|
91
|
-
// Test formatting options for all units (no type filter)
|
|
92
|
-
const allUnits = await formatUnitOptions()
|
|
93
|
-
expect(allUnits.length).toBe(3)
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
describe('bulkUpdate', () => {
|
|
98
|
-
it('should return 0 when trying to update an empty array of units', async () => {
|
|
99
|
-
const updatedCount = await bulkUpdate([])
|
|
100
|
-
expect(updatedCount).toBe(0)
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
describe('bulkDestroy', () => {
|
|
105
|
-
it('should return 0 when trying to delete an empty array of units', async () => {
|
|
106
|
-
const deletedCount = await bulkDestroy([])
|
|
107
|
-
expect(deletedCount).toBe(0)
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
})
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from 'bun:test'
|
|
2
|
-
import { refreshDatabase } from './setup'
|
|
3
|
-
import { bulkDestroy } from '../products/variants/destroy'
|
|
4
|
-
import { bulkStore, formatVariantOptions, generateVariantCombinations } from '../products/variants/store'
|
|
5
|
-
import { bulkUpdate } from '../products/variants/update'
|
|
6
|
-
|
|
7
|
-
beforeEach(async () => {
|
|
8
|
-
await refreshDatabase()
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
describe('Product Variant Module', () => {
|
|
12
|
-
describe('bulkStore', () => {
|
|
13
|
-
it('should create multiple product variants at once', async () => {
|
|
14
|
-
const requestsData = [
|
|
15
|
-
{
|
|
16
|
-
product_id: 1,
|
|
17
|
-
variant: 'Color',
|
|
18
|
-
type: 'dropdown',
|
|
19
|
-
description: 'Available colors',
|
|
20
|
-
options: JSON.stringify(['Red', 'Blue', 'Green']),
|
|
21
|
-
status: 'draft',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
product_id: 1,
|
|
25
|
-
variant: 'Size',
|
|
26
|
-
type: 'radio',
|
|
27
|
-
description: 'Available sizes',
|
|
28
|
-
options: JSON.stringify(['S', 'M', 'L', 'XL']),
|
|
29
|
-
status: 'draft',
|
|
30
|
-
},
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
const createdCount = await bulkStore(requestsData)
|
|
34
|
-
|
|
35
|
-
expect(createdCount).toBe(2)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('should return 0 when trying to create an empty array of variants', async () => {
|
|
39
|
-
const createdCount = await bulkStore([])
|
|
40
|
-
expect(createdCount).toBe(0)
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
describe('bulkUpdate', () => {
|
|
45
|
-
it('should return 0 when trying to update an empty array of variants', async () => {
|
|
46
|
-
const updateCount = await bulkUpdate([])
|
|
47
|
-
expect(updateCount).toBe(0)
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
describe('bulkDestroy', () => {
|
|
52
|
-
it('should return 0 when trying to delete an empty array of variants', async () => {
|
|
53
|
-
const deletedCount = await bulkDestroy([])
|
|
54
|
-
expect(deletedCount).toBe(0)
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
describe('formatVariantOptions', () => {
|
|
59
|
-
it('should format an array of options as a JSON string', () => {
|
|
60
|
-
const rawOptions = ['Red', 'Blue', 'Green']
|
|
61
|
-
const formattedOptions = formatVariantOptions(rawOptions)
|
|
62
|
-
expect(formattedOptions).toBe(JSON.stringify(rawOptions))
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('should trim whitespace from options', () => {
|
|
66
|
-
const rawOptions = [' Red ', 'Blue ', ' Green']
|
|
67
|
-
const formattedOptions = formatVariantOptions(rawOptions)
|
|
68
|
-
expect(formattedOptions).toBe(JSON.stringify(['Red', 'Blue', 'Green']))
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('should filter out empty options', () => {
|
|
72
|
-
const rawOptions = ['Red', '', 'Blue', ' ', 'Green']
|
|
73
|
-
const formattedOptions = formatVariantOptions(rawOptions)
|
|
74
|
-
expect(formattedOptions).toBe(JSON.stringify(['Red', 'Blue', 'Green']))
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('should return an empty array JSON string when given empty input', () => {
|
|
78
|
-
expect(formatVariantOptions([])).toBe('[]')
|
|
79
|
-
expect(formatVariantOptions([] as string[])).toBe('[]')
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
describe('generateVariantCombinations', () => {
|
|
84
|
-
it('should generate all possible combinations of variant options', () => {
|
|
85
|
-
const optionSets = {
|
|
86
|
-
size: ['S', 'M', 'L'],
|
|
87
|
-
color: ['Red', 'Blue'],
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const combinations = generateVariantCombinations(optionSets)
|
|
91
|
-
|
|
92
|
-
expect(combinations.length).toBe(6) // 3 sizes * 2 colors
|
|
93
|
-
expect(combinations).toContainEqual({ size: 'S', color: 'Red' })
|
|
94
|
-
expect(combinations).toContainEqual({ size: 'S', color: 'Blue' })
|
|
95
|
-
expect(combinations).toContainEqual({ size: 'M', color: 'Red' })
|
|
96
|
-
expect(combinations).toContainEqual({ size: 'M', color: 'Blue' })
|
|
97
|
-
expect(combinations).toContainEqual({ size: 'L', color: 'Red' })
|
|
98
|
-
expect(combinations).toContainEqual({ size: 'L', color: 'Blue' })
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('should handle three or more option types', () => {
|
|
102
|
-
const optionSets = {
|
|
103
|
-
size: ['S', 'M'],
|
|
104
|
-
color: ['Red', 'Blue'],
|
|
105
|
-
material: ['Cotton', 'Polyester'],
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const combinations = generateVariantCombinations(optionSets)
|
|
109
|
-
|
|
110
|
-
expect(combinations.length).toBe(8) // 2 sizes * 2 colors * 2 materials
|
|
111
|
-
expect(combinations).toContainEqual({ size: 'S', color: 'Red', material: 'Cotton' })
|
|
112
|
-
expect(combinations).toContainEqual({ size: 'M', color: 'Blue', material: 'Polyester' })
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('should return an empty array for empty input', () => {
|
|
116
|
-
const combinations = generateVariantCombinations({})
|
|
117
|
-
expect(combinations).toEqual([])
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('should handle a single option type correctly', () => {
|
|
121
|
-
const optionSets = {
|
|
122
|
-
size: ['S', 'M', 'L'],
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const combinations = generateVariantCombinations(optionSets)
|
|
126
|
-
|
|
127
|
-
expect(combinations.length).toBe(3)
|
|
128
|
-
expect(combinations).toContainEqual({ size: 'S' })
|
|
129
|
-
expect(combinations).toContainEqual({ size: 'M' })
|
|
130
|
-
expect(combinations).toContainEqual({ size: 'L' })
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
})
|