feat(medusa): Continue create product workflow changes (#4473)
This commit is contained in:
committed by
GitHub
parent
edf93d972d
commit
d2a8cf0378
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
|
||||
351
integration-tests/plugins/__tests__/product/admin/index.ts
Normal file
351
integration-tests/plugins/__tests__/product/admin/index.ts
Normal 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,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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:*",
|
||||
|
||||
Reference in New Issue
Block a user