feat(promotion, dashboard, core-flows, cart, types, utils, medusa): tax inclusive promotions (#12412)
* feat: tax inclusive promotions * feat: add a totals test case * feat: add integration test * chore: changeset * fix: typo * chore: refactor * fix: tests * fix: rest of buyget action tests * fix: cart spec * chore: expand integration test with item level totals * feat: add a few more test cases --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { PromotionStatus, PromotionType } from "@medusajs/utils"
|
||||
import { Modules, PromotionStatus, PromotionType } from "@medusajs/utils"
|
||||
import {
|
||||
createAdminUser,
|
||||
generatePublishableKey,
|
||||
generateStoreHeaders,
|
||||
} from "../../../../helpers/create-admin-user"
|
||||
import { medusaTshirtProduct } from "../../../__fixtures__/product"
|
||||
import { setupTaxStructure } from "../../../../modules/__tests__/fixtures/tax"
|
||||
|
||||
jest.setTimeout(50000)
|
||||
|
||||
@@ -71,6 +72,8 @@ medusaIntegrationTestRunner({
|
||||
beforeEach(async () => {
|
||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
||||
|
||||
await setupTaxStructure(appContainer.resolve(Modules.TAX))
|
||||
|
||||
promotion = standardPromotion = (
|
||||
await api.post(
|
||||
`/admin/promotions`,
|
||||
@@ -629,6 +632,729 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("should add tax inclusive promotion to cart successfully in a tax inclusive currency", async () => {
|
||||
const publishableKey = await generatePublishableKey(appContainer)
|
||||
const storeHeaders = generateStoreHeaders({ publishableKey })
|
||||
|
||||
const salesChannel = (
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "Webshop", description: "channel" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.sales_channel
|
||||
|
||||
await api.post(
|
||||
"/admin/price-preferences",
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "dkk",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const region = (
|
||||
await api.post(
|
||||
"/admin/regions",
|
||||
{
|
||||
name: "DK",
|
||||
currency_code: "dkk",
|
||||
countries: ["dk"],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.region
|
||||
|
||||
const product = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
{
|
||||
...medusaTshirtProduct,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/promotions`,
|
||||
{
|
||||
code: "FIXED_10",
|
||||
type: PromotionType.STANDARD,
|
||||
status: PromotionStatus.ACTIVE,
|
||||
is_tax_inclusive: true,
|
||||
is_automatic: true,
|
||||
application_method: {
|
||||
target_type: "items",
|
||||
type: "fixed",
|
||||
allocation: "across",
|
||||
currency_code: "DKK",
|
||||
value: 100,
|
||||
},
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.promotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
code: "FIXED_10",
|
||||
type: "standard",
|
||||
is_tax_inclusive: true,
|
||||
is_automatic: true,
|
||||
application_method: expect.objectContaining({
|
||||
value: 100,
|
||||
type: "fixed",
|
||||
target_type: "items",
|
||||
allocation: "across",
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const cart = (
|
||||
await api.post(
|
||||
`/store/carts?fields=*items,*items.adjustments`,
|
||||
{
|
||||
currency_code: "dkk",
|
||||
sales_channel_id: salesChannel.id,
|
||||
region_id: region.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: product.variants[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
promo_codes: [response.data.promotion.code],
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
).data.cart
|
||||
|
||||
/**
|
||||
* Orignal total -> 1300 DKK (tax incl.)
|
||||
* Tax rate -> 25%
|
||||
* Promotion -> FIXED 100 DKK (tax incl.)
|
||||
*
|
||||
* We want total to be 1300 DKK - 100 DKK = 1200 DKK
|
||||
*/
|
||||
expect(cart).toEqual(
|
||||
expect.objectContaining({
|
||||
currency_code: "dkk",
|
||||
|
||||
subtotal: 1040, // taxable base (item subtotal - discount subtotal) = 1040 - 80 = 960
|
||||
total: 1200, // total = taxable base * (1 + tax rate) = 960 * (1 + 0.25) = 1200
|
||||
tax_total: 240,
|
||||
|
||||
original_total: 1300,
|
||||
original_tax_total: 260,
|
||||
|
||||
discount_total: 100,
|
||||
discount_subtotal: 80,
|
||||
discount_tax_total: 20,
|
||||
|
||||
item_total: 1200,
|
||||
item_subtotal: 1040,
|
||||
item_tax_total: 240,
|
||||
|
||||
original_item_total: 1300,
|
||||
original_item_subtotal: 1040,
|
||||
original_item_tax_total: 260,
|
||||
|
||||
shipping_total: 0,
|
||||
shipping_subtotal: 0,
|
||||
shipping_tax_total: 0,
|
||||
|
||||
original_shipping_tax_total: 0,
|
||||
original_shipping_subtotal: 0,
|
||||
original_shipping_total: 0,
|
||||
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
quantity: 1,
|
||||
unit_price: 1300,
|
||||
|
||||
subtotal: 1040,
|
||||
tax_total: 240,
|
||||
total: 1200,
|
||||
|
||||
original_total: 1300,
|
||||
original_tax_total: 260,
|
||||
|
||||
discount_total: 100,
|
||||
discount_subtotal: 80,
|
||||
discount_tax_total: 20,
|
||||
|
||||
adjustments: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
amount: 100,
|
||||
is_tax_inclusive: true,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should add tax inclusive promotion to cart successfully in a tax inclusive currency with 2 items and each allocation", async () => {
|
||||
const publishableKey = await generatePublishableKey(appContainer)
|
||||
const storeHeaders = generateStoreHeaders({ publishableKey })
|
||||
|
||||
const salesChannel = (
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "Webshop", description: "channel" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.sales_channel
|
||||
|
||||
await api.post(
|
||||
"/admin/price-preferences",
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "dkk",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const region = (
|
||||
await api.post(
|
||||
"/admin/regions",
|
||||
{
|
||||
name: "DK",
|
||||
currency_code: "dkk",
|
||||
countries: ["dk"],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.region
|
||||
|
||||
const product = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Discounted Medusa T-Shirt",
|
||||
handle: "discounted-medusa-t-shirt",
|
||||
options: [
|
||||
{
|
||||
title: "Size",
|
||||
values: ["S", "M"],
|
||||
},
|
||||
],
|
||||
variants: [
|
||||
{
|
||||
title: "S",
|
||||
sku: "SHIRT-S",
|
||||
options: {
|
||||
Size: "S",
|
||||
},
|
||||
manage_inventory: false,
|
||||
prices: [
|
||||
{
|
||||
amount: 1000,
|
||||
currency_code: "dkk",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "M",
|
||||
sku: "SHIRT-M",
|
||||
options: {
|
||||
Size: "S",
|
||||
},
|
||||
manage_inventory: false,
|
||||
prices: [
|
||||
{
|
||||
amount: 500,
|
||||
currency_code: "dkk",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/promotions`,
|
||||
{
|
||||
code: "FIXED_10",
|
||||
type: PromotionType.STANDARD,
|
||||
status: PromotionStatus.ACTIVE,
|
||||
is_tax_inclusive: true,
|
||||
is_automatic: true,
|
||||
application_method: {
|
||||
target_type: "items",
|
||||
type: "fixed",
|
||||
allocation: "each",
|
||||
currency_code: "DKK",
|
||||
value: 100,
|
||||
max_quantity: 2,
|
||||
},
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.promotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
code: "FIXED_10",
|
||||
type: "standard",
|
||||
is_tax_inclusive: true,
|
||||
is_automatic: true,
|
||||
application_method: expect.objectContaining({
|
||||
value: 100,
|
||||
type: "fixed",
|
||||
target_type: "items",
|
||||
allocation: "each",
|
||||
max_quantity: 2,
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const cart = (
|
||||
await api.post(
|
||||
`/store/carts?fields=*items,*items.adjustments`,
|
||||
{
|
||||
currency_code: "dkk",
|
||||
sales_channel_id: salesChannel.id,
|
||||
region_id: region.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: product.variants[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
{
|
||||
variant_id: product.variants[1].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
promo_codes: [response.data.promotion.code],
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
).data.cart
|
||||
|
||||
/**
|
||||
* Orignal total -> 1500 DKK (tax incl.)
|
||||
* Promotion -> FIXED 100 DKK per item (tax incl.)
|
||||
* Tax rate -> 25%
|
||||
*
|
||||
* We want total to be 1500 DKK - 100 DKK - 100 DKK = 1300 DKK
|
||||
*/
|
||||
expect(cart).toEqual(
|
||||
expect.objectContaining({
|
||||
currency_code: "dkk",
|
||||
|
||||
total: 1300,
|
||||
subtotal: 1200, // taxable base (item subtotal - discount subtotal) = 1200 - 200 = 1000
|
||||
tax_total: 260,
|
||||
|
||||
discount_total: 200, // 2 * 100 DKK fixed tax inclusive
|
||||
discount_subtotal: 160,
|
||||
discount_tax_total: 40,
|
||||
|
||||
original_total: 1500,
|
||||
original_tax_total: 300,
|
||||
|
||||
item_total: 1300,
|
||||
item_subtotal: 1200,
|
||||
item_tax_total: 260,
|
||||
|
||||
original_item_total: 1500,
|
||||
original_item_subtotal: 1200,
|
||||
original_item_tax_total: 300,
|
||||
|
||||
shipping_total: 0,
|
||||
shipping_subtotal: 0,
|
||||
shipping_tax_total: 0,
|
||||
|
||||
original_shipping_tax_total: 0,
|
||||
original_shipping_subtotal: 0,
|
||||
original_shipping_total: 0,
|
||||
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
quantity: 1,
|
||||
unit_price: 500,
|
||||
|
||||
subtotal: 400,
|
||||
total: 400, // 400 - 80 = 320 -> 320 * 1.25 = 400
|
||||
tax_total: 80,
|
||||
|
||||
original_total: 500,
|
||||
original_tax_total: 100,
|
||||
|
||||
discount_total: 100,
|
||||
discount_subtotal: 80,
|
||||
discount_tax_total: 20,
|
||||
|
||||
adjustments: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
amount: 100,
|
||||
is_tax_inclusive: true,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
quantity: 1,
|
||||
unit_price: 1000,
|
||||
|
||||
subtotal: 800, // 800 - 80 = 720 -> 720 * 1.25 = 900
|
||||
total: 900,
|
||||
tax_total: 180,
|
||||
|
||||
original_total: 1000,
|
||||
original_tax_total: 200,
|
||||
|
||||
discount_total: 100,
|
||||
discount_subtotal: 80,
|
||||
discount_tax_total: 20,
|
||||
|
||||
adjustments: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
amount: 100,
|
||||
is_tax_inclusive: true,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should add tax exclusive promotion to cart successfully for tax inclusive currency", async () => {
|
||||
const publishableKey = await generatePublishableKey(appContainer)
|
||||
const storeHeaders = generateStoreHeaders({ publishableKey })
|
||||
|
||||
const salesChannel = (
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "Webshop", description: "channel" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.sales_channel
|
||||
|
||||
await api.post(
|
||||
"/admin/price-preferences",
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "dkk",
|
||||
is_tax_inclusive: true,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const region = (
|
||||
await api.post(
|
||||
"/admin/regions",
|
||||
{
|
||||
name: "DK",
|
||||
currency_code: "dkk",
|
||||
countries: ["dk"],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.region
|
||||
|
||||
const product = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
{
|
||||
...medusaTshirtProduct,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/promotions`,
|
||||
{
|
||||
code: "FIXED_10",
|
||||
type: PromotionType.STANDARD,
|
||||
status: PromotionStatus.ACTIVE,
|
||||
is_automatic: true,
|
||||
application_method: {
|
||||
target_type: "items",
|
||||
type: "fixed",
|
||||
allocation: "across",
|
||||
currency_code: "DKK",
|
||||
value: 100,
|
||||
},
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.promotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
code: "FIXED_10",
|
||||
type: "standard",
|
||||
is_tax_inclusive: false, // tax exclusive by default
|
||||
is_automatic: true,
|
||||
application_method: expect.objectContaining({
|
||||
value: 100,
|
||||
type: "fixed",
|
||||
target_type: "items",
|
||||
allocation: "across",
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const cart = (
|
||||
await api.post(
|
||||
`/store/carts?fields=*items,*items.adjustments`,
|
||||
{
|
||||
currency_code: "dkk",
|
||||
sales_channel_id: salesChannel.id,
|
||||
region_id: region.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: product.variants[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
promo_codes: [response.data.promotion.code],
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
).data.cart
|
||||
|
||||
/**
|
||||
* Orignal total -> 1300 DKK (tax incl.)
|
||||
* Tax rate -> 25%
|
||||
* Promotion -> FIXED 100 DKK (tax exclusive !)
|
||||
*/
|
||||
expect(cart).toEqual(
|
||||
expect.objectContaining({
|
||||
currency_code: "dkk",
|
||||
|
||||
subtotal: 1040, // taxable base (item subtotal - discount subtotal) = 1040 - 100 = 940
|
||||
total: 1175, // total = taxable base * (1 + tax rate) = 940 * (1 + 0.25) = 1175
|
||||
tax_total: 235,
|
||||
|
||||
original_total: 1300,
|
||||
original_tax_total: 260,
|
||||
|
||||
discount_total: 100,
|
||||
discount_subtotal: 100,
|
||||
discount_tax_total: 20,
|
||||
|
||||
item_total: 1175,
|
||||
item_subtotal: 1040,
|
||||
item_tax_total: 235,
|
||||
|
||||
original_item_total: 1300,
|
||||
original_item_subtotal: 1040,
|
||||
original_item_tax_total: 260,
|
||||
|
||||
shipping_total: 0,
|
||||
shipping_subtotal: 0,
|
||||
shipping_tax_total: 0,
|
||||
|
||||
original_shipping_tax_total: 0,
|
||||
original_shipping_subtotal: 0,
|
||||
original_shipping_total: 0,
|
||||
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
quantity: 1,
|
||||
unit_price: 1300,
|
||||
|
||||
subtotal: 1040,
|
||||
tax_total: 235,
|
||||
total: 1175,
|
||||
|
||||
original_total: 1300,
|
||||
original_tax_total: 260,
|
||||
|
||||
discount_total: 100,
|
||||
discount_subtotal: 100,
|
||||
discount_tax_total: 20,
|
||||
|
||||
adjustments: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
amount: 100,
|
||||
is_tax_inclusive: false,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should add tax exclusive promotion to cart successfully for tax exclusive currency", async () => {
|
||||
const publishableKey = await generatePublishableKey(appContainer)
|
||||
const storeHeaders = generateStoreHeaders({ publishableKey })
|
||||
|
||||
const salesChannel = (
|
||||
await api.post(
|
||||
"/admin/sales-channels",
|
||||
{ name: "Webshop", description: "channel" },
|
||||
adminHeaders
|
||||
)
|
||||
).data.sales_channel
|
||||
|
||||
await api.post(
|
||||
"/admin/price-preferences",
|
||||
{
|
||||
attribute: "currency_code",
|
||||
value: "dkk",
|
||||
is_tax_inclusive: false,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const region = (
|
||||
await api.post(
|
||||
"/admin/regions",
|
||||
{
|
||||
name: "DK",
|
||||
currency_code: "dkk",
|
||||
countries: ["dk"],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.region
|
||||
|
||||
const product = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
{
|
||||
...medusaTshirtProduct,
|
||||
shipping_profile_id: shippingProfile.id,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
const response = await api.post(
|
||||
`/admin/promotions`,
|
||||
{
|
||||
code: "FIXED_10",
|
||||
type: PromotionType.STANDARD,
|
||||
status: PromotionStatus.ACTIVE,
|
||||
is_automatic: true,
|
||||
application_method: {
|
||||
target_type: "items",
|
||||
type: "fixed",
|
||||
allocation: "across",
|
||||
currency_code: "DKK",
|
||||
value: 100,
|
||||
},
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.promotion).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
code: "FIXED_10",
|
||||
type: "standard",
|
||||
is_tax_inclusive: false, // tax exclusive by default
|
||||
is_automatic: true,
|
||||
application_method: expect.objectContaining({
|
||||
value: 100,
|
||||
type: "fixed",
|
||||
target_type: "items",
|
||||
allocation: "across",
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const cart = (
|
||||
await api.post(
|
||||
`/store/carts?fields=*items,*items.adjustments`,
|
||||
{
|
||||
currency_code: "dkk",
|
||||
sales_channel_id: salesChannel.id,
|
||||
region_id: region.id,
|
||||
items: [
|
||||
{
|
||||
variant_id: product.variants[0].id,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
promo_codes: [response.data.promotion.code],
|
||||
},
|
||||
storeHeaders
|
||||
)
|
||||
).data.cart
|
||||
|
||||
/**
|
||||
* Orignal total -> 1300 DKK (tax excl.)
|
||||
* Tax rate -> 25%
|
||||
* Promotion -> FIXED 100 DKK (tax exclusive !)
|
||||
*/
|
||||
expect(cart).toEqual(
|
||||
expect.objectContaining({
|
||||
currency_code: "dkk",
|
||||
|
||||
subtotal: 1300, // taxable base (item subtotal - discount subtotal) = 1300 - 100 = 1200
|
||||
total: 1500, // total = taxable base * (1 + tax rate) = 1200 * (1 + 0.25) = 1500
|
||||
tax_total: 300,
|
||||
|
||||
original_total: 1625,
|
||||
original_tax_total: 325,
|
||||
|
||||
discount_total: 125,
|
||||
discount_subtotal: 100,
|
||||
discount_tax_total: 25,
|
||||
|
||||
item_total: 1500,
|
||||
item_subtotal: 1300,
|
||||
item_tax_total: 300,
|
||||
|
||||
original_item_total: 1625,
|
||||
original_item_subtotal: 1300,
|
||||
original_item_tax_total: 325,
|
||||
|
||||
shipping_total: 0,
|
||||
shipping_subtotal: 0,
|
||||
shipping_tax_total: 0,
|
||||
|
||||
original_shipping_tax_total: 0,
|
||||
original_shipping_subtotal: 0,
|
||||
original_shipping_total: 0,
|
||||
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
quantity: 1,
|
||||
unit_price: 1300,
|
||||
|
||||
subtotal: 1300,
|
||||
total: 1500,
|
||||
tax_total: 300,
|
||||
|
||||
discount_total: 125,
|
||||
discount_subtotal: 100,
|
||||
discount_tax_total: 25,
|
||||
|
||||
original_total: 1625,
|
||||
original_tax_total: 325,
|
||||
|
||||
adjustments: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
amount: 100,
|
||||
is_tax_inclusive: false,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("DELETE /admin/promotions/:id", () => {
|
||||
|
||||
Reference in New Issue
Block a user