fix(medusa): Default sales channel on product create (#3249)
What: Assign the default sales channel if none is provided while creating a new product. FIXES: CORE-1114 Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
1 parent
10ff72c30a
commit
80452332d8
8 files changed
+409
-702
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(medusa): default sales channel on product create
|
||||||
@@ -1,448 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`/admin/products GET /admin/products returns a list of products with only giftcard in list 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"categories": Array [],
|
|
||||||
"collection": null,
|
|
||||||
"collection_id": null,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"description": "test-giftcard-description",
|
|
||||||
"discountable": false,
|
|
||||||
"external_id": null,
|
|
||||||
"handle": "test-giftcard",
|
|
||||||
"height": null,
|
|
||||||
"hs_code": null,
|
|
||||||
"id": StringMatching /\\^prod_\\*/,
|
|
||||||
"images": Array [],
|
|
||||||
"is_giftcard": true,
|
|
||||||
"length": null,
|
|
||||||
"material": null,
|
|
||||||
"metadata": null,
|
|
||||||
"mid_code": null,
|
|
||||||
"options": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^opt_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"product_id": StringMatching /\\^prod_\\*/,
|
|
||||||
"title": "Denominations",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"origin_country": null,
|
|
||||||
"profile_id": StringMatching /\\^sp_\\*/,
|
|
||||||
"sales_channels": Array [],
|
|
||||||
"status": "draft",
|
|
||||||
"subtitle": null,
|
|
||||||
"tags": Array [],
|
|
||||||
"thumbnail": null,
|
|
||||||
"title": "Test Giftcard",
|
|
||||||
"type": null,
|
|
||||||
"type_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variants": Array [
|
|
||||||
Object {
|
|
||||||
"allow_backorder": false,
|
|
||||||
"barcode": null,
|
|
||||||
"calculated_price": null,
|
|
||||||
"calculated_price_incl_tax": null,
|
|
||||||
"calculated_tax": null,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"ean": null,
|
|
||||||
"height": null,
|
|
||||||
"hs_code": null,
|
|
||||||
"id": StringMatching /\\^variant_\\*/,
|
|
||||||
"inventory_quantity": 0,
|
|
||||||
"length": null,
|
|
||||||
"manage_inventory": true,
|
|
||||||
"material": null,
|
|
||||||
"metadata": null,
|
|
||||||
"mid_code": null,
|
|
||||||
"options": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^opt_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"option_id": StringMatching /\\^opt_\\*/,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "100",
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"origin_country": null,
|
|
||||||
"original_price": null,
|
|
||||||
"original_price_incl_tax": null,
|
|
||||||
"original_tax": null,
|
|
||||||
"prices": Array [
|
|
||||||
Object {
|
|
||||||
"amount": 100,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "usd",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": Any<String>,
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list": null,
|
|
||||||
"price_list_id": null,
|
|
||||||
"region_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"product_id": StringMatching /\\^prod_\\*/,
|
|
||||||
"sku": null,
|
|
||||||
"tax_rates": null,
|
|
||||||
"title": "Test variant",
|
|
||||||
"upc": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"weight": null,
|
|
||||||
"width": null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"weight": null,
|
|
||||||
"width": null,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`/admin/products POST /admin/products creates a product 1`] = `
|
|
||||||
Object {
|
|
||||||
"categories": Array [],
|
|
||||||
"collection": Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"handle": "test-collection",
|
|
||||||
"id": "test-collection",
|
|
||||||
"metadata": null,
|
|
||||||
"title": "Test collection",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
},
|
|
||||||
"collection_id": "test-collection",
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"description": "test-product-description",
|
|
||||||
"discountable": true,
|
|
||||||
"external_id": null,
|
|
||||||
"handle": "test",
|
|
||||||
"height": null,
|
|
||||||
"hs_code": null,
|
|
||||||
"id": StringMatching /\\^prod_\\*/,
|
|
||||||
"images": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": Any<String>,
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"url": "test-image.png",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": Any<String>,
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"url": "test-image-2.png",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"is_giftcard": false,
|
|
||||||
"length": null,
|
|
||||||
"material": null,
|
|
||||||
"metadata": null,
|
|
||||||
"mid_code": null,
|
|
||||||
"options": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^opt_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"product_id": StringMatching /\\^prod_\\*/,
|
|
||||||
"title": "size",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^opt_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"product_id": StringMatching /\\^prod_\\*/,
|
|
||||||
"title": "color",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"origin_country": null,
|
|
||||||
"profile_id": StringMatching /\\^sp_\\*/,
|
|
||||||
"sales_channels": Array [],
|
|
||||||
"status": "draft",
|
|
||||||
"subtitle": null,
|
|
||||||
"tags": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": Any<String>,
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "123",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": Any<String>,
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "456",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"thumbnail": "test-image.png",
|
|
||||||
"title": "Test",
|
|
||||||
"type": Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": "test-type",
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "test-type",
|
|
||||||
},
|
|
||||||
"type_id": "test-type",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variants": Array [
|
|
||||||
Object {
|
|
||||||
"allow_backorder": false,
|
|
||||||
"barcode": null,
|
|
||||||
"calculated_price": null,
|
|
||||||
"calculated_price_incl_tax": null,
|
|
||||||
"calculated_tax": null,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"ean": null,
|
|
||||||
"height": null,
|
|
||||||
"hs_code": null,
|
|
||||||
"id": StringMatching /\\^variant_\\*/,
|
|
||||||
"inventory_quantity": 10,
|
|
||||||
"length": null,
|
|
||||||
"manage_inventory": true,
|
|
||||||
"material": null,
|
|
||||||
"metadata": null,
|
|
||||||
"mid_code": null,
|
|
||||||
"options": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^optval_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"option_id": StringMatching /\\^opt_\\*/,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "large",
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^optval_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"option_id": StringMatching /\\^opt_\\*/,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "green",
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"origin_country": null,
|
|
||||||
"original_price": null,
|
|
||||||
"original_price_incl_tax": null,
|
|
||||||
"original_tax": null,
|
|
||||||
"prices": Array [
|
|
||||||
Object {
|
|
||||||
"amount": 100,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "usd",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^ma_\\*/,
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list": null,
|
|
||||||
"price_list_id": null,
|
|
||||||
"region_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"amount": 45,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "eur",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^ma_\\*/,
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list": null,
|
|
||||||
"price_list_id": null,
|
|
||||||
"region_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"amount": 30,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "dkk",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^ma_\\*/,
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list": null,
|
|
||||||
"price_list_id": null,
|
|
||||||
"region_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": StringMatching /\\^variant_\\*/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"product_id": StringMatching /\\^prod_\\*/,
|
|
||||||
"sku": null,
|
|
||||||
"tax_rates": null,
|
|
||||||
"title": "Test variant",
|
|
||||||
"upc": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"weight": null,
|
|
||||||
"width": null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"weight": null,
|
|
||||||
"width": null,
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`/admin/products POST /admin/products updates a product (update prices, tags, update status, delete collection, delete type, replaces images) 1`] = `
|
|
||||||
Object {
|
|
||||||
"categories": Array [],
|
|
||||||
"collection": null,
|
|
||||||
"collection_id": null,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"description": "test-product-description",
|
|
||||||
"discountable": true,
|
|
||||||
"external_id": null,
|
|
||||||
"handle": "test-product",
|
|
||||||
"height": null,
|
|
||||||
"hs_code": null,
|
|
||||||
"id": "test-product",
|
|
||||||
"images": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^img_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"url": "test-image-2.png",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"is_giftcard": false,
|
|
||||||
"length": null,
|
|
||||||
"material": null,
|
|
||||||
"metadata": null,
|
|
||||||
"mid_code": null,
|
|
||||||
"options": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": "test-option",
|
|
||||||
"metadata": null,
|
|
||||||
"product_id": "test-product",
|
|
||||||
"title": "test-option",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"origin_country": null,
|
|
||||||
"profile_id": StringMatching /\\^sp_\\*/,
|
|
||||||
"sales_channels": Array [],
|
|
||||||
"status": "published",
|
|
||||||
"subtitle": null,
|
|
||||||
"tags": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": "tag1",
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "123",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"thumbnail": "test-image-2.png",
|
|
||||||
"title": "Test product",
|
|
||||||
"type": Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": StringMatching /\\^ptyp_\\*/,
|
|
||||||
"metadata": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "test-type-2",
|
|
||||||
},
|
|
||||||
"type_id": StringMatching /\\^ptyp_\\*/,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variants": Array [
|
|
||||||
Object {
|
|
||||||
"allow_backorder": false,
|
|
||||||
"barcode": "test-barcode",
|
|
||||||
"calculated_price": null,
|
|
||||||
"calculated_price_incl_tax": null,
|
|
||||||
"calculated_tax": null,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"ean": "test-ean",
|
|
||||||
"height": null,
|
|
||||||
"hs_code": null,
|
|
||||||
"id": "test-variant",
|
|
||||||
"inventory_quantity": 10,
|
|
||||||
"length": null,
|
|
||||||
"manage_inventory": true,
|
|
||||||
"material": null,
|
|
||||||
"metadata": null,
|
|
||||||
"mid_code": null,
|
|
||||||
"options": Array [
|
|
||||||
Object {
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": "test-variant-option",
|
|
||||||
"metadata": null,
|
|
||||||
"option_id": "test-option",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"value": "Default variant",
|
|
||||||
"variant_id": "test-variant",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"origin_country": null,
|
|
||||||
"original_price": null,
|
|
||||||
"original_price_incl_tax": null,
|
|
||||||
"original_tax": null,
|
|
||||||
"prices": Array [
|
|
||||||
Object {
|
|
||||||
"amount": 75,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "usd",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": "test-price",
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list": null,
|
|
||||||
"price_list_id": null,
|
|
||||||
"region_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": "test-variant",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"product_id": "test-product",
|
|
||||||
"sku": "test-sku",
|
|
||||||
"tax_rates": null,
|
|
||||||
"title": "Test variant",
|
|
||||||
"upc": "test-upc",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"weight": null,
|
|
||||||
"width": null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"weight": null,
|
|
||||||
"width": null,
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@@ -20,6 +20,7 @@ const {
|
|||||||
simpleProductFactory,
|
simpleProductFactory,
|
||||||
simpleDiscountFactory,
|
simpleDiscountFactory,
|
||||||
simpleProductCategoryFactory,
|
simpleProductCategoryFactory,
|
||||||
|
simpleSalesChannelFactory,
|
||||||
simpleRegionFactory,
|
simpleRegionFactory,
|
||||||
} = require("../../factories")
|
} = require("../../factories")
|
||||||
const { DiscountRuleType, AllocationType } = require("@medusajs/medusa/dist")
|
const { DiscountRuleType, AllocationType } = require("@medusajs/medusa/dist")
|
||||||
@@ -59,6 +60,12 @@ describe("/admin/products", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
|
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -686,55 +693,57 @@ describe("/admin/products", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
expect(response.data.products).toMatchSnapshot([
|
expect(response.data.products).toEqual(
|
||||||
{
|
expect.arrayContaining([
|
||||||
title: "Test Giftcard",
|
expect.objectContaining({
|
||||||
id: expect.stringMatching(/^prod_*/),
|
title: "Test Giftcard",
|
||||||
is_giftcard: true,
|
id: expect.stringMatching(/^prod_*/),
|
||||||
description: "test-giftcard-description",
|
is_giftcard: true,
|
||||||
profile_id: expect.stringMatching(/^sp_*/),
|
description: "test-giftcard-description",
|
||||||
options: [
|
profile_id: expect.stringMatching(/^sp_*/),
|
||||||
{
|
options: expect.arrayContaining([
|
||||||
title: "Denominations",
|
expect.objectContaining({
|
||||||
id: expect.stringMatching(/^opt_*/),
|
title: "Denominations",
|
||||||
product_id: expect.stringMatching(/^prod_*/),
|
id: expect.stringMatching(/^opt_*/),
|
||||||
created_at: expect.any(String),
|
product_id: expect.stringMatching(/^prod_*/),
|
||||||
updated_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
},
|
updated_at: expect.any(String),
|
||||||
],
|
}),
|
||||||
|
]),
|
||||||
|
|
||||||
variants: [
|
variants: expect.arrayContaining([
|
||||||
{
|
expect.objectContaining({
|
||||||
title: "Test variant",
|
title: "Test variant",
|
||||||
id: expect.stringMatching(/^variant_*/),
|
id: expect.stringMatching(/^variant_*/),
|
||||||
product_id: expect.stringMatching(/^prod_*/),
|
product_id: expect.stringMatching(/^prod_*/),
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
prices: [
|
prices: expect.arrayContaining([
|
||||||
{
|
expect.objectContaining({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
currency_code: "usd",
|
currency_code: "usd",
|
||||||
amount: 100,
|
amount: 100,
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
variant_id: expect.stringMatching(/^variant_*/),
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
}),
|
||||||
],
|
]),
|
||||||
options: [
|
options: expect.arrayContaining([
|
||||||
{
|
expect.objectContaining({
|
||||||
id: expect.stringMatching(/^opt_*/),
|
id: expect.stringMatching(/^opt_*/),
|
||||||
option_id: expect.stringMatching(/^opt_*/),
|
option_id: expect.stringMatching(/^opt_*/),
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
variant_id: expect.stringMatching(/^variant_*/),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
}),
|
||||||
],
|
]),
|
||||||
},
|
}),
|
||||||
],
|
]),
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
}),
|
||||||
])
|
])
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns a list of products not containing a giftcard in list", async () => {
|
it("returns a list of products not containing a giftcard in list", async () => {
|
||||||
@@ -1029,6 +1038,12 @@ describe("/admin/products", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
|
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -1077,126 +1092,128 @@ describe("/admin/products", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
expect(response.data.product).toMatchSnapshot({
|
expect(response.data.product).toEqual(
|
||||||
id: expect.stringMatching(/^prod_*/),
|
expect.objectContaining({
|
||||||
title: "Test",
|
id: expect.stringMatching(/^prod_*/),
|
||||||
discountable: true,
|
title: "Test",
|
||||||
is_giftcard: false,
|
discountable: true,
|
||||||
handle: "test",
|
is_giftcard: false,
|
||||||
status: "draft",
|
handle: "test",
|
||||||
created_at: expect.any(String),
|
status: "draft",
|
||||||
updated_at: expect.any(String),
|
|
||||||
profile_id: expect.stringMatching(/^sp_*/),
|
|
||||||
images: [
|
|
||||||
{
|
|
||||||
id: expect.any(String),
|
|
||||||
url: "test-image.png",
|
|
||||||
created_at: expect.any(String),
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: expect.any(String),
|
|
||||||
url: "test-image-2.png",
|
|
||||||
created_at: expect.any(String),
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
thumbnail: "test-image.png",
|
|
||||||
tags: [
|
|
||||||
{
|
|
||||||
id: expect.any(String),
|
|
||||||
value: "123",
|
|
||||||
created_at: expect.any(String),
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: expect.any(String),
|
|
||||||
value: "456",
|
|
||||||
created_at: expect.any(String),
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: {
|
|
||||||
value: "test-type",
|
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
profile_id: expect.stringMatching(/^sp_*/),
|
||||||
collection: {
|
images: expect.arrayContaining([
|
||||||
id: "test-collection",
|
expect.objectContaining({
|
||||||
title: "Test collection",
|
id: expect.any(String),
|
||||||
created_at: expect.any(String),
|
url: "test-image.png",
|
||||||
updated_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
},
|
updated_at: expect.any(String),
|
||||||
options: [
|
}),
|
||||||
{
|
expect.objectContaining({
|
||||||
id: expect.stringMatching(/^opt_*/),
|
id: expect.any(String),
|
||||||
product_id: expect.stringMatching(/^prod_*/),
|
url: "test-image-2.png",
|
||||||
title: "size",
|
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),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
}),
|
||||||
{
|
collection: expect.objectContaining({
|
||||||
id: expect.stringMatching(/^opt_*/),
|
id: "test-collection",
|
||||||
product_id: expect.stringMatching(/^prod_*/),
|
title: "Test collection",
|
||||||
title: "color",
|
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
}),
|
||||||
],
|
options: expect.arrayContaining([
|
||||||
variants: [
|
expect.objectContaining({
|
||||||
{
|
id: expect.stringMatching(/^opt_*/),
|
||||||
id: expect.stringMatching(/^variant_*/),
|
product_id: expect.stringMatching(/^prod_*/),
|
||||||
product_id: expect.stringMatching(/^prod_*/),
|
title: "size",
|
||||||
updated_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
created_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
title: "Test variant",
|
}),
|
||||||
prices: [
|
expect.objectContaining({
|
||||||
{
|
id: expect.stringMatching(/^opt_*/),
|
||||||
id: expect.stringMatching(/^ma_*/),
|
product_id: expect.stringMatching(/^prod_*/),
|
||||||
currency_code: "usd",
|
title: "color",
|
||||||
amount: 100,
|
created_at: expect.any(String),
|
||||||
created_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
}),
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
]),
|
||||||
},
|
variants: expect.arrayContaining([
|
||||||
{
|
expect.objectContaining({
|
||||||
id: expect.stringMatching(/^ma_*/),
|
id: expect.stringMatching(/^variant_*/),
|
||||||
currency_code: "eur",
|
product_id: expect.stringMatching(/^prod_*/),
|
||||||
amount: 45,
|
updated_at: expect.any(String),
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
title: "Test variant",
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
prices: expect.arrayContaining([
|
||||||
},
|
expect.objectContaining({
|
||||||
{
|
id: expect.stringMatching(/^ma_*/),
|
||||||
id: expect.stringMatching(/^ma_*/),
|
currency_code: "usd",
|
||||||
currency_code: "dkk",
|
amount: 100,
|
||||||
amount: 30,
|
created_at: expect.any(String),
|
||||||
created_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
variant_id: expect.stringMatching(/^variant_*/),
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
}),
|
||||||
},
|
expect.objectContaining({
|
||||||
],
|
id: expect.stringMatching(/^ma_*/),
|
||||||
options: [
|
currency_code: "eur",
|
||||||
{
|
amount: 45,
|
||||||
value: "large",
|
created_at: expect.any(String),
|
||||||
created_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
variant_id: expect.stringMatching(/^variant_*/),
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
}),
|
||||||
option_id: expect.stringMatching(/^opt_*/),
|
expect.objectContaining({
|
||||||
id: expect.stringMatching(/^optval_*/),
|
id: expect.stringMatching(/^ma_*/),
|
||||||
},
|
currency_code: "dkk",
|
||||||
{
|
amount: 30,
|
||||||
value: "green",
|
created_at: expect.any(String),
|
||||||
created_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
updated_at: expect.any(String),
|
variant_id: expect.stringMatching(/^variant_*/),
|
||||||
variant_id: expect.stringMatching(/^variant_*/),
|
}),
|
||||||
option_id: expect.stringMatching(/^opt_*/),
|
]),
|
||||||
id: expect.stringMatching(/^optval_*/),
|
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("creates a product that is not discountable", async () => {
|
it("creates a product that is not discountable", async () => {
|
||||||
@@ -1356,92 +1373,94 @@ describe("/admin/products", () => {
|
|||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
|
|
||||||
expect(response.data.product).toMatchSnapshot({
|
expect(response.data.product).toEqual(
|
||||||
id: "test-product",
|
expect.objectContaining({
|
||||||
created_at: expect.any(String),
|
id: "test-product",
|
||||||
description: "test-product-description",
|
|
||||||
discountable: true,
|
|
||||||
handle: "test-product",
|
|
||||||
images: [
|
|
||||||
{
|
|
||||||
created_at: expect.any(String),
|
|
||||||
deleted_at: null,
|
|
||||||
id: expect.stringMatching(/^img_*/),
|
|
||||||
metadata: null,
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
url: "test-image-2.png",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
is_giftcard: false,
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
created_at: expect.any(String),
|
|
||||||
id: "test-option",
|
|
||||||
product_id: "test-product",
|
|
||||||
title: "test-option",
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
profile_id: expect.stringMatching(/^sp_*/),
|
|
||||||
status: "published",
|
|
||||||
tags: [
|
|
||||||
{
|
|
||||||
created_at: expect.any(String),
|
|
||||||
id: "tag1",
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
value: "123",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
thumbnail: "test-image-2.png",
|
|
||||||
title: "Test product",
|
|
||||||
type: {
|
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
id: expect.stringMatching(/^ptyp_*/),
|
description: "test-product-description",
|
||||||
updated_at: expect.any(String),
|
discountable: true,
|
||||||
value: "test-type-2",
|
handle: "test-product",
|
||||||
},
|
images: expect.arrayContaining([
|
||||||
type_id: expect.stringMatching(/^ptyp_*/),
|
expect.objectContaining({
|
||||||
updated_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
variants: [
|
deleted_at: null,
|
||||||
{
|
id: expect.stringMatching(/^img_*/),
|
||||||
allow_backorder: false,
|
metadata: null,
|
||||||
barcode: "test-barcode",
|
updated_at: expect.any(String),
|
||||||
|
url: "test-image-2.png",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
is_giftcard: false,
|
||||||
|
options: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
created_at: expect.any(String),
|
||||||
|
id: "test-option",
|
||||||
|
product_id: "test-product",
|
||||||
|
title: "test-option",
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
profile_id: expect.stringMatching(/^sp_*/),
|
||||||
|
status: "published",
|
||||||
|
tags: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
created_at: expect.any(String),
|
||||||
|
id: "tag1",
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
value: "123",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
thumbnail: "test-image-2.png",
|
||||||
|
title: "Test product",
|
||||||
|
type: expect.objectContaining({
|
||||||
created_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
ean: "test-ean",
|
id: expect.stringMatching(/^ptyp_*/),
|
||||||
id: "test-variant",
|
|
||||||
inventory_quantity: 10,
|
|
||||||
manage_inventory: true,
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
created_at: expect.any(String),
|
|
||||||
deleted_at: null,
|
|
||||||
id: "test-variant-option",
|
|
||||||
metadata: null,
|
|
||||||
option_id: "test-option",
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
value: "Default variant",
|
|
||||||
variant_id: "test-variant",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
origin_country: null,
|
|
||||||
prices: [
|
|
||||||
{
|
|
||||||
amount: 75,
|
|
||||||
created_at: expect.any(String),
|
|
||||||
currency_code: "usd",
|
|
||||||
id: "test-price",
|
|
||||||
updated_at: expect.any(String),
|
|
||||||
variant_id: "test-variant",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
product_id: "test-product",
|
|
||||||
sku: "test-sku",
|
|
||||||
title: "Test variant",
|
|
||||||
upc: "test-upc",
|
|
||||||
updated_at: expect.any(String),
|
updated_at: expect.any(String),
|
||||||
},
|
value: "test-type-2",
|
||||||
],
|
}),
|
||||||
})
|
type_id: expect.stringMatching(/^ptyp_*/),
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
variants: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
allow_backorder: false,
|
||||||
|
barcode: "test-barcode",
|
||||||
|
created_at: expect.any(String),
|
||||||
|
ean: "test-ean",
|
||||||
|
id: "test-variant",
|
||||||
|
inventory_quantity: 10,
|
||||||
|
manage_inventory: true,
|
||||||
|
options: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
created_at: expect.any(String),
|
||||||
|
deleted_at: null,
|
||||||
|
id: "test-variant-option",
|
||||||
|
metadata: null,
|
||||||
|
option_id: "test-option",
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
value: "Default variant",
|
||||||
|
variant_id: "test-variant",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
origin_country: null,
|
||||||
|
prices: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
amount: 75,
|
||||||
|
created_at: expect.any(String),
|
||||||
|
currency_code: "usd",
|
||||||
|
id: "test-price",
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
variant_id: "test-variant",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
product_id: "test-product",
|
||||||
|
sku: "test-sku",
|
||||||
|
title: "Test variant",
|
||||||
|
upc: "test-upc",
|
||||||
|
updated_at: expect.any(String),
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("updates product (removes images when empty array included)", async () => {
|
it("updates product (removes images when empty array included)", async () => {
|
||||||
@@ -1813,6 +1832,11 @@ describe("/admin/products", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -1859,6 +1883,11 @@ describe("/admin/products", () => {
|
|||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
await priceListSeeder(dbConnection)
|
await priceListSeeder(dbConnection)
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -2326,6 +2355,11 @@ describe("/admin/products", () => {
|
|||||||
try {
|
try {
|
||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
throw err
|
throw err
|
||||||
@@ -2398,6 +2432,11 @@ describe("/admin/products", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -2871,6 +2910,11 @@ describe("/admin/products", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await productSeeder(dbConnection)
|
await productSeeder(dbConnection)
|
||||||
await adminSeeder(dbConnection)
|
await adminSeeder(dbConnection)
|
||||||
|
await simpleSalesChannelFactory(dbConnection, {
|
||||||
|
name: "Default channel",
|
||||||
|
id: "default-channel",
|
||||||
|
is_default: true,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
|||||||
@@ -850,6 +850,7 @@ describe("sales channels", () => {
|
|||||||
salesChannel = await simpleSalesChannelFactory(dbConnection, {
|
salesChannel = await simpleSalesChannelFactory(dbConnection, {
|
||||||
name: "test name",
|
name: "test name",
|
||||||
description: "test description",
|
description: "test description",
|
||||||
|
is_default: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -899,6 +900,47 @@ describe("sales channels", () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should assign the default sales channel to a product if none is provided when creating it", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
title: "Product-no-saleschannel",
|
||||||
|
description: "test-product-description",
|
||||||
|
type: { value: "test-type" },
|
||||||
|
options: [{ title: "size" }],
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
title: "Test variant",
|
||||||
|
inventory_quantity: 10,
|
||||||
|
prices: [{ currency_code: "usd", amount: 100 }],
|
||||||
|
options: [{ value: "large" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.post("/admin/products", payload, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.product).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
sales_channels: [
|
||||||
|
expect.objectContaining({
|
||||||
|
id: salesChannel.id,
|
||||||
|
name: salesChannel.name,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("POST /admin/products/:id", () => {
|
describe("POST /admin/products/:id", () => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { request } from "../../../../../helpers/test-request"
|
|||||||
import { ProductServiceMock } from "../../../../../services/__mocks__/product"
|
import { ProductServiceMock } from "../../../../../services/__mocks__/product"
|
||||||
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
import { ProductVariantServiceMock } from "../../../../../services/__mocks__/product-variant"
|
||||||
import { ShippingProfileServiceMock } from "../../../../../services/__mocks__/shipping-profile"
|
import { ShippingProfileServiceMock } from "../../../../../services/__mocks__/shipping-profile"
|
||||||
|
import { SalesChannelServiceMock } from "../../../../../services/__mocks__/sales-channel"
|
||||||
|
|
||||||
describe("POST /admin/products", () => {
|
describe("POST /admin/products", () => {
|
||||||
describe("successful creation with variants", () => {
|
describe("successful creation with variants", () => {
|
||||||
@@ -46,6 +47,7 @@ describe("POST /admin/products", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("returns 200", () => {
|
it("returns 200", () => {
|
||||||
|
expect(SalesChannelServiceMock.retrieveDefault).toHaveBeenCalledTimes(1)
|
||||||
expect(subject.status).toEqual(200)
|
expect(subject.status).toEqual(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -114,6 +116,13 @@ describe("POST /admin/products", () => {
|
|||||||
is_giftcard: false,
|
is_giftcard: false,
|
||||||
options: [{ title: "Denominations" }],
|
options: [{ title: "Denominations" }],
|
||||||
profile_id: IdMap.getId("default_shipping_profile"),
|
profile_id: IdMap.getId("default_shipping_profile"),
|
||||||
|
sales_channels: [
|
||||||
|
{
|
||||||
|
description: "sales channel 1 description",
|
||||||
|
is_disabled: false,
|
||||||
|
name: "sales channel 1 name",
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -173,6 +182,13 @@ describe("POST /admin/products", () => {
|
|||||||
is_giftcard: true,
|
is_giftcard: true,
|
||||||
status: "draft",
|
status: "draft",
|
||||||
profile_id: IdMap.getId("giftCardProfile"),
|
profile_id: IdMap.getId("giftCardProfile"),
|
||||||
|
sales_channels: [
|
||||||
|
{
|
||||||
|
description: "sales channel 1 description",
|
||||||
|
is_disabled: false,
|
||||||
|
name: "sales channel 1 name",
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
ProductService,
|
ProductService,
|
||||||
ProductVariantInventoryService,
|
ProductVariantInventoryService,
|
||||||
ProductVariantService,
|
ProductVariantService,
|
||||||
|
SalesChannelService,
|
||||||
ShippingProfileService,
|
ShippingProfileService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
import {
|
import {
|
||||||
@@ -121,6 +122,10 @@ export default async (req, res) => {
|
|||||||
const inventoryService: IInventoryService | undefined =
|
const inventoryService: IInventoryService | undefined =
|
||||||
req.scope.resolve("inventoryService")
|
req.scope.resolve("inventoryService")
|
||||||
|
|
||||||
|
const salesChannelService: SalesChannelService = req.scope.resolve(
|
||||||
|
"salesChannelService"
|
||||||
|
)
|
||||||
|
|
||||||
const entityManager: EntityManager = req.scope.resolve("manager")
|
const entityManager: EntityManager = req.scope.resolve("manager")
|
||||||
|
|
||||||
const newProduct = await entityManager.transaction(async (manager) => {
|
const newProduct = await entityManager.transaction(async (manager) => {
|
||||||
@@ -143,6 +148,14 @@ export default async (req, res) => {
|
|||||||
.retrieveDefault()
|
.retrieveDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no sales channel available, set the default one
|
||||||
|
if (!validated?.sales_channels?.length) {
|
||||||
|
const defaultSalesChannel = await salesChannelService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.retrieveDefault()
|
||||||
|
validated.sales_channels = [defaultSalesChannel]
|
||||||
|
}
|
||||||
|
|
||||||
const newProduct = await productService
|
const newProduct = await productService
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.create({ ...validated, profile_id: shippingProfile.id })
|
.create({ ...validated, profile_id: shippingProfile.id })
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { IdMap } from "medusa-test-utils";
|
import { IdMap } from "medusa-test-utils"
|
||||||
|
|
||||||
export const SalesChannelServiceMock = {
|
export const SalesChannelServiceMock = {
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
@@ -19,12 +19,14 @@ export const SalesChannelServiceMock = {
|
|||||||
|
|
||||||
listAndCount: jest.fn().mockImplementation(() => {
|
listAndCount: jest.fn().mockImplementation(() => {
|
||||||
return Promise.resolve([
|
return Promise.resolve([
|
||||||
[{
|
[
|
||||||
id: IdMap.getId("sales_channel_1"),
|
{
|
||||||
name: "sales channel 1 name",
|
id: IdMap.getId("sales_channel_1"),
|
||||||
description: "sales channel 1 description",
|
name: "sales channel 1 name",
|
||||||
is_disabled: false,
|
description: "sales channel 1 description",
|
||||||
}],
|
is_disabled: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
1,
|
1,
|
||||||
])
|
])
|
||||||
}),
|
}),
|
||||||
@@ -48,6 +50,14 @@ export const SalesChannelServiceMock = {
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
retrieveDefault: jest.fn().mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
name: "sales channel 1 name",
|
||||||
|
description: "sales channel 1 description",
|
||||||
|
is_disabled: false,
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
|
||||||
removeProducts: jest.fn().mockImplementation((id, productIds) => {
|
removeProducts: jest.fn().mockImplementation((id, productIds) => {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ class SalesChannelService extends TransactionBaseService {
|
|||||||
this.storeService_ = storeService
|
this.storeService_ = storeService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getManager(): EntityManager {
|
||||||
|
return this.transactionManager_ ?? this.manager_
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic retrieve used to find a sales channel by different attributes.
|
* A generic retrieve used to find a sales channel by different attributes.
|
||||||
*
|
*
|
||||||
@@ -60,7 +64,7 @@ class SalesChannelService extends TransactionBaseService {
|
|||||||
selector: Selector<SalesChannel>,
|
selector: Selector<SalesChannel>,
|
||||||
config: FindConfig<SalesChannel> = {}
|
config: FindConfig<SalesChannel> = {}
|
||||||
): Promise<SalesChannel> {
|
): Promise<SalesChannel> {
|
||||||
const manager = this.manager_
|
const manager = this.getManager()
|
||||||
|
|
||||||
const salesChannelRepo = manager.getCustomRepository(
|
const salesChannelRepo = manager.getCustomRepository(
|
||||||
this.salesChannelRepository_
|
this.salesChannelRepository_
|
||||||
@@ -145,7 +149,7 @@ class SalesChannelService extends TransactionBaseService {
|
|||||||
take: 20,
|
take: 20,
|
||||||
}
|
}
|
||||||
): Promise<[SalesChannel[], number]> {
|
): Promise<[SalesChannel[], number]> {
|
||||||
const manager = this.manager_
|
const manager = this.getManager()
|
||||||
const salesChannelRepo = manager.getCustomRepository(
|
const salesChannelRepo = manager.getCustomRepository(
|
||||||
this.salesChannelRepository_
|
this.salesChannelRepository_
|
||||||
)
|
)
|
||||||
@@ -289,6 +293,27 @@ class SalesChannelService extends TransactionBaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the default sales channel.
|
||||||
|
* @return the sales channel
|
||||||
|
*/
|
||||||
|
async retrieveDefault(): Promise<SalesChannel> {
|
||||||
|
const manager = this.getManager()
|
||||||
|
|
||||||
|
const store = await this.storeService_.withTransaction(manager).retrieve({
|
||||||
|
relations: ["default_sales_channel"],
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!store.default_sales_channel) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`Default Sales channel was not found`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return store.default_sales_channel
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a batch of product from a sales channel
|
* Remove a batch of product from a sales channel
|
||||||
* @param salesChannelId - The id of the sales channel on which to remove the products
|
* @param salesChannelId - The id of the sales channel on which to remove the products
|
||||||
|
|||||||
Reference in new issue
Block a user