feat(core-flows, product): options checks on product create/update (#9171)
**What** - validate that variants are unique with respect to options on product update/create and variant update/create - validate that the product has options upon creation - ensure variants have the same number of option values as the product has options - admin error handling - update tests --- FIXES FRMW-2707 CC-556
This commit is contained in:
@@ -71,10 +71,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Test product",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
options: { size: "large" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
@@ -93,10 +95,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Extra product",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "my variant",
|
||||
sku: "variant-sku",
|
||||
options: { size: "large" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
|
||||
@@ -49,6 +49,7 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "test-product",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
@@ -59,6 +60,7 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "test-product1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
@@ -67,10 +67,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Test product",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
options: { size: "large" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
@@ -89,10 +91,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Extra product",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "my variant",
|
||||
sku: "variant-sku",
|
||||
options: { size: "large" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
|
||||
@@ -839,9 +839,11 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "product 1",
|
||||
options: [{ title: "size", values: ["large"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "variant 1",
|
||||
options: { size: "large" },
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
inventory_items: [
|
||||
{
|
||||
|
||||
@@ -90,10 +90,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Test product",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
options: { size: "large" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
@@ -112,10 +114,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Extra product",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "my variant",
|
||||
sku: "variant-sku",
|
||||
options: { size: "large" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
|
||||
@@ -176,12 +176,12 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
|
||||
it('gets the metadata of a category', async () => {
|
||||
it("gets the metadata of a category", async () => {
|
||||
await api.post(
|
||||
`/admin/product-categories/${productCategory.id}`,
|
||||
{
|
||||
metadata: {
|
||||
test: "test"
|
||||
test: "test",
|
||||
},
|
||||
},
|
||||
adminHeaders
|
||||
@@ -193,7 +193,9 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.product_category.metadata).toEqual({ test: "test" })
|
||||
expect(response.data.product_category.metadata).toEqual({
|
||||
test: "test",
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1345,6 +1347,7 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "product 1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
categories: [{ id: productCategory.id }],
|
||||
},
|
||||
adminHeaders
|
||||
@@ -1354,6 +1357,7 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "product 2",
|
||||
options: [{ title: "color", values: ["r", "g"] }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
@@ -667,10 +667,12 @@ medusaIntegrationTestRunner({
|
||||
title: "Test Giftcard",
|
||||
is_giftcard: true,
|
||||
description: "test-giftcard-description",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "x" },
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1056,10 +1058,12 @@ medusaIntegrationTestRunner({
|
||||
const payload = {
|
||||
title: "Test product - 1",
|
||||
handle: "test-1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Custom inventory 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "x" },
|
||||
manage_inventory: true,
|
||||
inventory_items: [
|
||||
{
|
||||
@@ -1097,16 +1101,19 @@ medusaIntegrationTestRunner({
|
||||
const payload = {
|
||||
title: "Test product - 1",
|
||||
handle: "test-1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Custom inventory 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
manage_inventory: true,
|
||||
options: { size: "x" },
|
||||
inventory_items: [],
|
||||
},
|
||||
{
|
||||
title: "Custom inventory 2",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "l" },
|
||||
manage_inventory: false,
|
||||
},
|
||||
],
|
||||
@@ -1294,9 +1301,11 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Test create",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Price with rules",
|
||||
options: { size: "l" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
@@ -1345,10 +1354,12 @@ medusaIntegrationTestRunner({
|
||||
images: [{ url: "test-image.png" }, { url: "test-image-2.png" }],
|
||||
collection_id: baseCollection.id,
|
||||
tags: [{ id: baseTag1.id }, { id: baseTag2.id }],
|
||||
options: [{ title: "size", values: ["large"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "large" },
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1375,14 +1386,17 @@ medusaIntegrationTestRunner({
|
||||
images: [{ url: "test-image.png" }, { url: "test-image-2.png" }],
|
||||
collection_id: baseCollection.id,
|
||||
tags: [{ id: baseTag1.id }, { id: baseTag2.id }],
|
||||
options: [{ title: "size", values: ["l", x] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "x" },
|
||||
},
|
||||
{
|
||||
title: "Test variant 2",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "l" },
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1423,10 +1437,12 @@ medusaIntegrationTestRunner({
|
||||
title: "Test Giftcard",
|
||||
is_giftcard: true,
|
||||
description: "test-giftcard-description",
|
||||
options: [{ title: "size", values: ["large"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "large" },
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -2096,11 +2112,13 @@ medusaIntegrationTestRunner({
|
||||
const payload = {
|
||||
title: "Test product - 1",
|
||||
handle: "test-1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Custom inventory 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
manage_inventory: true,
|
||||
options: { size: "l" },
|
||||
inventory_items: [
|
||||
{
|
||||
inventory_item_id: inventoryItem1.id,
|
||||
@@ -2207,10 +2225,12 @@ medusaIntegrationTestRunner({
|
||||
const payload = {
|
||||
title: "Test product - 1",
|
||||
handle: "test-1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Custom inventory 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "l" },
|
||||
manage_inventory: true,
|
||||
inventory_items: [
|
||||
{
|
||||
@@ -2256,10 +2276,12 @@ medusaIntegrationTestRunner({
|
||||
const payload = {
|
||||
title: "Test product - 1",
|
||||
handle: "test-1",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Custom inventory 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "l" },
|
||||
manage_inventory: true,
|
||||
inventory_items: [
|
||||
{
|
||||
@@ -2678,10 +2700,12 @@ medusaIntegrationTestRunner({
|
||||
const payload = {
|
||||
title: baseProduct.title,
|
||||
handle: baseProduct.handle,
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "x" },
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -2708,10 +2732,12 @@ medusaIntegrationTestRunner({
|
||||
title: baseProduct.title,
|
||||
handle: baseProduct.handle,
|
||||
description: "test-product-description",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "x" },
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -2844,30 +2870,6 @@ medusaIntegrationTestRunner({
|
||||
).toEqual("Updated variant")
|
||||
})
|
||||
|
||||
it("removes options not present in update", async () => {
|
||||
const baseVariant = baseProduct.variants[0]
|
||||
const updatedProduct = (
|
||||
await api.post(
|
||||
`/admin/products/${baseProduct.id}/variants/${baseVariant.id}`,
|
||||
{
|
||||
title: "Updated variant",
|
||||
options: {
|
||||
size: "small",
|
||||
},
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
expect(
|
||||
updatedProduct.variants.find((v) => v.id === baseVariant.id).options
|
||||
).toEqual([
|
||||
expect.objectContaining({
|
||||
value: "small",
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it("updates multiple options in the same call", async () => {
|
||||
const baseVariant = baseProduct.variants[0]
|
||||
const updatedProduct = (
|
||||
|
||||
@@ -801,18 +801,24 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "product 1",
|
||||
options: [
|
||||
{ title: "size", values: ["large", "medium", "small"] },
|
||||
],
|
||||
variants: [
|
||||
{
|
||||
title: "variant 1",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "large" },
|
||||
},
|
||||
{
|
||||
title: "variant 2",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "small" },
|
||||
},
|
||||
{
|
||||
title: "variant 3",
|
||||
prices: [{ currency_code: "usd", amount: 100 }],
|
||||
options: { size: "medium" },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -517,12 +517,18 @@ medusaIntegrationTestRunner({
|
||||
;[product3, [variant3]] = await createProducts({
|
||||
title: "product not in price list",
|
||||
status: ProductStatus.PUBLISHED,
|
||||
variants: [{ title: "test variant 3", prices: [] }],
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{ title: "test variant 3", prices: [], options: { size: "large" } },
|
||||
],
|
||||
})
|
||||
;[product4, [variant4]] = await createProducts({
|
||||
title: "draft product",
|
||||
status: ProductStatus.DRAFT,
|
||||
variants: [{ title: "test variant 4", prices: [] }],
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
variants: [
|
||||
{ title: "test variant 4", prices: [], options: { size: "large" } },
|
||||
],
|
||||
})
|
||||
|
||||
const defaultSalesChannel = await createSalesChannel(
|
||||
@@ -1135,10 +1141,17 @@ medusaIntegrationTestRunner({
|
||||
;[product, [variant]] = await createProducts({
|
||||
title: "test product 1",
|
||||
status: ProductStatus.PUBLISHED,
|
||||
options: [{ title: "size", values: ["large"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "test variant 1",
|
||||
prices: [{ amount: 3000, currency_code: "usd" }],
|
||||
prices: [
|
||||
{
|
||||
amount: 3000,
|
||||
currency_code: "usd",
|
||||
options: { size: "large" },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1331,7 +1331,10 @@ medusaIntegrationTestRunner({
|
||||
const product1 = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
{ title: "Test product 1" },
|
||||
{
|
||||
title: "Test product 1",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
@@ -1339,7 +1342,10 @@ medusaIntegrationTestRunner({
|
||||
const product2 = (
|
||||
await api.post(
|
||||
"/admin/products",
|
||||
{ title: "Test product 2" },
|
||||
{
|
||||
title: "Test product 2",
|
||||
options: [{ title: "size", values: ["large", "small"] }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
).data.product
|
||||
|
||||
@@ -30,10 +30,12 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "Test product",
|
||||
options: [{ title: "size", values: ["x", "l"] }],
|
||||
variants: [
|
||||
{
|
||||
title: "Test variant",
|
||||
sku: "test-variant",
|
||||
options: { size: "l" },
|
||||
prices: [
|
||||
{
|
||||
currency_code: "usd",
|
||||
|
||||
@@ -327,6 +327,7 @@ medusaIntegrationTestRunner({
|
||||
"/admin/products",
|
||||
{
|
||||
title: "test name",
|
||||
options: [{ title: "size", values: ["large"] }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user