* refactor(medusa): LineItemService migration to TS + refactoring * feat(medusa): Cleanup line-item service * feat(medusa): Rebase develop * test(medusa): Fix integration cart tests * fix(medusa): Cart service updateUnitPrices
1967 lines
53 KiB
JavaScript
1967 lines
53 KiB
JavaScript
const path = require("path")
|
|
const {
|
|
Region,
|
|
LineItem,
|
|
GiftCard,
|
|
Cart,
|
|
CustomShippingOption,
|
|
PriceList,
|
|
MoneyAmount,
|
|
} = require("@medusajs/medusa")
|
|
|
|
const setupServer = require("../../../helpers/setup-server")
|
|
const { useApi } = require("../../../helpers/use-api")
|
|
const { initDb, useDb } = require("../../../helpers/use-db")
|
|
|
|
const cartSeeder = require("../../helpers/cart-seeder")
|
|
const productSeeder = require("../../helpers/product-seeder")
|
|
const swapSeeder = require("../../helpers/swap-seeder")
|
|
const { simpleCartFactory, simpleLineItemFactory } = require("../../factories")
|
|
const {
|
|
simpleDiscountFactory,
|
|
} = require("../../factories/simple-discount-factory")
|
|
const {
|
|
simpleCustomerFactory,
|
|
} = require("../../factories/simple-customer-factory")
|
|
const {
|
|
simpleCustomerGroupFactory,
|
|
} = require("../../factories/simple-customer-group-factory")
|
|
|
|
jest.setTimeout(30000)
|
|
|
|
describe("/store/carts", () => {
|
|
let medusaProcess
|
|
let dbConnection
|
|
|
|
const doAfterEach = async () => {
|
|
const db = useDb()
|
|
return await db.teardown()
|
|
}
|
|
|
|
beforeAll(async () => {
|
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
|
try {
|
|
dbConnection = await initDb({ cwd })
|
|
medusaProcess = await setupServer({ cwd })
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
})
|
|
|
|
afterAll(async () => {
|
|
const db = useDb()
|
|
await db.shutdown()
|
|
medusaProcess.kill()
|
|
})
|
|
|
|
describe("POST /store/carts", () => {
|
|
beforeEach(async () => {
|
|
const manager = dbConnection.manager
|
|
await manager.insert(Region, {
|
|
id: "region",
|
|
name: "Test Region",
|
|
currency_code: "usd",
|
|
tax_rate: 0,
|
|
})
|
|
await manager.query(
|
|
`UPDATE "country" SET region_id='region' WHERE iso_2 = 'us'`
|
|
)
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("creates a cart", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api.post("/store/carts")
|
|
expect(response.status).toEqual(200)
|
|
|
|
const getRes = await api.post(`/store/carts/${response.data.cart.id}`)
|
|
expect(getRes.status).toEqual(200)
|
|
})
|
|
|
|
it("fails to create a cart when no region exist", async () => {
|
|
const api = useApi()
|
|
|
|
await dbConnection.manager.query(
|
|
`UPDATE "country" SET region_id=null WHERE iso_2 = 'us'`
|
|
)
|
|
await dbConnection.manager.query(`DELETE from region`)
|
|
|
|
try {
|
|
await api.post("/store/carts")
|
|
} catch (error) {
|
|
expect(error.response.status).toEqual(400)
|
|
expect(error.response.data.message).toEqual(
|
|
"A region is required to create a cart"
|
|
)
|
|
}
|
|
})
|
|
|
|
it("creates a cart with items", async () => {
|
|
await productSeeder(dbConnection)
|
|
|
|
const yesterday = ((today) =>
|
|
new Date(today.setDate(today.getDate() - 1)))(new Date())
|
|
const tomorrow = ((today) =>
|
|
new Date(today.setDate(today.getDate() + 1)))(new Date())
|
|
|
|
const priceList1 = await dbConnection.manager.create(PriceList, {
|
|
id: "pl_current",
|
|
name: "Past winter sale",
|
|
description: "Winter sale for key accounts.",
|
|
type: "sale",
|
|
status: "active",
|
|
starts_at: yesterday,
|
|
ends_at: tomorrow,
|
|
})
|
|
|
|
await dbConnection.manager.save(priceList1)
|
|
|
|
const ma_sale_1 = dbConnection.manager.create(MoneyAmount, {
|
|
variant_id: "test-variant-sale",
|
|
currency_code: "usd",
|
|
amount: 800,
|
|
price_list_id: "pl_current",
|
|
})
|
|
|
|
await dbConnection.manager.save(ma_sale_1)
|
|
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post("/store/carts", {
|
|
items: [
|
|
{
|
|
variant_id: "test-variant_1",
|
|
quantity: 1,
|
|
},
|
|
{
|
|
variant_id: "test-variant-sale",
|
|
quantity: 2,
|
|
},
|
|
],
|
|
})
|
|
.catch((err) => console.log(err))
|
|
|
|
response.data.cart.items.sort((a, b) => a.quantity - b.quantity)
|
|
|
|
expect(response.status).toEqual(200)
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
variant_id: "test-variant_1",
|
|
quantity: 1,
|
|
}),
|
|
expect.objectContaining({
|
|
variant_id: "test-variant-sale",
|
|
quantity: 2,
|
|
unit_price: 800,
|
|
}),
|
|
])
|
|
|
|
const getRes = await api.post(`/store/carts/${response.data.cart.id}`)
|
|
expect(getRes.status).toEqual(200)
|
|
})
|
|
|
|
it("creates a cart with country", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api.post("/store/carts", {
|
|
country_code: "us",
|
|
})
|
|
expect(response.status).toEqual(200)
|
|
expect(response.data.cart.shipping_address.country_code).toEqual("us")
|
|
|
|
const getRes = await api.post(`/store/carts/${response.data.cart.id}`)
|
|
expect(getRes.status).toEqual(200)
|
|
})
|
|
|
|
it("creates a cart with context", async () => {
|
|
const api = useApi()
|
|
const response = await api.post("/store/carts", {
|
|
context: {
|
|
test_id: "test",
|
|
},
|
|
})
|
|
expect(response.status).toEqual(200)
|
|
|
|
const getRes = await api.post(`/store/carts/${response.data.cart.id}`)
|
|
expect(getRes.status).toEqual(200)
|
|
|
|
const cart = getRes.data.cart
|
|
expect(cart.context).toEqual({
|
|
ip: "::ffff:127.0.0.1",
|
|
user_agent: expect.stringContaining("axios/0.21."),
|
|
test_id: "test",
|
|
})
|
|
})
|
|
})
|
|
|
|
describe("POST /store/carts/:id/line-items", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
await swapSeeder(dbConnection)
|
|
} catch (err) {
|
|
console.log(err)
|
|
throw err
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("adds line item to cart", async () => {
|
|
const api = useApi()
|
|
|
|
// Add standard line item to cart
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 1,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 1,
|
|
adjustments: [],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item to cart containing a total fixed discount", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-total-fixed-discount/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-total-fixed-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 100,
|
|
discount_id: "total-fixed-100",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item to cart containing a total percentage discount", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-total-percentage-discount/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-total-percentage-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 200,
|
|
discount_id: "10Percent",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item to cart containing an item fixed discount", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-item-fixed-discount/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-item-fixed-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 400,
|
|
discount_id: "item-fixed-200",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item to cart containing an item percentage discount", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-item-percentage-discount/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-item-percentage-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 2,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 300,
|
|
discount_id: "item-percentage-15",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item to cart time limited sale", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "test-variant-sale",
|
|
quantity: 1,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart",
|
|
unit_price: 800,
|
|
variant_id: "test-variant-sale",
|
|
quantity: 1,
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item to cart time customer pricing", async () => {
|
|
const api = useApi()
|
|
|
|
// customer with customer-group 5
|
|
const authResponse = await api.post("/store/auth", {
|
|
email: "test5@email.com",
|
|
password: "test",
|
|
})
|
|
|
|
const [authCookie] = authResponse.headers["set-cookie"][0].split(";")
|
|
|
|
// Add standard line item to cart
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "test-variant-sale-customer",
|
|
quantity: 1,
|
|
},
|
|
{
|
|
// withCredentials: true,
|
|
headers: {
|
|
Cookie: authCookie,
|
|
},
|
|
}
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart",
|
|
unit_price: 700,
|
|
variant_id: "test-variant-sale-customer",
|
|
quantity: 1,
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item with quantity to cart with quantity discount", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 90,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart",
|
|
unit_price: 800,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 90,
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("adds line item with quantity to cart with quantity discount no ceiling", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 900,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart",
|
|
unit_price: 700,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 900,
|
|
}),
|
|
])
|
|
})
|
|
|
|
describe("ensures correct line item adjustment generation", () => {
|
|
const discountData = {
|
|
code: "MEDUSA185DKK",
|
|
id: "medusa-185",
|
|
rule: {
|
|
allocation: "total",
|
|
type: "fixed",
|
|
value: 185,
|
|
},
|
|
regions: ["test-region"],
|
|
}
|
|
|
|
let discountCart, discount
|
|
beforeEach(async () => {
|
|
try {
|
|
discount = await simpleDiscountFactory(
|
|
dbConnection,
|
|
discountData,
|
|
100
|
|
)
|
|
discountCart = await simpleCartFactory(
|
|
dbConnection,
|
|
{
|
|
id: "discount-cart",
|
|
customer: "test-customer",
|
|
region: "test-region",
|
|
shipping_address: {
|
|
address_1: "next door",
|
|
first_name: "lebron",
|
|
last_name: "james",
|
|
country_code: "dk",
|
|
postal_code: "100",
|
|
},
|
|
line_items: [
|
|
{
|
|
id: "test-li",
|
|
variant_id: "test-variant",
|
|
quantity: 1,
|
|
unit_price: 100,
|
|
adjustments: [
|
|
{
|
|
amount: 185,
|
|
description: "discount",
|
|
discount_id: "medusa-185",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
shipping_methods: [
|
|
{
|
|
shipping_option: "test-option",
|
|
price: 1000,
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
await dbConnection.manager
|
|
.createQueryBuilder()
|
|
.relation(Cart, "discounts")
|
|
.of(discountCart)
|
|
.add(discount)
|
|
} catch (err) {
|
|
console.log(err)
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("updates an old line item adjustment when a new line item is added to a discount cart", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/discount-cart/line-items",
|
|
{
|
|
quantity: 1,
|
|
variant_id: "test-variant-quantity",
|
|
},
|
|
{
|
|
withCredentials: true,
|
|
}
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items.length).toEqual(2)
|
|
expect(response.data.cart.items).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
item_id: "test-li",
|
|
amount: 17,
|
|
discount_id: "medusa-185",
|
|
}),
|
|
],
|
|
}),
|
|
expect.objectContaining({
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 168,
|
|
discount_id: "medusa-185",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
)
|
|
})
|
|
|
|
it("updates an existing item adjustment when a line item is updated", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleLineItemFactory(
|
|
dbConnection,
|
|
{
|
|
id: "line-item-2",
|
|
cart_id: discountCart.id,
|
|
variant_id: "test-variant-quantity",
|
|
unit_price: 950,
|
|
quantity: 1,
|
|
adjustments: [
|
|
{
|
|
id: "lia-2",
|
|
amount: 92,
|
|
description: "discount",
|
|
discount_id: "medusa-185",
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/discount-cart/line-items/line-item-2",
|
|
{
|
|
quantity: 2,
|
|
},
|
|
{
|
|
withCredentials: true,
|
|
}
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items.length).toEqual(2)
|
|
expect(response.data.cart.items).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
item_id: "test-li",
|
|
discount_id: "medusa-185",
|
|
amount: 9,
|
|
}),
|
|
],
|
|
}),
|
|
expect.objectContaining({
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
item_id: "line-item-2",
|
|
amount: 176,
|
|
discount_id: "medusa-185",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
)
|
|
})
|
|
|
|
it("updates an existing item adjustment when a line item is deleted from a discount cart", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleLineItemFactory(
|
|
dbConnection,
|
|
{
|
|
id: "line-item-2",
|
|
cart_id: discountCart.id,
|
|
variant_id: "test-variant-quantity",
|
|
unit_price: 1000,
|
|
quantity: 1,
|
|
adjustments: [
|
|
{
|
|
id: "lia-2",
|
|
amount: 93,
|
|
description: "discount",
|
|
discount_id: "medusa-185",
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
const response = await api
|
|
.delete("/store/carts/discount-cart/line-items/test-li", {
|
|
withCredentials: true,
|
|
})
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items.length).toEqual(1)
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
item_id: "line-item-2",
|
|
amount: 185,
|
|
discount_id: "medusa-185",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
})
|
|
})
|
|
|
|
describe("POST /store/carts/:id/line-items/:line_id", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
await swapSeeder(dbConnection)
|
|
} catch (err) {
|
|
console.log(err)
|
|
throw err
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("updates line item of cart", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-3/line-items/test-item3/",
|
|
{
|
|
quantity: 3,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-3",
|
|
unit_price: 8000,
|
|
variant_id: "test-variant-sale-cg",
|
|
quantity: 3,
|
|
adjustments: [],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("updates line item of a cart containing a total fixed discount", async () => {
|
|
const api = useApi()
|
|
await simpleLineItemFactory(dbConnection, {
|
|
id: "test-li-disc",
|
|
allow_discounts: true,
|
|
title: "Line Item Disc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 1000,
|
|
quantity: 1,
|
|
variant_id: "test-variant-quantity",
|
|
cart_id: "test-cart-w-total-fixed-discount",
|
|
})
|
|
|
|
const response = await api
|
|
.post(
|
|
`store/carts/test-cart-w-total-fixed-discount/line-items/test-li-disc`,
|
|
{
|
|
quantity: 3,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-total-fixed-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 3,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 100,
|
|
discount_id: "total-fixed-100",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("updates line item of a cart containing a total percentage discount", async () => {
|
|
const api = useApi()
|
|
await simpleLineItemFactory(dbConnection, {
|
|
id: "test-li-disc",
|
|
allow_discounts: true,
|
|
title: "Line Item Disc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 1000,
|
|
quantity: 1,
|
|
variant_id: "test-variant-quantity",
|
|
cart_id: "test-cart-w-total-percentage-discount",
|
|
})
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-total-percentage-discount/line-items/test-li-disc",
|
|
{
|
|
quantity: 10,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-total-percentage-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 10,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 1000,
|
|
discount_id: "10Percent",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("updates line item of a cart containing an item fixed discount", async () => {
|
|
const api = useApi()
|
|
await simpleLineItemFactory(dbConnection, {
|
|
id: "test-li-disc",
|
|
allow_discounts: true,
|
|
title: "Line Item Disc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 1000,
|
|
quantity: 1,
|
|
variant_id: "test-variant-quantity",
|
|
cart_id: "test-cart-w-item-fixed-discount",
|
|
})
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-item-fixed-discount/line-items/test-li-disc",
|
|
{
|
|
quantity: 4,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-item-fixed-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 4,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 800,
|
|
discount_id: "item-fixed-200",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
|
|
it("updates line item of a cart containing an item percentage discount", async () => {
|
|
const api = useApi()
|
|
await simpleLineItemFactory(dbConnection, {
|
|
id: "test-li-disc",
|
|
allow_discounts: true,
|
|
title: "Line Item Disc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 1000,
|
|
quantity: 1,
|
|
variant_id: "test-variant-quantity",
|
|
cart_id: "test-cart-w-item-percentage-discount",
|
|
})
|
|
|
|
const response = await api
|
|
.post(
|
|
"/store/carts/test-cart-w-item-percentage-discount/line-items/test-li-disc",
|
|
{
|
|
quantity: 3,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
expect(response.data.cart.items).toEqual([
|
|
expect.objectContaining({
|
|
cart_id: "test-cart-w-item-percentage-discount",
|
|
unit_price: 1000,
|
|
variant_id: "test-variant-quantity",
|
|
quantity: 3,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
amount: 450,
|
|
discount_id: "item-percentage-15",
|
|
description: "discount",
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
})
|
|
})
|
|
|
|
describe("POST /store/carts/:id", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
await swapSeeder(dbConnection)
|
|
} catch (err) {
|
|
console.log(err)
|
|
throw err
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
// We were experiencing some issues when having created a cart in a region
|
|
// containing multiple countries. At this point, the cart does not have a shipping
|
|
// address. Therefore, on subsequent requests to update the cart, the server
|
|
// would throw a 500 due to missing shipping address id on insertion.
|
|
it("updates a cart, that does not have a shipping address", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api.post("/store/carts", {
|
|
region_id: "test-region-multiple",
|
|
})
|
|
|
|
const getRes = await api.post(`/store/carts/${response.data.cart.id}`, {
|
|
region_id: "test-region",
|
|
})
|
|
|
|
expect(getRes.status).toEqual(200)
|
|
})
|
|
|
|
it("fails on apply discount if limit has been reached", async () => {
|
|
const api = useApi()
|
|
|
|
const err = await api
|
|
.post("/store/carts/test-cart", {
|
|
discounts: [{ code: "SPENT" }],
|
|
})
|
|
.catch((err) => err)
|
|
|
|
expect(err).toBeTruthy()
|
|
expect(err.response.status).toEqual(400)
|
|
expect(err.response.data.message).toEqual(
|
|
"Discount has been used maximum allowed times"
|
|
)
|
|
})
|
|
|
|
it("successfully passes customer conditions with `in` operator and applies discount", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleCustomerFactory(dbConnection, {
|
|
id: "cus_1234",
|
|
email: "oli@medusajs.com",
|
|
groups: [
|
|
{
|
|
id: "customer-group-1",
|
|
name: "VIP Customer",
|
|
},
|
|
],
|
|
})
|
|
|
|
await simpleCustomerGroupFactory(dbConnection, {
|
|
id: "customer-group-2",
|
|
name: "Loyal",
|
|
})
|
|
|
|
await simpleCartFactory(
|
|
dbConnection,
|
|
{
|
|
id: "test-customer-discount",
|
|
region: {
|
|
id: "test-region",
|
|
name: "Test region",
|
|
tax_rate: 12,
|
|
},
|
|
customer: "cus_1234",
|
|
line_items: [
|
|
{
|
|
variant_id: "test-variant",
|
|
unit_price: 100,
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
await simpleDiscountFactory(dbConnection, {
|
|
id: "test-discount",
|
|
code: "TEST",
|
|
regions: ["test-region"],
|
|
rule: {
|
|
type: "percentage",
|
|
value: "10",
|
|
allocation: "total",
|
|
conditions: [
|
|
{
|
|
type: "customer_groups",
|
|
operator: "in",
|
|
customer_groups: ["customer-group-1", "customer-group-2"],
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
const response = await api.post("/store/carts/test-customer-discount", {
|
|
discounts: [{ code: "TEST" }],
|
|
})
|
|
|
|
const cartRes = response.data.cart
|
|
expect(cartRes.discounts).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
code: "TEST",
|
|
}),
|
|
])
|
|
)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("successfully passes customer conditions with `not_in` operator and applies discount", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleCustomerFactory(dbConnection, {
|
|
id: "cus_1234",
|
|
email: "oli@medusajs.com",
|
|
groups: [
|
|
{
|
|
id: "customer-group-2",
|
|
name: "VIP Customer",
|
|
},
|
|
],
|
|
})
|
|
|
|
await simpleCustomerGroupFactory(dbConnection, {
|
|
id: "customer-group-1",
|
|
name: "Customer group 1",
|
|
})
|
|
|
|
await simpleCustomerGroupFactory(dbConnection, {
|
|
id: "customer-group-3",
|
|
name: "Customer group 3",
|
|
})
|
|
|
|
await simpleCartFactory(
|
|
dbConnection,
|
|
{
|
|
id: "test-customer-discount",
|
|
region: {
|
|
id: "test-region",
|
|
name: "Test region",
|
|
tax_rate: 12,
|
|
},
|
|
customer: "cus_1234",
|
|
line_items: [
|
|
{
|
|
variant_id: "test-variant",
|
|
unit_price: 100,
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
await simpleDiscountFactory(dbConnection, {
|
|
id: "test-discount",
|
|
code: "TEST",
|
|
regions: ["test-region"],
|
|
rule: {
|
|
type: "percentage",
|
|
value: "10",
|
|
allocation: "total",
|
|
conditions: [
|
|
{
|
|
type: "customer_groups",
|
|
operator: "not_in",
|
|
customer_groups: ["customer-group-1", "customer-group-3"],
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
const response = await api.post("/store/carts/test-customer-discount", {
|
|
discounts: [{ code: "TEST" }],
|
|
})
|
|
|
|
const cartRes = response.data.cart
|
|
expect(cartRes.discounts).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
code: "TEST",
|
|
}),
|
|
])
|
|
)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("successfully applies discount in case no conditions is defined for group", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleCustomerFactory(dbConnection, {
|
|
id: "cus_1234",
|
|
email: "oli@medusajs.com",
|
|
groups: [
|
|
{
|
|
id: "customer-group-1",
|
|
name: "VIP Customer",
|
|
},
|
|
],
|
|
})
|
|
|
|
await simpleCartFactory(
|
|
dbConnection,
|
|
{
|
|
id: "test-customer-discount",
|
|
region: {
|
|
id: "test-region",
|
|
name: "Test region",
|
|
tax_rate: 12,
|
|
},
|
|
customer: "cus_1234",
|
|
line_items: [
|
|
{
|
|
variant_id: "test-variant",
|
|
unit_price: 100,
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
await simpleDiscountFactory(dbConnection, {
|
|
id: "test-discount",
|
|
code: "TEST",
|
|
regions: ["test-region"],
|
|
rule: {
|
|
type: "percentage",
|
|
value: "10",
|
|
allocation: "total",
|
|
},
|
|
})
|
|
|
|
const response = await api.post("/store/carts/test-customer-discount", {
|
|
discounts: [{ code: "TEST" }],
|
|
})
|
|
|
|
const cartRes = response.data.cart
|
|
expect(cartRes.discounts).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
code: "TEST",
|
|
}),
|
|
])
|
|
)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("fails to apply discount if customer group is part of `not_in` conditions", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleCustomerFactory(dbConnection, {
|
|
id: "cus_1234",
|
|
email: "oli@medusajs.com",
|
|
groups: [
|
|
{
|
|
id: "customer-group-1",
|
|
name: "VIP Customer",
|
|
},
|
|
],
|
|
})
|
|
|
|
await simpleCartFactory(
|
|
dbConnection,
|
|
{
|
|
id: "test-customer-discount",
|
|
region: {
|
|
id: "test-region",
|
|
name: "Test region",
|
|
tax_rate: 12,
|
|
},
|
|
customer: "cus_1234",
|
|
line_items: [
|
|
{
|
|
variant_id: "test-variant",
|
|
unit_price: 100,
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
await simpleDiscountFactory(dbConnection, {
|
|
id: "test-discount",
|
|
code: "TEST",
|
|
regions: ["test-region"],
|
|
rule: {
|
|
type: "percentage",
|
|
value: "10",
|
|
allocation: "total",
|
|
conditions: [
|
|
{
|
|
type: "customer_groups",
|
|
operator: "not_in",
|
|
customer_groups: ["customer-group-1"],
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
try {
|
|
await api.post("/store/carts/test-customer-discount", {
|
|
discounts: [{ code: "TEST" }],
|
|
})
|
|
} catch (error) {
|
|
expect(error.response.status).toEqual(400)
|
|
expect(error.response.data.message).toEqual(
|
|
"Discount is not valid for customer"
|
|
)
|
|
}
|
|
})
|
|
|
|
it("fails to apply discount if customer group is not part of `in` conditions", async () => {
|
|
const api = useApi()
|
|
|
|
await simpleCustomerFactory(dbConnection, {
|
|
id: "cus_1234",
|
|
email: "oli@medusajs.com",
|
|
groups: [
|
|
{
|
|
id: "customer-group-2",
|
|
name: "VIP Customer",
|
|
},
|
|
],
|
|
})
|
|
|
|
await simpleCustomerGroupFactory(dbConnection, {
|
|
id: "customer-group-1",
|
|
name: "Customer group 1",
|
|
})
|
|
|
|
await simpleCartFactory(
|
|
dbConnection,
|
|
{
|
|
id: "test-customer-discount",
|
|
region: {
|
|
id: "test-region",
|
|
name: "Test region",
|
|
tax_rate: 12,
|
|
},
|
|
customer: "cus_1234",
|
|
line_items: [
|
|
{
|
|
variant_id: "test-variant",
|
|
unit_price: 100,
|
|
},
|
|
],
|
|
},
|
|
100
|
|
)
|
|
|
|
await simpleDiscountFactory(dbConnection, {
|
|
id: "test-discount",
|
|
code: "TEST",
|
|
regions: ["test-region"],
|
|
rule: {
|
|
type: "percentage",
|
|
value: "10",
|
|
allocation: "total",
|
|
conditions: [
|
|
{
|
|
type: "customer_groups",
|
|
operator: "in",
|
|
customer_groups: ["customer-group-1"],
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
try {
|
|
await api.post("/store/carts/test-customer-discount", {
|
|
discounts: [{ code: "TEST" }],
|
|
})
|
|
} catch (error) {
|
|
expect(error.response.status).toEqual(400)
|
|
expect(error.response.data.message).toEqual(
|
|
"Discount is not valid for customer"
|
|
)
|
|
}
|
|
})
|
|
|
|
it("fails to apply expired discount", async () => {
|
|
expect.assertions(2)
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post("/store/carts/test-cart", {
|
|
discounts: [{ code: "EXP_DISC" }],
|
|
})
|
|
} catch (error) {
|
|
expect(error.response.status).toEqual(400)
|
|
expect(error.response.data.message).toEqual("Discount is expired")
|
|
}
|
|
})
|
|
|
|
it("fails on discount before start day", async () => {
|
|
expect.assertions(2)
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post("/store/carts/test-cart", {
|
|
discounts: [{ code: "PREM_DISC" }],
|
|
})
|
|
} catch (error) {
|
|
expect(error.response.status).toEqual(400)
|
|
expect(error.response.data.message).toEqual("Discount is not valid yet")
|
|
}
|
|
})
|
|
|
|
it("fails on apply invalid dynamic discount", async () => {
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post("/store/carts/test-cart", {
|
|
discounts: [{ code: "INV_DYN_DISC" }],
|
|
})
|
|
} catch (error) {
|
|
expect(error.response.status).toEqual(400)
|
|
expect(error.response.data.message).toEqual("Discount is expired")
|
|
}
|
|
})
|
|
|
|
it("Applies dynamic discount to cart correctly", async () => {
|
|
const api = useApi()
|
|
|
|
const cart = await api.post(
|
|
"/store/carts/test-cart",
|
|
{
|
|
discounts: [{ code: "DYN_DISC" }],
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
expect(cart.data.cart.shipping_total).toBe(1000)
|
|
expect(cart.status).toEqual(200)
|
|
})
|
|
|
|
it("updates cart customer id", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api.post("/store/carts/test-cart", {
|
|
customer_id: "test-customer-2",
|
|
})
|
|
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("updates prices when cart customer id is updated", async () => {
|
|
const api = useApi()
|
|
|
|
const beforeUpdate = await api
|
|
.get(`/store/carts/test-cart-3`)
|
|
.catch((error) => console.log(error))
|
|
|
|
expect(beforeUpdate.data.cart.items[0].unit_price).toEqual(8000)
|
|
|
|
const response = await api
|
|
.post("/store/carts/test-cart-3", {
|
|
customer_id: "test-customer-2",
|
|
})
|
|
.catch((error) => console.log(error))
|
|
|
|
expect(response.status).toEqual(200)
|
|
expect(response.data.cart.items[0].unit_price).toEqual(500)
|
|
})
|
|
|
|
it("updates prices when cart region id is updated", async () => {
|
|
const api = useApi()
|
|
|
|
const beforeUpdate = await api
|
|
.get(`/store/carts/test-cart-3`)
|
|
.catch((error) => console.log(error))
|
|
|
|
expect(beforeUpdate.data.cart.items[0].unit_price).toEqual(8000)
|
|
expect(beforeUpdate.data.cart.region_id).toEqual("test-region")
|
|
|
|
const response = await api
|
|
.post("/store/carts/test-cart-3", {
|
|
region_id: "test-region-multiple",
|
|
})
|
|
.catch((error) => console.log(error))
|
|
|
|
expect(response.status).toEqual(200)
|
|
expect(response.data.cart.region_id).toEqual("test-region-multiple")
|
|
expect(response.data.cart.items[0].unit_price).toEqual(700)
|
|
})
|
|
|
|
it("updates address using string id", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api.post("/store/carts/test-cart", {
|
|
billing_address: "test-general-address",
|
|
shipping_address: "test-general-address",
|
|
})
|
|
|
|
expect(response.data.cart.shipping_address_id).toEqual(
|
|
"test-general-address"
|
|
)
|
|
expect(response.data.cart.billing_address_id).toEqual(
|
|
"test-general-address"
|
|
)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("updates address", async () => {
|
|
const api = useApi()
|
|
|
|
const response = await api.post("/store/carts/test-cart", {
|
|
shipping_address: {
|
|
first_name: "clark",
|
|
last_name: "kent",
|
|
address_1: "5th avenue",
|
|
city: "nyc",
|
|
country_code: "us",
|
|
postal_code: "something",
|
|
},
|
|
})
|
|
|
|
expect(response.data.cart.shipping_address.first_name).toEqual("clark")
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("adds free shipping to cart then removes it again", async () => {
|
|
const api = useApi()
|
|
|
|
let cart = await api.post(
|
|
"/store/carts/test-cart",
|
|
{
|
|
discounts: [{ code: "FREE_SHIPPING" }, { code: "CREATED" }],
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
expect(cart.data.cart.shipping_total).toBe(0)
|
|
expect(cart.status).toEqual(200)
|
|
|
|
cart = await api.post(
|
|
"/store/carts/test-cart",
|
|
{
|
|
discounts: [{ code: "CREATED" }],
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
expect(cart.data.cart.shipping_total).toBe(1000)
|
|
expect(cart.status).toEqual(200)
|
|
})
|
|
|
|
it("complete cart with giftcard total 0", async () => {
|
|
const manager = dbConnection.manager
|
|
await manager.insert(GiftCard, {
|
|
id: "gift_test",
|
|
code: "GC_TEST",
|
|
value: 20000,
|
|
balance: 20000,
|
|
region_id: "test-region",
|
|
})
|
|
|
|
const api = useApi()
|
|
|
|
await api.post(`/store/carts/test-cart-3`, {
|
|
gift_cards: [{ code: "GC_TEST" }],
|
|
})
|
|
|
|
const getRes = await api
|
|
.post(`/store/carts/test-cart-3/complete`)
|
|
.catch((err) => {
|
|
console.log(err.response.data)
|
|
})
|
|
|
|
expect(getRes.status).toEqual(200)
|
|
expect(getRes.data.type).toEqual("order")
|
|
})
|
|
|
|
it("complete cart with items inventory covered", async () => {
|
|
const api = useApi()
|
|
const getRes = await api.post(`/store/carts/test-cart-2/complete-cart`)
|
|
|
|
expect(getRes.status).toEqual(200)
|
|
|
|
const variantRes = await api.get("/store/variants/test-variant")
|
|
expect(variantRes.data.variant.inventory_quantity).toEqual(0)
|
|
})
|
|
|
|
it("returns early, if cart is already completed", async () => {
|
|
const manager = dbConnection.manager
|
|
const api = useApi()
|
|
await manager.query(
|
|
`UPDATE "cart" SET completed_at=current_timestamp WHERE id = 'test-cart-2'`
|
|
)
|
|
try {
|
|
await api.post(`/store/carts/test-cart-2/complete-cart`)
|
|
} catch (error) {
|
|
expect(error.response.data).toMatchSnapshot({
|
|
type: "not_allowed",
|
|
message: "Cart has already been completed",
|
|
code: "cart_incompatible_state",
|
|
})
|
|
expect(error.response.status).toEqual(409)
|
|
}
|
|
})
|
|
|
|
it("fails to complete cart with items inventory not/partially covered", async () => {
|
|
const manager = dbConnection.manager
|
|
|
|
const li = manager.create(LineItem, {
|
|
id: "test-item",
|
|
title: "Line Item",
|
|
description: "Line Item Desc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 8000,
|
|
quantity: 99,
|
|
variant_id: "test-variant-2",
|
|
cart_id: "test-cart-2",
|
|
})
|
|
await manager.save(li)
|
|
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post(`/store/carts/test-cart-2/complete-cart`)
|
|
} catch (e) {
|
|
expect(e.response.data).toMatchSnapshot({
|
|
code: "insufficient_inventory",
|
|
})
|
|
expect(e.response.status).toBe(409)
|
|
}
|
|
|
|
// check to see if payment has been cancelled and cart is not completed
|
|
const res = await api.get(`/store/carts/test-cart-2`)
|
|
expect(res.data.cart.payment.canceled_at).not.toBe(null)
|
|
expect(res.data.cart.completed_at).toBe(null)
|
|
})
|
|
|
|
it("fails to complete swap cart with items inventory not/partially covered", async () => {
|
|
const manager = dbConnection.manager
|
|
|
|
const li = manager.create(LineItem, {
|
|
id: "test-item",
|
|
title: "Line Item",
|
|
description: "Line Item Desc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 8000,
|
|
quantity: 99,
|
|
variant_id: "test-variant-2",
|
|
cart_id: "swap-cart",
|
|
})
|
|
await manager.save(li)
|
|
|
|
await manager.query(
|
|
"UPDATE swap SET cart_id='swap-cart' where id='test-swap'"
|
|
)
|
|
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post(`/store/carts/swap-cart/complete-cart`)
|
|
} catch (e) {
|
|
expect(e.response.data).toMatchSnapshot({
|
|
code: "insufficient_inventory",
|
|
})
|
|
expect(e.response.status).toBe(409)
|
|
}
|
|
|
|
// check to see if payment has been cancelled and cart is not completed
|
|
const res = await api.get(`/store/carts/swap-cart`)
|
|
expect(res.data.cart.payment_authorized_at).toBe(null)
|
|
expect(res.data.cart.payment.canceled_at).not.toBe(null)
|
|
})
|
|
|
|
it("successfully completes swap cart with items inventory not/partially covered due to backorder flag", async () => {
|
|
const manager = dbConnection.manager
|
|
|
|
const li = manager.create(LineItem, {
|
|
id: "test-item",
|
|
title: "Line Item",
|
|
description: "Line Item Desc",
|
|
thumbnail: "https://test.js/1234",
|
|
unit_price: 8000,
|
|
quantity: 99,
|
|
variant_id: "test-variant-2",
|
|
cart_id: "swap-cart",
|
|
})
|
|
await manager.save(li)
|
|
await manager.query(
|
|
"UPDATE swap SET cart_id='swap-cart' where id='test-swap'"
|
|
)
|
|
await manager.query(
|
|
"UPDATE swap SET allow_backorder=true where id='test-swap'"
|
|
)
|
|
await manager.query("DELETE FROM payment where swap_id='test-swap'")
|
|
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post(`/store/carts/swap-cart/complete-cart`)
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
|
|
// check to see if payment is authorized and cart is completed
|
|
const res = await api.get(`/store/carts/swap-cart`)
|
|
expect(res.data.cart.payment_authorized_at).not.toBe(null)
|
|
expect(res.data.cart.completed_at).not.toBe(null)
|
|
})
|
|
})
|
|
|
|
describe("POST /store/carts/:id/shipping-methods", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
const manager = dbConnection.manager
|
|
|
|
const _cart = await manager.create(Cart, {
|
|
id: "test-cart-with-cso",
|
|
customer_id: "some-customer",
|
|
email: "some-customer@email.com",
|
|
shipping_address: {
|
|
id: "test-shipping-address",
|
|
first_name: "lebron",
|
|
country_code: "us",
|
|
},
|
|
region_id: "test-region",
|
|
currency_code: "usd",
|
|
type: "swap",
|
|
})
|
|
|
|
const cartWithCustomSo = await manager.save(_cart)
|
|
|
|
await manager.insert(CustomShippingOption, {
|
|
id: "another-cso-test",
|
|
cart_id: "test-cart-with-cso",
|
|
shipping_option_id: "test-option",
|
|
price: 5,
|
|
})
|
|
} catch (err) {
|
|
console.log(err)
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("adds a normal shipping method to cart", async () => {
|
|
const api = useApi()
|
|
|
|
const cartWithShippingMethod = await api.post(
|
|
"/store/carts/test-cart/shipping-methods",
|
|
{
|
|
option_id: "test-option",
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
expect(cartWithShippingMethod.data.cart.shipping_methods).toContainEqual(
|
|
expect.objectContaining({ shipping_option_id: "test-option" })
|
|
)
|
|
expect(cartWithShippingMethod.status).toEqual(200)
|
|
})
|
|
|
|
it("given a cart with custom options and a shipping option already belonging to said cart, then it should add a shipping method based on the given custom shipping option", async () => {
|
|
const shippingOptionId = "test-option"
|
|
|
|
const api = useApi()
|
|
|
|
const cartWithCustomShippingMethod = await api
|
|
.post(
|
|
"/store/carts/test-cart-with-cso/shipping-methods",
|
|
{
|
|
option_id: shippingOptionId,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => err.response)
|
|
|
|
expect(
|
|
cartWithCustomShippingMethod.data.cart.shipping_methods
|
|
).toContainEqual(
|
|
expect.objectContaining({
|
|
shipping_option_id: shippingOptionId,
|
|
price: 5,
|
|
})
|
|
)
|
|
expect(cartWithCustomShippingMethod.status).toEqual(200)
|
|
})
|
|
|
|
it("given a cart with custom options and an option id not corresponding to any custom shipping option, then it should throw an invalid error", async () => {
|
|
const api = useApi()
|
|
|
|
try {
|
|
await api.post(
|
|
"/store/carts/test-cart-with-cso/shipping-methods",
|
|
{
|
|
option_id: "orphan-so",
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
} catch (err) {
|
|
expect(err.response.status).toEqual(400)
|
|
expect(err.response.data.message).toEqual("Wrong shipping option")
|
|
}
|
|
})
|
|
|
|
it("adds a giftcard to cart, but ensures discount only applied to discountable items", async () => {
|
|
const api = useApi()
|
|
|
|
// Add standard line item to cart
|
|
await api.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "test-variant",
|
|
quantity: 1,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
// Add gift card to cart
|
|
await api.post(
|
|
"/store/carts/test-cart/line-items",
|
|
{
|
|
variant_id: "giftcard-denom",
|
|
quantity: 1,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
// Add a 10% discount to the cart
|
|
const cartWithGiftcard = await api
|
|
.post(
|
|
"/store/carts/test-cart",
|
|
{
|
|
discounts: [{ code: "10PERCENT" }],
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
.catch((err) => console.log(err))
|
|
|
|
// Ensure that the discount is only applied to the standard item
|
|
const itemId = cartWithGiftcard.data.cart.items.find(item => !item.is_giftcard).id
|
|
expect(cartWithGiftcard.data.cart.items).toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
variant_id: "test-variant",
|
|
quantity: 1,
|
|
adjustments: [
|
|
expect.objectContaining({
|
|
discount_id: "10Percent",
|
|
amount: 100,
|
|
item_id: itemId,
|
|
}),
|
|
],
|
|
}),
|
|
])
|
|
)
|
|
expect(cartWithGiftcard.data.cart.total).toBe(2900) // 1000 (giftcard) + 900 (standard item with 10% discount) + 1000 Shipping
|
|
expect(cartWithGiftcard.data.cart.discount_total).toBe(100)
|
|
expect(cartWithGiftcard.status).toEqual(200)
|
|
})
|
|
|
|
it("adds no more than 1 shipping method per shipping profile", async () => {
|
|
const api = useApi()
|
|
const addShippingMethod = async (option_id) => {
|
|
return await api.post(
|
|
"/store/carts/test-cart/shipping-methods",
|
|
{
|
|
option_id,
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
}
|
|
|
|
await addShippingMethod("test-option")
|
|
const cartWithAnotherShippingMethod = await addShippingMethod(
|
|
"test-option-2"
|
|
)
|
|
|
|
expect(
|
|
cartWithAnotherShippingMethod.data.cart.shipping_methods.length
|
|
).toEqual(1)
|
|
expect(
|
|
cartWithAnotherShippingMethod.data.cart.shipping_methods
|
|
).toContainEqual(
|
|
expect.objectContaining({
|
|
shipping_option_id: "test-option-2",
|
|
price: 500,
|
|
})
|
|
)
|
|
expect(cartWithAnotherShippingMethod.status).toEqual(200)
|
|
})
|
|
})
|
|
|
|
describe("DELETE /store/carts/:id/discounts/:code", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
await dbConnection.manager.query(
|
|
`INSERT INTO "cart_discounts" (cart_id, discount_id) VALUES ('test-cart', 'free-shipping')`
|
|
)
|
|
} catch (err) {
|
|
console.log(err)
|
|
throw err
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("removes free shipping and updates shipping total", async () => {
|
|
const api = useApi()
|
|
|
|
const cartWithFreeShipping = await api.post(
|
|
"/store/carts/test-cart",
|
|
{
|
|
discounts: [{ code: "FREE_SHIPPING" }],
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
expect(cartWithFreeShipping.data.cart.shipping_total).toBe(0)
|
|
expect(cartWithFreeShipping.status).toEqual(200)
|
|
|
|
const response = await api.delete(
|
|
"/store/carts/test-cart/discounts/FREE_SHIPPING"
|
|
)
|
|
|
|
expect(response.data.cart.shipping_total).toBe(1000)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
})
|
|
|
|
describe("get-cart with session customer", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
} catch (err) {
|
|
console.log(err)
|
|
throw err
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("updates empty cart.customer_id on cart retrieval", async () => {
|
|
const api = useApi()
|
|
|
|
const customer = await api.post(
|
|
"/store/customers",
|
|
{
|
|
email: "oli@test.dk",
|
|
password: "olitest",
|
|
first_name: "oli",
|
|
last_name: "oli",
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
const cookie = customer.headers["set-cookie"][0]
|
|
|
|
const cart = await api.post("/store/carts", {}, { withCredentials: true })
|
|
|
|
const response = await api.get(`/store/carts/${cart.data.cart.id}`, {
|
|
headers: {
|
|
cookie,
|
|
},
|
|
withCredentials: true,
|
|
})
|
|
|
|
expect(response.data.cart.customer_id).toEqual(customer.data.customer.id)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
|
|
it("updates cart.customer_id on cart retrieval if cart.customer_id differ from session customer", async () => {
|
|
const api = useApi()
|
|
|
|
const customer = await api.post(
|
|
"/store/customers",
|
|
{
|
|
email: "oli@test.dk",
|
|
password: "olitest",
|
|
first_name: "oli",
|
|
last_name: "oli",
|
|
},
|
|
{ withCredentials: true }
|
|
)
|
|
|
|
const cookie = customer.headers["set-cookie"][0]
|
|
|
|
const cart = await api.post("/store/carts")
|
|
|
|
const updatedCart = await api.post(`/store/carts/${cart.data.cart.id}`, {
|
|
customer_id: "test-customer",
|
|
})
|
|
|
|
const response = await api.get(
|
|
`/store/carts/${updatedCart.data.cart.id}`,
|
|
{
|
|
headers: {
|
|
cookie,
|
|
},
|
|
}
|
|
)
|
|
|
|
expect(response.data.cart.customer_id).toEqual(customer.data.customer.id)
|
|
expect(response.status).toEqual(200)
|
|
})
|
|
})
|
|
|
|
describe("shipping address + region updates", () => {
|
|
beforeEach(async () => {
|
|
try {
|
|
await cartSeeder(dbConnection)
|
|
} catch (err) {
|
|
console.log(err)
|
|
throw err
|
|
}
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await doAfterEach()
|
|
})
|
|
|
|
it("updates region only - single to multiple countries", async () => {
|
|
const api = useApi()
|
|
|
|
const { data, status } = await api
|
|
.post(`/store/carts/test-cart`, {
|
|
region_id: `test-region-multiple`,
|
|
})
|
|
.catch((err) => {
|
|
console.log(err)
|
|
throw err
|
|
})
|
|
|
|
expect(status).toEqual(200)
|
|
expect(data.cart.region_id).toEqual("test-region-multiple")
|
|
expect(data.cart.shipping_address).toMatchSnapshot({
|
|
id: expect.any(String),
|
|
country_code: null,
|
|
created_at: expect.any(String),
|
|
updated_at: expect.any(String),
|
|
})
|
|
})
|
|
|
|
it("should reset the shipping_address on null value", async () => {
|
|
const api = useApi()
|
|
|
|
const { data, status } = await api
|
|
.post(`/store/carts/test-cart`, {
|
|
shipping_address: null,
|
|
})
|
|
.catch((err) => {
|
|
console.log(err)
|
|
throw err
|
|
})
|
|
|
|
expect(status).toEqual(200)
|
|
expect(data.cart.shipping_address).toEqual(null)
|
|
})
|
|
})
|
|
})
|