What:
- `query.index` helper. It queries the index module, and aggregate the rest of requested fields/relations if needed like `query.graph`.
Not covered in this PR:
- Hydrate only sub entities returned by the query. Example: 1 out of 5 variants have returned, it should only hydrate the data of the single entity, currently it will merge all the variants of the product.
- Generate types of indexed data
example:
```ts
const query = container.resolve(ContainerRegistrationKeys.QUERY)
await query.index({
entity: "product",
fields: [
"id",
"description",
"status",
"variants.sku",
"variants.barcode",
"variants.material",
"variants.options.value",
"variants.prices.amount",
"variants.prices.currency_code",
"variants.inventory_items.inventory.sku",
"variants.inventory_items.inventory.description",
],
filters: {
"variants.sku": { $like: "%-1" },
"variants.prices.amount": { $gt: 30 },
},
pagination: {
order: {
"variants.prices.amount": "DESC",
},
},
})
```
This query return all products where at least one variant has the title ending in `-1` and at least one price bigger than `30`.
The Index Module only hold the data used to paginate and filter, and the returned object is:
```json
{
"id": "prod_01JKEAM2GJZ14K64R0DHK0JE72",
"title": null,
"variants": [
{
"id": "variant_01JKEAM2HC89GWS95F6GF9C6YA",
"sku": "extra-variant-1",
"prices": [
{
"id": "price_01JKEAM2JADEWWX72F8QDP6QXT",
"amount": 80,
"currency_code": "USD"
}
]
}
]
}
```
All the rest of the fields will be hydrated from their respective modules, and the final result will be:
```json
{
"id": "prod_01JKEAY2RJTF8TW9A23KTGY1GD",
"description": "extra description",
"status": "draft",
"variants": [
{
"sku": "extra-variant-1",
"barcode": null,
"material": null,
"id": "variant_01JKEAY2S945CRZ6X4QZJ7GVBJ",
"options": [
{
"value": "Red"
}
],
"prices": [
{
"amount": 20,
"currency_code": "CAD",
"id": "price_01JKEAY2T2EEYSWZHPGG11B7W7"
},
{
"amount": 80,
"currency_code": "USD",
"id": "price_01JKEAY2T2NJK2E5468RK84CAR"
}
],
"inventory_items": [
{
"variant_id": "variant_01JKEAY2S945CRZ6X4QZJ7GVBJ",
"inventory_item_id": "iitem_01JKEAY2SNY2AWEHPZN0DDXVW6",
"inventory": {
"sku": "extra-variant-1",
"description": "extra variant 1",
"id": "iitem_01JKEAY2SNY2AWEHPZN0DDXVW6"
}
}
]
}
]
}
```
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
864 lines
18 KiB
TypeScript
864 lines
18 KiB
TypeScript
import {
|
|
configLoader,
|
|
container,
|
|
logger,
|
|
MedusaAppLoader,
|
|
} from "@medusajs/framework"
|
|
import { MedusaAppOutput, MedusaModule } from "@medusajs/framework/modules-sdk"
|
|
import { IndexTypes } from "@medusajs/framework/types"
|
|
import { ContainerRegistrationKeys, Modules } from "@medusajs/framework/utils"
|
|
import { initDb, TestDatabaseUtils } from "@medusajs/test-utils"
|
|
import { EntityManager } from "@mikro-orm/postgresql"
|
|
import { IndexData, IndexRelation } from "@models"
|
|
import { asValue } from "awilix"
|
|
import path from "path"
|
|
import { EventBusServiceMock } from "../__fixtures__"
|
|
import { dbName } from "../__fixtures__/medusa-config"
|
|
|
|
const eventBusMock = new EventBusServiceMock()
|
|
const queryMock = jest.fn().mockReturnValue({
|
|
graph: jest.fn(),
|
|
})
|
|
|
|
const dbUtils = TestDatabaseUtils.dbTestUtilFactory()
|
|
|
|
jest.setTimeout(300000)
|
|
|
|
let isFirstTime = true
|
|
let medusaAppLoader!: MedusaAppLoader
|
|
|
|
const beforeAll_ = async () => {
|
|
try {
|
|
await 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()
|
|
|
|
const 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 () => {
|
|
jest.clearAllMocks()
|
|
|
|
if (isFirstTime) {
|
|
isFirstTime = false
|
|
return
|
|
}
|
|
|
|
try {
|
|
await medusaAppLoader.runModulesLoader()
|
|
} 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 query", function () {
|
|
let medusaApp: MedusaAppOutput
|
|
let module: IndexTypes.IIndexService
|
|
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)
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
await beforeEach_()
|
|
|
|
module = medusaApp.sharedContainer!.resolve(Modules.INDEX)
|
|
|
|
const manager = (
|
|
(medusaApp.sharedContainer!.resolve(Modules.INDEX) as any).container_
|
|
.manager as EntityManager
|
|
).fork()
|
|
|
|
const indexRepository = manager.getRepository(IndexData)
|
|
|
|
await manager.persistAndFlush(
|
|
[
|
|
{
|
|
id: "prod_1",
|
|
name: "Product",
|
|
data: {
|
|
id: "prod_1",
|
|
},
|
|
},
|
|
{
|
|
id: "prod_2",
|
|
name: "Product",
|
|
data: {
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
id: "var_1",
|
|
name: "ProductVariant",
|
|
data: {
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
},
|
|
},
|
|
{
|
|
id: "var_2",
|
|
name: "ProductVariant",
|
|
data: {
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
},
|
|
},
|
|
{
|
|
id: "link_id_1",
|
|
name: "LinkProductVariantPriceSet",
|
|
data: {
|
|
id: "link_id_1",
|
|
variant_id: "var_1",
|
|
price_set_id: "price_set_1",
|
|
},
|
|
},
|
|
{
|
|
id: "link_id_2",
|
|
name: "LinkProductVariantPriceSet",
|
|
data: {
|
|
id: "link_id_2",
|
|
variant_id: "var_2",
|
|
price_set_id: "price_set_2",
|
|
},
|
|
},
|
|
{
|
|
id: "price_set_1",
|
|
name: "PriceSet",
|
|
data: {
|
|
id: "price_set_1",
|
|
},
|
|
},
|
|
{
|
|
id: "price_set_2",
|
|
name: "PriceSet",
|
|
data: {
|
|
id: "price_set_2",
|
|
},
|
|
},
|
|
{
|
|
id: "money_amount_1",
|
|
name: "Price",
|
|
data: {
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
},
|
|
{
|
|
id: "money_amount_2",
|
|
name: "Price",
|
|
data: {
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
},
|
|
].map((data) => indexRepository.create(data))
|
|
)
|
|
|
|
const indexRelationRepository = manager.getRepository(IndexRelation)
|
|
|
|
await manager.persistAndFlush(
|
|
[
|
|
{
|
|
parent_id: "prod_1",
|
|
parent_name: "Product",
|
|
child_id: "var_1",
|
|
child_name: "ProductVariant",
|
|
pivot: "Product-ProductVariant",
|
|
},
|
|
{
|
|
parent_id: "prod_1",
|
|
parent_name: "Product",
|
|
child_id: "var_2",
|
|
child_name: "ProductVariant",
|
|
pivot: "Product-ProductVariant",
|
|
},
|
|
{
|
|
parent_id: "var_1",
|
|
parent_name: "ProductVariant",
|
|
child_id: "link_id_1",
|
|
child_name: "LinkProductVariantPriceSet",
|
|
pivot: "ProductVariant-LinkProductVariantPriceSet",
|
|
},
|
|
{
|
|
parent_id: "var_2",
|
|
parent_name: "ProductVariant",
|
|
child_id: "link_id_2",
|
|
child_name: "LinkProductVariantPriceSet",
|
|
pivot: "ProductVariant-LinkProductVariantPriceSet",
|
|
},
|
|
{
|
|
parent_id: "link_id_1",
|
|
parent_name: "LinkProductVariantPriceSet",
|
|
child_id: "price_set_1",
|
|
child_name: "PriceSet",
|
|
pivot: "LinkProductVariantPriceSet-PriceSet",
|
|
},
|
|
{
|
|
parent_id: "link_id_2",
|
|
parent_name: "LinkProductVariantPriceSet",
|
|
child_id: "price_set_2",
|
|
child_name: "PriceSet",
|
|
pivot: "LinkProductVariantPriceSet-PriceSet",
|
|
},
|
|
{
|
|
parent_id: "price_set_1",
|
|
parent_name: "PriceSet",
|
|
child_id: "money_amount_1",
|
|
child_name: "Price",
|
|
pivot: "PriceSet-Price",
|
|
},
|
|
{
|
|
parent_id: "price_set_2",
|
|
parent_name: "PriceSet",
|
|
child_id: "money_amount_2",
|
|
child_name: "Price",
|
|
pivot: "PriceSet-Price",
|
|
},
|
|
].map((data) => indexRelationRepository.create(data))
|
|
)
|
|
})
|
|
|
|
afterEach(afterEach_)
|
|
|
|
it("should query all products ordered by sku DESC", async () => {
|
|
const { data } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
pagination: {
|
|
order: {
|
|
product: {
|
|
variants: {
|
|
sku: "DESC",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
variants: [],
|
|
},
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [
|
|
{
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query all products ordered by sku DESC with specific fields", async () => {
|
|
const { data } = await module.query({
|
|
fields: [
|
|
"product.*",
|
|
"product.variants.sku",
|
|
"product.variants.prices.amount",
|
|
],
|
|
pagination: {
|
|
order: {
|
|
product: {
|
|
variants: {
|
|
sku: "DESC",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
variants: [],
|
|
},
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [
|
|
{
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
],
|
|
},
|
|
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query all products ordered by price", async () => {
|
|
const { data } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
pagination: {
|
|
order: {
|
|
product: {
|
|
variants: {
|
|
prices: {
|
|
amount: "DESC",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [
|
|
{
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
variants: [],
|
|
},
|
|
])
|
|
|
|
const { data: dataAsc } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
pagination: {
|
|
order: {
|
|
product: {
|
|
variants: {
|
|
prices: {
|
|
amount: "ASC",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(dataAsc).toEqual([
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
variants: [],
|
|
},
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [
|
|
{
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query products filtering by variant sku", async () => {
|
|
const { data, metadata } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
filters: {
|
|
product: {
|
|
variants: {
|
|
sku: { $like: "aaa%" },
|
|
},
|
|
},
|
|
},
|
|
pagination: {
|
|
take: 100,
|
|
skip: 0,
|
|
},
|
|
})
|
|
|
|
expect(metadata).toEqual({
|
|
count: 1,
|
|
skip: 0,
|
|
take: 100,
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query products filtering by variant sku and join filters on prices amount", async () => {
|
|
const { data, metadata } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
joinFilters: {
|
|
"product.variants.prices.amount": { $gt: 110 },
|
|
},
|
|
filters: {
|
|
product: {
|
|
variants: {
|
|
sku: { $like: "aaa%" },
|
|
},
|
|
},
|
|
},
|
|
pagination: {
|
|
take: 100,
|
|
skip: 0,
|
|
},
|
|
})
|
|
|
|
expect(metadata).toEqual({
|
|
count: 1,
|
|
skip: 0,
|
|
take: 100,
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should filter using fields not selected", async () => {
|
|
const { data } = await module.query({
|
|
fields: ["product.id", "product.variants.*"],
|
|
pagination: {
|
|
order: {
|
|
product: {
|
|
variants: {
|
|
prices: {
|
|
amount: "DESC",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
},
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "prod_2",
|
|
variants: [],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query products filtering by price and returning the complete entity", async () => {
|
|
const { data, metadata } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
filters: {
|
|
product: {
|
|
variants: {
|
|
prices: {
|
|
amount: { $gt: 50 },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
keepFilteredEntities: true,
|
|
pagination: {
|
|
take: 100,
|
|
skip: 0,
|
|
},
|
|
})
|
|
|
|
expect(metadata).toEqual({
|
|
count: 1,
|
|
skip: 0,
|
|
take: 100,
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [
|
|
{
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query all products", async () => {
|
|
const { data } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [
|
|
{
|
|
id: "money_amount_1",
|
|
amount: 100,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [
|
|
{
|
|
id: "money_amount_2",
|
|
amount: 10,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
variants: [],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should paginate products", async () => {
|
|
const { data, metadata } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
pagination: {
|
|
take: 1,
|
|
skip: 1,
|
|
},
|
|
})
|
|
|
|
expect(metadata).toEqual({
|
|
count: 2,
|
|
skip: 1,
|
|
take: 1,
|
|
})
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
variants: [],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should handle null values on where clause", async () => {
|
|
const { data: data_, metadata } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
filters: {
|
|
product: {
|
|
variants: {
|
|
sku: null,
|
|
},
|
|
},
|
|
},
|
|
pagination: {
|
|
take: 100,
|
|
skip: 0,
|
|
},
|
|
})
|
|
|
|
expect(metadata).toEqual({
|
|
count: 1,
|
|
skip: 0,
|
|
take: 100,
|
|
})
|
|
|
|
expect(data_).toEqual([
|
|
{
|
|
id: "prod_2",
|
|
deep: { a: 1, obj: { b: 15 } },
|
|
title: "Product 2 title",
|
|
variants: [],
|
|
},
|
|
])
|
|
|
|
const { data, metadata: metadata2 } = await module.query({
|
|
fields: ["product.*", "product.variants.*", "product.variants.prices.*"],
|
|
filters: {
|
|
product: {
|
|
variants: {
|
|
sku: { $ne: null },
|
|
},
|
|
},
|
|
},
|
|
pagination: {
|
|
take: 100,
|
|
skip: 0,
|
|
},
|
|
})
|
|
|
|
expect(metadata2).toEqual({
|
|
count: 1,
|
|
skip: 0,
|
|
take: 100,
|
|
})
|
|
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_1",
|
|
variants: [
|
|
{
|
|
id: "var_1",
|
|
sku: "aaa test aaa",
|
|
prices: [{ id: "money_amount_1", amount: 100 }],
|
|
},
|
|
{
|
|
id: "var_2",
|
|
sku: "sku 123",
|
|
prices: [{ id: "money_amount_2", amount: 10 }],
|
|
},
|
|
],
|
|
},
|
|
])
|
|
})
|
|
|
|
it("should query products filtering by deep nested levels", async () => {
|
|
const { data, metadata } = await module.query({
|
|
fields: ["product.*"],
|
|
filters: {
|
|
product: {
|
|
deep: {
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
pagination: {
|
|
take: 1,
|
|
skip: 0,
|
|
},
|
|
})
|
|
|
|
expect(metadata).toEqual({
|
|
count: 1,
|
|
skip: 0,
|
|
take: 1,
|
|
})
|
|
expect(data).toEqual([
|
|
{
|
|
id: "prod_2",
|
|
title: "Product 2 title",
|
|
deep: {
|
|
a: 1,
|
|
obj: {
|
|
b: 15,
|
|
},
|
|
},
|
|
},
|
|
])
|
|
})
|
|
})
|