feat(medusa): Add purchasable prop on variants when setting availability (#3811)
* write integration tests * update variant inventory decorator * update types * add changeset * feedback comments * add yaml schemas * different oas approach * pr feedback * update oas --------- Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
@@ -50,6 +50,7 @@ describe("Create Variant", () => {
|
||||
describe("list-products", () => {
|
||||
const productId = "test-product"
|
||||
const variantId = "test-variant"
|
||||
let sc2
|
||||
beforeEach(async () => {
|
||||
await adminSeeder(dbConnection)
|
||||
|
||||
@@ -66,13 +67,14 @@ describe("Create Variant", () => {
|
||||
dbConnection,
|
||||
{
|
||||
id: productId,
|
||||
status: "published",
|
||||
variants: [{ id: variantId }],
|
||||
},
|
||||
100
|
||||
)
|
||||
|
||||
const sc1 = await simpleSalesChannelFactory(dbConnection, {})
|
||||
const sc2 = await simpleSalesChannelFactory(dbConnection, {})
|
||||
sc2 = await simpleSalesChannelFactory(dbConnection, {})
|
||||
const sc3 = await simpleSalesChannelFactory(dbConnection, {})
|
||||
|
||||
const sl1 = await stockLocationService.create({ name: "sl1" })
|
||||
@@ -120,5 +122,203 @@ describe("Create Variant", () => {
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
describe("/store/products", () => {
|
||||
beforeEach(async () => {
|
||||
const inventoryService = appContainer.resolve("inventoryService")
|
||||
const productVariantInventoryService = appContainer.resolve(
|
||||
"productVariantInventoryService"
|
||||
)
|
||||
|
||||
await simpleProductFactory(
|
||||
dbConnection,
|
||||
{
|
||||
id: `${productId}-1`,
|
||||
status: "published",
|
||||
variants: [
|
||||
{
|
||||
id: `${variantId}-1`,
|
||||
manage_inventory: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
101
|
||||
)
|
||||
await simpleProductFactory(
|
||||
dbConnection,
|
||||
{
|
||||
id: `${productId}-2`,
|
||||
status: "published",
|
||||
variants: [{ id: `${variantId}-2`, manage_inventory: true }],
|
||||
},
|
||||
102
|
||||
)
|
||||
await simpleProductFactory(
|
||||
dbConnection,
|
||||
{
|
||||
id: `${productId}-3`,
|
||||
status: "published",
|
||||
variants: [
|
||||
{
|
||||
id: `${variantId}-3`,
|
||||
manage_inventory: true,
|
||||
allow_backorder: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
103
|
||||
)
|
||||
const invItem = await inventoryService.createInventoryItem({
|
||||
sku: "test-sku-1",
|
||||
})
|
||||
await productVariantInventoryService.attachInventoryItem(
|
||||
`${variantId}-3`,
|
||||
invItem.id
|
||||
)
|
||||
await simpleProductFactory(
|
||||
dbConnection,
|
||||
{
|
||||
id: `${productId}-4`,
|
||||
status: "published",
|
||||
variants: [
|
||||
{
|
||||
id: `${variantId}-4`,
|
||||
manage_inventory: true,
|
||||
allow_backorder: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
104
|
||||
)
|
||||
const invItem1 = await inventoryService.createInventoryItem({
|
||||
sku: "test-sku-2",
|
||||
})
|
||||
await productVariantInventoryService.attachInventoryItem(
|
||||
`${variantId}-4`,
|
||||
invItem1.id
|
||||
)
|
||||
})
|
||||
|
||||
it("lists location availability correctly for store", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const res = await api.get(`/store/products`)
|
||||
|
||||
expect(res.status).toEqual(200)
|
||||
expect(res.data.products).toEqual([
|
||||
expect.objectContaining({
|
||||
id: `${productId}-4`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: false,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: `${productId}-3`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: false,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: `${productId}-2`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: `${productId}-1`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
inventory_quantity: 10,
|
||||
purchasable: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: productId,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: false,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("lists location availability correctly for store with sales channel id", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const productService = appContainer.resolve("productService")
|
||||
|
||||
const ids = [
|
||||
`${productId}`,
|
||||
`${productId}-1`,
|
||||
`${productId}-2`,
|
||||
`${productId}-3`,
|
||||
`${productId}-4`,
|
||||
]
|
||||
|
||||
for (const id of ids) {
|
||||
await productService.update(id, {
|
||||
sales_channels: [{ id: sc2.id }],
|
||||
})
|
||||
}
|
||||
|
||||
const res = await api.get(
|
||||
`/store/products?sales_channel_id[]=${sc2.id}`
|
||||
)
|
||||
|
||||
expect(res.status).toEqual(200)
|
||||
expect(res.data.products).toEqual([
|
||||
expect.objectContaining({
|
||||
id: `${productId}-4`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: false,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: `${productId}-3`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: `${productId}-2`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: `${productId}-1`,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
inventory_quantity: 10,
|
||||
purchasable: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: productId,
|
||||
variants: [
|
||||
expect.objectContaining({
|
||||
purchasable: true,
|
||||
inventory_quantity: 4,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { Product, ProductOption, ProductStatus, ProductType, ShippingProfile, ShippingProfileType, } from "@medusajs/medusa"
|
||||
import { ProductVariantFactoryData, simpleProductVariantFactory, } from "./simple-product-variant-factory"
|
||||
|
||||
import { Connection } from "typeorm"
|
||||
import faker from "faker"
|
||||
import { Product, ProductOption, ProductType, ShippingProfile, ShippingProfileType, } from "@medusajs/medusa"
|
||||
|
||||
import { ProductVariantFactoryData, simpleProductVariantFactory, } from "./simple-product-variant-factory"
|
||||
|
||||
export type ProductFactoryData = {
|
||||
id?: string
|
||||
is_giftcard?: boolean
|
||||
title?: string
|
||||
type?: string
|
||||
status?: ProductStatus
|
||||
options?: { id: string; title: string }[]
|
||||
variants?: ProductVariantFactoryData[]
|
||||
}
|
||||
@@ -45,6 +46,7 @@ export const simpleProductFactory = async (
|
||||
const toSave = manager.create(Product, {
|
||||
id: prodId,
|
||||
type_id: typeId,
|
||||
status: data.status || ProductStatus.DRAFT,
|
||||
title: data.title || faker.commerce.productName(),
|
||||
is_giftcard: data.is_giftcard || false,
|
||||
discountable: !data.is_giftcard,
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { Connection } from "typeorm"
|
||||
import faker from "faker"
|
||||
import {
|
||||
MoneyAmount,
|
||||
ProductOptionValue,
|
||||
ProductVariant,
|
||||
MoneyAmount,
|
||||
} from "@medusajs/medusa"
|
||||
|
||||
import { Connection } from "typeorm"
|
||||
import faker from "faker"
|
||||
|
||||
export type ProductVariantFactoryData = {
|
||||
product_id: string
|
||||
id?: string
|
||||
is_giftcard?: boolean
|
||||
inventory_quantity?: number
|
||||
title?: string
|
||||
allow_backorder?: boolean
|
||||
manage_inventory?: boolean
|
||||
options?: { option_id: string; value: string }[]
|
||||
prices?: { currency: string; amount: number }[]
|
||||
}
|
||||
@@ -31,6 +34,8 @@ export const simpleProductVariantFactory = async (
|
||||
const toSave = manager.create(ProductVariant, {
|
||||
id,
|
||||
product_id: data.product_id,
|
||||
allow_backorder: data.allow_backorder || false,
|
||||
manage_inventory: typeof data.manage_inventory !== 'undefined' ? data.manage_inventory : true,
|
||||
inventory_quantity:
|
||||
typeof data.inventory_quantity !== "undefined"
|
||||
? data.inventory_quantity
|
||||
|
||||
Reference in New Issue
Block a user