Feat(medusa) - delete cascade modules associations (#3190)

* delete cascade sales channel x locations, variant x inventory item
This commit is contained in:
Carlos R. L. Rodrigues
2023-02-08 17:23:47 -03:00
committed by GitHub
parent 3b474ec35c
commit d859ccf551
18 changed files with 672 additions and 63 deletions
@@ -362,5 +362,83 @@ describe("Inventory Items endpoints", () => {
}),
])
})
it("When deleting an inventory item it removes the product variants associated to it", async () => {
const api = useApi()
await simpleProductFactory(
dbConnection,
{
id: "test-product-new",
variants: [],
},
5
)
const response = await api.post(
`/admin/products/test-product-new/variants`,
{
title: "Test2",
sku: "MY_SKU2",
manage_inventory: true,
options: [
{
option_id: "test-product-new-option",
value: "Blue",
},
],
prices: [{ currency_code: "usd", amount: 100 }],
},
{ headers: { Authorization: "Bearer test_token" } }
)
const secondVariantId = response.data.product.variants.find(
(v) => v.sku === "MY_SKU2"
).id
const inventoryService = appContainer.resolve("inventoryService")
const variantInventoryService = appContainer.resolve(
"productVariantInventoryService"
)
const invItem2 = await inventoryService.createInventoryItem({
sku: "123456",
})
await variantInventoryService.attachInventoryItem(
variantId,
invItem2.id,
2
)
await variantInventoryService.attachInventoryItem(
secondVariantId,
invItem2.id,
2
)
expect(
await variantInventoryService.listInventoryItemsByVariant(variantId)
).toHaveLength(2)
expect(
await variantInventoryService.listInventoryItemsByVariant(
secondVariantId
)
).toHaveLength(2)
await api.delete(`/admin/inventory-items/${invItem2.id}`, {
headers: { Authorization: "Bearer test_token" },
})
expect(
await variantInventoryService.listInventoryItemsByVariant(variantId)
).toHaveLength(1)
expect(
await variantInventoryService.listInventoryItemsByVariant(
secondVariantId
)
).toHaveLength(1)
})
})
})
@@ -0,0 +1,111 @@
const path = require("path")
const { bootstrapApp } = require("../../../../helpers/bootstrap-app")
const { initDb, useDb } = require("../../../../helpers/use-db")
const { setPort, useApi } = require("../../../../helpers/use-api")
const adminSeeder = require("../../../helpers/admin-seeder")
jest.setTimeout(30000)
const { simpleProductFactory } = require("../../../factories")
describe("Delete Variant", () => {
let appContainer
let dbConnection
let express
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
dbConnection = await initDb({ cwd })
const { container, app, port } = await bootstrapApp({ cwd })
appContainer = container
setPort(port)
express = app.listen(port, (err) => {
process.send(port)
})
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
express.close()
})
afterEach(async () => {
jest.clearAllMocks()
const db = useDb()
return await db.teardown()
})
describe("Inventory Items", () => {
it("When deleting a product variant it removes the inventory items associated to it", async () => {
await adminSeeder(dbConnection)
const api = useApi()
await simpleProductFactory(
dbConnection,
{
id: "test-product",
variants: [{ id: "test-variant" }],
},
100
)
const response = await api.post(
`/admin/products/test-product/variants`,
{
title: "Test Variant w. inventory",
sku: "MY_SKU",
manage_inventory: true,
options: [
{
option_id: "test-product-option",
value: "SS",
},
],
prices: [{ currency_code: "usd", amount: 2300 }],
},
{ headers: { Authorization: "Bearer test_token" } }
)
const variantId = response.data.product.variants.find(
(v) => v.sku === "MY_SKU"
).id
const inventoryService = appContainer.resolve("inventoryService")
const variantInventoryService = appContainer.resolve(
"productVariantInventoryService"
)
const variantService = appContainer.resolve("productVariantService")
const invItem2 = await inventoryService.createInventoryItem({
sku: "123456",
})
await variantInventoryService.attachInventoryItem(
variantId,
invItem2.id,
2
)
expect(
await variantInventoryService.listInventoryItemsByVariant(variantId)
).toHaveLength(2)
await api.delete(`/admin/products/test-product/variants/${variantId}`, {
headers: { Authorization: "Bearer test_token" },
})
await expect(variantService.retrieve(variantId)).rejects.toThrow(
`Variant with id: ${variantId} was not found`
)
expect(
await variantInventoryService.listInventoryItemsByVariant(variantId)
).toHaveLength(0)
})
})
})
@@ -0,0 +1,85 @@
const path = require("path")
const { bootstrapApp } = require("../../../helpers/bootstrap-app")
const { initDb, useDb } = require("../../../helpers/use-db")
const { setPort, useApi } = require("../../../helpers/use-api")
const adminSeeder = require("../../helpers/admin-seeder")
jest.setTimeout(30000)
describe("Sales channels", () => {
let appContainer
let dbConnection
let express
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd })
const { container, app, port } = await bootstrapApp({ cwd })
appContainer = container
setPort(port)
express = app.listen(port, (err) => {
process.send(port)
})
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
express.close()
})
afterEach(async () => {
jest.clearAllMocks()
const db = useDb()
return await db.teardown()
})
describe("Stock Locations", () => {
it("When deleting a sales channel, removes all associated locations with it", async () => {
await adminSeeder(dbConnection)
const api = useApi()
const stockLocationService = appContainer.resolve("stockLocationService")
const salesChannelService = appContainer.resolve("salesChannelService")
const salesChannelLocationService = appContainer.resolve(
"salesChannelLocationService"
)
const loc = await stockLocationService.create({
name: "warehouse",
})
const loc2 = await stockLocationService.create({
name: "other place",
})
const sc = await salesChannelService.create({ name: "channel test" })
await salesChannelLocationService.associateLocation(sc.id, loc.id)
await salesChannelLocationService.associateLocation(sc.id, loc2.id)
expect(await salesChannelService.retrieve(sc.id)).toEqual(
expect.objectContaining({
id: sc.id,
name: "channel test",
})
)
expect(
await salesChannelLocationService.listLocations(sc.id)
).toHaveLength(2)
await api.delete(`/admin/sales-channels/${sc.id}`, {
headers: { Authorization: "Bearer test_token" },
})
await expect(salesChannelService.retrieve(sc.id)).rejects.toThrowError()
await expect(
salesChannelLocationService.listLocations(sc.id)
).rejects.toThrowError()
})
})
})
@@ -0,0 +1,93 @@
const path = require("path")
const { bootstrapApp } = require("../../../helpers/bootstrap-app")
const { initDb, useDb } = require("../../../helpers/use-db")
const { setPort, useApi } = require("../../../helpers/use-api")
const adminSeeder = require("../../helpers/admin-seeder")
jest.setTimeout(30000)
describe("Sales channels", () => {
let appContainer
let dbConnection
let express
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd })
const { container, app, port } = await bootstrapApp({ cwd })
appContainer = container
setPort(port)
express = app.listen(port, (err) => {
process.send(port)
})
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
express.close()
})
afterEach(async () => {
jest.clearAllMocks()
const db = useDb()
return await db.teardown()
})
describe("Stock Locations", () => {
it("When deleting a stock location, removes all associated sales channels with it", async () => {
await adminSeeder(dbConnection)
const api = useApi()
const stockLocationService = appContainer.resolve("stockLocationService")
const salesChannelService = appContainer.resolve("salesChannelService")
const salesChannelLocationService = appContainer.resolve(
"salesChannelLocationService"
)
const loc = await stockLocationService.create({
name: "warehouse",
})
const saleChannel = await salesChannelService.create({
name: "channel test",
})
const otherChannel = await salesChannelService.create({
name: "yet another channel",
})
await salesChannelLocationService.associateLocation(
saleChannel.id,
loc.id
)
await salesChannelLocationService.associateLocation(
otherChannel.id,
loc.id
)
expect(
await salesChannelLocationService.listLocations(saleChannel.id)
).toHaveLength(1)
expect(
await salesChannelLocationService.listLocations(otherChannel.id)
).toHaveLength(1)
await api.delete(`/admin/stock-locations/${loc.id}`, {
headers: { Authorization: "Bearer test_token" },
})
expect(
await salesChannelLocationService.listLocations(saleChannel.id)
).toHaveLength(0)
expect(
await salesChannelLocationService.listLocations(otherChannel.id)
).toHaveLength(0)
})
})
})
@@ -0,0 +1,94 @@
const path = require("path")
const { bootstrapApp } = require("../../../helpers/bootstrap-app")
const { initDb, useDb } = require("../../../helpers/use-db")
const { setPort, useApi } = require("../../../helpers/use-api")
const adminSeeder = require("../../helpers/admin-seeder")
jest.setTimeout(30000)
describe("Sales channels", () => {
let appContainer
let dbConnection
let express
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd })
const { container, app, port } = await bootstrapApp({ cwd })
appContainer = container
setPort(port)
express = app.listen(port, (err) => {
process.send(port)
})
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
express.close()
})
afterEach(async () => {
jest.clearAllMocks()
const db = useDb()
return await db.teardown()
})
describe("Stock Locations", () => {
it("When listing a sales channel, it brings all associated locations with it", async () => {
await adminSeeder(dbConnection)
const stockLocationService = appContainer.resolve("stockLocationService")
const salesChannelService = appContainer.resolve("salesChannelService")
const salesChannelLocationService = appContainer.resolve(
"salesChannelLocationService"
)
const loc = await stockLocationService.create({
name: "warehouse",
})
const loc2 = await stockLocationService.create({
name: "other place",
})
const sc = await salesChannelService.create({ name: "channel test" })
await salesChannelLocationService.associateLocation(sc.id, loc.id)
await salesChannelLocationService.associateLocation(sc.id, loc2.id)
expect(
await salesChannelLocationService.listLocations(sc.id)
).toHaveLength(2)
const [channels] = await salesChannelService.listAndCount(
{},
{
relations: ["locations"],
}
)
const createdSC = channels.find((c) => c.id === sc.id)
expect(channels).toHaveLength(2)
expect(createdSC.locations).toHaveLength(2)
expect(createdSC).toEqual(
expect.objectContaining({
id: sc.id,
name: "channel test",
locations: expect.arrayContaining([
expect.objectContaining({
sales_channel_id: sc.id,
location_id: loc.id,
}),
expect.objectContaining({
sales_channel_id: sc.id,
location_id: loc2.id,
}),
]),
})
)
})
})
})