chore: Move inventory tests to HTTP layer (#7613)
This commit is contained in:
@@ -1,608 +0,0 @@
|
||||
import {
|
||||
adminHeaders,
|
||||
createAdminUser,
|
||||
} from "../../../../helpers/create-admin-user"
|
||||
|
||||
import { IInventoryServiceNext } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { breaking } from "../../../../helpers/breaking"
|
||||
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env: {
|
||||
MEDUSA_FF_MEDUSA_V2: true,
|
||||
},
|
||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||
let appContainer
|
||||
let service: IInventoryServiceNext
|
||||
|
||||
beforeEach(async () => {
|
||||
appContainer = getContainer()
|
||||
|
||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
||||
|
||||
service = appContainer.resolve(ModuleRegistrationName.INVENTORY)
|
||||
})
|
||||
|
||||
describe("Reservation items", () => {
|
||||
it.skip("Create reservation item throws if available item quantity is less than reservation quantity", async () => {
|
||||
// const orderRes = await api.get(
|
||||
// `/admin/orders/${order.id}`,
|
||||
// adminHeaders
|
||||
// )
|
||||
// expect(orderRes.data.order.items[0].quantity).toBe(2)
|
||||
// expect(orderRes.data.order.items[0].fulfilled_quantity).toBeFalsy()
|
||||
// const payload = {
|
||||
// quantity: 1,
|
||||
// inventory_item_id: inventoryItem.id,
|
||||
// line_item_id: lineItemId,
|
||||
// location_id: locationId,
|
||||
// }
|
||||
// const res = await api
|
||||
// .post(`/admin/reservations`, payload, adminHeaders)
|
||||
// .catch((err) => err)
|
||||
// expect(res.response.status).toBe(400)
|
||||
// expect(res.response.data).toEqual({
|
||||
// type: "invalid_data",
|
||||
// message:
|
||||
// "The reservation quantity cannot be greater than the unfulfilled line item quantity",
|
||||
// })
|
||||
})
|
||||
|
||||
it.skip("Update reservation item throws if available item quantity is less than reservation quantity", async () => {
|
||||
// const orderRes = await api.get(
|
||||
// `/admin/orders/${order.id}`,
|
||||
// adminHeaders
|
||||
// )
|
||||
// expect(orderRes.data.order.items[0].quantity).toBe(2)
|
||||
// expect(orderRes.data.order.items[0].fulfilled_quantity).toBeFalsy()
|
||||
// const payload = {
|
||||
// quantity: 3,
|
||||
// }
|
||||
// const res = await api
|
||||
// .post(
|
||||
// `/admin/reservations/${reservationItem.id}`,
|
||||
// payload,
|
||||
// adminHeaders
|
||||
// )
|
||||
// .catch((err) => err)
|
||||
// expect(res.response.status).toBe(400)
|
||||
// expect(res.response.data).toEqual({
|
||||
// type: "invalid_data",
|
||||
// message:
|
||||
// "The reservation quantity cannot be greater than the unfulfilled line item quantity",
|
||||
// })
|
||||
})
|
||||
|
||||
describe("Create reservation item", () => {
|
||||
let invItemId
|
||||
let location
|
||||
|
||||
beforeEach(async () => {
|
||||
await breaking(null, async () => {
|
||||
const stockRes = await api.post(
|
||||
`/admin/stock-locations`,
|
||||
{
|
||||
name: "Fake Warehouse 1",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
location = stockRes.data.stock_location.id
|
||||
|
||||
const inventoryItemResponse = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "12345",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
invItemId = inventoryItemResponse.data.inventory_item.id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${invItemId}/location-levels`,
|
||||
{
|
||||
location_id: location,
|
||||
stocked_quantity: 100,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("should create a reservation item", async () => {
|
||||
await breaking(null, async () => {
|
||||
const reservationResponse = await api.post(
|
||||
`/admin/reservations`,
|
||||
{
|
||||
line_item_id: "line-item-id-1",
|
||||
inventory_item_id: invItemId,
|
||||
location_id: location,
|
||||
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: invItemId,
|
||||
location_id: location,
|
||||
description: "test description",
|
||||
quantity: 1,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Update reservation item", () => {
|
||||
let invItemId
|
||||
let location
|
||||
let reservationId
|
||||
|
||||
beforeEach(async () => {
|
||||
await breaking(null, async () => {
|
||||
const stockRes = await api.post(
|
||||
`/admin/stock-locations`,
|
||||
{
|
||||
name: "Fake Warehouse 1",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
location = stockRes.data.stock_location.id
|
||||
|
||||
const inventoryItemResponse = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "12345",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
invItemId = inventoryItemResponse.data.inventory_item.id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${invItemId}/location-levels`,
|
||||
{
|
||||
location_id: location,
|
||||
stocked_quantity: 100,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const reservationResponse = await api.post(
|
||||
`/admin/reservations`,
|
||||
{
|
||||
line_item_id: "line-item-id-1",
|
||||
inventory_item_id: invItemId,
|
||||
location_id: location,
|
||||
description: "test description",
|
||||
quantity: 1,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
reservationId = reservationResponse.data.reservation.id
|
||||
})
|
||||
})
|
||||
|
||||
it("should update a reservation item description", async () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 reservation item", () => {
|
||||
let invItemId
|
||||
let location
|
||||
let reservationId
|
||||
|
||||
beforeEach(async () => {
|
||||
await breaking(null, async () => {
|
||||
const stockRes = await api.post(
|
||||
`/admin/stock-locations`,
|
||||
{
|
||||
name: "Fake Warehouse 1",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
location = stockRes.data.stock_location.id
|
||||
|
||||
const inventoryItemResponse = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "12345",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
invItemId = inventoryItemResponse.data.inventory_item.id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${invItemId}/location-levels`,
|
||||
{
|
||||
location_id: location,
|
||||
stocked_quantity: 100,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const reservationResponse = await api.post(
|
||||
`/admin/reservations`,
|
||||
{
|
||||
line_item_id: "line-item-id-1",
|
||||
inventory_item_id: invItemId,
|
||||
location_id: location,
|
||||
description: "test description",
|
||||
quantity: 1,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
reservationId = reservationResponse.data.reservation.id
|
||||
})
|
||||
})
|
||||
|
||||
it("should update a reservation item", async () => {
|
||||
await breaking(null, 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("List reservation items", () => {
|
||||
let invItemId
|
||||
let invItemId2
|
||||
let location
|
||||
let reservation
|
||||
let reservation2
|
||||
let scId
|
||||
|
||||
beforeEach(async () => {
|
||||
await breaking(null, async () => {
|
||||
const stockRes = await api.post(
|
||||
`/admin/stock-locations`,
|
||||
{
|
||||
name: "Fake Warehouse 2",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
location = stockRes.data.stock_location.id
|
||||
|
||||
const scResponse = await api.post(
|
||||
`/admin/sales-channels`,
|
||||
{ name: "test" },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
scId = scResponse.data.sales_channel.id
|
||||
|
||||
await api.post(
|
||||
`/admin/stock-locations/${location}/sales-channels`,
|
||||
{
|
||||
add: [scId],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const inventoryItemResponse = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "12345",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
invItemId = inventoryItemResponse.data.inventory_item.id
|
||||
|
||||
const inventoryItemResponse2 = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "67890",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
invItemId2 = inventoryItemResponse2.data.inventory_item.id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${invItemId}/location-levels`,
|
||||
{
|
||||
location_id: location,
|
||||
stocked_quantity: 100,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${invItemId2}/location-levels`,
|
||||
{
|
||||
location_id: location,
|
||||
stocked_quantity: 100,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const reservationResponse = await api.post(
|
||||
`/admin/reservations`,
|
||||
{
|
||||
line_item_id: "line-item-id-1",
|
||||
inventory_item_id: invItemId,
|
||||
location_id: location,
|
||||
quantity: 2,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
reservation = reservationResponse.data.reservation
|
||||
|
||||
const reservationResponse2 = await api.post(
|
||||
`/admin/reservations`,
|
||||
{
|
||||
line_item_id: "line-item-id-2",
|
||||
inventory_item_id: invItemId2,
|
||||
location_id: location,
|
||||
description: "test description",
|
||||
quantity: 1,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
reservation2 = reservationResponse2.data.reservation
|
||||
})
|
||||
})
|
||||
|
||||
it("lists reservation items", async () => {
|
||||
await breaking(null, 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,
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Filters reservation items", () => {
|
||||
it("filters by location", async () => {
|
||||
await breaking(null, async () => {
|
||||
const reservationsRes = await api.get(
|
||||
`/admin/reservations?location_id[]=${location}`,
|
||||
adminHeaders
|
||||
)
|
||||
expect(reservationsRes.data.reservations.length).toBe(2)
|
||||
expect(reservationsRes.data.reservations[0].location_id).toBe(
|
||||
location
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("filters by itemID", async () => {
|
||||
await breaking(null, async () => {
|
||||
const reservationsRes = await api.get(
|
||||
`/admin/reservations?inventory_item_id[]=${invItemId}`,
|
||||
adminHeaders
|
||||
)
|
||||
expect(reservationsRes.data.reservations.length).toBe(1)
|
||||
expect(
|
||||
reservationsRes.data.reservations[0].inventory_item_id
|
||||
).toBe(invItemId)
|
||||
})
|
||||
})
|
||||
|
||||
it("filters by quantity", async () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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 () => {
|
||||
await breaking(null, 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
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it.skip("lists reservations with inventory_items and line items", async () => {
|
||||
await breaking(null, async () => {
|
||||
const res = await api.get(
|
||||
`/admin/reservations?expand=line_item,inventory_item`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(res.status).toEqual(200)
|
||||
expect(res.data.reservations.length).toEqual(1)
|
||||
expect(res.data.reservations).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
inventory_item: expect.objectContaining({}),
|
||||
line_item: expect.objectContaining({
|
||||
order: expect.objectContaining({}),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
1322
integration-tests/http/__tests__/inventory/admin/inventory.spec.ts
Normal file
1322
integration-tests/http/__tests__/inventory/admin/inventory.spec.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,989 +0,0 @@
|
||||
import { IInventoryServiceNext, IStockLocationService } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { createAdminUser } from "../../../helpers/create-admin-user"
|
||||
|
||||
const { medusaIntegrationTestRunner } = require("medusa-test-utils")
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
const { simpleProductFactory } = require("../../../factories")
|
||||
const adminHeaders = { headers: { "x-medusa-access-token": "test_token" } }
|
||||
|
||||
medusaIntegrationTestRunner({
|
||||
env: {
|
||||
MEDUSA_FF_MEDUSA_V2: true,
|
||||
},
|
||||
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||
let appContainer
|
||||
let shutdownServer
|
||||
let service: IInventoryServiceNext
|
||||
|
||||
let variantId
|
||||
let inventoryItems
|
||||
let locationId
|
||||
let location2Id
|
||||
let location3Id
|
||||
|
||||
beforeEach(async () => {
|
||||
appContainer = getContainer()
|
||||
|
||||
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
||||
|
||||
service = appContainer.resolve(ModuleRegistrationName.INVENTORY)
|
||||
})
|
||||
|
||||
describe("Inventory Items", () => {
|
||||
it.skip("should create, update and delete the inventory location levels", async () => {
|
||||
const inventoryItemId = inventoryItems[0].id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: locationId,
|
||||
stocked_quantity: 17,
|
||||
incoming_quantity: 2,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const inventoryService = appContainer.resolve("inventoryService")
|
||||
const stockLevel = await inventoryService.retrieveInventoryLevel(
|
||||
inventoryItemId,
|
||||
locationId
|
||||
)
|
||||
|
||||
expect(stockLevel.location_id).toEqual(locationId)
|
||||
expect(stockLevel.inventory_item_id).toEqual(inventoryItemId)
|
||||
expect(stockLevel.stocked_quantity).toEqual(17)
|
||||
expect(stockLevel.incoming_quantity).toEqual(2)
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`,
|
||||
{
|
||||
stocked_quantity: 21,
|
||||
incoming_quantity: 0,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const newStockLevel = await inventoryService.retrieveInventoryLevel(
|
||||
inventoryItemId,
|
||||
locationId
|
||||
)
|
||||
expect(newStockLevel.stocked_quantity).toEqual(21)
|
||||
expect(newStockLevel.incoming_quantity).toEqual(0)
|
||||
|
||||
await api.delete(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`,
|
||||
adminHeaders
|
||||
)
|
||||
const invLevel = await inventoryService
|
||||
.retrieveInventoryLevel(inventoryItemId, locationId)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(invLevel.message).toEqual(
|
||||
`Inventory level for item ${inventoryItemId} and location ${locationId} not found`
|
||||
)
|
||||
})
|
||||
|
||||
it.skip("should fail to update the location level to negative quantity", async () => {
|
||||
const inventoryItemId = inventoryItems[0].id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: locationId,
|
||||
stocked_quantity: 17,
|
||||
incoming_quantity: 2,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const res = await api
|
||||
.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`,
|
||||
{
|
||||
incoming_quantity: -1,
|
||||
stocked_quantity: -1,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
.catch((error) => error)
|
||||
|
||||
expect(res.response.status).toEqual(400)
|
||||
expect(res.response.data).toEqual({
|
||||
type: "invalid_data",
|
||||
message:
|
||||
"incoming_quantity must not be less than 0, stocked_quantity must not be less than 0",
|
||||
})
|
||||
})
|
||||
|
||||
it.skip("should create the inventory item using the api", async () => {
|
||||
const product = await simpleProductFactory(dbConnection, {})
|
||||
|
||||
const productRes = await api.get(
|
||||
`/admin/products/${product.id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const variantId = productRes.data.product.variants[0].id
|
||||
|
||||
let variantInventoryRes = await api.get(
|
||||
`/admin/variants/${variantId}/inventory`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(variantInventoryRes.data).toEqual({
|
||||
variant: {
|
||||
id: variantId,
|
||||
inventory: [],
|
||||
sales_channel_availability: [],
|
||||
},
|
||||
})
|
||||
expect(variantInventoryRes.status).toEqual(200)
|
||||
|
||||
const inventoryItemCreateRes = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{ variant_id: variantId, sku: "attach_this_to_variant" },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
variantInventoryRes = await api.get(
|
||||
`/admin/variants/${variantId}/inventory`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(variantInventoryRes.data).toEqual({
|
||||
variant: expect.objectContaining({
|
||||
id: variantId,
|
||||
inventory: [
|
||||
expect.objectContaining({
|
||||
...inventoryItemCreateRes.data.inventory_item,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
expect(variantInventoryRes.status).toEqual(200)
|
||||
})
|
||||
|
||||
it.skip("should list the location levels based on id param constraint", async () => {
|
||||
const inventoryItemId = inventoryItems[0].id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: location2Id,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: location3Id,
|
||||
stocked_quantity: 5,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const result = await api.get(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels?location_id[]=${location2Id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(result.status).toEqual(200)
|
||||
expect(result.data.inventory_item.location_levels).toHaveLength(1)
|
||||
expect(result.data.inventory_item.location_levels[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
stocked_quantity: 10,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
describe("List inventory levels", () => {
|
||||
let inventoryItemId
|
||||
let stockLocation1Id
|
||||
let stockLocation2Id
|
||||
|
||||
beforeEach(async () => {
|
||||
const inventoryItem = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{ sku: "test-sku" },
|
||||
adminHeaders
|
||||
)
|
||||
inventoryItemId = inventoryItem.data.inventory_item.id
|
||||
|
||||
const locationService = appContainer.resolve(
|
||||
ModuleRegistrationName.STOCK_LOCATION
|
||||
)
|
||||
const stockLocation1 = await locationService.create({
|
||||
name: "loc-1",
|
||||
})
|
||||
stockLocation1Id = stockLocation1.id
|
||||
|
||||
const stockLocation2 = await locationService.create({
|
||||
name: "loc-2",
|
||||
})
|
||||
stockLocation2Id = stockLocation2.id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: stockLocation1Id,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: stockLocation2Id,
|
||||
stocked_quantity: 15,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
})
|
||||
|
||||
it("should list the inventory levels", async () => {
|
||||
const response = await api.get(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data).toEqual(
|
||||
expect.objectContaining({
|
||||
count: 2,
|
||||
offset: 0,
|
||||
limit: 50,
|
||||
})
|
||||
)
|
||||
|
||||
expect(response.data.inventory_levels).toHaveLength(2)
|
||||
expect(response.data.inventory_levels).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
location_id: stockLocation1Id,
|
||||
stocked_quantity: 10,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
location_id: stockLocation2Id,
|
||||
stocked_quantity: 15,
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Update inventory item", () => {
|
||||
let inventoryItemId
|
||||
beforeEach(async () => {
|
||||
const inventoryItemResponse = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "test-sku",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
inventoryItemId = inventoryItemResponse.data.inventory_item.id
|
||||
})
|
||||
|
||||
it("should update the inventory item", async () => {
|
||||
const response = await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}`,
|
||||
{
|
||||
mid_code: "updated mid_code",
|
||||
weight: 120,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.inventory_item).toEqual(
|
||||
expect.objectContaining({
|
||||
sku: "test-sku",
|
||||
mid_code: "updated mid_code",
|
||||
weight: 120,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Bulk create/delete inventory levels", () => {
|
||||
const locationId = "loc_1"
|
||||
let inventoryItem
|
||||
|
||||
beforeEach(async () => {
|
||||
inventoryItem = await service.create({
|
||||
sku: "MY_SKU",
|
||||
})
|
||||
|
||||
await service.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: locationId,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should delete an inventory location level and create a new one", async () => {
|
||||
const result = await api.post(
|
||||
`/admin/inventory-items/${inventoryItem.id}/location-levels/batch`,
|
||||
{
|
||||
create: [
|
||||
{
|
||||
location_id: "location_2",
|
||||
},
|
||||
],
|
||||
delete: [locationId],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(result.status).toEqual(200)
|
||||
|
||||
const levelsListResult = await api.get(
|
||||
`/admin/inventory-items/${inventoryItem.id}/location-levels`,
|
||||
adminHeaders
|
||||
)
|
||||
expect(levelsListResult.status).toEqual(200)
|
||||
expect(levelsListResult.data.inventory_levels).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Delete inventory levels", () => {
|
||||
const locationId = "loc_1"
|
||||
let inventoryItem
|
||||
|
||||
beforeEach(async () => {
|
||||
inventoryItem = await service.create({
|
||||
sku: "MY_SKU",
|
||||
})
|
||||
|
||||
await service.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: locationId,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should delete an inventory location level without reservations", async () => {
|
||||
const result = await api.delete(
|
||||
`/admin/inventory-items/${inventoryItem.id}/location-levels/${locationId}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(result.status).toEqual(200)
|
||||
expect(result.data).toEqual({
|
||||
id: expect.any(String),
|
||||
object: "inventory-level",
|
||||
deleted: true,
|
||||
parent: expect.any(Object),
|
||||
})
|
||||
})
|
||||
|
||||
it("should fail delete an inventory location level with reservations", async () => {
|
||||
await service.createReservationItems({
|
||||
inventory_item_id: inventoryItem.id,
|
||||
location_id: locationId,
|
||||
quantity: 5,
|
||||
})
|
||||
|
||||
let error
|
||||
|
||||
await api
|
||||
.delete(
|
||||
`/admin/inventory-items/${inventoryItem.id}/location-levels/${locationId}`,
|
||||
adminHeaders
|
||||
)
|
||||
.catch((e) => (error = e))
|
||||
expect(error.response.status).toEqual(400)
|
||||
expect(error.response.data).toEqual({
|
||||
type: "not_allowed",
|
||||
message: `Cannot remove Inventory Level ${inventoryItem.id} at Location ${locationId} because there are reservations at location`,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Update inventory levels", () => {
|
||||
let locationId
|
||||
let inventoryItemId
|
||||
beforeEach(async () => {
|
||||
const invItemReps = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{ sku: "test-sku" },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
inventoryItemId = invItemReps.data.inventory_item.id
|
||||
|
||||
const stockLocation = await appContainer
|
||||
.resolve(ModuleRegistrationName.STOCK_LOCATION)
|
||||
.create({ name: "test-location" })
|
||||
|
||||
locationId = stockLocation.id
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: locationId,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
})
|
||||
|
||||
it("should update the stocked and incoming quantity for an inventory level", async () => {
|
||||
const result = await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels/${locationId}`,
|
||||
{
|
||||
stocked_quantity: 15,
|
||||
incoming_quantity: 5,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(result.status).toEqual(200)
|
||||
expect(result.data.inventory_item).toEqual(
|
||||
expect.objectContaining({
|
||||
id: inventoryItemId,
|
||||
location_levels: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: locationId,
|
||||
stocked_quantity: 15,
|
||||
reserved_quantity: 0,
|
||||
incoming_quantity: 5,
|
||||
metadata: null,
|
||||
}),
|
||||
]),
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail to update a non-existing location level", async () => {
|
||||
const error = await api
|
||||
.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels/does-not-exist`,
|
||||
{
|
||||
stocked_quantity: 15,
|
||||
incoming_quantity: 5,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(error.response.status).toEqual(404)
|
||||
expect(error.response.data).toEqual({
|
||||
type: "not_found",
|
||||
message: `Item ${inventoryItemId} is not stocked at location does-not-exist`,
|
||||
})
|
||||
})
|
||||
|
||||
it("should fail to update a non-existing inventory_item_id level", async () => {
|
||||
const error = await api
|
||||
.post(
|
||||
`/admin/inventory-items/does-not-exist/location-levels/${locationId}`,
|
||||
{
|
||||
stocked_quantity: 15,
|
||||
incoming_quantity: 5,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(error.response.status).toEqual(404)
|
||||
expect(error.response.data).toEqual({
|
||||
type: "not_found",
|
||||
message: `Item does-not-exist is not stocked at location ${locationId}`,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Retrieve inventory item", () => {
|
||||
let location1 = "loc_1"
|
||||
let location2 = "loc_2"
|
||||
beforeEach(async () => {
|
||||
await service.create([
|
||||
{
|
||||
sku: "MY_SKU",
|
||||
origin_country: "UK",
|
||||
hs_code: "hs001",
|
||||
mid_code: "mids",
|
||||
material: "material",
|
||||
weight: 300,
|
||||
length: 100,
|
||||
height: 200,
|
||||
width: 150,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should retrieve the inventory item", async () => {
|
||||
const [{ id: inventoryItemId }] = await service.list({})
|
||||
|
||||
await service.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location1,
|
||||
stocked_quantity: 15,
|
||||
incoming_quantity: 5,
|
||||
},
|
||||
{
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location2,
|
||||
stocked_quantity: 7,
|
||||
incoming_quantity: 0,
|
||||
reserved_quantity: 1,
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/inventory-items/${inventoryItemId}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.inventory_item).toEqual(
|
||||
expect.objectContaining({
|
||||
id: inventoryItemId,
|
||||
sku: "MY_SKU",
|
||||
origin_country: "UK",
|
||||
hs_code: "hs001",
|
||||
material: "material",
|
||||
mid_code: "mids",
|
||||
requires_shipping: true,
|
||||
weight: 300,
|
||||
length: 100,
|
||||
height: 200,
|
||||
width: 150,
|
||||
stocked_quantity: 22,
|
||||
reserved_quantity: 1,
|
||||
location_levels: [
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location1,
|
||||
stocked_quantity: 15,
|
||||
reserved_quantity: 0,
|
||||
incoming_quantity: 5,
|
||||
available_quantity: 15,
|
||||
metadata: null,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location2,
|
||||
stocked_quantity: 7,
|
||||
reserved_quantity: 1,
|
||||
incoming_quantity: 0,
|
||||
available_quantity: 6,
|
||||
metadata: null,
|
||||
}),
|
||||
],
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw if inventory item doesn't exist", async () => {
|
||||
const error = await api
|
||||
.get(`/admin/inventory-items/does-not-exist`, adminHeaders)
|
||||
.catch((e) => e)
|
||||
|
||||
expect(error.response.status).toEqual(404)
|
||||
expect(error.response.data).toEqual({
|
||||
type: "not_found",
|
||||
message: "Inventory item with id: does-not-exist was not found",
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Create inventory item level", () => {
|
||||
let location1
|
||||
let location2
|
||||
|
||||
beforeEach(async () => {
|
||||
await service.create([
|
||||
{
|
||||
sku: "MY_SKU",
|
||||
origin_country: "UK",
|
||||
hs_code: "hs001",
|
||||
mid_code: "mids",
|
||||
material: "material",
|
||||
weight: 300,
|
||||
length: 100,
|
||||
height: 200,
|
||||
width: 150,
|
||||
},
|
||||
])
|
||||
|
||||
const stockLocationService: IStockLocationService =
|
||||
appContainer.resolve(ModuleRegistrationName.STOCK_LOCATION)
|
||||
|
||||
location1 = await stockLocationService.create({
|
||||
name: "location-1",
|
||||
})
|
||||
|
||||
location2 = await stockLocationService.create({
|
||||
name: "location-2",
|
||||
})
|
||||
})
|
||||
|
||||
it("should create location levels for an inventory item", async () => {
|
||||
const [{ id: inventoryItemId }] = await service.list({})
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: location1.id,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
await api.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: location2.id,
|
||||
stocked_quantity: 5,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const levels = await service.listInventoryLevels({
|
||||
inventory_item_id: inventoryItemId,
|
||||
})
|
||||
|
||||
expect(levels).toHaveLength(2)
|
||||
expect(levels).toEqual([
|
||||
expect.objectContaining({
|
||||
location_id: location1.id,
|
||||
stocked_quantity: 10,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
location_id: location2.id,
|
||||
stocked_quantity: 5,
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("should fail to create a location level for an inventory item", async () => {
|
||||
const [{ id: inventoryItemId }] = await service.list({})
|
||||
|
||||
const error = await api
|
||||
.post(
|
||||
`/admin/inventory-items/${inventoryItemId}/location-levels`,
|
||||
{
|
||||
location_id: "{location1.id}",
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
.catch((error) => error)
|
||||
|
||||
expect(error.response.status).toEqual(404)
|
||||
expect(error.response.data).toEqual({
|
||||
type: "not_found",
|
||||
message: "Stock locations with ids: {location1.id} was not found",
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Create inventory items", () => {
|
||||
it("should create inventory items", async () => {
|
||||
const response = await api.post(
|
||||
`/admin/inventory-items`,
|
||||
{
|
||||
sku: "test-sku",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.inventory_item).toEqual(
|
||||
expect.objectContaining({
|
||||
sku: "test-sku",
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("List inventory items", () => {
|
||||
let location1 = "loc_1"
|
||||
let location2 = "loc_2"
|
||||
beforeEach(async () => {
|
||||
await service.create([
|
||||
{
|
||||
sku: "MY_SKU",
|
||||
origin_country: "UK",
|
||||
hs_code: "hs001",
|
||||
mid_code: "mids",
|
||||
material: "material",
|
||||
weight: 300,
|
||||
length: 100,
|
||||
height: 200,
|
||||
width: 150,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("should list the inventory items", async () => {
|
||||
const [{ id: inventoryItemId }] = await service.list({})
|
||||
|
||||
await service.createInventoryLevels([
|
||||
{
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location1,
|
||||
stocked_quantity: 10,
|
||||
},
|
||||
{
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location2,
|
||||
stocked_quantity: 5,
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/inventory-items?location_levels[location_id]=${location1}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.inventory_items).toHaveLength(1)
|
||||
expect(response.data.inventory_items[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
id: inventoryItemId,
|
||||
sku: "MY_SKU",
|
||||
origin_country: "UK",
|
||||
hs_code: "hs001",
|
||||
mid_code: "mids",
|
||||
material: "material",
|
||||
weight: 300,
|
||||
length: 100,
|
||||
height: 200,
|
||||
width: 150,
|
||||
requires_shipping: true,
|
||||
metadata: null,
|
||||
location_levels: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location1,
|
||||
stocked_quantity: 10,
|
||||
reserved_quantity: 0,
|
||||
incoming_quantity: 0,
|
||||
metadata: null,
|
||||
available_quantity: 10,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
inventory_item_id: inventoryItemId,
|
||||
location_id: location2,
|
||||
stocked_quantity: 5,
|
||||
reserved_quantity: 0,
|
||||
incoming_quantity: 0,
|
||||
metadata: null,
|
||||
available_quantity: 5,
|
||||
}),
|
||||
]),
|
||||
reserved_quantity: 0,
|
||||
stocked_quantity: 15,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should list the inventory items searching by title, description and sku", async () => {
|
||||
const inventoryService = appContainer.resolve("inventoryService")
|
||||
|
||||
await inventoryService.create([
|
||||
{
|
||||
title: "Test Item",
|
||||
},
|
||||
{
|
||||
description: "Test Desc",
|
||||
},
|
||||
{
|
||||
sku: "Test Sku",
|
||||
},
|
||||
])
|
||||
|
||||
const response = await api.get(
|
||||
`/admin/inventory-items?q=test`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(response.data.inventory_items).not.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
sku: "MY_SKU",
|
||||
}),
|
||||
])
|
||||
)
|
||||
expect(response.data.inventory_items).toHaveLength(3)
|
||||
expect(response.data.inventory_items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
sku: "Test Sku",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
description: "Test Desc",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
title: "Test Item",
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("delete inventory item", () => {
|
||||
let invItem
|
||||
beforeEach(async () => {
|
||||
invItem = await service.create({
|
||||
sku: "MY_SKU",
|
||||
origin_country: "UK",
|
||||
hs_code: "hs001",
|
||||
mid_code: "mids",
|
||||
material: "material",
|
||||
weight: 300,
|
||||
length: 100,
|
||||
height: 200,
|
||||
width: 150,
|
||||
})
|
||||
})
|
||||
|
||||
it("should remove associated levels and reservations when deleting an inventory item", async () => {
|
||||
const inventoryService = appContainer.resolve(
|
||||
ModuleRegistrationName.INVENTORY
|
||||
)
|
||||
|
||||
locationId = "location1"
|
||||
|
||||
await inventoryService.createInventoryLevels({
|
||||
inventory_item_id: invItem.id,
|
||||
location_id: locationId,
|
||||
stocked_quantity: 10,
|
||||
})
|
||||
|
||||
await inventoryService.createReservationItems({
|
||||
inventory_item_id: invItem.id,
|
||||
location_id: locationId,
|
||||
quantity: 5,
|
||||
})
|
||||
|
||||
const [, reservationCount] =
|
||||
await inventoryService.listAndCountReservationItems({
|
||||
location_id: locationId,
|
||||
})
|
||||
|
||||
expect(reservationCount).toEqual(1)
|
||||
|
||||
const [, inventoryLevelCount] =
|
||||
await inventoryService.listAndCountInventoryLevels({
|
||||
location_id: locationId,
|
||||
})
|
||||
|
||||
expect(inventoryLevelCount).toEqual(1)
|
||||
|
||||
const res = await api.delete(
|
||||
`/admin/inventory-items/${invItem.id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(res.status).toEqual(200)
|
||||
|
||||
const [, reservationCountPostDelete] =
|
||||
await inventoryService.listAndCountReservationItems({
|
||||
location_id: locationId,
|
||||
})
|
||||
|
||||
expect(reservationCountPostDelete).toEqual(0)
|
||||
|
||||
const [, inventoryLevelCountPostDelete] =
|
||||
await inventoryService.listAndCountInventoryLevels({
|
||||
location_id: locationId,
|
||||
})
|
||||
|
||||
expect(inventoryLevelCountPostDelete).toEqual(0)
|
||||
})
|
||||
|
||||
it("should remove the product variant associations when deleting an inventory item", async () => {
|
||||
const secondVariantId = "test-2"
|
||||
const variantId = "test"
|
||||
|
||||
const remoteLinks = appContainer.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_LINK
|
||||
)
|
||||
const remoteQuery = appContainer.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
|
||||
await remoteLinks.create([
|
||||
{
|
||||
productService: {
|
||||
variant_id: variantId,
|
||||
},
|
||||
inventoryService: {
|
||||
inventory_item_id: invItem.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
productService: {
|
||||
variant_id: secondVariantId,
|
||||
},
|
||||
inventoryService: {
|
||||
inventory_item_id: invItem.id,
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
let links = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: "product_variant_inventory_item",
|
||||
variables: {
|
||||
filter: { variant_id: [variantId, secondVariantId] },
|
||||
},
|
||||
fields: ["variant_id", "inventory_item_id"],
|
||||
})
|
||||
)
|
||||
|
||||
expect(links).toHaveLength(2)
|
||||
expect(links).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
variant_id: "test",
|
||||
inventory_item_id: invItem.id,
|
||||
},
|
||||
{
|
||||
variant_id: "test-2",
|
||||
inventory_item_id: invItem.id,
|
||||
},
|
||||
])
|
||||
)
|
||||
|
||||
await api.delete(`/admin/inventory-items/${invItem.id}`, adminHeaders)
|
||||
|
||||
links = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: "product_variant_inventory_item",
|
||||
variables: {
|
||||
filter: { variant_id: [variantId, secondVariantId] },
|
||||
},
|
||||
fields: ["variant_id", "inventory_item_id"],
|
||||
})
|
||||
)
|
||||
|
||||
expect(links).toHaveLength(0)
|
||||
expect(links).toEqual([])
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -72,6 +72,7 @@ export const AdminCreateInventoryLocationLevel = z
|
||||
location_id: z.string(),
|
||||
stocked_quantity: z.number().min(0).optional(),
|
||||
incoming_quantity: z.number().min(0).optional(),
|
||||
reserved_quantity: z.number().min(0).optional(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user