feat(pricing, types, utils): Exact match based on context + fallback on rule priority if not (#5214)

* initial

* initial service

* update pricing module service

* add integration test for rule-type

* update pricing-module integration tests

* update pricing service interface

* feat(pricing): PriceSets as entry point to pricing module

* chore: add price set money amount

* chore: add price set money amount

* chore: change name of test

* chore: added changeset

* chore: use filterable props from money amount in price sets

* chore: update migrations

* test update integration test

* fix weird behavior

* Update packages/pricing/integration-tests/__fixtures__/rule-type/index.ts

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

* Apply suggestions from code review

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

* move rule-type to common

* chore: reset migration

* chore: remove incorrect conflicts

* chore: address review

* chore: remove ghost price list

* Apply suggestions from code review

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>

* update id prefix

* use persist not persistAndflush

* rename key_value to rule_attribute

* more renaming

* feat(types,pricing): add price set money amount rules to pricing module

* chore: cleanup + add test cases for relationship update

* chore: revert package json

* chore: cleanup

* initial

* update pricing module service

* update pricing-module integration tests

* update pricing service interface

* chore: update migrations

* fix weird behavior

* Apply suggestions from code review

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

* move rule-type to common

* chore: delete duplicate migration files

* fix(link-modules): Fix link module initialization (#4990)

**What**
Add a new configuration on the relationship to specify if the relation is consumed from an internal service (from medusa core). In that case do not check if the service is part of the loaded modules

* initial price rule

* rebase develop

* save here

* final changes to create

* update price rule integration test

* add module integraiton tests for price rules

* fix merge

* redo wierd order change

* pr cleanup

* pr cleanup

* pr cleanup

* update pr

* sort out migrations

* [wip]

* wip

* chore: temporarily emulate mikroorm internals

* currency code hard filtering

* before creating subqueries

* chore: wip

* chore: wip

* chore: add exact match multiple contexts

* chore: add one more test

* chore: add query that works with exact match

* chore: qb the thingy

* chore: add some comments

* chore: removed extra filter

* chore: added some more comments + prettify

* chore: test with carlos

* chore: add fallbacks and exact match tests

* chore: cleanup

* feat(types,pricing): add price set money amount rules to pricing module (#5065)

* initial

* initial service

* update pricing module service

* add integration test for rule-type

* update pricing-module integration tests

* update pricing service interface

* feat(pricing): PriceSets as entry point to pricing module

* chore: add price set money amount

* chore: add price set money amount

* chore: change name of test

* chore: added changeset

* chore: use filterable props from money amount in price sets

* chore: update migrations

* test update integration test

* fix weird behavior

* Update packages/pricing/integration-tests/__fixtures__/rule-type/index.ts

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

* Apply suggestions from code review

Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>

* move rule-type to common

* chore: reset migration

* chore: remove incorrect conflicts

* chore: address review

* chore: remove ghost price list

* Apply suggestions from code review

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>

* update id prefix

* use persist not persistAndflush

* rename key_value to rule_attribute

* more renaming

* feat(types,pricing): add price set money amount rules to pricing module

* chore: cleanup + add test cases for relationship update

* chore: revert package json

* chore: cleanup

---------

Co-authored-by: Philip Korsholm <philip.korsholm@hotmail.com>
Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>

* chore: minor cleanup

* chore: added money amount scoping

* chore: added review comments

* chore: update changset and undo test scoping

* chore: introduce group by util + no queries on empty context

* Feat/pricing module methods (#5218)

chore: add removePrices to pricing module

* Revert "Feat/pricing module methods (#5218)" (#5236)

This reverts commit 95c8aaa66423d290a35b6e736e5b187e12d44a36.

* chore: review changes

* chore: update schema

* chore: reset migration

---------

Co-authored-by: Philip Korsholm <philip.korsholm@hotmail.com>
Co-authored-by: Philip Korsholm <88927411+pKorsholm@users.noreply.github.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
Co-authored-by: Adrien de Peretti <adrien.deperetti@gmail.com>
This commit is contained in:
Riqwan Thamir
2023-09-29 13:23:41 +02:00
committed by GitHub
co-authored by Oli Juhl Philip Korsholm Philip Korsholm Adrien de Peretti
parent dc298acefc
commit 1e7db5a5cb
49 changed files with 2414 additions and 553 deletions
@@ -2,6 +2,8 @@ import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Currency } from "@models"
import { defaultCurrencyData } from "./data"
export * from "./data"
export async function createCurrencies(
manager: SqlEntityManager,
currencyData: any[] = defaultCurrencyData
@@ -2,6 +2,8 @@ import { SqlEntityManager } from "@mikro-orm/postgresql"
import { MoneyAmount } from "@models"
import { defaultMoneyAmountsData } from "./data"
export * from "./data"
export async function createMoneyAmounts(
manager: SqlEntityManager,
moneyAmountsData: any[] = defaultMoneyAmountsData
@@ -1,24 +1,22 @@
import { CreatePriceRuleDTO } from "@medusajs/types"
export * from "./data"
export const defaultPriceRuleData = [
{
id: "price-rule-1",
price_set_id: "price-set-1",
rule_type_id: "rule-type-1",
value: "region_1",
value: "USD",
price_list_id: "test",
price_set_money_amount: {
money_amount: { amount: 100, currency_code: "EUR" },
},
price_set_money_amount_id: "price-set-money-amount-USD",
},
{
id: "price-rule-2",
price_set_id: "price-set-2",
rule_type_id: "rule-type-1",
value: "region_2",
rule_type_id: "rule-type-2",
value: "region_1",
price_list_id: "test",
price_set_money_amount: {
money_amount: { amount: 100, currency_code: "EUR" },
},
price_set_money_amount_id: "price-set-money-amount-EUR",
},
] as unknown as CreatePriceRuleDTO[]
@@ -1,11 +1,11 @@
import { PriceRule, PriceSet, PriceSetMoneyAmount, RuleType } from "@models"
import { PriceRule } from "@models"
import { CreatePriceRuleDTO } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { createMoneyAmounts } from "../money-amount"
import { createRuleTypes } from "../rule-type"
import { defaultPriceRuleData } from "./data"
export * from "./data"
export async function createPriceRules(
manager: SqlEntityManager,
pricesRulesData: CreatePriceRuleDTO[] = defaultPriceRuleData
@@ -13,66 +13,17 @@ export async function createPriceRules(
const priceRules: PriceRule[] = []
for (let priceRuleData of pricesRulesData) {
const priceRuleDataClone = { ...priceRuleData }
const priceRuleDataClone: any = { ...priceRuleData }
if (priceRuleDataClone.price_set_id) {
priceRuleDataClone.price_set = manager.getReference(
PriceSet,
priceRuleDataClone.price_set_id
)
}
priceRuleDataClone.price_set = priceRuleDataClone.price_set_id
let dbRuleType: RuleType | undefined = await manager.findOne(RuleType, {
id: priceRuleDataClone.rule_type_id,
})
if (!dbRuleType) {
const [createdRuleType] = await createRuleTypes(manager, [
{
id: priceRuleDataClone.rule_type_id,
name: "rule 1",
rule_attribute: "region_id",
},
])
dbRuleType = createdRuleType
}
priceRuleDataClone.rule_type = manager.getReference(
RuleType,
dbRuleType!.id
)
priceRuleDataClone.rule_type = priceRuleDataClone.rule_type_id
const priceSetMoneyAmountId =
priceRuleDataClone.price_set_money_amount_id ||
priceRuleDataClone.price_set_money_amount?.id
let psma: PriceSetMoneyAmount = await manager.findOne(PriceSetMoneyAmount, {id: priceSetMoneyAmountId})
if (!psma) {
const [ma] = await createMoneyAmounts(manager, [
priceRuleDataClone.price_set_money_amount.money_amount ?? {
amount: 100,
currency_code: "EUR",
},
])
psma = manager.create(PriceSetMoneyAmount, {
price_set: manager.getReference(
PriceSet,
priceRuleDataClone.price_set.id
),
money_amount: ma.id,
title: "test",
})
await manager.persist(psma).flush()
}
priceRuleDataClone.price_set_money_amount = manager.getReference(
PriceSetMoneyAmount,
psma.id
)
priceRuleDataClone.price_set_money_amount = priceSetMoneyAmountId
const priceRule = manager.create(PriceRule, priceRuleDataClone)
@@ -0,0 +1,20 @@
export const defaultPriceSetMoneyAmountRulesData = [
{
id: "psmar-1",
value: "EUR",
price_set_money_amount: "price-set-money-amount-USD",
rule_type: "rule-type-1",
},
{
id: "psmar-2",
value: "EU",
price_set_money_amount: "price-set-money-amount-EUR",
rule_type: "rule-type-2",
},
{
id: "psmar-3",
value: "CAD",
price_set_money_amount: "price-set-money-amount-CAD",
rule_type: "rule-type-2",
},
]
@@ -0,0 +1,22 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSetMoneyAmountRules } from "@models"
import { defaultPriceSetMoneyAmountRulesData } from "./data"
export * from "./data"
export async function createPriceSetMoneyAmountRules(
manager: SqlEntityManager,
psmarData: any[] = defaultPriceSetMoneyAmountRulesData
): Promise<PriceSetMoneyAmountRules[]> {
const priceSetMoneyAmountRules: PriceSetMoneyAmountRules[] = []
for (let data of psmarData) {
const psmar = manager.create(PriceSetMoneyAmountRules, data)
priceSetMoneyAmountRules.push(psmar)
}
await manager.persistAndFlush(priceSetMoneyAmountRules)
return priceSetMoneyAmountRules
}
@@ -0,0 +1,23 @@
export const defaultPriceSetMoneyAmountsData = [
{
id: "price-set-money-amount-USD",
title: "price set money amount USD",
price_set: "price-set-1",
money_amount: "money-amount-USD",
number_rules: 1,
},
{
id: "price-set-money-amount-EUR",
title: "price set money amount EUR",
price_set: "price-set-2",
money_amount: "money-amount-EUR",
number_rules: 1,
},
{
id: "price-set-money-amount-CAD",
title: "price set money amount CAD",
price_set: "price-set-3",
money_amount: "money-amount-CAD",
number_rules: 1,
},
]
@@ -0,0 +1,22 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSetMoneyAmount } from "@models"
import { defaultPriceSetMoneyAmountsData } from "./data"
export * from "./data"
export async function createPriceSetMoneyAmounts(
manager: SqlEntityManager,
psmaData: any[] = defaultPriceSetMoneyAmountsData
): Promise<PriceSetMoneyAmount[]> {
const priceSetMoneyAmount: PriceSetMoneyAmount[] = []
for (let data of psmaData) {
const psmar = manager.create(PriceSetMoneyAmount, data)
priceSetMoneyAmount.push(psmar)
}
await manager.persistAndFlush(priceSetMoneyAmount)
return priceSetMoneyAmount
}
@@ -3,6 +3,8 @@ import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSet, PriceSetMoneyAmount } from "@models"
import { defaultPriceSetsData } from "./data"
export * from "./data"
export async function createPriceSets(
manager: SqlEntityManager,
priceSetsData: CreatePriceSetDTO[] = defaultPriceSetsData
@@ -2,11 +2,11 @@ export const defaultRuleTypesData = [
{
id: "rule-type-1",
name: "rule 1",
rule_attribute: "region_id",
rule_attribute: "currency_code",
},
{
id: "rule-type-2",
name: "rule 2",
rule_attribute: "currency_code",
rule_attribute: "region_id",
},
]
@@ -1,7 +1,9 @@
import { RuleType } from "@models"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { RuleType } from "@models"
import { defaultRuleTypesData } from "./data"
export * from "./data"
export async function createRuleTypes(
manager: SqlEntityManager,
ruletypesData: any[] = defaultRuleTypesData
@@ -11,9 +13,10 @@ export async function createRuleTypes(
for (let ruleTypeData of ruletypesData) {
const ruleType = manager.create(RuleType, ruleTypeData)
await manager.persistAndFlush(ruleType)
ruleTypes.push(ruleType)
}
await manager.persistAndFlush(ruleTypes)
return ruleTypes
}
@@ -1,15 +1,16 @@
import { PriceSet, PriceSetMoneyAmount } from "@models"
import { PriceSetMoneyAmount } from "@models"
import { CreatePriceRuleDTO } from "@medusajs/types"
import { MikroOrmWrapper } from "../../../utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceRuleRepository } from "@repositories"
import { PriceRuleService } from "@services"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import { createPriceRules } from "../../../__fixtures__/price-rule"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { createPriceSetMoneyAmounts } from "../../../__fixtures__/price-set-money-amount"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
@@ -32,9 +33,10 @@ describe("PriceRule Service", () => {
})
await createCurrencies(testManager)
await createMoneyAmounts(testManager)
await createRuleTypes(testManager)
await createPriceSets(testManager)
await createPriceSetMoneyAmounts(testManager)
await createPriceRules(testManager)
})
@@ -291,11 +293,14 @@ describe("PriceRule Service", () => {
},
])
const psma: PriceSetMoneyAmount = testManager.create(PriceSetMoneyAmount, {
price_set: testManager.getReference(PriceSet, "price-set-1"),
money_amount: ma.id,
title: "test",
})
const psma: PriceSetMoneyAmount = testManager.create(
PriceSetMoneyAmount,
{
price_set: "price-set-1",
money_amount: ma.id,
title: "test",
}
)
await testManager.persist(psma).flush()
@@ -0,0 +1,300 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSetMoneyAmountRulesRepository } from "@repositories"
import { PriceSetMoneyAmountRulesService } from "@services"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { createPriceSetMoneyAmounts } from "../../../__fixtures__/price-set-money-amount"
import { createPriceSetMoneyAmountRules } from "../../../__fixtures__/price-set-money-amount-rules"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
describe("PriceSetMoneyAmountRules Service", () => {
let service: PriceSetMoneyAmountRulesService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
const priceSetMoneyAmountRulesRepository =
new PriceSetMoneyAmountRulesRepository({
manager: repositoryManager,
})
service = new PriceSetMoneyAmountRulesService({
priceSetMoneyAmountRulesRepository,
})
testManager = await MikroOrmWrapper.forkManager()
await createCurrencies(testManager)
await createMoneyAmounts(testManager)
await createPriceSets(testManager)
await createRuleTypes(testManager)
await createPriceSetMoneyAmounts(testManager)
await createPriceSetMoneyAmountRules(testManager)
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("list", () => {
it("should list psmar records", async () => {
const priceSetMoneyAmountRulesResult = await service.list()
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
expect.objectContaining({
id: "psmar-2",
}),
expect.objectContaining({
id: "psmar-3",
}),
])
})
it("should list psmar record by id", async () => {
const priceSetMoneyAmountRulesResult = await service.list({
id: ["psmar-1"],
})
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
])
})
})
describe("listAndCount", () => {
it("should return psmar records and count", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCount()
expect(count).toEqual(3)
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
expect.objectContaining({
id: "psmar-2",
}),
expect.objectContaining({
id: "psmar-3",
}),
])
})
it("should return psmar records and count when filtered", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCount({
id: ["psmar-1"],
})
expect(count).toEqual(1)
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
])
})
it("should return psmar and count when using skip and take", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCount({}, { skip: 1, take: 1 })
expect(count).toEqual(3)
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-2",
}),
])
})
it("should return requested fields", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCount(
{},
{
take: 1,
select: ["value"],
}
)
const serialized = JSON.parse(
JSON.stringify(priceSetMoneyAmountRulesResult)
)
expect(count).toEqual(3)
expect(serialized).toEqual([
{
id: "psmar-1",
value: "EUR",
},
])
})
})
describe("retrieve", () => {
it("should return priceSetMoneyAmountRules for the given id", async () => {
const priceSetMoneyAmountRules = await service.retrieve("psmar-1")
expect(priceSetMoneyAmountRules).toEqual(
expect.objectContaining({
id: "psmar-1",
})
)
})
it("should throw an error when priceSetMoneyAmountRules with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"PriceSetMoneyAmountRules with id: does-not-exist was not found"
)
})
it("should throw an error when an id is not provided", async () => {
let error
try {
await service.retrieve(undefined as unknown as string)
} catch (e) {
error = e
}
expect(error.message).toEqual(
'"priceSetMoneyAmountRulesId" must be defined'
)
})
it("should return priceSetMoneyAmountRules based on config select param", async () => {
const priceSetMoneyAmountRulesResult = await service.retrieve("psmar-1", {
select: ["value"],
})
const serialized = JSON.parse(
JSON.stringify(priceSetMoneyAmountRulesResult)
)
expect(serialized).toEqual({
value: "EUR",
id: "psmar-1",
})
})
})
describe("delete", () => {
const id = "psmar-1"
it("should delete the priceSetMoneyAmountRules given an id successfully", async () => {
await service.delete([id])
const priceSetMoneyAmountRules = await service.list({
id: [id],
})
expect(priceSetMoneyAmountRules).toHaveLength(0)
})
})
describe("update", () => {
const id = "psmar-1"
it("should update the value of the priceSetMoneyAmountRules successfully", async () => {
await service.update([
{
id,
value: "New value",
price_set_money_amount: "price-set-money-amount-CAD",
rule_type: "rule-type-2",
},
])
const psmar = await service.retrieve(id, {
relations: ["price_set_money_amount", "rule_type"],
})
expect(psmar).toEqual(
expect.objectContaining({
id,
value: "New value",
price_set_money_amount: expect.objectContaining({
id: "price-set-money-amount-CAD",
}),
rule_type: expect.objectContaining({
id: "rule-type-2",
}),
})
)
})
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
value: "random value",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'PriceSetMoneyAmountRules with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a priceSetMoneyAmountRules successfully", async () => {
const created = await service.create([
{
price_set_money_amount: "price-set-money-amount-EUR",
rule_type: "rule-type-2",
value: "New priceSetMoneyAmountRule",
},
])
const [priceSetMoneyAmountRules] = await service.list(
{
id: [created[0]?.id],
},
{
relations: ["price_set_money_amount", "rule_type"],
}
)
expect(priceSetMoneyAmountRules).toEqual(
expect.objectContaining({
id: created[0]?.id,
value: "New priceSetMoneyAmountRule",
price_set_money_amount: expect.objectContaining({
id: "price-set-money-amount-EUR",
}),
rule_type: expect.objectContaining({
id: "rule-type-2",
}),
})
)
})
})
})
@@ -0,0 +1,693 @@
import {
CreatePriceRuleDTO,
CreatePriceSetDTO,
IPricingModuleService,
} from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSet } from "@models"
import { initialize } from "../../../../src"
import {
createCurrencies,
defaultCurrencyData,
} from "../../../__fixtures__/currency"
import {
createMoneyAmounts,
defaultMoneyAmountsData,
} from "../../../__fixtures__/money-amount"
import {
createPriceRules,
defaultPriceRuleData,
} from "../../../__fixtures__/price-rule"
import {
createPriceSets,
defaultPriceSetsData,
} from "../../../__fixtures__/price-set"
import {
createPriceSetMoneyAmounts,
defaultPriceSetMoneyAmountsData,
} from "../../../__fixtures__/price-set-money-amount"
import {
createRuleTypes,
defaultRuleTypesData,
} from "../../../__fixtures__/rule-type"
import { DB_URL, MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
async function seedData({
moneyAmountsData = defaultMoneyAmountsData,
priceSetsData = defaultPriceSetsData,
currencyData = defaultCurrencyData,
priceRuleData = defaultPriceRuleData,
priceSetMoneyAmountsData = defaultPriceSetMoneyAmountsData,
ruleTypesData = defaultRuleTypesData,
} = {}) {
const testManager = MikroOrmWrapper.forkManager()
await createCurrencies(testManager, currencyData)
await createMoneyAmounts(testManager, moneyAmountsData)
await createPriceSets(testManager, priceSetsData)
await createPriceSetMoneyAmounts(testManager, priceSetMoneyAmountsData)
await createRuleTypes(testManager, ruleTypesData)
await createPriceRules(testManager, priceRuleData)
}
describe("PricingModule Service - Calculate Price", () => {
let service: IPricingModuleService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let data!: PriceSet[]
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = MikroOrmWrapper.forkManager()
testManager = MikroOrmWrapper.forkManager()
service = await initialize({
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("calculatePrices", () => {
beforeEach(async () => {
const currencyData = [
{
symbol: "zł",
name: "Polish Zloty",
symbol_native: "zł",
code: "PLN",
},
{
symbol: "€",
name: "Euro",
symbol_native: "€",
code: "EUR",
},
]
const moneyAmountsData = [
{
id: "money-amount-currency_code-EUR",
currency_code: "EUR",
amount: 500,
min_quantity: 1,
max_quantity: 10,
},
{
id: "money-amount-currency_code-PLN",
currency_code: "PLN",
amount: 400,
min_quantity: 1,
max_quantity: 5,
},
{
id: "money-amount-region_id-PLN",
currency_code: "PLN",
amount: 300,
min_quantity: 1,
max_quantity: 4,
},
{
id: "money-amount-region_id-PL-EUR",
currency_code: "EUR",
amount: 200,
min_quantity: 1,
max_quantity: 3,
},
{
id: "money-amount-region_id-PL-EUR-4-qty",
currency_code: "EUR",
amount: 50,
min_quantity: 4,
max_quantity: 10,
},
{
id: "money-amount-region_id-PL-EUR-customer-group",
currency_code: "EUR",
amount: 100,
min_quantity: 1,
max_quantity: 3,
},
]
const priceSetsData = [
{
id: "price-set-EUR",
},
{
id: "price-set-PLN",
},
] as unknown as CreatePriceSetDTO[]
const priceSetMoneyAmountsData = [
{
id: "psma-currency_code-EUR",
title: "psma EUR - currency_code",
price_set: "price-set-EUR",
money_amount: "money-amount-currency_code-EUR",
number_rules: 1,
},
{
id: "psma-currency_code-PLN",
title: "psma PLN - currency_code",
price_set: "price-set-PLN",
money_amount: "money-amount-currency_code-PLN",
number_rules: 1,
},
{
id: "psma-region_id-PLN",
title: "psma PLN - region_id",
price_set: "price-set-PLN",
money_amount: "money-amount-region_id-PLN",
number_rules: 1,
},
{
id: "psma-region_id_currency_code-PL-EUR",
title: "psma PLN - region_id PL with EUR currency",
price_set: "price-set-PLN",
money_amount: "money-amount-region_id-PL-EUR",
number_rules: 2,
},
{
id: "psma-region_id_currency_code-PL-EUR-4-qty",
title: "psma PLN - region_id PL with EUR currency for quantity 4",
price_set: "price-set-PLN",
money_amount: "money-amount-region_id-PL-EUR-4-qty",
number_rules: 2,
},
{
id: "psma-region_id_currency_code-PL-EUR-customer-group",
title: "psma PLN - region_id PL with EUR currency for customer group",
price_set: "price-set-PLN",
money_amount: "money-amount-region_id-PL-EUR-customer-group",
number_rules: 3,
},
]
const ruleTypesData = [
{
id: "rule-type-currency_code",
name: "rule type currency code",
rule_attribute: "currency_code",
default_priority: 2,
},
{
id: "rule-type-region_id",
name: "rule type region id",
rule_attribute: "region_id",
default_priority: 1,
},
{
id: "rule-type-customer_group_id",
name: "rule type customer group id",
rule_attribute: "customer_group_id",
default_priority: 3,
},
]
const priceRuleData = [
{
id: "price-rule-currency_code-EUR",
price_set_id: "price-set-EUR",
rule_type_id: "rule-type-currency_code",
value: "EUR",
price_list_id: "test",
price_set_money_amount_id: "psma-currency_code-EUR",
},
{
id: "price-rule-currency_code-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-currency_code",
value: "PLN",
price_list_id: "test",
price_set_money_amount_id: "psma-currency_code-PLN",
},
{
id: "price-rule-region_id-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
value: "PL",
price_list_id: "test",
price_set_money_amount_id: "psma-region_id-PLN",
},
{
id: "price-rule-region_id-currency_code-PL",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
value: "PL",
price_list_id: "test",
price_set_money_amount_id: "psma-region_id_currency_code-PL-EUR",
},
{
id: "price-rule-region_id-currency_code-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-currency_code",
value: "EUR",
price_list_id: "test",
price_set_money_amount_id: "psma-region_id_currency_code-PL-EUR",
},
{
id: "price-rule-region_id-currency_code-PL-4-qty",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
value: "PL",
price_list_id: "test",
price_set_money_amount_id:
"psma-region_id_currency_code-PL-EUR-4-qty",
},
{
id: "price-rule-region_id-currency_code-PLN-4-qty",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-currency_code",
value: "EUR",
price_list_id: "test",
price_set_money_amount_id:
"psma-region_id_currency_code-PL-EUR-4-qty",
},
{
id: "price-rule-region_id-currency_customer_group_code-PL",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-region_id",
value: "PL",
price_list_id: "test",
price_set_money_amount_id:
"psma-region_id_currency_code-PL-EUR-customer-group",
},
{
id: "price-rule-region_id-currency_customer_group_code-PLN",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-currency_code",
value: "EUR",
price_list_id: "test",
price_set_money_amount_id:
"psma-region_id_currency_code-PL-EUR-customer-group",
},
{
id: "price-rule-region_id-currency_customer_group_code-test_customer_group",
price_set_id: "price-set-PLN",
rule_type_id: "rule-type-customer_group_id",
value: "test-customer-group",
price_list_id: "test",
price_set_money_amount_id:
"psma-region_id_currency_code-PL-EUR-customer-group",
},
] as unknown as CreatePriceRuleDTO[]
await seedData({
currencyData,
moneyAmountsData,
priceSetsData,
priceSetMoneyAmountsData,
priceRuleData,
ruleTypesData,
})
})
it("should return null values when no context is set", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
{
id: "price-set-PLN",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("should return filled prices when 1 context is present and price is setup for EUR", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { currency_code: "EUR" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
{
id: "price-set-PLN",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("should return filled prices when 1 context is present and price is setup for PLN region_id", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { region_id: "PL" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
{
id: "price-set-PLN",
amount: "300",
currency_code: "PLN",
min_quantity: "1",
max_quantity: "4",
},
])
})
it("should return filled prices when 1 context is present and price is setup for PLN currency_code", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { currency_code: "PLN" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
{
id: "price-set-PLN",
amount: "400",
currency_code: "PLN",
min_quantity: "1",
max_quantity: "5",
},
])
})
it("should return null prices when 1 context is present and price is NOT setup", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { does_not_exist: "EUR" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
{
id: "price-set-PLN",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("should return filled prices when 2 contexts are present and price is setup", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { currency_code: "EUR", region_id: "PL" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
{
id: "price-set-PLN",
amount: "200",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "3",
},
])
})
it("should return filled prices when 2 contexts are present and price is setup along with declaring quantity", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-PLN"] },
{
context: { currency_code: "EUR", region_id: "PL", quantity: 5 },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-PLN",
amount: "50",
currency_code: "EUR",
min_quantity: "4",
max_quantity: "10",
},
])
})
it("should return filled prices when 3 contexts are present and price is partially setup for 2", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: {
currency_code: "EUR",
region_id: "PL",
customer_group_id: "test",
},
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
{
id: "price-set-PLN",
amount: "200",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "3",
},
])
})
it("should return filled prices when 3 contexts are present and price is setup for 3", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: {
currency_code: "EUR",
region_id: "PL",
customer_group_id: "test-customer-group",
},
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
// Currency Code + Region value + customer group id
{
id: "price-set-PLN",
amount: "100",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "3",
},
])
})
it("should return filled prices when 3 contexts are present and price is setup for 3, but value is incorrect for 1. It falls back to 2 rule context", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: {
currency_code: "EUR",
region_id: "PL",
customer_group_id: "does-not-exist",
},
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
// Currency Code + Region value
{
id: "price-set-PLN",
amount: "200",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "3",
},
])
})
it("should return filled prices when 3 contexts are present and price is setup for 3, but value is incorrect for 2. It falls back to 1 rule context when 1 rule is not setup", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: {
currency_code: "does-not-exist",
region_id: "PL",
customer_group_id: "does-not-exist",
},
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
// PLN price set is not setup for EUR currency_code so it will default to a null set
{
id: "price-set-PLN",
amount: "300",
currency_code: "PLN",
min_quantity: "1",
max_quantity: "4",
},
])
})
it("should return filled prices when 3 contexts are present and price is setup for 3, but value is incorrect for 2. It falls back to 1 rule context when 1 rule is setup", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: {
currency_code: "EUR",
region_id: "does-not-exist",
customer_group_id: "does-not-exist",
},
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
// PLN price set is not setup for EUR currency_code so it will default to a null set
{
id: "price-set-PLN",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("should return null prices when 2 context is present and prices are NOT setup", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { does_not_exist: "EUR", does_not_exist_2: "Berlin" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
{
id: "price-set-PLN",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("should return filled prices when 2 context is present and prices are setup, but only for one of the contexts", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-EUR", "price-set-PLN"] },
{
context: { currency_code: "EUR", does_not_exist: "Berlin" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-EUR",
amount: "500",
currency_code: "EUR",
min_quantity: "1",
max_quantity: "10",
},
{
id: "price-set-PLN",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
})
})
@@ -1,21 +1,20 @@
import { CreatePriceRuleDTO, IPricingModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { PriceSet } from "@models"
import { PriceSetMoneyAmount, initialize } from "../../../../src"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { DB_URL, MikroOrmWrapper } from "../../../utils"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { createPriceRules } from "../../../__fixtures__/price-rule"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { createPriceSetMoneyAmounts } from "../../../__fixtures__/price-set-money-amount"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { DB_URL, MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
describe("PricingModule Service - PriceRule", () => {
let service: IPricingModuleService
let testManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
@@ -29,9 +28,10 @@ describe("PricingModule Service - PriceRule", () => {
})
await createCurrencies(testManager)
await createMoneyAmounts(testManager)
await createRuleTypes(testManager)
await createPriceSets(testManager)
await createPriceSetMoneyAmounts(testManager)
await createPriceRules(testManager)
})
@@ -288,11 +288,14 @@ describe("PricingModule Service - PriceRule", () => {
},
])
const psma: PriceSetMoneyAmount = testManager.create(PriceSetMoneyAmount, {
price_set: testManager.getReference(PriceSet, "price-set-1"),
money_amount: ma.id,
title: "test",
})
const psma: PriceSetMoneyAmount = testManager.create(
PriceSetMoneyAmount,
{
price_set: "price-set-1",
money_amount: ma.id,
title: "test",
}
)
await testManager.persist(psma).flush()
@@ -0,0 +1,291 @@
import { IPricingModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { initialize } from "../../../../src"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import { createPriceSets } from "../../../__fixtures__/price-set"
import { createPriceSetMoneyAmounts } from "../../../__fixtures__/price-set-money-amount"
import { createPriceSetMoneyAmountRules } from "../../../__fixtures__/price-set-money-amount-rules"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { DB_URL, MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
describe("PricingModule Service - PriceSetMoneyAmountRules", () => {
let service: IPricingModuleService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
service = await initialize({
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
testManager = await MikroOrmWrapper.forkManager()
await createCurrencies(testManager)
await createMoneyAmounts(testManager)
await createPriceSets(testManager)
await createRuleTypes(testManager)
await createPriceSetMoneyAmounts(testManager)
await createPriceSetMoneyAmountRules(testManager)
})
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("listPriceSetMoneyAmountRules", () => {
it("should list psmar records", async () => {
const priceSetMoneyAmountRulesResult =
await service.listPriceSetMoneyAmountRules()
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
expect.objectContaining({
id: "psmar-2",
}),
expect.objectContaining({
id: "psmar-3",
}),
])
})
it("should list psmar record by id", async () => {
const priceSetMoneyAmountRulesResult =
await service.listPriceSetMoneyAmountRules({
id: ["psmar-1"],
})
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
])
})
})
describe("listAndCount", () => {
it("should return psmar records and count", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCountPriceSetMoneyAmountRules()
expect(count).toEqual(3)
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
expect.objectContaining({
id: "psmar-2",
}),
expect.objectContaining({
id: "psmar-3",
}),
])
})
it("should return psmar records and count when filtered", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCountPriceSetMoneyAmountRules({
id: ["psmar-1"],
})
expect(count).toEqual(1)
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-1",
}),
])
})
it("should return psmar and count when using skip and take", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCountPriceSetMoneyAmountRules(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(3)
expect(priceSetMoneyAmountRulesResult).toEqual([
expect.objectContaining({
id: "psmar-2",
}),
])
})
it("should return requested fields", async () => {
const [priceSetMoneyAmountRulesResult, count] =
await service.listAndCountPriceSetMoneyAmountRules(
{},
{
take: 1,
select: ["value"],
}
)
const serialized = JSON.parse(
JSON.stringify(priceSetMoneyAmountRulesResult)
)
expect(count).toEqual(3)
expect(serialized).toEqual([
{
id: "psmar-1",
value: "EUR",
},
])
})
})
describe("retrievePriceSetMoneyAmountRules", () => {
it("should return priceSetMoneyAmountRules for the given id", async () => {
const priceSetMoneyAmountRules =
await service.retrievePriceSetMoneyAmountRules("psmar-1")
expect(priceSetMoneyAmountRules).toEqual(
expect.objectContaining({
id: "psmar-1",
})
)
})
it("should throw an error when priceSetMoneyAmountRules with id does not exist", async () => {
let error
try {
await service.retrievePriceSetMoneyAmountRules("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"PriceSetMoneyAmountRules with id: does-not-exist was not found"
)
})
it("should throw an error when an id is not provided", async () => {
let error
try {
await service.retrievePriceSetMoneyAmountRules(
undefined as unknown as string
)
} catch (e) {
error = e
}
expect(error.message).toEqual(
'"priceSetMoneyAmountRulesId" must be defined'
)
})
it("should return priceSetMoneyAmountRules based on config select param", async () => {
const priceSetMoneyAmountRulesResult =
await service.retrievePriceSetMoneyAmountRules("psmar-1", {
select: ["value"],
})
const serialized = JSON.parse(
JSON.stringify(priceSetMoneyAmountRulesResult)
)
expect(serialized).toEqual({
value: "EUR",
id: "psmar-1",
})
})
})
describe("deletePriceSetMoneyAmountRules", () => {
const id = "psmar-1"
it("should delete the priceSetMoneyAmountRuless given an id successfully", async () => {
await service.deletePriceSetMoneyAmountRules([id])
const currencies = await service.listPriceSetMoneyAmountRules({
id: [id],
})
expect(currencies).toHaveLength(0)
})
})
describe("updatePriceSetMoneyAmountRules", () => {
const id = "psmar-1"
it("should update the value of the priceSetMoneyAmountRules successfully", async () => {
await service.updatePriceSetMoneyAmountRules([
{
id,
value: "New value",
},
])
const psmar = await service.retrievePriceSetMoneyAmountRules(id)
expect(psmar.value).toEqual("New value")
})
it("should throw an error when a id does not exist", async () => {
let error
try {
await service.updatePriceSetMoneyAmountRules([
{
id: "does-not-exist",
value: "random value",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'PriceSetMoneyAmountRules with id "does-not-exist" not found'
)
})
})
describe("createPriceSetMoneyAmountRules", () => {
it("should create a priceSetMoneyAmountRules successfully", async () => {
const created = await service.createPriceSetMoneyAmountRules([
{
price_set_money_amount: "price-set-money-amount-EUR",
rule_type: "rule-type-2",
value: "New priceSetMoneyAmountRule",
},
])
const [priceSetMoneyAmountRules] =
await service.listPriceSetMoneyAmountRules(
{
id: [created[0]?.id],
},
{
relations: ["price_set_money_amount", "rule_type"],
}
)
expect(priceSetMoneyAmountRules).toEqual(
expect.objectContaining({
id: created[0]?.id,
value: "New priceSetMoneyAmountRule",
price_set_money_amount: expect.objectContaining({
id: "price-set-money-amount-EUR",
}),
rule_type: expect.objectContaining({
id: "rule-type-2",
}),
})
)
})
})
})
@@ -4,144 +4,62 @@ import { PriceSet } from "@models"
import { initialize } from "../../../../src"
import { createCurrencies } from "../../../__fixtures__/currency"
import { createMoneyAmounts } from "../../../__fixtures__/money-amount"
import {
createMoneyAmounts,
defaultMoneyAmountsData,
} from "../../../__fixtures__/money-amount"
import {
createPriceRules,
defaultPriceRuleData,
} from "../../../__fixtures__/price-rule"
import { createPriceSets } from "../../../__fixtures__/price-set"
import {
createPriceSetMoneyAmounts,
defaultPriceSetMoneyAmountsData,
} from "../../../__fixtures__/price-set-money-amount"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { DB_URL, MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
async function seedData({
moneyAmountsData = defaultMoneyAmountsData,
priceRuleData = defaultPriceRuleData,
priceSetMoneyAmountsData = defaultPriceSetMoneyAmountsData,
} = {}) {
const testManager = MikroOrmWrapper.forkManager()
await createCurrencies(testManager)
await createMoneyAmounts(testManager, moneyAmountsData)
await createPriceSets(testManager)
await createPriceSetMoneyAmounts(testManager, priceSetMoneyAmountsData)
await createRuleTypes(testManager)
await createPriceRules(testManager, priceRuleData)
}
describe("PricingModule Service - PriceSet", () => {
let service: IPricingModuleService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let data!: PriceSet[]
const moneyAmountsInputData = [
{
id: "money-amount-USD",
currency_code: "USD",
amount: 500,
min_quantity: 1,
max_quantity: 10,
},
{
id: "money-amount-EUR",
currency_code: "EUR",
amount: 500,
min_quantity: 1,
max_quantity: 10,
},
]
const priceSetInputData = [
{
id: "price-set-1",
money_amounts: [{ id: "money-amount-USD" }],
},
{
id: "price-set-2",
money_amounts: [{ id: "money-amount-EUR" }],
},
{
id: "price-set-3",
money_amounts: [],
},
]
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = MikroOrmWrapper.forkManager()
service = await initialize({
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRICING_DB_SCHEMA,
},
})
testManager = MikroOrmWrapper.forkManager()
await createCurrencies(testManager)
await createMoneyAmounts(testManager, moneyAmountsInputData)
data = await createPriceSets(testManager, priceSetInputData)
})
beforeEach(async () => await seedData())
afterEach(async () => {
await MikroOrmWrapper.clearDatabase()
})
describe("calculatePrices", () => {
it("retrieves the calculated prices when no context is set", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-1", "price-set-2"] },
{}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-1",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
{
id: "price-set-2",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("retrieves the calculated prices when a context is set", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-1", "price-set-2"] },
{
context: {
currency_code: "USD",
},
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-1",
amount: "500",
currency_code: "USD",
min_quantity: "1",
max_quantity: "10",
},
{
id: "price-set-2",
amount: null,
currency_code: null,
min_quantity: null,
max_quantity: null,
},
])
})
it("retrieves the calculated prices only when id exists in the database", async () => {
const priceSetsResult = await service.calculatePrices(
{ id: ["price-set-doesnotexist", "price-set-1"] },
{
context: { currency_code: "USD" },
}
)
expect(priceSetsResult).toEqual([
{
id: "price-set-1",
amount: "500",
currency_code: "USD",
min_quantity: "1",
max_quantity: "10",
},
])
})
})
describe("list", () => {
it("list priceSets", async () => {
const priceSetsResult = await service.list()
@@ -1,6 +1,3 @@
import { DB_URL, MikroOrmWrapper } from "../../../utils"
import { Currency } from "@models"
import { IPricingModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
@@ -3,8 +3,8 @@ import { SqlEntityManager } from "@mikro-orm/postgresql"
import { RuleTypeRepository } from "@repositories"
import { RuleTypeService } from "@services"
import { MikroOrmWrapper } from "../../../utils"
import { createRuleTypes } from "../../../__fixtures__/rule-type"
import { MikroOrmWrapper } from "../../../utils"
jest.setTimeout(30000)
@@ -13,7 +13,6 @@ describe("RuleType Service", () => {
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
beforeEach(async () => {
await MikroOrmWrapper.setupDatabase()
repositoryManager = await MikroOrmWrapper.forkManager()
@@ -131,9 +130,8 @@ describe("RuleType Service", () => {
})
describe("retrieve", () => {
it("should return ruleType for the given id", async () => {
const ruleType = await service.retrieve('rule-type-1')
const ruleType = await service.retrieve("rule-type-1")
expect(ruleType).toEqual(
expect.objectContaining({
@@ -170,15 +168,15 @@ describe("RuleType Service", () => {
})
it("should return ruleType based on config select param", async () => {
const ruleTypeResult = await service.retrieve('rule-type-1', {
const ruleTypeResult = await service.retrieve("rule-type-1", {
select: ["name"],
})
const serialized = JSON.parse(JSON.stringify(ruleTypeResult))
expect(serialized).toEqual({
name: 'rule 1',
id: 'rule-type-1'
name: "rule 1",
id: "rule-type-1",
})
})
})
@@ -189,11 +187,11 @@ describe("RuleType Service", () => {
it("should delete the ruleTypes given an id successfully", async () => {
await service.delete([id])
const currencies = await service.list({
const ruleTypes = await service.list({
id: [id],
})
expect(currencies).toHaveLength(0)
expect(ruleTypes).toHaveLength(0)
})
})
@@ -238,7 +236,7 @@ describe("RuleType Service", () => {
await service.create([
{
name: "Test Rule",
rule_attribute: 'region_id',
rule_attribute: "region_id",
},
])
@@ -249,7 +247,7 @@ describe("RuleType Service", () => {
expect(ruleType).toEqual(
expect.objectContaining({
name: "Test Rule",
rule_attribute: 'region_id',
rule_attribute: "region_id",
})
)
})