From 128351a8f0a658add31afb163ec9f74669c775f1 Mon Sep 17 00:00:00 2001 From: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> Date: Wed, 14 Oct 2020 08:28:56 +0200 Subject: [PATCH] hotfix(CartService): Preserve metadata on line-item updates --- .../store/carts/__tests__/update-line-item.js | 48 ++++++++++++++++++- .../routes/store/carts/update-line-item.js | 3 +- .../medusa/src/services/__mocks__/cart.js | 33 +++++++++++++ .../src/services/__mocks__/line-item.js | 40 +++++++++------- packages/medusa/src/services/line-item.js | 5 +- 5 files changed, 108 insertions(+), 21 deletions(-) diff --git a/packages/medusa/src/api/routes/store/carts/__tests__/update-line-item.js b/packages/medusa/src/api/routes/store/carts/__tests__/update-line-item.js index 4816a29e69..018c7054e1 100644 --- a/packages/medusa/src/api/routes/store/carts/__tests__/update-line-item.js +++ b/packages/medusa/src/api/routes/store/carts/__tests__/update-line-item.js @@ -34,7 +34,8 @@ describe("POST /store/carts/:id/line-items/:line_id", () => { expect(LineItemServiceMock.generate).toHaveBeenCalledWith( IdMap.getId("eur-10-us-12"), IdMap.getId("region-france"), - 3 + 3, + {} ) }) @@ -48,6 +49,51 @@ describe("POST /store/carts/:id/line-items/:line_id", () => { }) }) + describe("successfully updates a line item with metadata", () => { + let subject + + beforeAll(async () => { + const cartId = IdMap.getId("cartLineItemMetadata") + const lineId = IdMap.getId("lineWithMetadata") + subject = await request( + "POST", + `/store/carts/${cartId}/line-items/${lineId}`, + { + payload: { + quantity: 3, + }, + } + ) + }) + + afterAll(() => { + jest.clearAllMocks() + }) + + it("calls CartService create", () => { + expect(CartServiceMock.updateLineItem).toHaveBeenCalledTimes(1) + }) + + it("calls LineItemService generate", () => { + expect(LineItemServiceMock.generate).toHaveBeenCalledTimes(1) + expect(LineItemServiceMock.generate).toHaveBeenCalledWith( + IdMap.getId("eur-10-us-12"), + IdMap.getId("region-france"), + 3, + { status: "confirmed" } + ) + }) + + it("returns 200", () => { + expect(subject.status).toEqual(200) + }) + + it("returns the cart", () => { + expect(subject.body.cart._id).toEqual(IdMap.getId("cartLineItemMetadata")) + expect(subject.body.cart.decorated).toEqual(true) + }) + }) + describe("removes line item on quantity 0", () => { let subject diff --git a/packages/medusa/src/api/routes/store/carts/update-line-item.js b/packages/medusa/src/api/routes/store/carts/update-line-item.js index 5db4dcf80a..9c47d4603a 100644 --- a/packages/medusa/src/api/routes/store/carts/update-line-item.js +++ b/packages/medusa/src/api/routes/store/carts/update-line-item.js @@ -34,7 +34,8 @@ export default async (req, res) => { const lineItem = await lineItemService.generate( existing.content.variant._id, cart.region_id, - value.quantity + value.quantity, + existing.metadata || {} ) cart = await cartService.updateLineItem(cart._id, line_id, lineItem) diff --git a/packages/medusa/src/services/__mocks__/cart.js b/packages/medusa/src/services/__mocks__/cart.js index be59dbebbc..3844fa5d45 100644 --- a/packages/medusa/src/services/__mocks__/cart.js +++ b/packages/medusa/src/services/__mocks__/cart.js @@ -184,6 +184,33 @@ export const carts = { }, ], }, + cartWithMetadataLineItem: { + _id: IdMap.getId("cartLineItemMetadata"), + discounts: [], + region_id: IdMap.getId("region-france"), + items: [ + { + _id: IdMap.getId("lineWithMetadata"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: { + unit_price: 10, + variant: { + _id: IdMap.getId("eur-10-us-12"), + }, + product: { + _id: IdMap.getId("product"), + }, + quantity: 1, + }, + quantity: 10, + metadata: { + status: "confirmed", + }, + }, + ], + }, } export const CartServiceMock = { @@ -199,6 +226,9 @@ export const CartServiceMock = { if (cartId === IdMap.getId("fr-cart")) { return Promise.resolve(carts.frCart) } + if (cartId === IdMap.getId("cartLineItemMetadata")) { + return Promise.resolve(carts.cartWithMetadataLineItem) + } if (cartId === IdMap.getId("regionCart")) { return Promise.resolve(carts.regionCart) } @@ -239,6 +269,9 @@ export const CartServiceMock = { if (cartId === IdMap.getId("fr-cart")) { return Promise.resolve(carts.frCart) } + if (cartId === IdMap.getId("cartLineItemMetadata")) { + return Promise.resolve(carts.cartWithMetadataLineItem) + } if (cartId === IdMap.getId("regionCart")) { return Promise.resolve(carts.regionCart) } diff --git a/packages/medusa/src/services/__mocks__/line-item.js b/packages/medusa/src/services/__mocks__/line-item.js index a459e534e2..c0e0822e12 100644 --- a/packages/medusa/src/services/__mocks__/line-item.js +++ b/packages/medusa/src/services/__mocks__/line-item.js @@ -29,25 +29,31 @@ export const LineItemServiceMock = { return false }), - generate: jest.fn().mockImplementation((variantId, regionId, quantity) => { - if (variantId === IdMap.getId("fail") || regionId === IdMap.getId("fail")) { - throw new MedusaError(MedusaError.Types.INVALID_DATA, "Doesn't exist") - } + generate: jest + .fn() + .mockImplementation((variantId, regionId, quantity, metadata = {}) => { + if ( + variantId === IdMap.getId("fail") || + regionId === IdMap.getId("fail") + ) { + throw new MedusaError(MedusaError.Types.INVALID_DATA, "Doesn't exist") + } - return Promise.resolve({ - content: { - variant: { - _id: variantId, + return Promise.resolve({ + content: { + variant: { + _id: variantId, + }, + product: { + _id: `p_${variantId}`, + }, + quantity: 1, + unit_price: 100, }, - product: { - _id: `p_${variantId}`, - }, - quantity: 1, - unit_price: 100, - }, - quantity, - }) - }), + quantity, + metadata, + }) + }), } const mock = jest.fn().mockImplementation(() => { diff --git a/packages/medusa/src/services/line-item.js b/packages/medusa/src/services/line-item.js index 5370d340bf..b7fec039cd 100644 --- a/packages/medusa/src/services/line-item.js +++ b/packages/medusa/src/services/line-item.js @@ -120,12 +120,13 @@ class LineItemService extends BaseService { product, quantity: 1, }, - metadata, + metadata: { + ...metadata, + }, } if (product.is_giftcard) { line.is_giftcard = true - line.metadata = metadata } return line