Files

558 lines
17 KiB
TypeScript

import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import {
adminHeaders,
createAdminUser,
} from "../../../../helpers/create-admin-user"
jest.setTimeout(50000)
medusaIntegrationTestRunner({
testSuite: ({ dbConnection, getContainer, api }) => {
let inventoryItem1
let inventoryItem2
let stockLocation1
let stockLocation2
beforeEach(async () => {
await createAdminUser(dbConnection, adminHeaders, getContainer())
stockLocation1 = (
await api.post(`/admin/stock-locations`, { name: "loc1" }, adminHeaders)
).data.stock_location
stockLocation2 = (
await api.post(`/admin/stock-locations`, { name: "loc2" }, adminHeaders)
).data.stock_location
inventoryItem1 = (
await api.post(
`/admin/inventory-items`,
{
sku: "12345",
origin_country: "UK",
hs_code: "hs001",
mid_code: "mids",
material: "material",
weight: 300,
length: 100,
height: 200,
width: 150,
},
adminHeaders
)
).data.inventory_item
inventoryItem2 = (
await api.post(
`/admin/inventory-items`,
{ sku: "second", origin_country: "UK", hs_code: "hs001" },
adminHeaders
)
).data.inventory_item
})
describe("POST /admin/reservations", () => {
beforeEach(async () => {
await api.post(
`/admin/inventory-items/${inventoryItem1.id}/location-levels`,
{
location_id: stockLocation1.id,
stocked_quantity: 100,
},
adminHeaders
)
})
it("should create a reservation item", async () => {
const reservationResponse = await api.post(
`/admin/reservations`,
{
line_item_id: "line-item-id-1",
inventory_item_id: inventoryItem1.id,
location_id: stockLocation1.id,
description: "test description",
quantity: 1,
},
adminHeaders
)
expect(reservationResponse.status).toEqual(200)
expect(reservationResponse.data.reservation).toEqual(
expect.objectContaining({
line_item_id: "line-item-id-1",
inventory_item_id: inventoryItem1.id,
location_id: stockLocation1.id,
description: "test description",
quantity: 1,
})
)
})
it("should throw if available quantity is less than reservation quantity", async () => {
const payload = {
quantity: 10000,
inventory_item_id: inventoryItem1.id,
line_item_id: "line-item-id",
location_id: stockLocation1.id,
}
const res = await api
.post(
`/admin/reservations?fields=*inventory_item.location_levels`,
payload,
adminHeaders
)
.catch((err) => err)
const res1 = await api.get(
`/admin/inventory-items/${inventoryItem1.id}`,
adminHeaders
)
expect(res.response.status).toBe(400)
expect(res.response.data).toEqual({
type: "not_allowed",
message: `Not enough stock available for item ${inventoryItem1.id} at location ${stockLocation1.id}`,
})
})
})
describe("POST /admin/reservations/:id", () => {
let reservationId
beforeEach(async () => {
await api.post(
`/admin/inventory-items/${inventoryItem1.id}/location-levels`,
{
location_id: stockLocation1.id,
stocked_quantity: 100,
},
adminHeaders
)
const reservationResponse = await api.post(
`/admin/reservations`,
{
line_item_id: "line-item-id-1",
inventory_item_id: inventoryItem1.id,
location_id: stockLocation1.id,
description: "test description",
quantity: 1,
},
adminHeaders
)
reservationId = reservationResponse.data.reservation.id
})
it("should throw if available quantity is less than reservation quantity", async () => {
const payload = { quantity: 100000 }
const res = await api
.post(`/admin/reservations/${reservationId}`, payload, adminHeaders)
.catch((err) => err)
expect(res.response.status).toBe(400)
expect(res.response.data).toEqual({
type: "not_allowed",
message: `Not enough stock available for item ${inventoryItem1.id} at location ${stockLocation1.id}`,
})
})
it("should update a reservation item description", async () => {
const reservationResponse = await api.post(
`/admin/reservations/${reservationId}`,
{
description: "test description 1",
},
adminHeaders
)
expect(reservationResponse.status).toEqual(200)
expect(reservationResponse.data.reservation).toEqual(
expect.objectContaining({
description: "test description 1",
})
)
})
it("should update a reservation item", async () => {
const reservationResponse = await api.post(
`/admin/reservations/${reservationId}`,
{
quantity: 3,
},
adminHeaders
)
expect(reservationResponse.status).toEqual(200)
expect(reservationResponse.data.reservation).toEqual(
expect.objectContaining({
quantity: 3,
})
)
})
})
describe("DELETE /admin/reservations/:id", () => {
let reservationId
beforeEach(async () => {
await api.post(
`/admin/inventory-items/${inventoryItem1.id}/location-levels`,
{
location_id: stockLocation1.id,
stocked_quantity: 100,
},
adminHeaders
)
const reservationResponse = await api.post(
`/admin/reservations`,
{
line_item_id: "line-item-id-1",
inventory_item_id: inventoryItem1.id,
location_id: stockLocation1.id,
description: "test description",
quantity: 1,
},
adminHeaders
)
reservationId = reservationResponse.data.reservation.id
})
it("should update a reservation item", async () => {
const reservationResponse = await api.delete(
`/admin/reservations/${reservationId}`,
adminHeaders
)
expect(reservationResponse.status).toEqual(200)
expect(reservationResponse.data).toEqual(
expect.objectContaining({
id: reservationId,
object: "reservation",
deleted: true,
})
)
let error
await api
.get(`/admin/reservations/${reservationId}`, adminHeaders)
.catch((err) => {
error = err
})
expect(error.response.status).toBe(404)
})
})
describe("GET /admin/reservations", () => {
let reservation
let reservation2
let scId
beforeEach(async () => {
const scResponse = await api.post(
`/admin/sales-channels`,
{ name: "test" },
adminHeaders
)
scId = scResponse.data.sales_channel.id
await api.post(
`/admin/stock-locations/${stockLocation1.id}/sales-channels`,
{
add: [scId],
},
adminHeaders
)
await api.post(
`/admin/inventory-items/${inventoryItem1.id}/location-levels`,
{
location_id: stockLocation1.id,
stocked_quantity: 100,
},
adminHeaders
)
await api.post(
`/admin/inventory-items/${inventoryItem2.id}/location-levels`,
{
location_id: stockLocation1.id,
stocked_quantity: 100,
},
adminHeaders
)
const reservationResponse = await api.post(
`/admin/reservations`,
{
line_item_id: "line-item-id-1",
inventory_item_id: inventoryItem1.id,
location_id: stockLocation1.id,
quantity: 2,
},
adminHeaders
)
reservation = reservationResponse.data.reservation
const reservationResponse2 = await api.post(
`/admin/reservations`,
{
line_item_id: "line-item-id-2",
inventory_item_id: inventoryItem2.id,
location_id: stockLocation1.id,
description: "test description",
quantity: 1,
},
adminHeaders
)
reservation2 = reservationResponse2.data.reservation
})
it("lists reservation items", async () => {
const reservationsRes = await api
.get(`/admin/reservations`, adminHeaders)
.catch(console.warn)
expect(reservationsRes.data.reservations.length).toBe(2)
expect(reservationsRes.data.reservations).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: reservation.id,
}),
expect.objectContaining({
id: reservation2.id,
}),
])
)
})
it("lists reservation items with free text search on SKU on inventory item", async () => {
const reservationsRes = await api
.get(`/admin/reservations?q=second`, adminHeaders)
.catch(console.warn)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations).toEqual([
{
id: reservation2.id,
created_at: expect.any(String),
description: "test description",
inventory_item: {
created_at: expect.any(String),
description: null,
height: null,
hs_code: "hs001",
id: inventoryItem2.id,
length: null,
material: null,
metadata: null,
mid_code: null,
origin_country: "UK",
requires_shipping: true,
reserved_quantity: 1,
sku: "second",
stocked_quantity: 100,
thumbnail: null,
title: null,
updated_at: expect.any(String),
weight: null,
width: null,
},
inventory_item_id: inventoryItem2.id,
line_item_id: "line-item-id-2",
location_id: stockLocation1.id,
metadata: null,
quantity: 1,
updated_at: expect.any(String),
},
])
})
it("lists reservation items with free text search on descroption", async () => {
const reservationsRes = await api
.get(`/admin/reservations?q=test`, adminHeaders)
.catch(console.warn)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations).toEqual([
{
id: reservation2.id,
created_at: expect.any(String),
description: "test description",
inventory_item: {
created_at: expect.any(String),
description: null,
height: null,
hs_code: "hs001",
id: inventoryItem2.id,
length: null,
material: null,
metadata: null,
mid_code: null,
origin_country: "UK",
requires_shipping: true,
reserved_quantity: 1,
sku: "second",
stocked_quantity: 100,
thumbnail: null,
title: null,
updated_at: expect.any(String),
weight: null,
width: null,
},
inventory_item_id: inventoryItem2.id,
line_item_id: "line-item-id-2",
location_id: stockLocation1.id,
metadata: null,
quantity: 1,
updated_at: expect.any(String),
},
])
})
it("lists reservations with inventory_items", async () => {
const res = await api.get(
`/admin/reservations?fields=%2binventory_item.*`,
adminHeaders
)
expect(res.status).toEqual(200)
expect(res.data.reservations.length).toEqual(2)
expect(res.data.reservations).toEqual(
expect.arrayContaining([
expect.objectContaining({
inventory_item: expect.objectContaining({
id: inventoryItem1.id,
}),
}),
expect.objectContaining({
inventory_item: expect.objectContaining({
id: inventoryItem2.id,
}),
}),
])
)
})
describe("Filters reservation items", () => {
it("filters by location", async () => {
const reservationsRes = await api.get(
`/admin/reservations?location_id[]=${stockLocation1.id}`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(2)
expect(reservationsRes.data.reservations[0].location_id).toBe(
stockLocation1.id
)
})
it("filters by itemID", async () => {
const reservationsRes = await api.get(
`/admin/reservations?inventory_item_id[]=${inventoryItem1.id}`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].inventory_item_id).toBe(
inventoryItem1.id
)
})
it("filters by quantity", async () => {
const reservationsRes = await api.get(
`/admin/reservations?quantity[$gt]=1`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].id).toBe(reservation.id)
})
it("filters by date", async () => {
const reservationsRes = await api.get(
`/admin/reservations?created_at[$gte]=${new Date(
reservation2.created_at
).toISOString()}`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].id).toBe(reservation2.id)
})
it("filters by description using equals", async () => {
const reservationsRes = await api
.get(
`/admin/reservations?description=test%20description`,
adminHeaders
)
.catch(console.warn)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].id).toBe(reservation2.id)
})
it("filters by description using equals removes results", async () => {
const reservationsRes = await api.get(
`/admin/reservations?description=description`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(0)
})
it("filters by description using contains", async () => {
const reservationsRes = await api.get(
`/admin/reservations?description[$ilike]=%descri%`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].id).toBe(reservation2.id)
})
it("filters by description using starts_with", async () => {
const reservationsRes = await api
.get(`/admin/reservations?description[$ilike]=test%`, adminHeaders)
.catch(console.log)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].id).toBe(reservation2.id)
})
it("filters by description using starts_with removes results", async () => {
const reservationsRes = await api.get(
`/admin/reservations?description[$ilike]=description%`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(0)
})
it("filters by description using ends_with", async () => {
const reservationsRes = await api.get(
`/admin/reservations?description[$ilike]=%test`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(0)
})
it("filters by description using ends_with removes results", async () => {
const reservationsRes = await api.get(
`/admin/reservations?description[$ilike]=%description`,
adminHeaders
)
expect(reservationsRes.data.reservations.length).toBe(1)
expect(reservationsRes.data.reservations[0].id).toBe(reservation2.id)
})
})
})
},
})