Fixes: FRMW-2742
In this PR, we fix the build output of the backend source code, which eliminates a lot of magic between the development and production environments.
Right now, we only compile the source files from the `src` directory and write them within the `dist` directory.
**Here's how the `src` directory with a custom module looks like**
```
src
├── modules
│ └── hello
│ ├── index.ts
```
**Here's the build output**
```
dist
├── modules
│ └── hello
│ ├── index.js
```
Let's imagine a file at the root of your project (maybe the `medusa-config.js` file) that wants to import the `modules/hello/index` file. How can we ensure that the import will work in both the development and production environments?
If we write the import targeting the `src` directory, it will break in production because it should target the `dist` directory.
## Solution
The solution is to compile everything within the project and mimic the file structure in the build output, not just the `src` directory.
**Here's how the fixed output should look like**
```
dist
├── src
│ ├── modules
│ │ └── hello
│ │ ├── index.js
├── medusa-config.js
├── yarn.lock
├── package.json
```
If you notice carefully, we also have `medusa-config.js`, `yarn.lock`, and `package.json` within the `dist` directory. We do so to create a standalone built application, something you can copy/paste to your server and run without relying on the original source code.
- This results in small containers since you are not copying unnecessary files.
- Clear distinction between the development and the production code. If you want to run the production server, then `cd` into the `dist` directory and run it from there.
## Changes in the PR
- Breaking: Remove the `dist` and `build` folders. Instead, write them production artefacts within the `.medusa` directory as `.medusa/admin` and `.medusa/server`.
- Breaking: Change the output of the `.medusa/server` folder to mimic the root project structure.
- Refactor: Remove `Symbol.for("ts-node.register.instance")]` check to find from where to load the source code.
- Refactor: Use `tsc` for creating the production build. This ensures we respect `tsconfig` settings when creating the build and also perform type-checking.
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
760 lines
19 KiB
TypeScript
760 lines
19 KiB
TypeScript
import {
|
|
configLoader,
|
|
container,
|
|
logger,
|
|
MedusaAppLoader,
|
|
} from "@medusajs/framework"
|
|
import { MedusaAppOutput, MedusaModule } from "@medusajs/framework/modules-sdk"
|
|
import { EventBusTypes, IndexTypes } from "@medusajs/framework/types"
|
|
import {
|
|
ContainerRegistrationKeys,
|
|
ModuleRegistrationName,
|
|
Modules,
|
|
} from "@medusajs/framework/utils"
|
|
import { EntityManager } from "@mikro-orm/postgresql"
|
|
import { IndexData, IndexRelation } from "@models"
|
|
import { asValue } from "awilix"
|
|
import { initDb, TestDatabaseUtils } from "medusa-test-utils"
|
|
import * as path from "path"
|
|
import { EventBusServiceMock } from "../__fixtures__"
|
|
import { dbName } from "../__fixtures__/medusa-config"
|
|
|
|
const eventBusMock = new EventBusServiceMock()
|
|
const queryMock = {
|
|
graph: jest.fn(),
|
|
}
|
|
|
|
const dbUtils = TestDatabaseUtils.dbTestUtilFactory()
|
|
|
|
jest.setTimeout(300000)
|
|
|
|
const productId = "prod_1"
|
|
const variantId = "var_1"
|
|
const priceSetId = "price_set_1"
|
|
const priceId = "money_amount_1"
|
|
const linkId = "link_id_1"
|
|
|
|
const sendEvents = async (eventDataToEmit) => {
|
|
let a = 0
|
|
|
|
queryMock.graph = jest.fn().mockImplementation((query) => {
|
|
const entity = query.entity
|
|
if (entity === "product") {
|
|
return {
|
|
data: {
|
|
id: a++ > 0 ? "aaaa" : productId,
|
|
},
|
|
}
|
|
} else if (entity === "product_variant") {
|
|
return {
|
|
data: {
|
|
id: variantId,
|
|
sku: "aaa test aaa",
|
|
product: {
|
|
id: productId,
|
|
},
|
|
},
|
|
}
|
|
} else if (entity === "price_set") {
|
|
return {
|
|
data: {
|
|
id: priceSetId,
|
|
},
|
|
}
|
|
} else if (entity === "price") {
|
|
return {
|
|
data: {
|
|
id: priceId,
|
|
amount: 100,
|
|
price_set: [
|
|
{
|
|
id: priceSetId,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
} else if (entity === "product_variant_price_set") {
|
|
return {
|
|
data: {
|
|
id: linkId,
|
|
variant_id: variantId,
|
|
price_set_id: priceSetId,
|
|
variant: [
|
|
{
|
|
id: variantId,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
}
|
|
|
|
return {}
|
|
})
|
|
|
|
await eventBusMock.emit(eventDataToEmit)
|
|
}
|
|
|
|
let isFirstTime = true
|
|
let medusaAppLoader!: MedusaAppLoader
|
|
let index!: IndexTypes.IIndexService
|
|
|
|
const beforeAll_ = async () => {
|
|
try {
|
|
configLoader(path.join(__dirname, "./../__fixtures__"), "medusa-config")
|
|
|
|
console.log(`Creating database ${dbName}`)
|
|
await dbUtils.create(dbName)
|
|
dbUtils.pgConnection_ = await initDb()
|
|
|
|
container.register({
|
|
[ContainerRegistrationKeys.LOGGER]: asValue(logger),
|
|
[ContainerRegistrationKeys.QUERY]: asValue(null),
|
|
[ContainerRegistrationKeys.PG_CONNECTION]: asValue(dbUtils.pgConnection_),
|
|
})
|
|
|
|
medusaAppLoader = new MedusaAppLoader(container as any)
|
|
|
|
// Migrations
|
|
await medusaAppLoader.runModulesMigrations()
|
|
const linkPlanner = await medusaAppLoader.getLinksExecutionPlanner()
|
|
const plan = await linkPlanner.createPlan()
|
|
await linkPlanner.executePlan(plan)
|
|
|
|
// Clear partially loaded instances
|
|
MedusaModule.clearInstances()
|
|
|
|
// Bootstrap modules
|
|
const globalApp = await medusaAppLoader.load()
|
|
|
|
index = container.resolve(Modules.INDEX)
|
|
|
|
// Mock event bus the index module
|
|
;(index as any).eventBusModuleService_ = eventBusMock
|
|
|
|
await globalApp.onApplicationStart()
|
|
;(index as any).storageProvider_.query_ = queryMock
|
|
|
|
return globalApp
|
|
} catch (error) {
|
|
console.error("Error initializing", error?.message)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
const beforeEach_ = async (eventDataToEmit) => {
|
|
jest.clearAllMocks()
|
|
|
|
if (isFirstTime) {
|
|
isFirstTime = false
|
|
await sendEvents(eventDataToEmit)
|
|
return
|
|
}
|
|
|
|
try {
|
|
await medusaAppLoader.runModulesLoader()
|
|
|
|
await sendEvents(eventDataToEmit)
|
|
} catch (error) {
|
|
console.error("Error runner modules loaders", error?.message)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
const afterEach_ = async () => {
|
|
try {
|
|
await dbUtils.teardown({ schema: "public" })
|
|
} catch (error) {
|
|
console.error("Error tearing down database:", error?.message)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
describe("IndexModuleService", function () {
|
|
let medusaApp: MedusaAppOutput
|
|
let onApplicationPrepareShutdown!: () => Promise<void>
|
|
let onApplicationShutdown!: () => Promise<void>
|
|
|
|
beforeAll(async () => {
|
|
medusaApp = await beforeAll_()
|
|
onApplicationPrepareShutdown = medusaApp.onApplicationPrepareShutdown
|
|
onApplicationShutdown = medusaApp.onApplicationShutdown
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await onApplicationPrepareShutdown()
|
|
await onApplicationShutdown()
|
|
await dbUtils.shutdown(dbName)
|
|
})
|
|
|
|
describe("on created or attached events", function () {
|
|
let manager
|
|
|
|
const eventDataToEmit: EventBusTypes.Event[] = [
|
|
{
|
|
name: "product.created",
|
|
data: {
|
|
id: productId,
|
|
},
|
|
},
|
|
{
|
|
name: "product.created",
|
|
data: {
|
|
id: "PRODUCTASDASDAS",
|
|
},
|
|
},
|
|
{
|
|
name: "variant.created",
|
|
data: {
|
|
id: variantId,
|
|
product: {
|
|
id: productId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "PriceSet.created",
|
|
data: {
|
|
id: priceSetId,
|
|
},
|
|
},
|
|
{
|
|
name: "price.created",
|
|
data: {
|
|
id: priceId,
|
|
price_set: {
|
|
id: priceSetId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "LinkProductVariantPriceSet.attached",
|
|
data: {
|
|
id: linkId,
|
|
variant_id: variantId,
|
|
price_set_id: priceSetId,
|
|
},
|
|
},
|
|
]
|
|
|
|
beforeEach(async () => {
|
|
await beforeEach_(eventDataToEmit)
|
|
|
|
manager = (
|
|
medusaApp.sharedContainer!.resolve(ModuleRegistrationName.INDEX) as any
|
|
).container_.manager as EntityManager
|
|
})
|
|
|
|
afterEach(afterEach_)
|
|
|
|
it("should create the corresponding index entries and index relation entries", async function () {
|
|
/**
|
|
* Validate all index entries and index relation entries
|
|
*/
|
|
|
|
const indexEntries: IndexData[] = await manager.find(IndexData, {})
|
|
|
|
const productIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "Product"
|
|
})
|
|
|
|
expect(productIndexEntries).toHaveLength(2)
|
|
|
|
const variantIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "ProductVariant"
|
|
})
|
|
|
|
expect(variantIndexEntries).toHaveLength(1)
|
|
|
|
const priceSetIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "PriceSet"
|
|
})
|
|
|
|
expect(priceSetIndexEntries).toHaveLength(1)
|
|
|
|
const priceIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "Price"
|
|
})
|
|
|
|
expect(priceIndexEntries).toHaveLength(1)
|
|
|
|
const linkIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "LinkProductVariantPriceSet"
|
|
})
|
|
|
|
expect(linkIndexEntries).toHaveLength(1)
|
|
|
|
const indexRelationEntries: IndexRelation[] = await manager.find(
|
|
IndexRelation,
|
|
{}
|
|
)
|
|
|
|
expect(indexRelationEntries).toHaveLength(4)
|
|
|
|
const productVariantIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === productId &&
|
|
entry.parent_name === "Product" &&
|
|
entry.child_id === variantId &&
|
|
entry.child_name === "ProductVariant"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(productVariantIndexRelationEntries).toHaveLength(1)
|
|
|
|
const variantLinkIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === variantId &&
|
|
entry.parent_name === "ProductVariant" &&
|
|
entry.child_id === linkId &&
|
|
entry.child_name === "LinkProductVariantPriceSet"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(variantLinkIndexRelationEntries).toHaveLength(1)
|
|
|
|
const linkPriceSetIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === linkId &&
|
|
entry.parent_name === "LinkProductVariantPriceSet" &&
|
|
entry.child_id === priceSetId &&
|
|
entry.child_name === "PriceSet"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(linkPriceSetIndexRelationEntries).toHaveLength(1)
|
|
|
|
const priceSetPriceIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === priceSetId &&
|
|
entry.parent_name === "PriceSet" &&
|
|
entry.child_id === priceId &&
|
|
entry.child_name === "Price"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(priceSetPriceIndexRelationEntries).toHaveLength(1)
|
|
})
|
|
})
|
|
|
|
describe("on unordered created or attached events", function () {
|
|
let manager
|
|
|
|
const eventDataToEmit: EventBusTypes.Event[] = [
|
|
{
|
|
name: "variant.created",
|
|
data: {
|
|
id: variantId,
|
|
product: {
|
|
id: productId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "product.created",
|
|
data: {
|
|
id: productId,
|
|
},
|
|
},
|
|
{
|
|
name: "product.created",
|
|
data: {
|
|
id: "PRODUCTASDASDAS",
|
|
},
|
|
},
|
|
{
|
|
name: "PriceSet.created",
|
|
data: {
|
|
id: priceSetId,
|
|
},
|
|
},
|
|
{
|
|
name: "price.created",
|
|
data: {
|
|
id: priceId,
|
|
price_set: {
|
|
id: priceSetId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "LinkProductVariantPriceSet.attached",
|
|
data: {
|
|
id: linkId,
|
|
variant_id: variantId,
|
|
price_set_id: priceSetId,
|
|
},
|
|
},
|
|
]
|
|
|
|
beforeEach(async () => {
|
|
await beforeEach_(eventDataToEmit)
|
|
|
|
manager = (
|
|
medusaApp.sharedContainer!.resolve(ModuleRegistrationName.INDEX) as any
|
|
).container_.manager as EntityManager
|
|
})
|
|
|
|
afterEach(afterEach_)
|
|
|
|
it("should create the corresponding index entries and index relation entries", async function () {
|
|
/**
|
|
* Validate all index entries and index relation entries
|
|
*/
|
|
|
|
const indexEntries: IndexData[] = await manager.find(IndexData, {})
|
|
|
|
const productIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "Product"
|
|
})
|
|
|
|
expect(productIndexEntries).toHaveLength(2)
|
|
expect(productIndexEntries[0].id).toEqual(productId)
|
|
|
|
const variantIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "ProductVariant"
|
|
})
|
|
|
|
expect(variantIndexEntries).toHaveLength(1)
|
|
expect(variantIndexEntries[0].id).toEqual(variantId)
|
|
|
|
const priceSetIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "PriceSet"
|
|
})
|
|
|
|
expect(priceSetIndexEntries).toHaveLength(1)
|
|
expect(priceSetIndexEntries[0].id).toEqual(priceSetId)
|
|
|
|
const priceIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "Price"
|
|
})
|
|
|
|
expect(priceIndexEntries).toHaveLength(1)
|
|
expect(priceIndexEntries[0].id).toEqual(priceId)
|
|
|
|
const linkIndexEntries = indexEntries.filter((entry) => {
|
|
return entry.name === "LinkProductVariantPriceSet"
|
|
})
|
|
|
|
expect(linkIndexEntries).toHaveLength(1)
|
|
expect(linkIndexEntries[0].id).toEqual(linkId)
|
|
|
|
const indexRelationEntries: IndexRelation[] = await manager.find(
|
|
IndexRelation,
|
|
{}
|
|
)
|
|
|
|
expect(indexRelationEntries).toHaveLength(4)
|
|
|
|
const productVariantIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === productId &&
|
|
entry.parent_name === "Product" &&
|
|
entry.child_id === variantId &&
|
|
entry.child_name === "ProductVariant"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(productVariantIndexRelationEntries).toHaveLength(1)
|
|
|
|
const variantLinkIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === variantId &&
|
|
entry.parent_name === "ProductVariant" &&
|
|
entry.child_id === linkId &&
|
|
entry.child_name === "LinkProductVariantPriceSet"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(variantLinkIndexRelationEntries).toHaveLength(1)
|
|
|
|
const linkPriceSetIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === linkId &&
|
|
entry.parent_name === "LinkProductVariantPriceSet" &&
|
|
entry.child_id === priceSetId &&
|
|
entry.child_name === "PriceSet"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(linkPriceSetIndexRelationEntries).toHaveLength(1)
|
|
|
|
const priceSetPriceIndexRelationEntries = indexRelationEntries.filter(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === priceSetId &&
|
|
entry.parent_name === "PriceSet" &&
|
|
entry.child_id === priceId &&
|
|
entry.child_name === "Price"
|
|
)
|
|
}
|
|
)
|
|
|
|
expect(priceSetPriceIndexRelationEntries).toHaveLength(1)
|
|
})
|
|
})
|
|
|
|
describe("on updated events", function () {
|
|
let manager
|
|
|
|
const updateData = async (manager) => {
|
|
const indexRepository = manager.getRepository(IndexData)
|
|
await indexRepository.upsertMany([
|
|
{
|
|
id: productId,
|
|
name: "Product",
|
|
data: {
|
|
id: productId,
|
|
},
|
|
},
|
|
{
|
|
id: variantId,
|
|
name: "ProductVariant",
|
|
data: {
|
|
id: variantId,
|
|
sku: "aaa test aaa",
|
|
product: {
|
|
id: productId,
|
|
},
|
|
},
|
|
},
|
|
])
|
|
}
|
|
|
|
const eventDataToEmit: EventBusTypes.Event[] = [
|
|
{
|
|
name: "product.updated",
|
|
data: {
|
|
id: productId,
|
|
},
|
|
},
|
|
{
|
|
name: "variant.updated",
|
|
data: {
|
|
id: variantId,
|
|
product: {
|
|
id: productId,
|
|
},
|
|
},
|
|
},
|
|
]
|
|
|
|
beforeEach(async () => {
|
|
await beforeEach_(eventDataToEmit)
|
|
|
|
manager = (
|
|
medusaApp.sharedContainer!.resolve(ModuleRegistrationName.INDEX) as any
|
|
).container_.manager as EntityManager
|
|
|
|
await updateData(manager)
|
|
|
|
queryMock.graph = jest.fn().mockImplementation((query) => {
|
|
const entity = query.entity
|
|
if (entity === "product") {
|
|
return {
|
|
data: {
|
|
id: productId,
|
|
title: "updated Title",
|
|
},
|
|
}
|
|
} else if (entity === "product_variant") {
|
|
return {
|
|
data: {
|
|
id: variantId,
|
|
sku: "updated sku",
|
|
product: [
|
|
{
|
|
id: productId,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
}
|
|
|
|
return {}
|
|
})
|
|
|
|
await eventBusMock.emit(eventDataToEmit)
|
|
})
|
|
|
|
afterEach(afterEach_)
|
|
|
|
it("should update the corresponding index entries", async () => {
|
|
const updatedIndexEntries = await manager.find(IndexData, {})
|
|
|
|
expect(updatedIndexEntries).toHaveLength(2)
|
|
|
|
const productEntry = updatedIndexEntries.find((entry) => {
|
|
return entry.name === "Product" && entry.id === productId
|
|
})
|
|
|
|
expect(productEntry?.data?.title).toEqual("updated Title")
|
|
|
|
const variantEntry = updatedIndexEntries.find((entry) => {
|
|
return entry.name === "ProductVariant" && entry.id === variantId
|
|
})
|
|
|
|
expect(variantEntry?.data?.sku).toEqual("updated sku")
|
|
})
|
|
})
|
|
|
|
describe("on deleted events", function () {
|
|
let manager
|
|
|
|
const eventDataToEmit: EventBusTypes.Event[] = [
|
|
{
|
|
name: "product.created",
|
|
data: {
|
|
id: productId,
|
|
},
|
|
},
|
|
{
|
|
name: "variant.created",
|
|
data: {
|
|
id: variantId,
|
|
product: {
|
|
id: productId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "PriceSet.created",
|
|
data: {
|
|
id: priceSetId,
|
|
},
|
|
},
|
|
{
|
|
name: "price.created",
|
|
data: {
|
|
id: priceId,
|
|
price_set: {
|
|
id: priceSetId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "LinkProductVariantPriceSet.attached",
|
|
data: {
|
|
id: linkId,
|
|
variant_id: variantId,
|
|
price_set_id: priceSetId,
|
|
},
|
|
},
|
|
]
|
|
|
|
const deleteEventDataToEmit: EventBusTypes.Event[] = [
|
|
{
|
|
name: "product.deleted",
|
|
data: {
|
|
id: productId,
|
|
},
|
|
},
|
|
{
|
|
name: "variant.deleted",
|
|
data: {
|
|
id: variantId,
|
|
},
|
|
},
|
|
]
|
|
|
|
beforeEach(async () => {
|
|
await beforeEach_(eventDataToEmit)
|
|
|
|
manager = (
|
|
medusaApp.sharedContainer!.resolve(ModuleRegistrationName.INDEX) as any
|
|
).container_.manager as EntityManager
|
|
|
|
queryMock.graph = jest.fn().mockImplementation((query) => {
|
|
const entity = query.entity
|
|
if (entity === "product") {
|
|
return {
|
|
data: {
|
|
id: productId,
|
|
},
|
|
}
|
|
} else if (entity === "product_variant") {
|
|
return {
|
|
data: {
|
|
id: variantId,
|
|
product: [
|
|
{
|
|
id: productId,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
}
|
|
|
|
return {}
|
|
})
|
|
|
|
await eventBusMock.emit(deleteEventDataToEmit)
|
|
})
|
|
|
|
afterEach(afterEach_)
|
|
|
|
it("should consume all deleted events and delete the index entries", async () => {
|
|
const indexEntries = await manager.find(IndexData, {})
|
|
const indexRelationEntries = await manager.find(IndexRelation, {})
|
|
|
|
expect(indexEntries).toHaveLength(3)
|
|
expect(indexRelationEntries).toHaveLength(2)
|
|
|
|
const linkIndexEntry = indexEntries.find((entry) => {
|
|
return (
|
|
entry.name === "LinkProductVariantPriceSet" && entry.id === linkId
|
|
)
|
|
})!
|
|
|
|
const priceSetIndexEntry = indexEntries.find((entry) => {
|
|
return entry.name === "PriceSet" && entry.id === priceSetId
|
|
})!
|
|
|
|
const priceIndexEntry = indexEntries.find((entry) => {
|
|
return entry.name === "Price" && entry.id === priceId
|
|
})!
|
|
|
|
const linkPriceSetIndexRelationEntry = indexRelationEntries.find(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === linkId &&
|
|
entry.parent_name === "LinkProductVariantPriceSet" &&
|
|
entry.child_id === priceSetId &&
|
|
entry.child_name === "PriceSet"
|
|
)
|
|
}
|
|
)!
|
|
|
|
expect(linkPriceSetIndexRelationEntry.parent).toEqual(linkIndexEntry)
|
|
expect(linkPriceSetIndexRelationEntry.child).toEqual(priceSetIndexEntry)
|
|
|
|
const priceSetPriceIndexRelationEntry = indexRelationEntries.find(
|
|
(entry) => {
|
|
return (
|
|
entry.parent_id === priceSetId &&
|
|
entry.parent_name === "PriceSet" &&
|
|
entry.child_id === priceId &&
|
|
entry.child_name === "Price"
|
|
)
|
|
}
|
|
)!
|
|
|
|
expect(priceSetPriceIndexRelationEntry.parent).toEqual(priceSetIndexEntry)
|
|
expect(priceSetPriceIndexRelationEntry.child).toEqual(priceIndexEntry)
|
|
})
|
|
})
|
|
})
|