feat(medusa): Continue create product workflow changes (#4473)

This commit is contained in:
Adrien de Peretti
2023-07-24 13:30:24 +02:00
committed by GitHub
parent edf93d972d
commit d2a8cf0378
103 changed files with 1859 additions and 524 deletions

View File

@@ -43,7 +43,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -157,7 +159,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,

View File

@@ -12,10 +12,7 @@ const {
DiscountConditionOperator,
} = require("@medusajs/medusa")
const { IdMap } = require("medusa-test-utils")
const {
simpleDiscountFactory,
simpleSalesChannelFactory,
} = require("../../../factories")
const { simpleDiscountFactory } = require("../../../factories")
jest.setTimeout(30000)

View File

@@ -1879,7 +1879,7 @@ describe("/admin/discounts", () => {
const cond = discount.data.discount.rule.conditions[0]
const response = await api.post(
`/admin/discounts/test-discount/conditions/${cond.id}?expand=rule,rule.conditions,rule.conditions.products`,
`/admin/discounts/test-discount/conditions/${cond.id}?expand=rule.conditions.products.profiles`,
{
products: [prod2.id],
},
@@ -1911,6 +1911,8 @@ describe("/admin/discounts", () => {
created_at: expect.any(String),
updated_at: expect.any(String),
profile_id: expect.any(String),
profiles: expect.any(Array),
profile: expect.any(Object),
type_id: expect.any(String),
id: "test-product",
},
@@ -2047,7 +2049,7 @@ describe("/admin/discounts", () => {
const api = useApi()
const discountCondition = await api.get(
"/admin/discounts/test-discount/conditions/test-condition?expand=products&fields=id,type",
"/admin/discounts/test-discount/conditions/test-condition?expand=products.profiles&fields=id,type",
adminReqConfig
)
@@ -2061,6 +2063,8 @@ describe("/admin/discounts", () => {
{
id: "test-product",
profile_id: expect.any(String),
profiles: expect.any(Array),
profile: expect.any(Object),
type_id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
@@ -2353,7 +2357,7 @@ describe("/admin/discounts", () => {
const cond = discount.data.discount.rule.conditions[0]
const response = await api.post(
`/admin/discounts/test-discount/conditions/${cond.id}/batch?expand=rule,rule.conditions,rule.conditions.products`,
`/admin/discounts/test-discount/conditions/${cond.id}/batch?expand=rule.conditions.products.profiles`,
{
resources: [{ id: prod2.id }, { id: prod3.id }],
},
@@ -2490,7 +2494,7 @@ describe("/admin/discounts", () => {
const cond = discount.data.discount.rule.conditions[0]
const response = await api.delete(
`/admin/discounts/test-discount/conditions/${cond.id}/batch?expand=rule,rule.conditions,rule.conditions.products`,
`/admin/discounts/test-discount/conditions/${cond.id}/batch?expand=rule.conditions.products.profiles`,
{
...adminReqConfig,
data: {

View File

@@ -26,9 +26,6 @@ const { IdMap } = require("medusa-test-utils")
jest.setTimeout(50000)
const testProductId = "test-product"
const testProduct1Id = "test-product1"
const testProductFilteringId1 = "test-product_filtering_1"
const adminHeaders = {
headers: {
Authorization: "Bearer test_token",

View File

@@ -28,7 +28,7 @@ describe("/admin/shipping-options", () => {
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd })
medusaProcess = await setupServer({ cwd, verbose: false })
medusaProcess = await setupServer({ cwd })
})
afterAll(async () => {

View File

@@ -25,7 +25,7 @@ describe("/admin/shipping-profiles", () => {
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd })
medusaProcess = await setupServer({ cwd, verbose: false })
medusaProcess = await setupServer({ cwd })
})
afterAll(async () => {

View File

@@ -222,6 +222,7 @@ describe("/store/products", () => {
"tags",
"collection",
"type",
"profiles",
])
})
@@ -992,7 +993,12 @@ describe("/store/products", () => {
it("response contains only fields defined with `fields` param", async () => {
const api = useApi()
const fields = allowedStoreProductsFields
// profile_id is not a column in the products table, so it should be ignored as it
// will be rejected by typeorm as invalid, though, it is an entity property
// that we want to return, so it part of the allowedStoreProductsFields
const fields = allowedStoreProductsFields.filter(
(f) => f !== "profile_id"
)
const response = await api.get(
`/store/products/test-product?fields=${fields.join(",")}`

View File

@@ -91,8 +91,11 @@ export const simpleProductFactory = async (
discountable: !data.is_giftcard,
tags: [] as ProductTag[],
profile_id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id,
profiles: [
{ id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id },
] as ShippingProfile[],
metadata: data.metadata || null,
} as Product
} as unknown as Product
if (typeof data.tags !== "undefined") {
for (let i = 0; i < data.tags.length; i++) {

View File

@@ -52,7 +52,7 @@ export const simpleProductVariantFactory = async (
const options = data.options || [{ option_id: "test-option", value: "Large" }]
for (const o of options) {
await manager.insert(ProductOptionValue, {
id: `${o.value}-${o.option_id ?? Math.random()}`,
id: `${variant.id}-${o.option_id ?? Math.random()}`,
value: o.value,
variant_id: id,
option_id: o.option_id,

View File

@@ -40,13 +40,13 @@ export const simpleShippingOptionFactory = async (
const defaultProfile = await manager.findOne(ShippingProfile, {
where: {
type: ShippingProfileType.DEFAULT,
}
},
})
const gcProfile = await manager.findOne(ShippingProfile, {
where: {
type: ShippingProfileType.GIFT_CARD,
}
},
})
let region_id = data.region_id
@@ -62,7 +62,7 @@ export const simpleShippingOptionFactory = async (
is_return: data.is_return ?? false,
region_id: region_id,
provider_id: "test-ful",
profile_id: data.is_giftcard ? gcProfile.id : defaultProfile.id,
profile_id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id,
price_type: data.price_type ?? ShippingOptionPriceType.FLAT_RATE,
data: data.data ?? {},
requirements: (data.requirements || []) as ShippingOptionRequirement[],

View File

@@ -106,6 +106,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-reg",
title: "Multi Reg Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
status: "published",
collection_id: "test-collection",

View File

@@ -444,14 +444,16 @@ module.exports = async (dataSource, data = {}) => {
await manager.save(priceList1)
await manager.insert(Product, {
const giftCardProduct = manager.create(Product, {
id: "giftcard-product",
title: "Giftcard",
is_giftcard: true,
discountable: false,
profile_id: gcProfile.id,
profiles: [{ id: gcProfile.id }],
options: [{ id: "denom", title: "Denomination" }],
})
await manager.save(Product, giftCardProduct)
await manager.insert(ProductVariant, {
id: "giftcard-denom",
@@ -466,12 +468,14 @@ module.exports = async (dataSource, data = {}) => {
],
})
await manager.insert(Product, {
const testProduct = manager.create(Product, {
id: "test-product",
title: "test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
options: [{ id: "test-option", title: "Size" }],
})
await manager.save(Product, testProduct)
await manager.insert(ProductVariant, {
id: "test-variant-quantity",

View File

@@ -34,6 +34,7 @@ module.exports = async (dataSource, data = {}) => {
id: "test-product",
title: "test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
options: [{ id: "test-option", title: "Size" }],
})
@@ -52,6 +53,7 @@ module.exports = async (dataSource, data = {}) => {
id: "test-product-2",
title: "test product 2",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
options: [{ id: "test-option-color", title: "Color" }],
})

View File

@@ -33,6 +33,7 @@ module.exports = async (dataSource, data = {}) => {
id: "test-product",
title: "test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
options: [{ id: "test-option", title: "Size" }],
})

View File

@@ -238,6 +238,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product",
title: "Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],
@@ -305,6 +306,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-quantity",
title: "Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],
@@ -413,6 +415,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-sale",
title: "Test product sale",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],
@@ -480,6 +483,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-sale-overlap",
title: "Test product sale",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],
@@ -540,6 +544,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-multi-region",
title: "Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-multi-region-description1",
collection_id: "test-collection",
tags: [],
@@ -606,6 +611,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-quantity-customer",
title: "Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],
@@ -713,6 +719,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-sale-customer",
title: "Test product sale",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],
@@ -781,6 +788,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product-sale-customer-quantity",
title: "Test product sale",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
tags: [],

View File

@@ -98,6 +98,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product",
title: "Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
collection_id: "test-collection",
type: { id: "test-type", value: "test-type" },
@@ -215,6 +216,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product1",
title: "Test product1",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description1",
collection_id: "test-collection",
type: { id: "test-type", value: "test-type" },
@@ -283,6 +285,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product_filtering_1",
title: "Test product filtering 1",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
collection_id: "test-collection1",
@@ -297,6 +300,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product_filtering_2",
title: "Test product filtering 2",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
collection_id: "test-collection2",
@@ -311,6 +315,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product_filtering_3",
title: "Test product filtering 3",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
collection_id: "test-collection1",
@@ -325,6 +330,7 @@ module.exports = async (dataSource, data = {}) => {
handle: "test-product_filtering_4",
title: "Test product filtering 4",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
status: "proposed",
deleted_at: new Date().toISOString(),

View File

@@ -130,6 +130,7 @@ module.exports = async (dataSource, defaultSalesChannel) => {
handle: "test-product",
title: "Test product",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
status: "published",
collection_id: "test-collection",
@@ -323,6 +324,7 @@ module.exports = async (dataSource, defaultSalesChannel) => {
handle: "test-product_filtering_1",
title: "Test product filtering 1",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
collection_id: "test-collection1",
@@ -338,6 +340,7 @@ module.exports = async (dataSource, defaultSalesChannel) => {
handle: "test-product_filtering_2",
title: "Test product filtering 2",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
collection_id: "test-collection2",
@@ -353,6 +356,7 @@ module.exports = async (dataSource, defaultSalesChannel) => {
handle: "test-product_filtering_3",
title: "Test product filtering 3",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
collection_id: "test-collection1",
@@ -369,6 +373,7 @@ module.exports = async (dataSource, defaultSalesChannel) => {
is_giftcard: true,
title: "giftcard",
profile_id: defaultProfile.id,
profiles: [{ id: defaultProfile.id }],
description: "test-product-description",
type: { id: "test-type", value: "test-type" },
status: "published",

View File

@@ -83,7 +83,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -240,7 +242,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -395,7 +399,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -515,7 +521,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -693,7 +701,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -861,7 +871,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -1112,7 +1124,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -1361,7 +1375,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -1570,7 +1586,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -1690,7 +1708,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -1868,7 +1888,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -2030,7 +2052,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -2139,7 +2163,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -2255,7 +2281,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,
@@ -2372,7 +2400,9 @@ Object {
"metadata": null,
"mid_code": null,
"origin_country": null,
"profile": Any<Object>,
"profile_id": Any<String>,
"profiles": Any<Array>,
"status": "draft",
"subtitle": null,
"thumbnail": null,

View File

@@ -120,6 +120,8 @@ describe("medusa-plugin-sendgrid", () => {
updated_at: expect.any(Date),
product: {
profile_id: expect.any(String),
profile: expect.any(Object),
profiles: expect.any(Array),
created_at: expect.any(Date),
updated_at: expect.any(Date),
},
@@ -242,6 +244,8 @@ describe("medusa-plugin-sendgrid", () => {
updated_at: expect.any(Date),
product: {
profile_id: expect.any(String),
profile: expect.any(Object),
profiles: expect.any(Array),
created_at: expect.any(Date),
updated_at: expect.any(Date),
},
@@ -303,6 +307,8 @@ describe("medusa-plugin-sendgrid", () => {
updated_at: expect.any(Date),
product: {
profile_id: expect.any(String),
profile: expect.any(Object),
profiles: expect.any(Array),
created_at: expect.any(Date),
updated_at: expect.any(Date),
},
@@ -485,6 +491,8 @@ describe("medusa-plugin-sendgrid", () => {
updated_at: expect.any(Date),
product: {
profile_id: expect.any(String),
profile: expect.any(Object),
profiles: expect.any(Array),
created_at: expect.any(Date),
updated_at: expect.any(Date),
},
@@ -592,6 +600,8 @@ describe("medusa-plugin-sendgrid", () => {
updated_at: expect.any(Date),
product: {
profile_id: expect.any(String),
profile: expect.any(Object),
profiles: expect.any(Array),
created_at: expect.any(Date),
updated_at: expect.any(Date),
},
@@ -780,6 +790,8 @@ const getReturnSnap = (received = false) => {
updated_at: expect.any(Date),
product: {
profile_id: expect.any(String),
profile: expect.any(Object),
profiles: expect.any(Array),
created_at: expect.any(Date),
updated_at: expect.any(Date),
},

View File

@@ -0,0 +1,351 @@
import path from "path"
import { bootstrapApp } from "../../../../environment-helpers/bootstrap-app"
import { setPort, useApi } from "../../../../environment-helpers/use-api"
import { initDb, useDb } from "../../../../environment-helpers/use-db"
import adminSeeder from "../../../../helpers/admin-seeder"
import productSeeder from "../../../../helpers/product-seeder"
import { simpleSalesChannelFactory } from "../../../../factories"
import { AxiosInstance } from "axios"
jest.setTimeout(50000)
const adminHeaders = {
headers: {
Authorization: "Bearer test_token",
},
}
describe("/admin/products", () => {
let medusaProcess
let dbConnection
let express
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
dbConnection = await initDb({ cwd } as any)
const { app, port } = await bootstrapApp({ cwd })
setPort(port)
express = app.listen(port, () => {
process.send?.(port)
})
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
medusaProcess.kill()
})
describe("POST /admin/products", () => {
beforeEach(async () => {
await productSeeder(dbConnection)
await adminSeeder(dbConnection)
await simpleSalesChannelFactory(dbConnection, {
name: "Default channel",
id: "default-channel",
is_default: true,
})
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("should create a product", async () => {
const api = useApi()! as AxiosInstance
const payload = {
title: "Test",
description: "test-product-description",
type: { value: "test-type" },
images: ["test-image.png", "test-image-2.png"],
collection_id: "test-collection",
tags: [{ value: "123" }, { value: "456" }],
options: [{ title: "size" }, { title: "color" }],
variants: [
{
title: "Test variant",
inventory_quantity: 10,
prices: [
{
currency_code: "usd",
amount: 100,
},
{
currency_code: "eur",
amount: 45,
},
{
currency_code: "dkk",
amount: 30,
},
],
options: [{ value: "large" }, { value: "green" }],
},
],
}
const response = await api
.post("/admin/products", payload, adminHeaders)
.catch((err) => {
console.log(err)
})
expect(response?.status).toEqual(200)
expect(response?.data.product).toEqual(
expect.objectContaining({
id: expect.stringMatching(/^prod_*/),
title: "Test",
discountable: true,
is_giftcard: false,
handle: "test",
status: "draft",
created_at: expect.any(String),
updated_at: expect.any(String),
profile_id: expect.stringMatching(/^sp_*/),
images: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
url: "test-image.png",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
expect.objectContaining({
id: expect.any(String),
url: "test-image-2.png",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
]),
thumbnail: "test-image.png",
tags: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: "123",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
expect.objectContaining({
id: expect.any(String),
value: "456",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
]),
type: expect.objectContaining({
value: "test-type",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
collection: expect.objectContaining({
id: "test-collection",
title: "Test collection",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
options: expect.arrayContaining([
expect.objectContaining({
id: expect.stringMatching(/^opt_*/),
product_id: expect.stringMatching(/^prod_*/),
title: "size",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
expect.objectContaining({
id: expect.stringMatching(/^opt_*/),
product_id: expect.stringMatching(/^prod_*/),
title: "color",
created_at: expect.any(String),
updated_at: expect.any(String),
}),
]),
variants: expect.arrayContaining([
expect.objectContaining({
id: expect.stringMatching(/^variant_*/),
product_id: expect.stringMatching(/^prod_*/),
updated_at: expect.any(String),
created_at: expect.any(String),
title: "Test variant",
prices: expect.arrayContaining([
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "usd",
amount: 100,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
}),
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "eur",
amount: 45,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
}),
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "dkk",
amount: 30,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
}),
]),
options: expect.arrayContaining([
expect.objectContaining({
value: "large",
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
option_id: expect.stringMatching(/^opt_*/),
id: expect.stringMatching(/^optval_*/),
}),
expect.objectContaining({
value: "green",
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
option_id: expect.stringMatching(/^opt_*/),
id: expect.stringMatching(/^optval_*/),
}),
]),
}),
]),
})
)
})
it("should create a product that is not discountable", async () => {
const api = useApi()! as AxiosInstance
const payload = {
title: "Test",
discountable: false,
description: "test-product-description",
type: { value: "test-type" },
images: ["test-image.png", "test-image-2.png"],
collection_id: "test-collection",
tags: [{ value: "123" }, { value: "456" }],
options: [{ title: "size" }, { title: "color" }],
variants: [
{
title: "Test variant",
inventory_quantity: 10,
prices: [{ currency_code: "usd", amount: 100 }],
options: [{ value: "large" }, { value: "green" }],
},
],
}
const response = await api
.post("/admin/products", payload, adminHeaders)
.catch((err) => {
console.log(err)
})
expect(response?.status).toEqual(200)
expect(response?.data.product).toEqual(
expect.objectContaining({
discountable: false,
})
)
})
it("should sets the variant ranks when creating a product", async () => {
const api = useApi()! as AxiosInstance
const payload = {
title: "Test product - 1",
description: "test-product-description 1",
type: { value: "test-type 1" },
images: ["test-image.png", "test-image-2.png"],
collection_id: "test-collection",
tags: [{ value: "123" }, { value: "456" }],
options: [{ title: "size" }, { title: "color" }],
variants: [
{
title: "Test variant 1",
inventory_quantity: 10,
prices: [{ currency_code: "usd", amount: 100 }],
options: [{ value: "large" }, { value: "green" }],
},
{
title: "Test variant 2",
inventory_quantity: 10,
prices: [{ currency_code: "usd", amount: 100 }],
options: [{ value: "large" }, { value: "green" }],
},
],
}
const creationResponse = await api
.post("/admin/products", payload, adminHeaders)
.catch((err) => {
console.log(err)
})
expect(creationResponse?.status).toEqual(200)
const productId = creationResponse?.data.product.id
const response = await api
.get(`/admin/products/${productId}`, adminHeaders)
.catch((err) => {
console.log(err)
})
expect(response?.data.product).toEqual(
expect.objectContaining({
title: "Test product - 1",
variants: [
expect.objectContaining({
title: "Test variant 1",
}),
expect.objectContaining({
title: "Test variant 2",
}),
],
})
)
})
it("should create a giftcard", async () => {
const api = useApi()! as AxiosInstance
const payload = {
title: "Test Giftcard",
is_giftcard: true,
description: "test-giftcard-description",
options: [{ title: "Denominations" }],
variants: [
{
title: "Test variant",
prices: [{ currency_code: "usd", amount: 100 }],
options: [{ value: "100" }],
},
],
}
const response = await api
.post("/admin/products", payload, adminHeaders)
.catch((err) => {
console.log(err)
})
expect(response?.status).toEqual(200)
expect(response?.data.product).toEqual(
expect.objectContaining({
title: "Test Giftcard",
discountable: false,
})
)
})
})
})

View File

@@ -2,6 +2,7 @@ const DB_HOST = process.env.DB_HOST
const DB_USERNAME = process.env.DB_USERNAME
const DB_PASSWORD = process.env.DB_PASSWORD
const DB_NAME = process.env.DB_TEMP_NAME
const DB_URL = `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`
module.exports = {
plugins: [
@@ -23,7 +24,7 @@ module.exports = {
],
projectConfig: {
// redis_url: REDIS_URL,
database_url: `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`,
database_url: DB_URL,
database_type: "postgres",
jwt_secret: "test",
cookie_secret: "test",
@@ -44,5 +45,16 @@ module.exports = {
resolve: "@medusajs/cache-inmemory",
options: { ttl: 5 },
},
productModuleService: {
scope: "internal",
resources: "isolated",
resolve: "@medusajs/product",
options: {
database: {
clientUrl: DB_URL,
debug: false,
},
},
},
},
}

View File

@@ -12,6 +12,7 @@
"@medusajs/cache-inmemory": "workspace:*",
"@medusajs/event-bus-local": "workspace:*",
"@medusajs/medusa": "workspace:*",
"@medusajs/product": "workspace:^",
"faker": "^5.5.3",
"medusa-fulfillment-webshipper": "workspace:*",
"medusa-interfaces": "workspace:*",