chore: Move price list tests to HTTP folder (#7632)

* chore: Move price list tests to HTTP folder

* chore: Remove several unused helpers
This commit is contained in:
Stevche Radevski
2024-06-06 17:17:41 +02:00
committed by GitHub
parent 9576de2be4
commit a62a8be016
8 changed files with 874 additions and 2036 deletions
File diff suppressed because it is too large Load Diff
@@ -1,241 +0,0 @@
const { ProductVariantMoneyAmount } = require("@medusajs/medusa")
const { MoneyAmount } = require("@medusajs/medusa")
const {
Region,
Product,
ProductVariant,
PriceList,
CustomerGroup,
Customer,
Image,
ShippingProfile,
ProductCollection,
ProductOption,
} = require("@medusajs/medusa")
module.exports = async (dataSource, data = {}) => {
const manager = dataSource.manager
const yesterday = ((today) => new Date(today.setDate(today.getDate() - 1)))(
new Date()
)
const tenDaysAgo = ((today) => new Date(today.setDate(today.getDate() - 10)))(
new Date()
)
const defaultProfile = await manager.findOne(ShippingProfile, {
where: { type: ShippingProfile.default },
})
const collection = manager.create(ProductCollection, {
id: "test-collection",
handle: "test-collection",
title: "Test collection",
})
await manager.save(collection)
await manager.insert(Region, {
id: "reg-europe",
name: "Test Region Europe",
currency_code: "eur",
tax_rate: 0,
})
await manager.insert(Region, {
id: "reg-us",
name: "Test Region US",
currency_code: "usd",
tax_rate: 0,
})
const customer = manager.create(Customer, {
id: "test-customer",
email: "john@doe.com",
first_name: "John",
last_name: "Doe",
password_hash:
"c2NyeXB0AAEAAAABAAAAAVMdaddoGjwU1TafDLLlBKnOTQga7P2dbrfgf3fB+rCD/cJOMuGzAvRdKutbYkVpuJWTU39P7OpuWNkUVoEETOVLMJafbI8qs8Qx/7jMQXkN", // password matching "test"
has_account: true,
})
const customerGroup = manager.create(CustomerGroup, {
id: "test-group",
name: "test-group",
})
await manager.save(customerGroup)
customer.groups = [customerGroup]
await manager.save(customer)
const priceListActive = manager.create(PriceList, {
id: "pl",
name: "VIP sale",
description: "All year sale for VIP customers.",
type: "sale",
status: "active",
})
await manager.save(priceListActive)
const priceListExpired = manager.create(PriceList, {
id: "pl_expired",
name: "VIP summer sale",
description: "Summer sale for VIP customers.",
type: "sale",
status: "active",
starts_at: tenDaysAgo,
ends_at: yesterday,
})
await manager.save(priceListExpired)
const priceListWithCustomers = manager.create(PriceList, {
id: "pl_with_customers",
name: "VIP winter sale",
description: "Winter sale for VIP customers.",
type: "sale",
status: "active",
})
priceListWithCustomers.customer_groups = [customerGroup]
await manager.save(priceListWithCustomers)
const productMultiReg = manager.create(Product, {
id: "test-product",
handle: "test-product-reg",
title: "Multi Reg Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
status: "published",
collection_id: "test-collection",
})
const image = manager.create(Image, {
id: "test-image",
url: "test-image.png",
})
productMultiReg.images = [image]
await manager.save(productMultiReg)
await manager.save(ProductOption, {
id: "test-option",
title: "test-option",
product_id: "test-product",
})
const variantMultiReg = manager.create(ProductVariant, {
id: "test-variant",
inventory_quantity: 10,
title: "Test variant",
variant_rank: 0,
sku: "test-sku",
ean: "test-ean",
upc: "test-upc",
barcode: "test-barcode",
product_id: "test-product",
options: [
{
id: "test-variant-option-reg",
value: "Default variant",
option_id: "test-option",
},
],
})
await manager.insert(MoneyAmount, {
id: "test-price-multi-usd",
currency_code: "usd",
amount: 100,
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma",
money_amount_id: "test-price-multi-usd",
variant_id: "test-variant",
})
await manager.insert(MoneyAmount, {
id: "test-price-discount-multi-usd",
currency_code: "usd",
amount: 80,
price_list_id: "pl",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma1",
money_amount_id: "test-price-discount-multi-usd",
variant_id: "test-variant",
})
await manager.insert(MoneyAmount, {
id: "test-price-discount-expired-multi-usd",
currency_code: "usd",
amount: 70,
price_list_id: "pl_expired",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma2",
money_amount_id: "test-price-discount-expired-multi-usd",
variant_id: "test-variant",
})
await manager.insert(MoneyAmount, {
id: "test-price-multi-eur",
currency_code: "eur",
amount: 100,
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma3",
money_amount_id: "test-price-multi-eur",
variant_id: "test-variant",
})
await manager.insert(MoneyAmount, {
id: "test-price-discount-multi-eur",
currency_code: "eur",
amount: 80,
price_list_id: "pl",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma4",
money_amount_id: "test-price-discount-multi-eur",
variant_id: "test-variant",
})
await manager.insert(MoneyAmount, {
id: "test-price-discount-multi-eur-with-customer",
currency_code: "eur",
amount: 40,
price_list_id: "pl_with_customers",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma5",
money_amount_id: "test-price-discount-multi-eur-with-customer",
variant_id: "test-variant",
})
await manager.insert(MoneyAmount, {
id: "test-price-discount-expired-multi-eur",
currency_code: "eur",
amount: 70,
price_list_id: "pl_expired",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma6",
money_amount_id: "test-price-discount-expired-multi-eur",
variant_id: "test-variant",
})
await manager.save(variantMultiReg)
}
@@ -1,113 +0,0 @@
const { Customer, Address, CustomerGroup } = require("@medusajs/medusa")
module.exports = async (dataSource, data = {}) => {
const manager = dataSource.manager
const testAddr = manager.create(Address, {
id: "test-address",
first_name: "Lebron",
last_name: "James",
})
await manager.save(testAddr)
const customer = manager.create(Customer, {
id: "test-customer-1",
email: "test1@email.com",
})
customer.billing_address = testAddr
customer.shipping_addresses = [testAddr]
await manager.save(customer)
await manager.insert(Customer, {
id: "test-customer-2",
email: "test2@email.com",
})
await manager.insert(Customer, {
id: "test-customer-3",
email: "test3@email.com",
})
await manager.insert(Customer, {
id: "test-customer-has_account",
email: "test4@email.com",
has_account: true,
})
const customer5 = manager.create(Customer, {
id: "test-customer-5",
email: "test5@email.com",
})
await manager.save(customer5)
const customer6 = manager.create(Customer, {
id: "test-customer-6",
email: "test6@email.com",
})
await manager.save(customer6)
const customer7 = manager.create(Customer, {
id: "test-customer-7",
email: "test7@email.com",
})
await manager.save(customer7)
const deletionCustomer = manager.create(Customer, {
id: "test-customer-delete-cg",
email: "test-deletetion-cg@email.com",
})
await manager.save(deletionCustomer)
await manager.insert(CustomerGroup, {
id: "customer-group-1",
name: "vip-customers",
})
await manager.insert(CustomerGroup, {
id: "customer-group-2",
name: "test-group-2",
metadata: { data1: "value1" },
})
await manager.insert(CustomerGroup, {
id: "customer-group-3",
name: "test-group-3",
})
await manager.insert(CustomerGroup, {
id: "test-group-4",
name: "test-group-4",
})
const c_group_5 = manager.create(CustomerGroup, {
id: "test-group-5",
name: "test-group-5",
})
await manager.save(c_group_5)
const c_group_6 = manager.create(CustomerGroup, {
id: "test-group-6",
name: "test-group-6",
})
await manager.save(c_group_6)
customer5.groups = [c_group_5]
await manager.save(customer5)
customer6.groups = [c_group_5]
await manager.save(customer6)
customer7.groups = [c_group_5, c_group_6]
await manager.save(customer7)
const c_group_delete = manager.create(CustomerGroup, {
id: "test-group-delete",
name: "test-group-delete",
})
await manager.save(c_group_delete)
deletionCustomer.groups = [c_group_delete]
await manager.save(deletionCustomer)
}
+17
View File
@@ -40,3 +40,20 @@ export const getProductFixture = (
],
...(overrides ?? {}),
})
export const getPricelistFixture = (overrides: Partial<any>) => {
return {
// BREAKING: `name` field was renamed to `title`
title: "Winter sales",
description: "Winter sale. 25% off selected items.",
type: "sale",
status: "active",
starts_at: "2022-07-01T00:00:00.000Z",
ends_at: "2022-07-31T00:00:00.000Z",
// BREAKING: There is no explicit customer_groups field in v2, we use rules instead
// BREAKING: Variant ID is required in prices
// BREAKING: Currency code is required in prices
prices: [],
...overrides,
}
}
@@ -1,101 +0,0 @@
const { ProductVariantMoneyAmount } = require("@medusajs/medusa")
const { Region, PriceList, MoneyAmount } = require("@medusajs/medusa")
module.exports = async (dataSource, data = {}) => {
const manager = dataSource.manager
const priceListNoCustomerGroups = manager.create(PriceList, {
id: "pl_no_customer_groups",
name: "VIP winter sale",
description: "Winter sale for VIP customers. 25% off selected items.",
type: "sale",
status: "active",
starts_at: "2022-07-01T00:00:00.000Z",
ends_at: "2022-07-31T00:00:00.000Z",
})
await manager.save(priceListNoCustomerGroups)
await manager.insert(Region, {
id: "region-pl",
name: "Test Region",
currency_code: "eur",
tax_rate: 0,
})
const moneyAmount1 = manager.create(MoneyAmount, {
id: "ma_test_1",
amount: 100,
currency_code: "usd",
min_quantity: 1,
max_quantity: 100,
price_list_id: "pl_no_customer_groups",
})
await manager.save(moneyAmount1)
const moneyAmount2 = manager.create(MoneyAmount, {
id: "ma_test_2",
amount: 80,
currency_code: "usd",
min_quantity: 101,
max_quantity: 500,
price_list_id: "pl_no_customer_groups",
})
await manager.save(moneyAmount2)
const moneyAmount3 = manager.create(MoneyAmount, {
id: "ma_test_3",
amount: 50,
currency_code: "usd",
min_quantity: 501,
max_quantity: 1000,
price_list_id: "pl_no_customer_groups",
})
await manager.save(moneyAmount3)
const moneyAmount4 = manager.create(MoneyAmount, {
id: "ma_test_4",
amount: 70,
currency_code: "usd",
})
await manager.save(moneyAmount4)
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma1-pl",
money_amount_id: "ma_test_1",
variant_id: "test-variant",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma2-pl",
money_amount_id: "ma_test_2",
variant_id: "test-variant",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma3-pl",
money_amount_id: "ma_test_3",
variant_id: "test-variant",
})
await manager.insert(ProductVariantMoneyAmount, {
id: "pvma4-pl",
money_amount_id: "ma_test_4",
variant_id: "test-variant",
})
const priceListWithMA = manager.create(PriceList, {
id: "pl_with_some_ma",
name: "Weeken sale",
description: "Desc. of the list",
type: "sale",
status: "active",
starts_at: "2022-07-01T00:00:00.000Z",
ends_at: "2022-07-31T00:00:00.000Z",
})
priceListWithMA.prices = [moneyAmount4]
await manager.save(priceListWithMA)
}
@@ -1,84 +0,0 @@
const {
Region,
ShippingProfile,
ShippingOption,
ShippingOptionRequirement,
ShippingProfileType,
} = require("@medusajs/medusa")
module.exports = async (dataSource, data = {}) => {
const manager = dataSource.manager
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
})
const defaultProfile = await manager.findOne(ShippingProfile, {
where: { type: ShippingProfileType.DEFAULT },
})
await manager.insert(ShippingOption, {
id: "test-out",
name: "Test out",
profile_id: defaultProfile.id,
region_id: "region",
provider_id: "test-ful",
data: {},
price_type: "flat_rate",
amount: 2000,
is_return: false,
})
await manager.insert(ShippingOption, {
id: "test-option-req",
name: "With req",
profile_id: defaultProfile.id,
region_id: "region",
provider_id: "test-ful",
data: {},
price_type: "flat_rate",
amount: 2000,
is_return: false,
})
await manager.insert(ShippingOption, {
id: "test-option-req-admin-only",
name: "With req",
profile_id: defaultProfile.id,
region_id: "region",
admin_only: true,
provider_id: "test-ful",
data: {},
price_type: "flat_rate",
amount: 2000,
is_return: false,
})
await manager.insert(ShippingOption, {
id: "test-option-req-return",
name: "With req",
profile_id: defaultProfile.id,
region_id: "region",
is_return: true,
provider_id: "test-ful",
data: {},
price_type: "flat_rate",
amount: 2000,
})
await manager.insert(ShippingOptionRequirement, {
id: "option-req",
shipping_option_id: "test-option-req",
type: "min_subtotal",
amount: 5,
})
await manager.insert(ShippingOptionRequirement, {
id: "option-req-2",
shipping_option_id: "test-option-req",
type: "max_subtotal",
amount: 10,
})
}
@@ -0,0 +1,855 @@
import { medusaIntegrationTestRunner } from "medusa-test-utils"
import {
createAdminUser,
adminHeaders,
} from "../../../../helpers/create-admin-user"
import {
getPricelistFixture,
getProductFixture,
} from "../../../../helpers/fixtures"
jest.setTimeout(30000)
medusaIntegrationTestRunner({
env: {},
testSuite: ({ dbConnection, getContainer, api }) => {
let pricelist1
let pricelist2
let region1
let product1
let customerGroup1
beforeEach(async () => {
const container = getContainer()
await createAdminUser(dbConnection, adminHeaders, container)
region1 = (
await api.post(
"/admin/regions",
{
name: "Test Region",
currency_code: "usd",
},
adminHeaders
)
).data.region
product1 = (
await api.post(
"/admin/products",
getProductFixture({ title: "Test product" }),
adminHeaders
)
).data.product
customerGroup1 = (
await api.post(
"/admin/customer-groups",
{
name: "vip-customers",
metadata: {
data1: "value1",
},
},
adminHeaders
)
).data.customer_group
pricelist1 = (
await api.post(
"/admin/price-lists",
getPricelistFixture({
title: "New sale",
prices: [
{
amount: 100,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: 1,
max_quantity: 100,
},
{
amount: 80,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: 101,
max_quantity: 500,
},
],
}),
adminHeaders
)
).data.price_list
pricelist2 = (
await api.post(
"/admin/price-lists",
getPricelistFixture({
title: "Another sale",
description: "50% off on all items",
}),
adminHeaders
)
).data.price_list
// BREAKING: You need to register rule types before you can use them
await api.post(
"/admin/pricing/rule-types",
{ name: "Region ID", rule_attribute: "region_id", default_priority: 0 },
adminHeaders
)
await api.post(
"/admin/pricing/rule-types",
{
name: "Customer Group ID",
rule_attribute: "customer_group_id",
default_priority: 0,
},
adminHeaders
)
})
describe("/admin/price-lists", () => {
describe("POST /admin/price-list", () => {
it("creates a price list", async () => {
const payload = getPricelistFixture({
title: "VIP Summer sale",
description:
"Summer sale for VIP customers. 25% off selected items.",
rules: {
customer_group_id: [customerGroup1.id],
},
prices: [
{
amount: 85,
currency_code: "usd",
variant_id: product1.variants[0].id,
},
{
amount: 105,
currency_code: region1.currency_code,
region_id: region1.id,
variant_id: product1.variants[0].id,
},
],
})
const response = await api.post(
"/admin/price-lists",
payload,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list).toEqual(
expect.objectContaining({
id: expect.any(String),
title: "VIP Summer sale",
description:
"Summer sale for VIP customers. 25% off selected items.",
type: "sale",
status: "active",
starts_at: "2022-07-01T00:00:00.000Z",
ends_at: "2022-07-31T00:00:00.000Z",
rules: {
customer_group_id: [expect.stringContaining("cusgroup_")],
},
prices: [
expect.objectContaining({
id: expect.any(String),
amount: 85,
currency_code: "usd",
variant_id: product1.variants[0].id,
}),
expect.objectContaining({
id: expect.any(String),
amount: 105,
currency_code: region1.currency_code,
variant_id: product1.variants[0].id,
}),
],
})
)
})
})
describe("GET /admin/price-lists", () => {
it("returns a price list by :id", async () => {
const response = await api.get(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list).toEqual(
expect.objectContaining({
id: expect.any(String),
title: pricelist1.title,
description: pricelist1.description,
type: pricelist1.type,
status: pricelist1.status,
starts_at: pricelist1.starts_at,
ends_at: pricelist1.ends_at,
prices: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
amount: 100,
currency_code: "usd",
// BREAKING: Min and max quantity are returned as string
min_quantity: "1",
max_quantity: "100",
variant_id: product1.variants[0].id,
created_at: expect.any(String),
updated_at: expect.any(String),
// BREAKING: `variant` and `variants` are not returned as part of the prices
}),
expect.objectContaining({
id: expect.any(String),
amount: 80,
currency_code: "usd",
min_quantity: "101",
max_quantity: "500",
variant_id: product1.variants[0].id,
created_at: expect.any(String),
updated_at: expect.any(String),
}),
]),
created_at: expect.any(String),
updated_at: expect.any(String),
})
)
})
it("returns a list of price lists", async () => {
const response = await api.get("/admin/price-lists", adminHeaders)
expect(response.status).toEqual(200)
expect(response.data.price_lists).toHaveLength(2)
expect(response.data.price_lists).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: pricelist1.id,
}),
expect.objectContaining({
id: pricelist2.id,
}),
])
)
})
it("given a search query, returns matching results by name", async () => {
const response = await api.get(
"/admin/price-lists?q=new",
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_lists).toEqual([
expect.objectContaining({
title: pricelist1.title,
}),
])
expect(response.data.count).toEqual(1)
})
it("given a search query, returns matching results by description", async () => {
const response = await api.get(
"/admin/price-lists?q=50%",
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_lists).toEqual([
expect.objectContaining({
id: pricelist2.id,
}),
])
expect(response.data.count).toEqual(1)
})
it("given a search query, returns empty list when does not exist", async () => {
const response = await api.get(
"/admin/price-lists?q=blablabla",
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_lists).toEqual([])
expect(response.data.count).toEqual(0)
})
it("given a search query and a status filter not matching any price list, returns an empty set", async () => {
const response = await api.get(
"/admin/price-lists?q=new&status[]=draft",
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_lists).toEqual([])
expect(response.data.count).toEqual(0)
})
it("given a search query and a status filter matching a price list, returns a price list", async () => {
const response = await api.get(
"/admin/price-lists?q=new&status[]=active",
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_lists).toEqual(
expect.arrayContaining([
expect.objectContaining({
title: "New sale",
status: "active",
}),
])
)
expect(response.data.count).toEqual(1)
})
it.skip("lists only price lists with customer_group", async () => {
// BREAKING: You can no longer filter by customer groups
const response = await api.get(
`/admin/price-lists?customer_groups[]=customer-group-1,customer-group-2`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_lists.length).toEqual(2)
expect(response.data.price_lists).toHaveLength(2)
expect(response.data.price_lists).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: "test-list-cgroup-1" }),
expect.objectContaining({ id: "test-list-cgroup-2" }),
])
)
})
})
describe("POST /admin/price-lists/:id", () => {
it("removes configuration with update", async () => {
const updateResult = await api.post(
`/admin/price-lists/${pricelist1.id}`,
{ ends_at: null, starts_at: null, rules: {} },
adminHeaders
)
expect(updateResult.status).toEqual(200)
expect(updateResult.data.price_list.starts_at).toBeFalsy()
expect(updateResult.data.price_list.ends_at).toBeFalsy()
expect(updateResult.data.price_list.rules).toEqual({})
})
it("updates a price list", async () => {
const payload = {
title: "Loyalty Reward - Winter Sale",
description: "Winter sale for our most loyal customers",
type: "sale",
status: "draft",
starts_at: "2022-09-01T00:00:00.000Z",
ends_at: "2022-12-31T00:00:00.000Z",
rules: {
customer_group_id: [customerGroup1.id],
},
}
const response = await api.post(
`/admin/price-lists/${pricelist1.id}`,
payload,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list).toEqual(
expect.objectContaining({
id: pricelist1.id,
title: "Loyalty Reward - Winter Sale",
description: "Winter sale for our most loyal customers",
type: "sale",
status: "draft",
starts_at: "2022-09-01T00:00:00.000Z",
ends_at: "2022-12-31T00:00:00.000Z",
prices: expect.arrayContaining([
expect.objectContaining({
amount: 100,
currency_code: "usd",
id: expect.any(String),
max_quantity: "100",
min_quantity: "1",
}),
expect.objectContaining({
amount: 80,
currency_code: "usd",
id: expect.any(String),
max_quantity: "500",
min_quantity: "101",
}),
]),
rules: {
customer_group_id: [customerGroup1.id],
},
created_at: expect.any(String),
updated_at: expect.any(String),
})
)
})
it("updates the amount and currency of a price in the price list", async () => {
const payload = {
// BREAKING: Updates of prices happen through the batch endpoint, and doing it through the price list update endpoint is no longer supported
update: [
{
id: pricelist1.prices.find((p) => p.amount === 80).id,
amount: 250,
currency_code: "eur",
variant_id: product1.variants[0].id,
},
],
}
await api.post(
`/admin/price-lists/${pricelist1.id}/prices/batch`,
payload,
adminHeaders
)
const response = await api.get(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list.prices).toEqual([
expect.objectContaining({
amount: 100,
currency_code: "usd",
id: expect.any(String),
max_quantity: "100",
min_quantity: "1",
}),
expect.objectContaining({
amount: 250,
currency_code: "eur",
id: expect.any(String),
max_quantity: "500",
min_quantity: "101",
}),
])
})
})
describe("POST /admin/price-lists/:id/prices/batch", () => {
it("Adds a batch of new prices to a price list without overriding existing prices", async () => {
// BREAKING: The payload of the batch request changed
const payload = {
create: [
{
amount: 45,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: 1001,
max_quantity: 2000,
},
{
amount: 35,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: 2001,
max_quantity: 3000,
},
{
amount: 25,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: 3001,
max_quantity: 4000,
},
],
}
await api.post(
`/admin/price-lists/${pricelist1.id}/prices/batch`,
payload,
adminHeaders
)
const response = await api.get(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(5)
expect(response.data.price_list.prices).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
amount: 100,
currency_code: "usd",
min_quantity: "1",
max_quantity: "100",
variant_id: product1.variants[0].id,
}),
expect.objectContaining({
id: expect.any(String),
amount: 80,
currency_code: "usd",
min_quantity: "101",
max_quantity: "500",
variant_id: product1.variants[0].id,
}),
expect.objectContaining({
id: expect.any(String),
amount: 45,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: "1001",
max_quantity: "2000",
}),
expect.objectContaining({
id: expect.any(String),
amount: 35,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: "2001",
max_quantity: "3000",
}),
expect.objectContaining({
id: expect.any(String),
amount: 25,
currency_code: "usd",
variant_id: product1.variants[0].id,
min_quantity: "3001",
max_quantity: "4000",
}),
])
)
})
it.skip("Adds a batch of new prices to a price list overriding existing prices", async () => {
// BREAKING: There is no support for overriding configuration
const payload = {
prices: [
{
amount: 45,
currency_code: "usd",
variant_id: "test-variant",
min_quantity: 1001,
max_quantity: 2000,
},
{
amount: 35,
currency_code: "usd",
variant_id: "test-variant",
min_quantity: 2001,
max_quantity: 3000,
},
{
amount: 25,
currency_code: "usd",
variant_id: "test-variant",
min_quantity: 3001,
max_quantity: 4000,
},
],
override: true,
}
const response = await api.post(
"/admin/price-lists/pl_no_customer_groups/prices/batch",
payload,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(3)
expect(response.data.price_list.prices).toMatchSnapshot([
{
id: expect.any(String),
price_list_id: "pl_no_customer_groups",
amount: 45,
currency_code: "usd",
variant_id: "test-variant",
min_quantity: 1001,
max_quantity: 2000,
created_at: expect.any(String),
updated_at: expect.any(String),
variant: expect.any(Object),
variants: expect.any(Array),
},
{
id: expect.any(String),
price_list_id: "pl_no_customer_groups",
amount: 35,
currency_code: "usd",
variant_id: "test-variant",
min_quantity: 2001,
max_quantity: 3000,
created_at: expect.any(String),
updated_at: expect.any(String),
variant: expect.any(Object),
variants: expect.any(Array),
},
{
id: expect.any(String),
price_list_id: "pl_no_customer_groups",
amount: 25,
currency_code: "usd",
variant_id: "test-variant",
min_quantity: 3001,
max_quantity: 4000,
created_at: expect.any(String),
updated_at: expect.any(String),
variant: expect.any(Object),
variants: expect.any(Array),
},
])
})
it("Adds a batch of new prices where a MA record have a `region_id` instead of `currency_code`", async () => {
// BREAKING: As mentioned, currency code is required now
const payload = {
create: [
{
amount: 100,
variant_id: product1.variants[0].id,
currency_code: "eur",
region_id: region1.id,
},
{
amount: 200,
variant_id: product1.variants[0].id,
currency_code: "eur",
},
],
}
await api.post(
`/admin/price-lists/${pricelist1.id}/prices/batch`,
payload,
adminHeaders
)
const response = await api.get(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(4)
expect(response.data.price_list.prices).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
amount: 100,
currency_code: "usd",
min_quantity: "1",
max_quantity: "100",
variant_id: product1.variants[0].id,
}),
expect.objectContaining({
id: expect.any(String),
amount: 80,
currency_code: "usd",
min_quantity: "101",
max_quantity: "500",
variant_id: product1.variants[0].id,
}),
expect.objectContaining({
id: expect.any(String),
amount: 100,
currency_code: "eur",
// region_id: region1.id,
variant_id: product1.variants[0].id,
}),
expect.objectContaining({
id: expect.any(String),
amount: 200,
currency_code: "eur",
variant_id: product1.variants[0].id,
}),
])
)
})
})
describe("DELETE /admin/price-lists/:id", () => {
it("Deletes a price list", async () => {
const response = await api.delete(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data).toEqual({
id: pricelist1.id,
object: "price_list",
deleted: true,
})
const err = await api
.get(`/admin/price-lists/${pricelist1.id}`, adminHeaders)
.catch((e) => e)
expect(err.response.status).toBe(404)
expect(err.response.data.message).toEqual(
`Price list with id: ${pricelist1.id} was not found`
)
})
})
describe("tests cascade on delete", () => {
it("Deletes a variant and ensures that prices associated with the variant are deleted from PriceList", async () => {
await api.delete(
`/admin/products/${product1.id}/variants/${product1.variants[0].id}`,
adminHeaders
)
const response = await api.get(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(0)
})
})
describe("DELETE /admin/price-lists/:id/prices/batch", () => {
// BREAKING: The batch method signature changed
it("Deletes several prices associated with a price list", async () => {
await api.post(
`/admin/price-lists/${pricelist1.id}/prices/batch`,
{
delete: [pricelist1.prices[0].id],
},
adminHeaders
)
const response = await api.get(
`/admin/price-lists/${pricelist1.id}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.price_list.prices).toEqual([
expect.objectContaining({
amount: 80,
currency_code: "usd",
min_quantity: "101",
max_quantity: "500",
variant_id: product1.variants[0].id,
}),
])
})
})
// BREAKING: There is no longer a GET /admin/price-lists/:id/products endpoint. Get products through `/admin/products` endpoint instead
// BREAKING: There is no longer a DELETE /admin/price-lists/test-list/products/${product.id}/prices endpoint
// BREAKING: There is no longer a DELETE /admin/price-lists/test-list/variants/${variant.id}/prices endpoint
})
},
})
// TODO: Revisit tax inclusive pricing
// describe("[MEDUSA_FF_TAX_INCLUSIVE_PRICING] /admin/price-lists", () => {
// let medusaProcess
// let dbConnection
// beforeAll(async () => {
// const cwd = path.resolve(path.join(__dirname, "..", ".."))
// const [process, connection] = await startServerWithEnvironment({
// cwd,
// env: { MEDUSA_FF_TAX_INCLUSIVE_PRICING: true },
// })
// dbConnection = connection
// medusaProcess = process
// })
// afterAll(async () => {
// const db = useDb()
// await db.shutdown()
// medusaProcess.kill()
// })
// describe("POST /admin/price-list", () => {
// const priceListIncludesTaxId = "price-list-1-includes-tax"
// beforeEach(async () => {
// try {
// await adminSeeder(dbConnection)
// await customerSeeder(dbConnection)
// await productSeeder(dbConnection)
// await simplePriceListFactory(dbConnection, {
// id: priceListIncludesTaxId,
// })
// } catch (err) {
// console.log(err)
// throw err
// }
// })
// afterEach(async () => {
// const db = useDb()
// await db.teardown()
// })
// it("should creates a price list that includes tax", async () => {
// const payload = {
// name: "VIP Summer sale",
// description: "Summer sale for VIP customers. 25% off selected items.",
// type: "sale",
// status: "active",
// starts_at: "2022-07-01T00:00:00.000Z",
// ends_at: "2022-07-31T00:00:00.000Z",
// customer_groups: [
// {
// id: "customer-group-1",
// },
// ],
// prices: [
// {
// amount: 85,
// currency_code: "usd",
// variant_id: "test-variant",
// },
// ],
// includes_tax: true,
// }
// const response = await api
// .post("/admin/price-lists", payload, adminHeaders)
// .catch((err) => {
// console.warn(err.response.data)
// })
// expect(response.status).toEqual(200)
// expect(response.data.price_list).toEqual(
// expect.objectContaining({
// id: expect.any(String),
// includes_tax: true,
// })
// )
// })
// it("should update a price list that include_tax", async () => {
// let response = await api
// .get(`/admin/price-lists/${priceListIncludesTaxId}`, adminHeaders)
// .catch((err) => {
// console.log(err)
// })
// expect(response.data.price_list.includes_tax).toBe(false)
// response = await api
// .post(
// `/admin/price-lists/${priceListIncludesTaxId}`,
// { includes_tax: true },
// adminHeaders
// )
// .catch((err) => {
// console.log(err)
// })
// expect(response.data.price_list.includes_tax).toBe(true)
// })
// })
// })
@@ -68,8 +68,8 @@ export type AdminCreatePriceListType = z.infer<typeof AdminCreatePriceList>
export const AdminUpdatePriceList = z.object({
title: z.string().optional(),
description: z.string().optional(),
starts_at: z.string().optional(),
ends_at: z.string().optional(),
starts_at: z.string().optional().nullable(),
ends_at: z.string().optional().nullable(),
status: z.nativeEnum(PriceListStatus).optional(),
type: z.nativeEnum(PriceListType).optional(),
rules: z.record(z.string(), z.array(z.string())).optional(),