Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] develop from medusajs:develop #9

Merged
merged 5 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/calm-needles-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@medusajs/workflow-engine-redis": patch
"@medusajs/workflows-sdk": patch
"@medusajs/core-flows": patch
"@medusajs/utils": patch
---

fix: when/then step name
5 changes: 5 additions & 0 deletions .changeset/cuddly-students-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/api-key": patch
---

refactor: migrate api key module to DML
5 changes: 5 additions & 0 deletions .changeset/green-turkeys-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/utils": patch
---

fix(utils): DML one to one definition
7 changes: 7 additions & 0 deletions .changeset/honest-cars-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@medusajs/core-flows": patch
"@medusajs/types": patch
"@medusajs/dashboard": patch
---

fix(): Deleted default sales channel should be prevented
144 changes: 144 additions & 0 deletions integration-tests/http/__tests__/product/store/product.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,150 @@ medusaIntegrationTestRunner({
)
})

it("should handle inventory items and location levels correctly", async () => {
const container = getContainer()
const channelService = container.resolve("sales_channel")
const locationService = container.resolve("stock_location")
const inventoryService = container.resolve("inventory")
const productService = container.resolve("product")
const pubKeyService = container.resolve("api_key")
const linkService = container.resolve("remoteLink")

const [channelOne, channelTwo] =
await channelService.createSalesChannels([
{ name: "Sales Channel 1" },
{ name: "Sales Channel 2" },
])

const product = await productService.createProducts({
status: "published",
title: "my prod",
options: [{ title: "color", values: ["green", "blue"] }],
variants: [
{ title: "variant one", options: { color: "green" } },
{ title: "variant two", options: { color: "blue" } },
],
})
console.log(product)
const [variantOne, variantTwo] = product.variants

const [itemOne, itemTwo, itemThree] =
await inventoryService.createInventoryItems([
{ sku: "sku-one" },
{ sku: "sku-two" },
{ sku: "sku-three" },
])

const [locationOne, locationTwo] =
await locationService.createStockLocations([
{ name: "Location One" },
{ name: "Location Two" },
])

await inventoryService.createInventoryLevels([
{
location_id: locationOne.id,
inventory_item_id: itemOne.id,
stocked_quantity: 23,
},
{
location_id: locationOne.id,
inventory_item_id: itemTwo.id,
stocked_quantity: 10,
},
{
location_id: locationTwo.id,
inventory_item_id: itemThree.id,
stocked_quantity: 5,
},
])

const [pubKeyOne, pubKeyTwo] = await pubKeyService.createApiKeys([
{ title: "pub key one", type: "publishable", created_by: "me" },
{ title: "pub key two", type: "publishable", created_by: "me" },
])

await linkService.create([
{
product: { product_id: product.id },
sales_channel: { sales_channel_id: channelOne.id },
},
{
product: { product_id: product.id },
sales_channel: { sales_channel_id: channelTwo.id },
},
{
product: { variant_id: variantOne.id },
inventory: { inventory_item_id: itemOne.id },
},
{
product: { variant_id: variantTwo.id },
inventory: { inventory_item_id: itemTwo.id },
},
{
product: { variant_id: variantTwo.id },
inventory: { inventory_item_id: itemThree.id },
data: { required_quantity: 2 },
},
{
sales_channel: { sales_channel_id: channelOne.id },
stock_location: { stock_location_id: locationOne.id },
},
{
sales_channel: { sales_channel_id: channelTwo.id },
stock_location: { stock_location_id: locationOne.id },
},
{
sales_channel: { sales_channel_id: channelTwo.id },
stock_location: { stock_location_id: locationTwo.id },
},
{
api_key: { publishable_key_id: pubKeyOne.id },
sales_channel: { sales_channel_id: channelOne.id },
},
{
api_key: { publishable_key_id: pubKeyTwo.id },
sales_channel: { sales_channel_id: channelTwo.id },
},
])

let response = await api.get(
`/store/products?fields=+variants.inventory_quantity`,
{ headers: { "x-publishable-api-key": pubKeyOne.token } }
)

expect(response.status).toEqual(200)
for (const variant of response.data.products
.map((p) => p.variants)
.flat()) {
if (variant.id === variantOne.id) {
expect(variant.inventory_quantity).toEqual(23)
} else if (variant.id === variantTwo.id) {
expect(variant.inventory_quantity).toEqual(0)
} else {
throw new Error("Unexpected variant")
}
}

response = await api.get(
`/store/products?fields=+variants.inventory_quantity`,
{ headers: { "x-publishable-api-key": pubKeyTwo.token } }
)

expect(response.status).toEqual(200)
for (const variant of response.data.products
.map((p) => p.variants)
.flat()) {
if (variant.id === variantOne.id) {
expect(variant.inventory_quantity).toEqual(23)
} else if (variant.id === variantTwo.id) {
expect(variant.inventory_quantity).toEqual(2)
} else {
throw new Error("Unexpected variant")
}
}
})

it("should list all inventory items for a variant", async () => {
let response = await api.get(
`/store/products?sales_channel_id[]=${salesChannel1.id}&fields=variants.inventory_items.inventory.location_levels.*`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import {
adminHeaders,
createAdminUser,
} from "../../../../helpers/create-admin-user"
import { Modules } from "@medusajs/framework/utils"

jest.setTimeout(60000)

medusaIntegrationTestRunner({
testSuite: ({ dbConnection, getContainer, api }) => {
let salesChannel1
let salesChannel2
let container

beforeEach(async () => {
const container = getContainer()
container = getContainer()
await createAdminUser(dbConnection, adminHeaders, container)

salesChannel1 = (
Expand Down Expand Up @@ -245,6 +247,34 @@ medusaIntegrationTestRunner({
})

describe("DELETE /admin/sales-channels/:id", () => {
it("should fail to delete the requested sales channel if it is used as a default sales channel", async () => {
const salesChannel = (
await api.post(
"/admin/sales-channels",
{ name: "Test channel", description: "Test" },
adminHeaders
)
).data.sales_channel

const storeModule = container.resolve(Modules.STORE)
await storeModule.createStores({
name: "New store",
supported_currencies: [
{ currency_code: "usd", is_default: true },
{ currency_code: "dkk" },
],
default_sales_channel_id: salesChannel.id,
})

const errorResponse = await api
.delete(`/admin/sales-channels/${salesChannel.id}`, adminHeaders)
.catch((err) => err)

expect(errorResponse.response.data.message).toEqual(
`Cannot delete default sales channels: ${salesChannel.id}`
)
})

it("should delete the requested sales channel", async () => {
const toDelete = (
await api.get(
Expand All @@ -268,17 +298,19 @@ medusaIntegrationTestRunner({
object: "sales-channel",
})

await api
const err = await api
.get(
`/admin/sales-channels/${salesChannel1.id}?fields=id,deleted_at`,
adminHeaders
)
.catch((err) => {
expect(err.response.data.type).toEqual("not_found")
expect(err.response.data.message).toEqual(
`Sales channel with id: ${salesChannel1.id} not found`
)
return err
})

expect(err.response.data.type).toEqual("not_found")
expect(err.response.data.message).toEqual(
`Sales channel with id: ${salesChannel1.id} not found`
)
})

it("should successfully delete channel associations", async () => {
Expand Down
Loading
Loading