feat(medusa): Performance improvements of Carts domain (#2648)

**What**

I have created a new method on the cart service which is `addLineItems`, allowing a user to add one or multiple items in an optimized way. Also updated the `generate` method from the line item service which now also accept a object data or a collection of data which. Various places have been optimized and cache support has been added to the price selection strategy.

The overall optimization allows to reach another 9000% improvement in the response time as a median (Creating a cart with 6 items):

|   | Min (ms)  | Median (ms)  | Max (ms)  | Median Improvement (%)
|---|:-:|---|---|---|
| Before optimisation  | 1200  | 9999 | 12698  |  N/A
| After optimisation | 63  | 252  | 500  | 39x
| After re optimisation | 56 | 82  | 399  | 121x
| After including addressed feedback | 65 | 202  | 495  | 49x

FIXES CORE-722
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2022-12-07 14:39:12 +00:00
1 parent 3b2c929408
commit 42d9c7222b
71 files changed
+1204 -439

No files matched your search

@@ -32,9 +32,7 @@ import { RegionServiceMock } from "../__mocks__/region"
}
const productVariantService = {
withTransaction: function () {
return this
},
...ProductVariantServiceMock,
retrieve: (query) => {
if (query === IdMap.getId("test-giftcard")) {
return {
@@ -58,15 +56,25 @@ import { RegionServiceMock } from "../__mocks__/region"
}
},
getRegionPrice: () => 100,
list: jest.fn().mockImplementation(async (selector) => {
return (selector.id || []).map((id) => ({
id,
title: "Test variant",
product: {
title: "Test product",
thumbnail: "",
discountable: false,
is_giftcard: true,
},
}))
}),
}
const pricingService = {
withTransaction: function () {
return this
},
getProductVariantPricingById: () => {
...PricingServiceMock,
getProductVariantsPricing: () => {
return {
calculated_price: 100,
[IdMap.getId("test-giftcard")]: { calculated_price: 100 },
}
},
getProductVariantPricing: () => {
@@ -106,15 +114,17 @@ import { RegionServiceMock } from "../__mocks__/region"
})
expect(lineItemRepository.create).toHaveBeenCalledTimes(1)
expect(lineItemRepository.create).toHaveBeenCalledWith({
variant_id: IdMap.getId("test-variant"),
cart_id: IdMap.getId("test-cart"),
title: "Test product",
description: "Test variant",
thumbnail: "",
unit_price: 100,
quantity: 1,
})
expect(lineItemRepository.create).toHaveBeenCalledWith([
{
variant_id: IdMap.getId("test-variant"),
cart_id: IdMap.getId("test-cart"),
title: "Test product",
description: "Test variant",
thumbnail: "",
unit_price: 100,
quantity: 1,
},
])
})
it("successfully create a line item with price and quantity", async () => {
@@ -126,12 +136,14 @@ import { RegionServiceMock } from "../__mocks__/region"
})
expect(lineItemRepository.create).toHaveBeenCalledTimes(1)
expect(lineItemRepository.create).toHaveBeenCalledWith({
variant_id: IdMap.getId("test-variant"),
cart_id: IdMap.getId("test-cart"),
unit_price: 50,
quantity: 2,
})
expect(lineItemRepository.create).toHaveBeenCalledWith([
{
variant_id: IdMap.getId("test-variant"),
cart_id: IdMap.getId("test-cart"),
unit_price: 50,
quantity: 2,
},
])
})
it("successfully create a line item giftcard", async () => {
@@ -147,8 +159,7 @@ import { RegionServiceMock } from "../__mocks__/region"
})
expect(lineItemRepository.create).toHaveBeenCalledTimes(2)
expect(lineItemRepository.create).toHaveBeenNthCalledWith(
2,
expect(lineItemRepository.create).toHaveBeenNthCalledWith(2, [
expect.objectContaining({
allow_discounts: false,
variant_id: IdMap.getId("test-giftcard"),
@@ -161,8 +172,8 @@ import { RegionServiceMock } from "../__mocks__/region"
is_giftcard: true,
should_merge: true,
metadata: {},
})
)
}),
])
})
})
@@ -190,6 +201,7 @@ import { RegionServiceMock } from "../__mocks__/region"
const lineItemService = new LineItemService({
manager: MockManager,
lineItemRepository,
productVariantService: ProductVariantServiceMock,
})
beforeEach(async () => {
@@ -329,9 +341,7 @@ describe("LineItemService", () => {
}
const productVariantService = {
withTransaction: function () {
return this
},
...ProductVariantServiceMock,
retrieve: (query) => {
if (query === IdMap.getId("test-giftcard")) {
return {
@@ -355,16 +365,26 @@ describe("LineItemService", () => {
}
},
getRegionPrice: () => 100,
list: jest.fn().mockImplementation(async (selector) => {
return (selector.id || []).map((id) => ({
id,
title: "Test variant",
product: {
title: "Test product",
thumbnail: "",
},
}))
}),
}
const pricingService = {
withTransaction: function () {
return this
},
getProductVariantPricingById: () => {
...PricingServiceMock,
getProductVariantsPricing: () => {
return {
calculated_price: 100,
calculated_price_includes_tax: true,
[IdMap.getId("test-variant")]: {
calculated_price: 100,
calculated_price_includes_tax: true,
},
}
},
getProductVariantPricing: () => {
@@ -423,6 +443,41 @@ describe("LineItemService", () => {
}),
})
})
it("successfully create a line item with tax inclusive set to true by passing an object", async () => {
await lineItemService.generate(
{
variantId: IdMap.getId("test-variant"),
quantity: 1,
},
{
region_id: IdMap.getId("test-region"),
}
)
expect(lineItemRepository.create).toHaveBeenCalledTimes(1)
expect(lineItemRepository.create).toHaveBeenCalledWith({
unit_price: 100,
title: "Test product",
description: "Test variant",
thumbnail: "",
variant_id: IdMap.getId("test-variant"),
quantity: 1,
allow_discounts: undefined,
is_giftcard: undefined,
metadata: {},
should_merge: true,
includes_tax: true,
variant: expect.objectContaining({
id: expect.any(String),
product: expect.objectContaining({
thumbnail: "",
title: "Test product",
}),
title: "Test variant",
}),
})
})
})
describe("generate", () => {
const lineItemRepository = MockRepository({
@@ -448,9 +503,7 @@ describe("LineItemService", () => {
}
const productVariantService = {
withTransaction: function () {
return this
},
...ProductVariantServiceMock,
retrieve: (query) => {
if (query === IdMap.getId("test-giftcard")) {
return {
@@ -464,26 +517,30 @@ describe("LineItemService", () => {
},
}
}
return {
id: IdMap.getId("test-variant"),
title: "Test variant",
product: {
title: "Test product",
thumbnail: "",
},
}
},
getRegionPrice: () => 100,
list: jest.fn().mockImplementation(async (selector) => {
return (selector.id || []).map((id) => {
return {
id,
title: "Test variant",
product: {
title: "Test product",
thumbnail: "",
},
}
})
}),
}
const pricingService = {
withTransaction: function () {
return this
},
getProductVariantPricingById: () => {
...PricingServiceMock,
getProductVariantsPricing: () => {
return {
calculated_price: 100,
calculated_price_includes_tax: false,
[IdMap.getId("test-variant")]: {
calculated_price: 100,
calculated_price_includes_tax: false,
},
}
},
getProductVariantPricing: () => {
@@ -542,6 +599,41 @@ describe("LineItemService", () => {
}),
})
})
it("successfully create a line item with tax inclusive set to false by passing an object", async () => {
await lineItemService.generate(
{
variantId: IdMap.getId("test-variant"),
quantity: 1,
},
{
region_id: IdMap.getId("test-region"),
}
)
expect(lineItemRepository.create).toHaveBeenCalledTimes(1)
expect(lineItemRepository.create).toHaveBeenCalledWith({
unit_price: 100,
title: "Test product",
description: "Test variant",
thumbnail: "",
variant_id: IdMap.getId("test-variant"),
quantity: 1,
allow_discounts: undefined,
is_giftcard: undefined,
metadata: {},
should_merge: true,
includes_tax: false,
variant: expect.objectContaining({
id: expect.any(String),
product: expect.objectContaining({
thumbnail: "",
title: "Test product",
}),
title: "Test variant",
}),
})
})
})
describe("clone", () => {