chore: Use module test runner in all modules (#6706)

I replaced the custom test setup with the test runner. This should make migrating to mikroorm 6 a lot easier once we do it.

There are few more modules to be done, but I thought the PR is super big already so we can tackle them separately.

Note that there are no or very little test changes, it is mostly the setup around the tests.
This commit is contained in:
Stevche Radevski authored and GitHub committed 2024-03-14 21:01:50 +00:00
1 parent 1eb90f739b
commit 68d869607f
102 files changed
+21692 -25473

No files matched your search

@@ -1,43 +0,0 @@
import {
EmitData,
EventBusTypes,
IEventBusModuleService,
Message,
Subscriber,
} from "@medusajs/types"
export class EventBusService implements IEventBusModuleService {
emit<T>(
eventName: string,
data: T,
options?: Record<string, unknown>
): Promise<void>
emit<T>(data: EmitData<T>[]): Promise<void>
emit<T>(data: Message<T>[]): Promise<void>
async emit<
T,
TInput extends
| string
| EventBusTypes.EmitData<T>[]
| EventBusTypes.Message<T>[] = string
>(
eventOrData: TInput,
data?: T,
options: Record<string, unknown> = {}
): Promise<void> {}
subscribe(event: string | symbol, subscriber: Subscriber): this {
return this
}
unsubscribe(
event: string | symbol,
subscriber: Subscriber,
context?: EventBusTypes.SubscriberContext
): this {
return this
}
withTransaction() {}
}
@@ -1,482 +0,0 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { IProductModuleService } from "@medusajs/types"
import { kebabCase } from "@medusajs/utils"
import { knex } from "@mikro-orm/knex"
import { initModules } from "medusa-test-utils"
import * as CustomRepositories from "../__fixtures__/module"
import {
buildProductAndRelationsData,
createProductAndTags,
} from "../__fixtures__/product"
import { productsData } from "../__fixtures__/product/data"
import { DB_URL, TestDatabase } from "../utils"
import { getInitModuleConfig } from "../utils/get-init-module-config"
const sharedPgConnection = knex<any, any>({
client: "pg",
searchPath: process.env.MEDUSA_PRODUCT_DB_SCHEMA,
connection: {
connectionString: DB_URL,
},
})
const beforeEach_ = async () => {
await TestDatabase.setupDatabase()
return await TestDatabase.forkManager()
}
const afterEach_ = async () => {
await TestDatabase.clearDatabase()
}
describe("Product module", function () {
describe("Using built-in data access layer", function () {
let module: IProductModuleService
let shutdownFunc: () => Promise<void>
beforeAll(async () => {
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterAll(async () => {
await shutdownFunc()
})
beforeEach(async () => {
const testManager = await beforeEach_()
await createProductAndTags(testManager, productsData)
})
afterEach(afterEach_)
it("should initialize", async () => {
expect(module).toBeDefined()
})
it("should have a connection that is not the shared connection", async () => {
expect(
(module as any).baseRepository_.manager_.getConnection().client
).not.toEqual(sharedPgConnection)
})
it("should return a list of product", async () => {
const products = await module.list()
expect(products).toHaveLength(3)
})
})
describe("Using custom data access layer", function () {
let module
let shutdownFunc: () => Promise<void>
beforeAll(async () => {
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig({
repositories: CustomRepositories,
})
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterAll(async () => {
await shutdownFunc()
})
beforeEach(async () => {
const testManager = await beforeEach_()
await createProductAndTags(testManager, productsData)
})
afterEach(afterEach_)
it("should initialize", async () => {
expect(module).toBeDefined()
})
it("should have a connection that is not the shared connection", async () => {
expect(
(module as any).baseRepository_.manager_.getConnection().client
).not.toEqual(sharedPgConnection)
})
it("should return a list of product", async () => {
const products = await module.list()
expect(module.productService_.productRepository_.find).toHaveBeenCalled()
expect(products).toHaveLength(0)
})
})
describe("Using custom data access layer and manager", function () {
let module
let shutdownFunc: () => Promise<void>
afterEach(async () => {
await shutdownFunc()
})
beforeEach(async () => {
const testManager = await beforeEach_()
await createProductAndTags(testManager, productsData)
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig({
manager: testManager,
repositories: CustomRepositories,
})
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterEach(afterEach_)
it("should initialize and return a list of product", async () => {
expect(module).toBeDefined()
})
it("should have a connection that is not the shared connection", async () => {
expect(
(module as any).baseRepository_.manager_.getConnection().client
).not.toEqual(sharedPgConnection)
})
it("should return a list of product", async () => {
const products = await module.list()
expect(module.productService_.productRepository_.find).toHaveBeenCalled()
expect(products).toHaveLength(0)
})
})
describe("Using an existing connection", function () {
let module: IProductModuleService
let shutdownFunc: () => Promise<void>
afterEach(async () => {
await shutdownFunc()
})
beforeEach(async () => {
const testManager = await beforeEach_()
await createProductAndTags(testManager, productsData)
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig({
database: {
connection: sharedPgConnection,
},
})
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterEach(afterEach_)
it("should initialize and return a list of product", async () => {
expect(module).toBeDefined()
})
it("should have a connection that is the shared connection", async () => {
expect(
JSON.stringify(
(module as any).baseRepository_.manager_.getConnection().client
)
).toEqual(JSON.stringify(sharedPgConnection))
})
})
describe("create", function () {
let module: IProductModuleService
let images = ["image-1"]
let shutdownFunc: () => Promise<void>
afterEach(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await beforeEach_()
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig({
database: {
connection: sharedPgConnection,
},
})
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterEach(afterEach_)
it("should create a product", async () => {
const data = buildProductAndRelationsData({
images,
thumbnail: images[0],
})
const productsCreated = await module.create([data])
const products = await module.list(
{ id: productsCreated[0].id },
{
relations: [
"images",
"categories",
"variants",
"variants.options",
"options",
"options.values",
"tags",
"type",
],
}
)
expect(products).toHaveLength(1)
expect(products[0].images).toHaveLength(1)
expect(products[0].options).toHaveLength(1)
expect(products[0].tags).toHaveLength(1)
expect(products[0].categories).toHaveLength(0)
expect(products[0].variants).toHaveLength(1)
expect(products[0]).toEqual(
expect.objectContaining({
id: expect.any(String),
title: data.title,
handle: kebabCase(data.title),
description: data.description,
subtitle: data.subtitle,
is_giftcard: data.is_giftcard,
discountable: data.discountable,
thumbnail: images[0],
status: data.status,
images: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
url: images[0],
}),
]),
options: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
title: data.options[0].title,
values: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: data.variants[0].options?.[0].value,
}),
]),
}),
]),
tags: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: data.tags[0].value,
}),
]),
type: expect.objectContaining({
id: expect.any(String),
value: data.type.value,
}),
variants: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
title: data.variants[0].title,
sku: data.variants[0].sku,
allow_backorder: false,
manage_inventory: true,
inventory_quantity: 100,
variant_rank: 0,
options: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: data.variants[0].options?.[0].value,
}),
]),
}),
]),
})
)
})
})
describe("softDelete", function () {
let module: IProductModuleService
let images = ["image-1"]
let shutdownFunc: () => Promise<void>
afterEach(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await beforeEach_()
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterEach(afterEach_)
it("should soft delete a product and its cascaded relations", async () => {
const data = buildProductAndRelationsData({
images,
thumbnail: images[0],
})
const products = await module.create([data])
await module.softDelete([products[0].id])
const deletedProducts = await module.list(
{ id: products[0].id },
{
relations: [
"variants",
"variants.options",
"options",
"options.values",
],
withDeleted: true,
}
)
expect(deletedProducts).toHaveLength(1)
expect(deletedProducts[0].deleted_at).not.toBeNull()
for (const option of deletedProducts[0].options) {
expect(option.deleted_at).not.toBeNull()
}
const productOptionsValues = deletedProducts[0].options
.map((o) => o.values)
.flat()
for (const optionValue of productOptionsValues) {
expect(optionValue.deleted_at).not.toBeNull()
}
for (const variant of deletedProducts[0].variants) {
expect(variant.deleted_at).not.toBeNull()
}
const variantsOptions = deletedProducts[0].options
.map((o) => o.values)
.flat()
for (const option of variantsOptions) {
expect(option.deleted_at).not.toBeNull()
}
})
})
describe("restore", function () {
let module: IProductModuleService
let images = ["image-1"]
let shutdownFunc: () => Promise<void>
afterEach(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await beforeEach_()
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
module = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterEach(afterEach_)
it("should restore a soft deleted product and its cascaded relations", async () => {
const data = buildProductAndRelationsData({
images,
thumbnail: images[0],
})
const products = await module.create([data])
await module.softDelete([products[0].id])
await module.restore([products[0].id])
const deletedProducts = await module.list(
{ id: products[0].id },
{
relations: [
"variants",
"variants.options",
"variants.options",
"options",
"options.values",
],
withDeleted: true,
}
)
expect(deletedProducts).toHaveLength(1)
expect(deletedProducts[0].deleted_at).toBeNull()
for (const option of deletedProducts[0].options) {
expect(option.deleted_at).toBeNull()
}
const productOptionsValues = deletedProducts[0].options
.map((o) => o.values)
.flat()
for (const optionValue of productOptionsValues) {
expect(optionValue.deleted_at).toBeNull()
}
for (const variant of deletedProducts[0].variants) {
expect(variant.deleted_at).toBeNull()
}
const variantsOptions = deletedProducts[0].options
.map((o) => o.values)
.flat()
for (const option of variantsOptions) {
expect(option.deleted_at).toBeNull()
}
})
})
})
File diff suppressed because it is too large. Load diff
@@ -1,366 +1,367 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { ProductCollection } from "@models"
import { ProductCollectionService } from "@services"
import { createCollections } from "../../../__fixtures__/product"
import { TestDatabase } from "../../../utils"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import ContainerLoader from "../../../../src/loaders/container"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { IProductModuleService } from "@medusajs/types"
jest.setTimeout(30000)
describe("Product collection Service", () => {
let service: ProductCollectionService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let collectionsData: ProductCollection[] = []
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
medusaApp,
}: SuiteOptions<IProductModuleService>) => {
describe("Product collection Service", () => {
let service: ProductCollectionService
beforeEach(async () => {
await TestDatabase.setupDatabase()
repositoryManager = await TestDatabase.forkManager()
const container = createMedusaContainer()
container.register("manager", asValue(repositoryManager))
await ContainerLoader({ container })
service = container.resolve("productCollectionService")
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("list", () => {
const data = [
{
id: "test-1",
title: "col 1",
},
{
id: "test-2",
title: "col 2",
},
{
id: "test-3",
title: "col 3 extra",
},
{
id: "test-4",
title: "col 4 extra",
},
]
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
collectionsData = await createCollections(testManager, data)
})
it("list product collections", async () => {
const productCollectionResults = await service.list()
expect(productCollectionResults).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
expect.objectContaining({
id: "test-2",
title: "col 2",
}),
expect.objectContaining({
id: "test-3",
title: "col 3 extra",
}),
expect.objectContaining({
id: "test-4",
title: "col 4 extra",
}),
])
})
it("list product collections by id", async () => {
const productCollectionResults = await service.list({ id: data![0].id })
expect(productCollectionResults).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
])
})
it("list product collections by title matching string", async () => {
const productCollectionResults = await service.list({
title: "col 3 extra",
beforeEach(() => {
service = medusaApp.modules["productService"].productCollectionService_
})
expect(productCollectionResults).toEqual([
expect.objectContaining({
id: "test-3",
title: "col 3 extra",
}),
])
})
})
describe("listAndCount", () => {
const data = [
{
id: "test-1",
title: "col 1",
},
{
id: "test-2",
title: "col 2",
},
{
id: "test-3",
title: "col 3 extra",
},
{
id: "test-4",
title: "col 4 extra",
},
]
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
collectionsData = await createCollections(testManager, data)
})
it("should return all collections and count", async () => {
const [productCollectionResults, count] = await service.listAndCount()
const serialized = JSON.parse(JSON.stringify(productCollectionResults))
expect(serialized).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
expect.objectContaining({
id: "test-2",
title: "col 2",
}),
expect.objectContaining({
id: "test-3",
title: "col 3 extra",
}),
expect.objectContaining({
id: "test-4",
title: "col 4 extra",
}),
])
})
it("should return count and collections based on filter data", async () => {
const [productCollectionResults, count] = await service.listAndCount({
id: data![0].id,
})
const serialized = JSON.parse(JSON.stringify(productCollectionResults))
expect(count).toEqual(1)
expect(serialized).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
])
})
it("should return count and collections based on config data", async () => {
const [productCollectionResults, count] = await service.listAndCount(
{},
{
relations: ["products"],
select: ["title"],
take: 1,
skip: 1,
}
)
const serialized = JSON.parse(JSON.stringify(productCollectionResults))
expect(count).toEqual(4)
expect(serialized).toEqual([
{
id: "test-2",
title: "col 2",
products: [],
},
])
})
})
describe("retrieve", () => {
const collectionData = {
id: "collection-1",
title: "collection 1",
}
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
await createCollections(testManager, [collectionData])
})
it("should return collection for the given id", async () => {
const productCollectionResults = await service.retrieve(collectionData.id)
expect(productCollectionResults).toEqual(
expect.objectContaining({
id: collectionData.id,
})
)
})
it("should throw an error when collection with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductCollection 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("productCollection - id must be defined")
})
it("should return collection based on config select param", async () => {
const productCollectionResults = await service.retrieve(
collectionData.id,
{
select: ["id", "title"],
}
)
const serialized = JSON.parse(JSON.stringify(productCollectionResults))
expect(serialized).toEqual({
id: collectionData.id,
title: collectionData.title,
})
})
it("should return collection based on config relation param", async () => {
const productCollectionResults = await service.retrieve(
collectionData.id,
{
select: ["id", "title"],
relations: ["products"],
}
)
const serialized = JSON.parse(JSON.stringify(productCollectionResults))
expect(serialized).toEqual({
id: collectionData.id,
title: collectionData.title,
products: [],
})
})
})
describe("delete", () => {
const collectionId = "collection-1"
const collectionData = {
id: collectionId,
title: "collection 1",
}
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
await createCollections(testManager, [collectionData])
})
it("should delete the product collection given an ID successfully", async () => {
await service.delete([collectionId])
const collections = await service.list({
id: collectionId,
})
expect(collections).toHaveLength(0)
})
})
describe("update", () => {
const collectionId = "collection-1"
const collectionData = {
id: collectionId,
title: "collection 1",
}
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
await createCollections(testManager, [collectionData])
})
it("should update the value of the collection successfully", async () => {
await service.update([
{
id: collectionId,
title: "New Collection",
},
])
const productCollection = await service.retrieve(collectionId)
expect(productCollection.title).toEqual("New Collection")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
describe("list", () => {
const data = [
{
id: "does-not-exist",
title: "New Collection",
id: "test-1",
title: "col 1",
},
])
} catch (e) {
error = e
}
{
id: "test-2",
title: "col 2",
},
{
id: "test-3",
title: "col 3 extra",
},
{
id: "test-4",
title: "col 4 extra",
},
]
expect(error.message).toEqual(
'ProductCollection with id "does-not-exist" not found'
)
})
})
beforeEach(async () => {
await createCollections(MikroOrmWrapper.forkManager(), data)
})
describe("create", () => {
it("should create a collection successfully", async () => {
await service.create([
{
title: "New Collection",
},
])
it("list product collections", async () => {
const productCollectionResults = await service.list()
const [productCollection] = await service.list({
title: "New Collection",
expect(productCollectionResults).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
expect.objectContaining({
id: "test-2",
title: "col 2",
}),
expect.objectContaining({
id: "test-3",
title: "col 3 extra",
}),
expect.objectContaining({
id: "test-4",
title: "col 4 extra",
}),
])
})
it("list product collections by id", async () => {
const productCollectionResults = await service.list({
id: data![0].id,
})
expect(productCollectionResults).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
])
})
it("list product collections by title matching string", async () => {
const productCollectionResults = await service.list({
title: "col 3 extra",
})
expect(productCollectionResults).toEqual([
expect.objectContaining({
id: "test-3",
title: "col 3 extra",
}),
])
})
})
expect(productCollection.title).toEqual("New Collection")
describe("listAndCount", () => {
const data = [
{
id: "test-1",
title: "col 1",
},
{
id: "test-2",
title: "col 2",
},
{
id: "test-3",
title: "col 3 extra",
},
{
id: "test-4",
title: "col 4 extra",
},
]
beforeEach(async () => {
await createCollections(MikroOrmWrapper.forkManager(), data)
})
it("should return all collections and count", async () => {
const [productCollectionResults, count] = await service.listAndCount()
const serialized = JSON.parse(
JSON.stringify(productCollectionResults)
)
expect(serialized).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
expect.objectContaining({
id: "test-2",
title: "col 2",
}),
expect.objectContaining({
id: "test-3",
title: "col 3 extra",
}),
expect.objectContaining({
id: "test-4",
title: "col 4 extra",
}),
])
})
it("should return count and collections based on filter data", async () => {
const [productCollectionResults, count] = await service.listAndCount({
id: data![0].id,
})
const serialized = JSON.parse(
JSON.stringify(productCollectionResults)
)
expect(count).toEqual(1)
expect(serialized).toEqual([
expect.objectContaining({
id: "test-1",
title: "col 1",
}),
])
})
it("should return count and collections based on config data", async () => {
const [productCollectionResults, count] = await service.listAndCount(
{},
{
relations: ["products"],
select: ["title"],
take: 1,
skip: 1,
}
)
const serialized = JSON.parse(
JSON.stringify(productCollectionResults)
)
expect(count).toEqual(4)
expect(serialized).toEqual([
{
id: "test-2",
title: "col 2",
products: [],
},
])
})
})
describe("retrieve", () => {
const collectionData = {
id: "collection-1",
title: "collection 1",
}
beforeEach(async () => {
await createCollections(MikroOrmWrapper.forkManager(), [
collectionData,
])
})
it("should return collection for the given id", async () => {
const productCollectionResults = await service.retrieve(
collectionData.id
)
expect(productCollectionResults).toEqual(
expect.objectContaining({
id: collectionData.id,
})
)
})
it("should throw an error when collection with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductCollection 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(
"productCollection - id must be defined"
)
})
it("should return collection based on config select param", async () => {
const productCollectionResults = await service.retrieve(
collectionData.id,
{
select: ["id", "title"],
}
)
const serialized = JSON.parse(
JSON.stringify(productCollectionResults)
)
expect(serialized).toEqual({
id: collectionData.id,
title: collectionData.title,
})
})
it("should return collection based on config relation param", async () => {
const productCollectionResults = await service.retrieve(
collectionData.id,
{
select: ["id", "title"],
relations: ["products"],
}
)
const serialized = JSON.parse(
JSON.stringify(productCollectionResults)
)
expect(serialized).toEqual({
id: collectionData.id,
title: collectionData.title,
products: [],
})
})
})
describe("delete", () => {
const collectionId = "collection-1"
const collectionData = {
id: collectionId,
title: "collection 1",
}
beforeEach(async () => {
await createCollections(MikroOrmWrapper.forkManager(), [
collectionData,
])
})
it("should delete the product collection given an ID successfully", async () => {
await service.delete([collectionId])
const collections = await service.list({
id: collectionId,
})
expect(collections).toHaveLength(0)
})
})
describe("update", () => {
const collectionId = "collection-1"
const collectionData = {
id: collectionId,
title: "collection 1",
}
beforeEach(async () => {
await createCollections(MikroOrmWrapper.forkManager(), [
collectionData,
])
})
it("should update the value of the collection successfully", async () => {
await service.update([
{
id: collectionId,
title: "New Collection",
},
])
const productCollection = await service.retrieve(collectionId)
expect(productCollection.title).toEqual("New Collection")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
title: "New Collection",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductCollection with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a collection successfully", async () => {
await service.create([
{
title: "New Collection",
},
])
const [productCollection] = await service.list({
title: "New Collection",
})
expect(productCollection.title).toEqual("New Collection")
})
})
})
})
},
})
@@ -1,442 +1,443 @@
import { IProductModuleService, ProductTypes } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product, ProductCollection } from "@models"
import { EventBusService } from "../../../__fixtures__/event-bus"
import { MockEventBusService } from "medusa-test-utils"
import { createCollections } from "../../../__fixtures__/product"
import { getInitModuleConfig, TestDatabase } from "../../../utils"
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { initModules } from "medusa-test-utils"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
describe("ProductModuleService product collections", () => {
let service: IProductModuleService
let testManager: SqlEntityManager
let productOne: Product
let productTwo: Product
let productCollectionOne: ProductCollection
let productCollectionTwo: ProductCollection
let productCollections: ProductCollection[]
jest.setTimeout(30000)
let shutdownFunc: () => Promise<void>
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
injectedDependencies: {
eventBusModuleService: new MockEventBusService(),
},
testSuite: ({
MikroOrmWrapper,
service,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductModuleService product collections", () => {
let productOne: Product
let productTwo: Product
let productCollectionOne: ProductCollection
let productCollectionTwo: ProductCollection
let productCollections: ProductCollection[]
beforeAll(async () => {
MedusaModule.clearInstances()
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
service = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterAll(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await TestDatabase.setupDatabase()
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
const productCollectionsData = [
{
id: "test-1",
title: "collection 1",
products: [productOne],
},
{
id: "test-2",
title: "collection",
products: [productTwo],
},
]
productCollections = await createCollections(
testManager,
productCollectionsData
)
productCollectionOne = productCollections[0]
productCollectionTwo = productCollections[1]
})
afterEach(async () => {
await TestDatabase.clearDatabase()
jest.clearAllMocks()
})
describe("listCollections", () => {
it("should return collections queried by ID", async () => {
const results = await service.listCollections({
id: productCollectionOne.id,
})
expect(results).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
})
it("should return collections based on the options and filter parameter", async () => {
let results = await service.listCollections(
{
id: productCollectionOne.id,
},
{
take: 1,
}
)
expect(results).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
results = await service.listCollections({}, { take: 1, skip: 1 })
expect(results).toEqual([
expect.objectContaining({
id: productCollectionTwo.id,
}),
])
})
it("should return only requested fields and relations for collections", async () => {
const results = await service.listCollections(
{
id: productCollectionOne.id,
},
{
select: ["id", "title", "products.title"],
relations: ["products"],
}
)
expect(results).toEqual([
expect.objectContaining({
id: "test-1",
title: "collection 1",
products: [
expect.objectContaining({
id: "product-1",
title: "product 1",
}),
],
}),
])
})
})
describe("listAndCountCollections", () => {
it("should return collections and count queried by ID", async () => {
const results = await service.listAndCountCollections({
id: productCollectionOne.id,
})
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
})
it("should return collections and count based on the options and filter parameter", async () => {
let results = await service.listAndCountCollections(
{
id: productCollectionOne.id,
},
{
take: 1,
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
results = await service.listAndCountCollections({}, { take: 1 })
expect(results[1]).toEqual(2)
results = await service.listAndCountCollections({}, { take: 1, skip: 1 })
expect(results[1]).toEqual(2)
expect(results[0]).toEqual([
expect.objectContaining({
id: productCollectionTwo.id,
}),
])
})
it("should return only requested fields and relations for collections", async () => {
const results = await service.listAndCountCollections(
{
id: productCollectionOne.id,
},
{
select: ["id", "title", "products.title"],
relations: ["products"],
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: "test-1",
title: "collection 1",
products: [
expect.objectContaining({
id: "product-1",
title: "product 1",
}),
],
}),
])
})
})
describe("retrieveCollection", () => {
it("should return the requested collection", async () => {
const result = await service.retrieveCollection(productCollectionOne.id)
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "collection 1",
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
)
})
it("should return requested attributes when requested through config", async () => {
const result = await service.retrieveCollection(productCollectionOne.id, {
select: ["id", "title", "products.title"],
relations: ["products"],
})
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "collection 1",
products: [
expect.objectContaining({
id: "product-1",
title: "product 1",
}),
],
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
)
})
it("should throw an error when a collection with ID does not exist", async () => {
let error
try {
await service.retrieveCollection("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductCollection with id: does-not-exist was not found"
)
})
})
describe("deleteCollections", () => {
const collectionId = "test-1"
it("should delete the product collection given an ID successfully", async () => {
await service.deleteCollections([collectionId])
const collections = await service.listCollections({
id: collectionId,
})
expect(collections).toHaveLength(0)
})
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(EventBusService.prototype, "emit")
await service.deleteCollections([collectionId])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith([
{
eventName: "product-collection.deleted",
data: { id: collectionId },
},
])
})
})
describe("updateCollections", () => {
const collectionId = "test-1"
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(EventBusService.prototype, "emit")
await service.upsertCollections([
{
id: collectionId,
title: "New Collection",
},
])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith([
{
eventName: "product-collection.updated",
data: { id: collectionId },
},
])
})
it("should update the value of the collection successfully", async () => {
await service.upsertCollections([
{
id: collectionId,
title: "New Collection",
},
])
const productCollection = await service.retrieveCollection(collectionId)
expect(productCollection.title).toEqual("New Collection")
})
it("should add products to a collection successfully", async () => {
await service.upsertCollections([
{
id: collectionId,
product_ids: [productOne.id, productTwo.id],
},
])
const productCollection = await service.retrieveCollection(collectionId, {
select: ["products.id"],
relations: ["products"],
})
expect(productCollection.products).toHaveLength(2)
expect(productCollection).toEqual(
expect.objectContaining({
products: expect.arrayContaining([
expect.objectContaining({
id: productOne.id,
}),
expect.objectContaining({
id: productTwo.id,
}),
]),
})
)
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.upsertCollections([
const productCollectionsData = [
{
id: "does-not-exist",
title: "New Collection",
id: "test-1",
title: "collection 1",
products: [productOne],
},
])
} catch (e) {
error = e
}
{
id: "test-2",
title: "collection",
products: [productTwo],
},
]
expect(error.message).toEqual(
'ProductCollection with id "does-not-exist" not found'
)
})
})
productCollections = await createCollections(
testManager,
productCollectionsData
)
describe("createCollections", () => {
it("should create a collection successfully", async () => {
const res = await service.createCollections([
{
title: "New Collection",
},
])
const [productCollection] = await service.listCollections({
title: "New Collection",
productCollectionOne = productCollections[0]
productCollectionTwo = productCollections[1]
})
expect(productCollection.title).toEqual("New Collection")
})
afterEach(async () => {
jest.clearAllMocks()
})
it("should create collection with products successfully", async () => {
await service.createCollections([
{
title: "New Collection with products",
handle: "new-collection-with-products",
product_ids: [productOne.id, productTwo.id],
},
])
describe("listCollections", () => {
it("should return collections queried by ID", async () => {
const results = await service.listCollections({
id: productCollectionOne.id,
})
const [productCollection] = await service.listCollections(
{
handle: "new-collection-with-products",
},
{
select: ["title", "handle", "products.id"],
relations: ["products"],
}
)
expect(productCollection).toEqual(
expect.objectContaining({
title: "New Collection with products",
handle: "new-collection-with-products",
products: [
expect(results).toEqual([
expect.objectContaining({
id: productOne.id,
id: productCollectionOne.id,
}),
expect.objectContaining({
id: productTwo.id,
}),
],
])
})
)
it("should return collections based on the options and filter parameter", async () => {
let results = await service.listCollections(
{
id: productCollectionOne.id,
},
{
take: 1,
}
)
expect(results).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
results = await service.listCollections({}, { take: 1, skip: 1 })
expect(results).toEqual([
expect.objectContaining({
id: productCollectionTwo.id,
}),
])
})
it("should return only requested fields and relations for collections", async () => {
const results = await service.listCollections(
{
id: productCollectionOne.id,
},
{
select: ["id", "title", "products.title"],
relations: ["products"],
}
)
expect(results).toEqual([
expect.objectContaining({
id: "test-1",
title: "collection 1",
products: [
expect.objectContaining({
id: "product-1",
title: "product 1",
}),
],
}),
])
})
})
describe("listAndCountCollections", () => {
it("should return collections and count queried by ID", async () => {
const results = await service.listAndCountCollections({
id: productCollectionOne.id,
})
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
})
it("should return collections and count based on the options and filter parameter", async () => {
let results = await service.listAndCountCollections(
{
id: productCollectionOne.id,
},
{
take: 1,
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: productCollectionOne.id,
}),
])
results = await service.listAndCountCollections({}, { take: 1 })
expect(results[1]).toEqual(2)
results = await service.listAndCountCollections(
{},
{ take: 1, skip: 1 }
)
expect(results[1]).toEqual(2)
expect(results[0]).toEqual([
expect.objectContaining({
id: productCollectionTwo.id,
}),
])
})
it("should return only requested fields and relations for collections", async () => {
const results = await service.listAndCountCollections(
{
id: productCollectionOne.id,
},
{
select: ["id", "title", "products.title"],
relations: ["products"],
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: "test-1",
title: "collection 1",
products: [
expect.objectContaining({
id: "product-1",
title: "product 1",
}),
],
}),
])
})
})
describe("retrieveCollection", () => {
it("should return the requested collection", async () => {
const result = await service.retrieveCollection(
productCollectionOne.id
)
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "collection 1",
})
)
})
it("should return requested attributes when requested through config", async () => {
const result = await service.retrieveCollection(
productCollectionOne.id,
{
select: ["id", "title", "products.title"],
relations: ["products"],
}
)
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "collection 1",
products: [
expect.objectContaining({
id: "product-1",
title: "product 1",
}),
],
})
)
})
it("should throw an error when a collection with ID does not exist", async () => {
let error
try {
await service.retrieveCollection("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductCollection with id: does-not-exist was not found"
)
})
})
describe("deleteCollections", () => {
const collectionId = "test-1"
it("should delete the product collection given an ID successfully", async () => {
await service.deleteCollections([collectionId])
const collections = await service.listCollections({
id: collectionId,
})
expect(collections).toHaveLength(0)
})
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
await service.deleteCollections([collectionId])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith([
{
eventName: "product-collection.deleted",
data: { id: collectionId },
},
])
})
})
describe("updateCollections", () => {
const collectionId = "test-1"
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
await service.upsertCollections([
{
id: collectionId,
title: "New Collection",
},
])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith([
{
eventName: "product-collection.updated",
data: { id: collectionId },
},
])
})
it("should update the value of the collection successfully", async () => {
await service.upsertCollections([
{
id: collectionId,
title: "New Collection",
},
])
const productCollection = await service.retrieveCollection(
collectionId
)
expect(productCollection.title).toEqual("New Collection")
})
it("should add products to a collection successfully", async () => {
await service.upsertCollections([
{
id: collectionId,
product_ids: [productOne.id, productTwo.id],
},
])
const productCollection = await service.retrieveCollection(
collectionId,
{
select: ["products.id"],
relations: ["products"],
}
)
expect(productCollection.products).toHaveLength(2)
expect(productCollection).toEqual(
expect.objectContaining({
products: expect.arrayContaining([
expect.objectContaining({
id: productOne.id,
}),
expect.objectContaining({
id: productTwo.id,
}),
]),
})
)
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.upsertCollections([
{
id: "does-not-exist",
title: "New Collection",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductCollection with id "does-not-exist" not found'
)
})
})
describe("createCollections", () => {
it("should create a collection successfully", async () => {
const res = await service.createCollections([
{
title: "New Collection",
},
])
const [productCollection] = await service.listCollections({
title: "New Collection",
})
expect(productCollection.title).toEqual("New Collection")
})
it("should create collection with products successfully", async () => {
await service.createCollections([
{
title: "New Collection with products",
handle: "new-collection-with-products",
product_ids: [productOne.id, productTwo.id],
},
])
const [productCollection] = await service.listCollections(
{
handle: "new-collection-with-products",
},
{
select: ["title", "handle", "products.id"],
relations: ["products"],
}
)
expect(productCollection).toEqual(
expect.objectContaining({
title: "New Collection with products",
handle: "new-collection-with-products",
products: [
expect.objectContaining({
id: productOne.id,
}),
expect.objectContaining({
id: productTwo.id,
}),
],
})
)
})
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
const collections = await service.createCollections([
{
title: "New Collection",
},
])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith([
{
eventName: "product-collection.created",
data: { id: collections[0].id },
},
])
})
})
})
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(EventBusService.prototype, "emit")
const collections = await service.createCollections([
{
title: "New Collection",
},
])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith([
{
eventName: "product-collection.created",
data: { id: collections[0].id },
},
])
})
})
},
})
@@ -1,325 +1,307 @@
import { IProductModuleService, ProductTypes } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product, ProductOption } from "@models"
import { getInitModuleConfig, TestDatabase } from "../../../utils"
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { initModules } from "medusa-test-utils"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
describe("ProductModuleService product options", () => {
let service: IProductModuleService
let testManager: SqlEntityManager
let optionOne: ProductOption
let optionTwo: ProductOption
let productOne: Product
let productTwo: Product
jest.setTimeout(30000)
let shutdownFunc: () => Promise<void>
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
service,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductModuleService product options", () => {
let optionOne: ProductOption
let optionTwo: ProductOption
let productOne: Product
let productTwo: Product
beforeAll(async () => {
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
service = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterAll(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await TestDatabase.setupDatabase()
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
optionOne = testManager.create(ProductOption, {
id: "option-1",
title: "option 1",
product: productOne,
})
optionTwo = testManager.create(ProductOption, {
id: "option-2",
title: "option 1",
product: productTwo,
})
await testManager.persistAndFlush([optionOne, optionTwo])
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("listOptions", () => {
it("should return options and count queried by ID", async () => {
const options = await service.listOptions({
id: optionOne.id,
})
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
})
it("should return options and count based on the options and filter parameter", async () => {
let options = await service.listOptions(
{
id: optionOne.id,
},
{
take: 1,
}
)
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
options = await service.listOptions({}, { take: 1, skip: 1 })
expect(options).toEqual([
expect.objectContaining({
id: optionTwo.id,
}),
])
})
it("should return only requested fields and relations for options", async () => {
const options = await service.listOptions(
{
id: optionOne.id,
},
{
select: ["title", "product.id"],
relations: ["product"],
take: 1,
}
)
expect(options).toEqual([
{
id: optionOne.id,
title: optionOne.title,
product_id: productOne.id,
product: {
id: productOne.id,
},
},
])
})
})
describe("listAndCountOptions", () => {
it("should return options and count queried by ID", async () => {
const [options, count] = await service.listAndCountOptions({
id: optionOne.id,
})
expect(count).toEqual(1)
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
})
it("should return options and count based on the options and filter parameter", async () => {
let [options, count] = await service.listAndCountOptions(
{
id: optionOne.id,
},
{
take: 1,
}
)
expect(count).toEqual(1)
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
;[options, count] = await service.listAndCountOptions({}, { take: 1 })
expect(count).toEqual(2)
;[options, count] = await service.listAndCountOptions(
{},
{ take: 1, skip: 1 }
)
expect(count).toEqual(2)
expect(options).toEqual([
expect.objectContaining({
id: optionTwo.id,
}),
])
})
it("should return only requested fields and relations for options", async () => {
const [options, count] = await service.listAndCountOptions(
{
id: optionOne.id,
},
{
select: ["title", "product.id"],
relations: ["product"],
take: 1,
}
)
expect(count).toEqual(1)
expect(options).toEqual([
{
id: optionOne.id,
title: optionOne.title,
product_id: productOne.id,
product: {
id: productOne.id,
},
},
])
})
})
describe("retrieveOption", () => {
it("should return the requested option", async () => {
const option = await service.retrieveOption(optionOne.id)
expect(option).toEqual(
expect.objectContaining({
id: optionOne.id,
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
)
})
it("should return requested attributes when requested through config", async () => {
const option = await service.retrieveOption(optionOne.id, {
select: ["id", "product.title"],
relations: ["product"],
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
optionOne = testManager.create(ProductOption, {
id: "option-1",
title: "option 1",
product: productOne,
})
optionTwo = testManager.create(ProductOption, {
id: "option-2",
title: "option 1",
product: productTwo,
})
await testManager.persistAndFlush([optionOne, optionTwo])
})
expect(option).toEqual(
expect.objectContaining({
id: optionOne.id,
product: {
id: "product-1",
title: "product 1",
},
describe("listOptions", () => {
it("should return options and count queried by ID", async () => {
const options = await service.listOptions({
id: optionOne.id,
})
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
})
)
})
it("should throw an error when a option with ID does not exist", async () => {
let error
it("should return options and count based on the options and filter parameter", async () => {
let options = await service.listOptions(
{
id: optionOne.id,
},
{
take: 1,
}
)
try {
await service.retrieveOption("does-not-exist")
} catch (e) {
error = e
}
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
expect(error.message).toEqual(
"ProductOption with id: does-not-exist was not found"
)
})
})
options = await service.listOptions({}, { take: 1, skip: 1 })
describe("deleteOptions", () => {
const optionId = "option-1"
expect(options).toEqual([
expect.objectContaining({
id: optionTwo.id,
}),
])
})
it("should delete the product option given an ID successfully", async () => {
await service.deleteOptions([optionId])
it("should return only requested fields and relations for options", async () => {
const options = await service.listOptions(
{
id: optionOne.id,
},
{
select: ["title", "product.id"],
relations: ["product"],
take: 1,
}
)
const options = await service.listOptions({
id: optionId,
expect(options).toEqual([
{
id: optionOne.id,
title: optionOne.title,
product_id: productOne.id,
product: {
id: productOne.id,
},
},
])
})
})
expect(options).toHaveLength(0)
})
})
describe("listAndCountOptions", () => {
it("should return options and count queried by ID", async () => {
const [options, count] = await service.listAndCountOptions({
id: optionOne.id,
})
describe("updateOptions", () => {
const optionId = "option-1"
it("should update the title of the option successfully", async () => {
await service.updateOptions([
{
id: optionId,
title: "new test",
},
])
const productOption = await service.retrieveOption(optionId)
expect(productOption.title).toEqual("new test")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.updateOptions([
{
id: "does-not-exist",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductOption with id "does-not-exist" not found'
)
})
})
describe("createOptions", () => {
it("should create a option successfully", async () => {
const res = await service.createOptions([
{
title: "test",
product_id: productOne.id,
},
])
const [productOption] = await service.listOptions(
{
title: "test",
},
{
select: ["id", "title", "product.id"],
relations: ["product"],
}
)
expect(productOption).toEqual(
expect.objectContaining({
title: "test",
product: expect.objectContaining({
id: productOne.id,
}),
expect(count).toEqual(1)
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
})
)
it("should return options and count based on the options and filter parameter", async () => {
let [options, count] = await service.listAndCountOptions(
{
id: optionOne.id,
},
{
take: 1,
}
)
expect(count).toEqual(1)
expect(options).toEqual([
expect.objectContaining({
id: optionOne.id,
}),
])
;[options, count] = await service.listAndCountOptions({}, { take: 1 })
expect(count).toEqual(2)
;[options, count] = await service.listAndCountOptions(
{},
{ take: 1, skip: 1 }
)
expect(count).toEqual(2)
expect(options).toEqual([
expect.objectContaining({
id: optionTwo.id,
}),
])
})
it("should return only requested fields and relations for options", async () => {
const [options, count] = await service.listAndCountOptions(
{
id: optionOne.id,
},
{
select: ["title", "product.id"],
relations: ["product"],
take: 1,
}
)
expect(count).toEqual(1)
expect(options).toEqual([
{
id: optionOne.id,
title: optionOne.title,
product_id: productOne.id,
product: {
id: productOne.id,
},
},
])
})
})
describe("retrieveOption", () => {
it("should return the requested option", async () => {
const option = await service.retrieveOption(optionOne.id)
expect(option).toEqual(
expect.objectContaining({
id: optionOne.id,
})
)
})
it("should return requested attributes when requested through config", async () => {
const option = await service.retrieveOption(optionOne.id, {
select: ["id", "product.title"],
relations: ["product"],
})
expect(option).toEqual(
expect.objectContaining({
id: optionOne.id,
product: {
id: "product-1",
title: "product 1",
},
})
)
})
it("should throw an error when a option with ID does not exist", async () => {
let error
try {
await service.retrieveOption("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductOption with id: does-not-exist was not found"
)
})
})
describe("deleteOptions", () => {
const optionId = "option-1"
it("should delete the product option given an ID successfully", async () => {
await service.deleteOptions([optionId])
const options = await service.listOptions({
id: optionId,
})
expect(options).toHaveLength(0)
})
})
describe("updateOptions", () => {
const optionId = "option-1"
it("should update the title of the option successfully", async () => {
await service.updateOptions([
{
id: optionId,
title: "new test",
},
])
const productOption = await service.retrieveOption(optionId)
expect(productOption.title).toEqual("new test")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.updateOptions([
{
id: "does-not-exist",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductOption with id "does-not-exist" not found'
)
})
})
describe("createOptions", () => {
it("should create a option successfully", async () => {
const res = await service.createOptions([
{
title: "test",
product_id: productOne.id,
},
])
const [productOption] = await service.listOptions(
{
title: "test",
},
{
select: ["id", "title", "product.id"],
relations: ["product"],
}
)
expect(productOption).toEqual(
expect.objectContaining({
title: "test",
product: expect.objectContaining({
id: productOne.id,
}),
})
)
})
})
})
})
},
})
@@ -1,313 +1,298 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { Modules } from "@medusajs/modules-sdk"
import { IProductModuleService, ProductTypes } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product, ProductTag } from "@models"
import { initModules } from "medusa-test-utils"
import { TestDatabase, getInitModuleConfig } from "../../../utils"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
describe("ProductModuleService product tags", () => {
let service: IProductModuleService
let testManager: SqlEntityManager
let tagOne: ProductTag
let tagTwo: ProductTag
let productOne: Product
let productTwo: Product
jest.setTimeout(30000)
let shutdownFunc: () => Promise<void>
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
service,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductModuleService product tags", () => {
let tagOne: ProductTag
let tagTwo: ProductTag
let productOne: Product
let productTwo: Product
beforeAll(async () => {
MedusaModule.clearInstances()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
service = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterAll(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await TestDatabase.setupDatabase()
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
tagOne = testManager.create(ProductTag, {
id: "tag-1",
value: "tag 1",
products: [productOne],
})
tagTwo = testManager.create(ProductTag, {
id: "tag-2",
value: "tag",
products: [productTwo],
})
await testManager.persistAndFlush([tagOne, tagTwo])
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("listTags", () => {
it("should return tags and count queried by ID", async () => {
const tags = await service.listTags({
id: tagOne.id,
})
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
})
it("should return tags and count based on the options and filter parameter", async () => {
let tags = await service.listTags(
{
id: tagOne.id,
},
{
take: 1,
}
)
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
tags = await service.listTags({}, { take: 1, skip: 1 })
expect(tags).toEqual([
expect.objectContaining({
id: tagTwo.id,
}),
])
})
it("should return only requested fields and relations for tags", async () => {
const tags = await service.listTags(
{
id: tagOne.id,
},
{
select: ["value", "products.id"],
relations: ["products"],
take: 1,
}
)
expect(tags).toEqual([
{
id: tagOne.id,
value: tagOne.value,
products: [
{
id: productOne.id,
},
],
},
])
})
})
describe("listAndCountTags", () => {
it("should return tags and count queried by ID", async () => {
const [tags, count] = await service.listAndCountTags({
id: tagOne.id,
})
expect(count).toEqual(1)
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
})
it("should return tags and count based on the options and filter parameter", async () => {
let [tags, count] = await service.listAndCountTags(
{
id: tagOne.id,
},
{
take: 1,
}
)
expect(count).toEqual(1)
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
;[tags, count] = await service.listAndCountTags({}, { take: 1 })
expect(count).toEqual(2)
;[tags, count] = await service.listAndCountTags({}, { take: 1, skip: 1 })
expect(count).toEqual(2)
expect(tags).toEqual([
expect.objectContaining({
id: tagTwo.id,
}),
])
})
it("should return only requested fields and relations for tags", async () => {
const [tags, count] = await service.listAndCountTags(
{
id: tagOne.id,
},
{
select: ["value", "products.id"],
relations: ["products"],
take: 1,
}
)
expect(count).toEqual(1)
expect(tags).toEqual([
{
id: tagOne.id,
value: tagOne.value,
products: [
{
id: productOne.id,
},
],
},
])
})
})
describe("retrieveTag", () => {
it("should return the requested tag", async () => {
const tag = await service.retrieveTag(tagOne.id)
expect(tag).toEqual(
expect.objectContaining({
id: tagOne.id,
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
)
})
it("should return requested attributes when requested through config", async () => {
const tag = await service.retrieveTag(tagOne.id, {
select: ["id", "value", "products.title"],
relations: ["products"],
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
tagOne = testManager.create(ProductTag, {
id: "tag-1",
value: "tag 1",
products: [productOne],
})
tagTwo = testManager.create(ProductTag, {
id: "tag-2",
value: "tag",
products: [productTwo],
})
await testManager.persistAndFlush([tagOne, tagTwo])
})
expect(tag).toEqual(
expect.objectContaining({
id: tagOne.id,
value: tagOne.value,
products: [
describe("listTags", () => {
it("should return tags and count queried by ID", async () => {
const tags = await service.listTags({
id: tagOne.id,
})
expect(tags).toEqual([
expect.objectContaining({
title: "product 1",
id: tagOne.id,
}),
],
])
})
)
})
it("should throw an error when a tag with ID does not exist", async () => {
let error
it("should return tags and count based on the options and filter parameter", async () => {
let tags = await service.listTags(
{
id: tagOne.id,
},
{
take: 1,
}
)
try {
await service.retrieveTag("does-not-exist")
} catch (e) {
error = e
}
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
expect(error.message).toEqual(
"ProductTag with id: does-not-exist was not found"
)
})
})
tags = await service.listTags({}, { take: 1, skip: 1 })
describe("deleteTags", () => {
const tagId = "tag-1"
expect(tags).toEqual([
expect.objectContaining({
id: tagTwo.id,
}),
])
})
it("should delete the product tag given an ID successfully", async () => {
await service.deleteTags([tagId])
it("should return only requested fields and relations for tags", async () => {
const tags = await service.listTags(
{
id: tagOne.id,
},
{
select: ["value", "products.id"],
relations: ["products"],
take: 1,
}
)
const tags = await service.listTags({
id: tagId,
expect(tags).toEqual([
{
id: tagOne.id,
value: tagOne.value,
products: [
{
id: productOne.id,
},
],
},
])
})
})
expect(tags).toHaveLength(0)
})
})
describe("listAndCountTags", () => {
it("should return tags and count queried by ID", async () => {
const [tags, count] = await service.listAndCountTags({
id: tagOne.id,
})
describe("updateTags", () => {
const tagId = "tag-1"
expect(count).toEqual(1)
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
})
it("should update the value of the tag successfully", async () => {
await service.updateTags([
{
id: tagId,
value: "UK",
},
])
it("should return tags and count based on the options and filter parameter", async () => {
let [tags, count] = await service.listAndCountTags(
{
id: tagOne.id,
},
{
take: 1,
}
)
const productTag = await service.retrieveTag(tagId)
expect(count).toEqual(1)
expect(tags).toEqual([
expect.objectContaining({
id: tagOne.id,
}),
])
;[tags, count] = await service.listAndCountTags({}, { take: 1 })
expect(productTag.value).toEqual("UK")
})
expect(count).toEqual(2)
;[tags, count] = await service.listAndCountTags(
{},
{ take: 1, skip: 1 }
)
it("should throw an error when an id does not exist", async () => {
let error
expect(count).toEqual(2)
expect(tags).toEqual([
expect.objectContaining({
id: tagTwo.id,
}),
])
})
try {
await service.updateTags([
{
id: "does-not-exist",
it("should return only requested fields and relations for tags", async () => {
const [tags, count] = await service.listAndCountTags(
{
id: tagOne.id,
},
{
select: ["value", "products.id"],
relations: ["products"],
take: 1,
}
)
expect(count).toEqual(1)
expect(tags).toEqual([
{
id: tagOne.id,
value: tagOne.value,
products: [
{
id: productOne.id,
},
],
},
])
})
})
describe("retrieveTag", () => {
it("should return the requested tag", async () => {
const tag = await service.retrieveTag(tagOne.id)
expect(tag).toEqual(
expect.objectContaining({
id: tagOne.id,
})
)
})
it("should return requested attributes when requested through config", async () => {
const tag = await service.retrieveTag(tagOne.id, {
select: ["id", "value", "products.title"],
relations: ["products"],
})
expect(tag).toEqual(
expect.objectContaining({
id: tagOne.id,
value: tagOne.value,
products: [
expect.objectContaining({
title: "product 1",
}),
],
})
)
})
it("should throw an error when a tag with ID does not exist", async () => {
let error
try {
await service.retrieveTag("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductTag with id: does-not-exist was not found"
)
})
})
describe("deleteTags", () => {
const tagId = "tag-1"
it("should delete the product tag given an ID successfully", async () => {
await service.deleteTags([tagId])
const tags = await service.listTags({
id: tagId,
})
expect(tags).toHaveLength(0)
})
})
describe("updateTags", () => {
const tagId = "tag-1"
it("should update the value of the tag successfully", async () => {
await service.updateTags([
{
id: tagId,
value: "UK",
},
])
const productTag = await service.retrieveTag(tagId)
expect(productTag.value).toEqual("UK")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.updateTags([
{
id: "does-not-exist",
value: "UK",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductTag with id "does-not-exist" not found'
)
})
})
describe("createTags", () => {
it("should create a tag successfully", async () => {
const res = await service.createTags([
{
value: "UK",
},
])
const productTag = await service.listTags({
value: "UK",
},
])
} catch (e) {
error = e
}
})
expect(error.message).toEqual(
'ProductTag with id "does-not-exist" not found'
)
})
})
describe("createTags", () => {
it("should create a tag successfully", async () => {
const res = await service.createTags([
{
value: "UK",
},
])
const productTag = await service.listTags({
value: "UK",
expect(productTag[0]?.value).toEqual("UK")
})
})
expect(productTag[0]?.value).toEqual("UK")
})
})
},
})
@@ -1,281 +1,263 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { Modules } from "@medusajs/modules-sdk"
import { IProductModuleService } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { ProductType } from "@models"
import { initModules } from "medusa-test-utils"
import { getInitModuleConfig, TestDatabase } from "../../../utils"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
describe("ProductModuleService product types", () => {
let service: IProductModuleService
let testManager: SqlEntityManager
let typeOne: ProductType
let typeTwo: ProductType
jest.setTimeout(30000)
let shutdownFunc: () => Promise<void>
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
service,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductModuleService product types", () => {
let typeOne: ProductType
let typeTwo: ProductType
beforeAll(async () => {
MedusaModule.clearInstances()
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
const initModulesConfig = getInitModuleConfig()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
service = medusaApp.modules[Modules.PRODUCT]
shutdownFunc = shutdown
})
afterAll(async () => {
await shutdownFunc()
})
beforeEach(async () => {
await TestDatabase.setupDatabase()
testManager = await TestDatabase.forkManager()
typeOne = testManager.create(ProductType, {
id: "type-1",
value: "type 1",
})
typeTwo = testManager.create(ProductType, {
id: "type-2",
value: "type",
})
await testManager.persistAndFlush([typeOne, typeTwo])
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("listTypes", () => {
it("should return types and count queried by ID", async () => {
const types = await service.listTypes({
id: typeOne.id,
})
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
})
it("should return types and count based on the options and filter parameter", async () => {
let types = await service.listTypes(
{
id: typeOne.id,
},
{
take: 1,
}
)
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
types = await service.listTypes({}, { take: 1, skip: 1 })
expect(types).toEqual([
expect.objectContaining({
id: typeTwo.id,
}),
])
})
it("should return only requested fields for types", async () => {
const types = await service.listTypes(
{
id: typeOne.id,
},
{
select: ["value"],
take: 1,
}
)
expect(types).toEqual([
{
id: typeOne.id,
value: typeOne.value,
},
])
})
})
describe("listAndCountTypes", () => {
it("should return types and count queried by ID", async () => {
const [types, count] = await service.listAndCountTypes({
id: typeOne.id,
})
expect(count).toEqual(1)
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
})
it("should return types and count based on the options and filter parameter", async () => {
let [types, count] = await service.listAndCountTypes(
{
id: typeOne.id,
},
{
take: 1,
}
)
expect(count).toEqual(1)
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
;[types, count] = await service.listAndCountTypes({}, { take: 1 })
expect(count).toEqual(2)
;[types, count] = await service.listAndCountTypes(
{},
{ take: 1, skip: 1 }
)
expect(count).toEqual(2)
expect(types).toEqual([
expect.objectContaining({
id: typeTwo.id,
}),
])
})
it("should return only requested fields for types", async () => {
const [types, count] = await service.listAndCountTypes(
{
id: typeOne.id,
},
{
select: ["value"],
take: 1,
}
)
expect(count).toEqual(1)
expect(types).toEqual([
{
id: typeOne.id,
value: typeOne.value,
},
])
})
})
describe("retrieveType", () => {
it("should return the requested type", async () => {
const type = await service.retrieveType(typeOne.id)
expect(type).toEqual(
expect.objectContaining({
id: typeOne.id,
typeOne = testManager.create(ProductType, {
id: "type-1",
value: "type 1",
})
)
})
it("should return requested attributes when requested through config", async () => {
const type = await service.retrieveType(typeOne.id, {
select: ["id", "value"],
typeTwo = testManager.create(ProductType, {
id: "type-2",
value: "type",
})
await testManager.persistAndFlush([typeOne, typeTwo])
})
expect(type).toEqual({
id: typeOne.id,
value: typeOne.value,
})
})
describe("listTypes", () => {
it("should return types and count queried by ID", async () => {
const types = await service.listTypes({
id: typeOne.id,
})
it("should throw an error when a type with ID does not exist", async () => {
let error
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
})
try {
await service.retrieveType("does-not-exist")
} catch (e) {
error = e
}
it("should return types and count based on the options and filter parameter", async () => {
let types = await service.listTypes(
{
id: typeOne.id,
},
{
take: 1,
}
)
expect(error.message).toEqual(
"ProductType with id: does-not-exist was not found"
)
})
})
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
describe("deleteTypes", () => {
const typeId = "type-1"
types = await service.listTypes({}, { take: 1, skip: 1 })
it("should delete the product type given an ID successfully", async () => {
await service.deleteTypes([typeId])
expect(types).toEqual([
expect.objectContaining({
id: typeTwo.id,
}),
])
})
const types = await service.listTypes({
id: typeId,
it("should return only requested fields for types", async () => {
const types = await service.listTypes(
{
id: typeOne.id,
},
{
select: ["value"],
take: 1,
}
)
expect(types).toEqual([
{
id: typeOne.id,
value: typeOne.value,
},
])
})
})
expect(types).toHaveLength(0)
})
})
describe("listAndCountTypes", () => {
it("should return types and count queried by ID", async () => {
const [types, count] = await service.listAndCountTypes({
id: typeOne.id,
})
describe("updateTypes", () => {
const typeId = "type-1"
expect(count).toEqual(1)
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
})
it("should update the value of the type successfully", async () => {
await service.updateTypes([
{
id: typeId,
value: "UK",
},
])
it("should return types and count based on the options and filter parameter", async () => {
let [types, count] = await service.listAndCountTypes(
{
id: typeOne.id,
},
{
take: 1,
}
)
const productType = await service.retrieveType(typeId)
expect(count).toEqual(1)
expect(types).toEqual([
expect.objectContaining({
id: typeOne.id,
}),
])
;[types, count] = await service.listAndCountTypes({}, { take: 1 })
expect(productType.value).toEqual("UK")
})
expect(count).toEqual(2)
;[types, count] = await service.listAndCountTypes(
{},
{ take: 1, skip: 1 }
)
it("should throw an error when an id does not exist", async () => {
let error
expect(count).toEqual(2)
expect(types).toEqual([
expect.objectContaining({
id: typeTwo.id,
}),
])
})
try {
await service.updateTypes([
{
id: "does-not-exist",
it("should return only requested fields for types", async () => {
const [types, count] = await service.listAndCountTypes(
{
id: typeOne.id,
},
{
select: ["value"],
take: 1,
}
)
expect(count).toEqual(1)
expect(types).toEqual([
{
id: typeOne.id,
value: typeOne.value,
},
])
})
})
describe("retrieveType", () => {
it("should return the requested type", async () => {
const type = await service.retrieveType(typeOne.id)
expect(type).toEqual(
expect.objectContaining({
id: typeOne.id,
})
)
})
it("should return requested attributes when requested through config", async () => {
const type = await service.retrieveType(typeOne.id, {
select: ["id", "value"],
})
expect(type).toEqual({
id: typeOne.id,
value: typeOne.value,
})
})
it("should throw an error when a type with ID does not exist", async () => {
let error
try {
await service.retrieveType("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductType with id: does-not-exist was not found"
)
})
})
describe("deleteTypes", () => {
const typeId = "type-1"
it("should delete the product type given an ID successfully", async () => {
await service.deleteTypes([typeId])
const types = await service.listTypes({
id: typeId,
})
expect(types).toHaveLength(0)
})
})
describe("updateTypes", () => {
const typeId = "type-1"
it("should update the value of the type successfully", async () => {
await service.updateTypes([
{
id: typeId,
value: "UK",
},
])
const productType = await service.retrieveType(typeId)
expect(productType.value).toEqual("UK")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.updateTypes([
{
id: "does-not-exist",
value: "UK",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductType with id "does-not-exist" not found'
)
})
})
describe("createTypes", () => {
it("should create a type successfully", async () => {
const res = await service.createTypes([
{
value: "UK",
},
])
const productType = await service.listTypes({
value: "UK",
},
])
} catch (e) {
error = e
}
})
expect(error.message).toEqual(
'ProductType with id "does-not-exist" not found'
)
})
})
describe("createTypes", () => {
it("should create a type successfully", async () => {
const res = await service.createTypes([
{
value: "UK",
},
])
const productType = await service.listTypes({
value: "UK",
expect(productType[0]?.value).toEqual("UK")
})
})
expect(productType[0]?.value).toEqual("UK")
})
})
},
})
@@ -1,186 +1,170 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { Modules } from "@medusajs/modules-sdk"
import { IProductModuleService, ProductTypes } from "@medusajs/types"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product, ProductVariant } from "@models"
import { initModules } from "medusa-test-utils"
import { TestDatabase, getInitModuleConfig } from "../../../utils"
describe("ProductModuleService product variants", () => {
let service: IProductModuleService
let testManager: SqlEntityManager
let variantOne: ProductVariant
let variantTwo: ProductVariant
let productOne: Product
let productTwo: Product
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
let shutdownFunc: () => Promise<void>
jest.setTimeout(30000)
beforeAll(async () => {
MedusaModule.clearInstances()
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
service,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductModuleService product variants", () => {
let variantOne: ProductVariant
let variantTwo: ProductVariant
let productOne: Product
let productTwo: Product
const initModulesConfig = getInitModuleConfig()
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
const { medusaApp, shutdown } = await initModules(initModulesConfig)
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
service = medusaApp.modules[Modules.PRODUCT]
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
shutdownFunc = shutdown
})
variantOne = testManager.create(ProductVariant, {
id: "test-1",
title: "variant 1",
inventory_quantity: 10,
product: productOne,
})
afterAll(async () => {
await shutdownFunc()
})
variantTwo = testManager.create(ProductVariant, {
id: "test-2",
title: "variant",
inventory_quantity: 10,
product: productTwo,
})
beforeEach(async () => {
await TestDatabase.setupDatabase()
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
productTwo = testManager.create(Product, {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
})
variantOne = testManager.create(ProductVariant, {
id: "test-1",
title: "variant 1",
inventory_quantity: 10,
product: productOne,
})
variantTwo = testManager.create(ProductVariant, {
id: "test-2",
title: "variant",
inventory_quantity: 10,
product: productTwo,
})
await testManager.persistAndFlush([variantOne, variantTwo])
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("listAndCountVariants", () => {
it("should return variants and count queried by ID", async () => {
const results = await service.listAndCountVariants({
id: variantOne.id,
await testManager.persistAndFlush([variantOne, variantTwo])
})
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: variantOne.id,
}),
])
})
describe("listAndCountVariants", () => {
it("should return variants and count queried by ID", async () => {
const results = await service.listAndCountVariants({
id: variantOne.id,
})
it("should return variants and count based on the options and filter parameter", async () => {
let results = await service.listAndCountVariants(
{
id: variantOne.id,
},
{
take: 1,
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: variantOne.id,
}),
])
results = await service.listAndCountVariants({}, { take: 1 })
expect(results[1]).toEqual(2)
results = await service.listAndCountVariants({}, { take: 1, skip: 1 })
expect(results[1]).toEqual(2)
expect(results[0]).toEqual([
expect.objectContaining({
id: variantTwo.id,
}),
])
})
it("should return only requested fields and relations for variants", async () => {
const results = await service.listAndCountVariants(
{
id: variantOne.id,
},
{
select: ["id", "title", "product.title"] as any,
relations: ["product"],
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: "test-1",
title: "variant 1",
// TODO: investigate why this is returning more than the expected results
product: expect.objectContaining({
id: "product-1",
title: "product 1",
}),
}),
])
})
})
describe("retrieveVariant", () => {
it("should return the requested variant", async () => {
const result = await service.retrieveVariant(variantOne.id)
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "variant 1",
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: variantOne.id,
}),
])
})
)
})
it("should return requested attributes when requested through config", async () => {
const result = await service.retrieveVariant(variantOne.id, {
select: ["id", "title", "product.title"] as any,
relations: ["product"],
it("should return variants and count based on the options and filter parameter", async () => {
let results = await service.listAndCountVariants(
{
id: variantOne.id,
},
{
take: 1,
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: variantOne.id,
}),
])
results = await service.listAndCountVariants({}, { take: 1 })
expect(results[1]).toEqual(2)
results = await service.listAndCountVariants({}, { take: 1, skip: 1 })
expect(results[1]).toEqual(2)
expect(results[0]).toEqual([
expect.objectContaining({
id: variantTwo.id,
}),
])
})
it("should return only requested fields and relations for variants", async () => {
const results = await service.listAndCountVariants(
{
id: variantOne.id,
},
{
select: ["id", "title", "product.title"] as any,
relations: ["product"],
}
)
expect(results[1]).toEqual(1)
expect(results[0]).toEqual([
expect.objectContaining({
id: "test-1",
title: "variant 1",
// TODO: investigate why this is returning more than the expected results
product: expect.objectContaining({
id: "product-1",
title: "product 1",
}),
}),
])
})
})
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "variant 1",
product: expect.objectContaining({
id: "product-1",
title: "product 1",
}),
describe("retrieveVariant", () => {
it("should return the requested variant", async () => {
const result = await service.retrieveVariant(variantOne.id)
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "variant 1",
})
)
})
)
it("should return requested attributes when requested through config", async () => {
const result = await service.retrieveVariant(variantOne.id, {
select: ["id", "title", "product.title"] as any,
relations: ["product"],
})
expect(result).toEqual(
expect.objectContaining({
id: "test-1",
title: "variant 1",
product: expect.objectContaining({
id: "product-1",
title: "product 1",
}),
})
)
})
it("should throw an error when a variant with ID does not exist", async () => {
let error
try {
await service.retrieveVariant("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductVariant with id: does-not-exist was not found"
)
})
})
})
it("should throw an error when a variant with ID does not exist", async () => {
let error
try {
await service.retrieveVariant("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductVariant with id: does-not-exist was not found"
)
})
})
},
})
@@ -1,376 +1,370 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { ProductOptionService } from "@services"
import { Product } from "@models"
import { TestDatabase } from "../../../utils"
import { createOptions } from "../../../__fixtures__/product"
import { ProductTypes } from "@medusajs/types"
import { asValue } from "awilix"
import { createMedusaContainer } from "@medusajs/utils"
import ContainerLoader from "../../../../src/loaders/container"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { IProductModuleService } from "@medusajs/types"
jest.setTimeout(30000)
describe("ProductOption Service", () => {
let service: ProductOptionService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let productOne: Product
let productTwo: Product
let data!: Product[]
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
medusaApp,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductOption Service", () => {
let service: ProductOptionService
const productOneData = {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
}
const productTwoData = {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
}
beforeEach(async () => {
await TestDatabase.setupDatabase()
repositoryManager = await TestDatabase.forkManager()
const container = createMedusaContainer()
container.register("manager", asValue(repositoryManager))
await ContainerLoader({ container })
service = container.resolve("productOptionService")
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, productOneData)
productTwo = testManager.create(Product, productTwoData)
data = await createOptions(testManager, [
{
id: "option-1",
title: "Option 1",
product: productOne,
},
{
id: "option-2",
title: "Option 2",
product: productOne,
},
])
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("list", () => {
it("list product option", async () => {
const optionResults = await service.list()
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-1",
title: "Option 1",
}),
expect.objectContaining({
id: "option-2",
title: "Option 2",
}),
])
})
it("list product option by id", async () => {
const optionResults = await service.list({ id: "option-2" })
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-2",
title: "Option 2",
}),
])
})
it("list product option by title matching string", async () => {
const optionResults = await service.list({ title: "Option 1" })
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-1",
title: "Option 1",
}),
])
})
})
describe("listAndCount", () => {
it("should return product option and count", async () => {
const [optionResults, count] = await service.listAndCount()
expect(count).toEqual(2)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-1",
title: "Option 1",
}),
expect.objectContaining({
id: "option-2",
title: "Option 2",
}),
])
})
it("should return product option and count when filtered", async () => {
const [optionResults, count] = await service.listAndCount({
id: "option-2",
beforeEach(() => {
service = medusaApp.modules["productService"].productOptionService_
})
expect(count).toEqual(1)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-2",
}),
])
})
let productOne: Product
let productTwo: Product
it("should return product option and count when using skip and take", async () => {
const [optionResults, count] = await service.listAndCount(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-2",
}),
])
})
it("should return requested fields", async () => {
const [optionResults, count] = await service.listAndCount(
{},
{
take: 1,
select: ["title"],
}
)
const serialized = JSON.parse(JSON.stringify(optionResults))
expect(count).toEqual(2)
expect(serialized).toEqual([
expect.objectContaining({
id: "option-1",
}),
])
})
})
describe("retrieve", () => {
const optionId = "option-1"
const optionValue = "Option 1"
it("should return option for the given id", async () => {
const option = await service.retrieve(optionId)
expect(option).toEqual(
expect.objectContaining({
id: optionId,
})
)
})
it("should throw an error when option with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
const productOneData = {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
}
expect(error.message).toEqual(
"ProductOption 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
const productTwoData = {
id: "product-2",
title: "product 2",
status: ProductTypes.ProductStatus.PUBLISHED,
}
expect(error.message).toEqual("productOption - id must be defined")
})
beforeEach(async () => {
const testManager = MikroOrmWrapper.forkManager()
productOne = testManager.create(Product, productOneData)
productTwo = testManager.create(Product, productTwoData)
it("should return option based on config select param", async () => {
const option = await service.retrieve(optionId, {
select: ["id", "title"],
})
const serialized = JSON.parse(JSON.stringify(option))
expect(serialized).toEqual({
id: optionId,
title: optionValue,
})
})
})
describe("delete", () => {
const optionId = "option-1"
it("should delete the product option given an ID successfully", async () => {
await service.delete([optionId])
const options = await service.list({
id: optionId,
})
expect(options).toHaveLength(0)
})
})
describe("update", () => {
const optionId = "option-1"
it("should update the title of the option successfully", async () => {
await service.update([
{
id: optionId,
title: "UK",
},
])
const productOption = await service.retrieve(optionId)
expect(productOption.title).toEqual("UK")
})
it("should update the relationship of the option successfully", async () => {
await service.update([
{
id: optionId,
product_id: productTwo.id,
},
])
const productOption = await service.retrieve(optionId, {
relations: ["product"],
})
expect(productOption).toEqual(
expect.objectContaining({
id: optionId,
product: expect.objectContaining({
id: productTwo.id,
}),
})
)
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
await createOptions(testManager, [
{
id: "does-not-exist",
title: "UK",
id: "option-1",
title: "Option 1",
product: productOne,
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductOption with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a option successfully", async () => {
await service.create([
{
title: "UK",
product: productOne,
},
])
const [productOption] = await service.list(
{
title: "UK",
},
{
relations: ["product"],
}
)
expect(productOption).toEqual(
expect.objectContaining({
title: "UK",
product: expect.objectContaining({
id: productOne.id,
}),
})
)
})
})
describe("upsert", function () {
it("should create an option and update another option successfully", async () => {
const productOption = (
await service.create([
{
title: "UK",
id: "option-2",
title: "Option 2",
product: productOne,
},
])
)[0]
})
const optionToUpdate = {
id: productOption.id,
title: "US",
}
describe("list", () => {
it("list product option", async () => {
const optionResults = await service.list()
const newOption = {
title: "US2",
product_id: productOne.id,
}
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-1",
title: "Option 1",
}),
expect.objectContaining({
id: "option-2",
title: "Option 2",
}),
])
})
await service.upsert([optionToUpdate, newOption])
it("list product option by id", async () => {
const optionResults = await service.list({ id: "option-2" })
const productOptions = await service.list(
{
title: "US%",
},
{
relations: ["product"],
}
)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-2",
title: "Option 2",
}),
])
})
expect(JSON.parse(JSON.stringify(productOptions))).toEqual(
expect.arrayContaining([
expect.objectContaining({
it("list product option by title matching string", async () => {
const optionResults = await service.list({ title: "Option 1" })
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-1",
title: "Option 1",
}),
])
})
})
describe("listAndCount", () => {
it("should return product option and count", async () => {
const [optionResults, count] = await service.listAndCount()
expect(count).toEqual(2)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-1",
title: "Option 1",
}),
expect.objectContaining({
id: "option-2",
title: "Option 2",
}),
])
})
it("should return product option and count when filtered", async () => {
const [optionResults, count] = await service.listAndCount({
id: "option-2",
})
expect(count).toEqual(1)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-2",
}),
])
})
it("should return product option and count when using skip and take", async () => {
const [optionResults, count] = await service.listAndCount(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(optionResults).toEqual([
expect.objectContaining({
id: "option-2",
}),
])
})
it("should return requested fields", async () => {
const [optionResults, count] = await service.listAndCount(
{},
{
take: 1,
select: ["title"],
}
)
const serialized = JSON.parse(JSON.stringify(optionResults))
expect(count).toEqual(2)
expect(serialized).toEqual([
expect.objectContaining({
id: "option-1",
}),
])
})
})
describe("retrieve", () => {
const optionId = "option-1"
const optionValue = "Option 1"
it("should return option for the given id", async () => {
const option = await service.retrieve(optionId)
expect(option).toEqual(
expect.objectContaining({
id: optionId,
})
)
})
it("should throw an error when option with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductOption 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("productOption - id must be defined")
})
it("should return option based on config select param", async () => {
const option = await service.retrieve(optionId, {
select: ["id", "title"],
})
const serialized = JSON.parse(JSON.stringify(option))
expect(serialized).toEqual({
id: optionId,
title: optionValue,
})
})
})
describe("delete", () => {
const optionId = "option-1"
it("should delete the product option given an ID successfully", async () => {
await service.delete([optionId])
const options = await service.list({
id: optionId,
})
expect(options).toHaveLength(0)
})
})
describe("update", () => {
const optionId = "option-1"
it("should update the title of the option successfully", async () => {
await service.update([
{
id: optionId,
title: "UK",
},
])
const productOption = await service.retrieve(optionId)
expect(productOption.title).toEqual("UK")
})
it("should update the relationship of the option successfully", async () => {
await service.update([
{
id: optionId,
product_id: productTwo.id,
},
])
const productOption = await service.retrieve(optionId, {
relations: ["product"],
})
expect(productOption).toEqual(
expect.objectContaining({
id: optionId,
product: expect.objectContaining({
id: productTwo.id,
}),
})
)
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
title: "UK",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductOption with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a option successfully", async () => {
await service.create([
{
title: "UK",
product: productOne,
},
])
const [productOption] = await service.list(
{
title: "UK",
},
{
relations: ["product"],
}
)
expect(productOption).toEqual(
expect.objectContaining({
title: "UK",
product: expect.objectContaining({
id: productOne.id,
}),
})
)
})
})
describe("upsert", function () {
it("should create an option and update another option successfully", async () => {
const productOption = (
await service.create([
{
title: "UK",
product: productOne,
},
])
)[0]
const optionToUpdate = {
id: productOption.id,
title: "US",
product: expect.objectContaining({
id: productOne.id,
}),
}),
expect.objectContaining({
title: newOption.title,
product: expect.objectContaining({
id: productOne.id,
}),
}),
])
)
}
const newOption = {
title: "US2",
product_id: productOne.id,
}
await service.upsert([optionToUpdate, newOption])
const productOptions = await service.list(
{
title: "US%",
},
{
relations: ["product"],
}
)
expect(JSON.parse(JSON.stringify(productOptions))).toEqual(
expect.arrayContaining([
expect.objectContaining({
title: "US",
product: expect.objectContaining({
id: productOne.id,
}),
}),
expect.objectContaining({
title: newOption.title,
product: expect.objectContaining({
id: productOne.id,
}),
}),
])
)
})
})
})
})
},
})
@@ -1,341 +1,335 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product } from "@models"
import { ProductTagService } from "@services"
import { ProductTypes } from "@medusajs/types"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import ContainerLoader from "../../../../src/loaders/container"
import { createProductAndTags } from "../../../__fixtures__/product"
import { TestDatabase } from "../../../utils"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { IProductModuleService } from "@medusajs/types"
jest.setTimeout(30000)
describe("ProductTag Service", () => {
let service: ProductTagService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let data!: Product[]
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
medusaApp,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductTag Service", () => {
let data!: Product[]
let service: ProductTagService
const productsData = [
{
id: "test-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
tags: [
{
id: "tag-1",
value: "France",
},
],
},
{
id: "test-2",
title: "product",
status: ProductTypes.ProductStatus.PUBLISHED,
tags: [
{
id: "tag-2",
value: "Germany",
},
{
id: "tag-3",
value: "United States",
},
{
id: "tag-4",
value: "United Kingdom",
},
],
},
]
beforeEach(async () => {
await TestDatabase.setupDatabase()
repositoryManager = await TestDatabase.forkManager()
const container = createMedusaContainer()
container.register("manager", asValue(repositoryManager))
await ContainerLoader({ container })
service = container.resolve("productTagService")
testManager = await TestDatabase.forkManager()
data = await createProductAndTags(testManager, productsData)
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("list", () => {
it("list product tags", async () => {
const tagsResults = await service.list()
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
value: "France",
}),
expect.objectContaining({
id: "tag-2",
value: "Germany",
}),
expect.objectContaining({
id: "tag-3",
value: "United States",
}),
expect.objectContaining({
id: "tag-4",
value: "United Kingdom",
}),
])
})
it("list product tags by id", async () => {
const tagsResults = await service.list({ id: data[0].tags![0].id })
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
value: "France",
}),
])
})
it("list product tags by value matching string", async () => {
const tagsResults = await service.list({ value: "united kingdom" })
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-4",
value: "United Kingdom",
}),
])
})
})
describe("listAndCount", () => {
it("should return product tags and count", async () => {
const [tagsResults, count] = await service.listAndCount()
expect(count).toEqual(4)
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
value: "France",
}),
expect.objectContaining({
id: "tag-2",
value: "Germany",
}),
expect.objectContaining({
id: "tag-3",
value: "United States",
}),
expect.objectContaining({
id: "tag-4",
value: "United Kingdom",
}),
])
})
it("should return product tags and count when filtered", async () => {
const [tagsResults, count] = await service.listAndCount({
id: data[0].tags![0].id,
beforeEach(() => {
service = medusaApp.modules["productService"].productTagService_
})
expect(count).toEqual(1)
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
}),
])
})
it("should return product tags and count when using skip and take", async () => {
const [tagsResults, count] = await service.listAndCount(
{},
{ skip: 1, take: 2 }
)
expect(count).toEqual(4)
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-2",
}),
expect.objectContaining({
id: "tag-3",
}),
])
})
it("should return requested fields and relations", async () => {
const [tagsResults, count] = await service.listAndCount(
{},
const productsData = [
{
take: 1,
select: ["value", "products.id"],
relations: ["products"],
}
)
const serialized = JSON.parse(JSON.stringify(tagsResults))
expect(count).toEqual(4)
expect(serialized).toEqual([
expect.objectContaining({
id: "tag-1",
products: [
id: "test-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
tags: [
{
id: "test-1",
id: "tag-1",
value: "France",
},
],
}),
])
})
})
},
{
id: "test-2",
title: "product",
status: ProductTypes.ProductStatus.PUBLISHED,
tags: [
{
id: "tag-2",
value: "Germany",
},
{
id: "tag-3",
value: "United States",
},
{
id: "tag-4",
value: "United Kingdom",
},
],
},
]
describe("retrieve", () => {
const tagId = "tag-1"
const tagValue = "France"
const productId = "test-1"
beforeEach(async () => {
data = await createProductAndTags(
MikroOrmWrapper.forkManager(),
productsData
)
})
it("should return tag for the given id", async () => {
const tag = await service.retrieve(tagId)
describe("list", () => {
it("list product tags", async () => {
const tagsResults = await service.list()
expect(tag).toEqual(
expect.objectContaining({
id: tagId,
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
value: "France",
}),
expect.objectContaining({
id: "tag-2",
value: "Germany",
}),
expect.objectContaining({
id: "tag-3",
value: "United States",
}),
expect.objectContaining({
id: "tag-4",
value: "United Kingdom",
}),
])
})
)
})
it("should throw an error when tag with id does not exist", async () => {
let error
it("list product tags by id", async () => {
const tagsResults = await service.list({ id: data[0].tags![0].id })
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
value: "France",
}),
])
})
expect(error.message).toEqual(
"ProductTag with id: does-not-exist was not found"
)
})
it("list product tags by value matching string", async () => {
const tagsResults = await service.list({ value: "united kingdom" })
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("productTag - id must be defined")
})
it("should return tag based on config select param", async () => {
const tag = await service.retrieve(tagId, {
select: ["id", "value"],
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-4",
value: "United Kingdom",
}),
])
})
})
const serialized = JSON.parse(JSON.stringify(tag))
describe("listAndCount", () => {
it("should return product tags and count", async () => {
const [tagsResults, count] = await service.listAndCount()
expect(serialized).toEqual({
id: tagId,
value: tagValue,
})
})
expect(count).toEqual(4)
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
value: "France",
}),
expect.objectContaining({
id: "tag-2",
value: "Germany",
}),
expect.objectContaining({
id: "tag-3",
value: "United States",
}),
expect.objectContaining({
id: "tag-4",
value: "United Kingdom",
}),
])
})
it("should return tag based on config relation param", async () => {
const tag = await service.retrieve(tagId, {
select: ["id", "value", "products.id"],
relations: ["products"],
it("should return product tags and count when filtered", async () => {
const [tagsResults, count] = await service.listAndCount({
id: data[0].tags![0].id,
})
expect(count).toEqual(1)
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-1",
}),
])
})
it("should return product tags and count when using skip and take", async () => {
const [tagsResults, count] = await service.listAndCount(
{},
{ skip: 1, take: 2 }
)
expect(count).toEqual(4)
expect(tagsResults).toEqual([
expect.objectContaining({
id: "tag-2",
}),
expect.objectContaining({
id: "tag-3",
}),
])
})
it("should return requested fields and relations", async () => {
const [tagsResults, count] = await service.listAndCount(
{},
{
take: 1,
select: ["value", "products.id"],
relations: ["products"],
}
)
const serialized = JSON.parse(JSON.stringify(tagsResults))
expect(count).toEqual(4)
expect(serialized).toEqual([
expect.objectContaining({
id: "tag-1",
products: [
{
id: "test-1",
},
],
}),
])
})
})
const serialized = JSON.parse(JSON.stringify(tag))
describe("retrieve", () => {
const tagId = "tag-1"
const tagValue = "France"
const productId = "test-1"
expect(serialized).toEqual({
id: tagId,
value: tagValue,
products: [
expect.objectContaining({
id: productId,
}),
],
})
})
})
it("should return tag for the given id", async () => {
const tag = await service.retrieve(tagId)
describe("delete", () => {
const tagId = "tag-1"
expect(tag).toEqual(
expect.objectContaining({
id: tagId,
})
)
})
it("should delete the product tag given an ID successfully", async () => {
await service.delete([tagId])
it("should throw an error when tag with id does not exist", async () => {
let error
const tags = await service.list({
id: tagId,
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductTag 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("productTag - id must be defined")
})
it("should return tag based on config select param", async () => {
const tag = await service.retrieve(tagId, {
select: ["id", "value"],
})
const serialized = JSON.parse(JSON.stringify(tag))
expect(serialized).toEqual({
id: tagId,
value: tagValue,
})
})
it("should return tag based on config relation param", async () => {
const tag = await service.retrieve(tagId, {
select: ["id", "value", "products.id"],
relations: ["products"],
})
const serialized = JSON.parse(JSON.stringify(tag))
expect(serialized).toEqual({
id: tagId,
value: tagValue,
products: [
expect.objectContaining({
id: productId,
}),
],
})
})
})
expect(tags).toHaveLength(0)
})
})
describe("delete", () => {
const tagId = "tag-1"
describe("update", () => {
const tagId = "tag-1"
it("should delete the product tag given an ID successfully", async () => {
await service.delete([tagId])
it("should update the value of the tag successfully", async () => {
await service.update([
{
id: tagId,
value: "UK",
},
])
const tags = await service.list({
id: tagId,
})
const productTag = await service.retrieve(tagId)
expect(tags).toHaveLength(0)
})
})
expect(productTag.value).toEqual("UK")
})
describe("update", () => {
const tagId = "tag-1"
it("should throw an error when an id does not exist", async () => {
let error
it("should update the value of the tag successfully", async () => {
await service.update([
{
id: tagId,
value: "UK",
},
])
try {
await service.update([
{
id: "does-not-exist",
const productTag = await service.retrieve(tagId)
expect(productTag.value).toEqual("UK")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
value: "UK",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductTag with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a tag successfully", async () => {
await service.create([
{
value: "UK",
},
])
const [productTag] = await service.list({
value: "UK",
},
])
} catch (e) {
error = e
}
})
expect(error.message).toEqual(
'ProductTag with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a tag successfully", async () => {
await service.create([
{
value: "UK",
},
])
const [productTag] = await service.list({
value: "UK",
expect(productTag.value).toEqual("UK")
})
})
expect(productTag.value).toEqual("UK")
})
})
},
})
@@ -1,284 +1,277 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import ContainerLoader from "../../../../src/loaders/container"
import { ProductTypeService } from "@services"
import { Product } from "@models"
import { TestDatabase } from "../../../utils"
import { createProductAndTypes } from "../../../__fixtures__/product"
import { ProductTypes } from "@medusajs/types"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { IProductModuleService } from "@medusajs/types"
jest.setTimeout(30000)
describe("ProductType Service", () => {
let service: ProductTypeService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let data!: Product[]
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
medusaApp,
}: SuiteOptions<IProductModuleService>) => {
describe("ProductType Service", () => {
let data!: Product[]
let service: ProductTypeService
const productsData = [
{
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
type: {
id: "type-1",
value: "Type 1",
},
},
{
id: "product-2",
title: "product",
status: ProductTypes.ProductStatus.PUBLISHED,
type: {
id: "type-2",
value: "Type 2",
},
},
]
beforeEach(async () => {
await TestDatabase.setupDatabase()
repositoryManager = await TestDatabase.forkManager()
const container = createMedusaContainer()
container.register("manager", asValue(repositoryManager))
await ContainerLoader({ container })
service = container.resolve("productTypeService")
testManager = await TestDatabase.forkManager()
data = await createProductAndTypes(testManager, productsData)
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("list", () => {
it("list product type", async () => {
const typeResults = await service.list()
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
expect.objectContaining({
id: "type-2",
value: "Type 2",
}),
])
})
it("list product type by id", async () => {
const typeResults = await service.list({ id: data[0].type.id })
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
])
})
it("list product type by value matching string", async () => {
const typeResults = await service.list({ value: "Type 1" })
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
])
})
})
describe("listAndCount", () => {
it("should return product type and count", async () => {
const [typeResults, count] = await service.listAndCount()
expect(count).toEqual(2)
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
expect.objectContaining({
id: "type-2",
value: "Type 2",
}),
])
})
it("should return product type and count when filtered", async () => {
const [typeResults, count] = await service.listAndCount({
id: data[0].type.id,
beforeEach(() => {
service = medusaApp.modules["productService"].productTypeService_
})
expect(count).toEqual(1)
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
}),
])
})
it("should return product type and count when using skip and take", async () => {
const [typeResults, count] = await service.listAndCount(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-2",
}),
])
})
it("should return requested fields", async () => {
const [typeResults, count] = await service.listAndCount(
{},
const productsData = [
{
take: 1,
select: ["value"],
}
)
const serialized = JSON.parse(JSON.stringify(typeResults))
expect(count).toEqual(2)
expect(serialized).toEqual([
expect.objectContaining({
id: "type-1",
}),
])
})
})
describe("retrieve", () => {
const typeId = "type-1"
const typeValue = "Type 1"
it("should return type for the given id", async () => {
const type = await service.retrieve(typeId)
expect(type).toEqual(
expect.objectContaining({
id: typeId,
})
)
})
it("should throw an error when type with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductType 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("productType - id must be defined")
})
it("should return type based on config select param", async () => {
const type = await service.retrieve(typeId, {
select: ["id", "value"],
})
const serialized = JSON.parse(JSON.stringify(type))
expect(serialized).toEqual({
id: typeId,
value: typeValue,
})
})
})
describe("delete", () => {
const typeId = "type-1"
it("should delete the product type given an ID successfully", async () => {
await service.delete([typeId])
const types = await service.list({
id: typeId,
})
expect(types).toHaveLength(0)
})
})
describe("update", () => {
const typeId = "type-1"
it("should update the value of the type successfully", async () => {
await service.update([
{
id: typeId,
value: "UK",
},
])
const productType = await service.retrieve(typeId)
expect(productType.value).toEqual("UK")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
value: "UK",
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
type: {
id: "type-1",
value: "Type 1",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductType with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a type successfully", async () => {
await service.create([
{
value: "UK",
},
])
{
id: "product-2",
title: "product",
status: ProductTypes.ProductStatus.PUBLISHED,
type: {
id: "type-2",
value: "Type 2",
},
},
]
const [productType] = await service.list({
value: "UK",
beforeEach(async () => {
data = await createProductAndTypes(
MikroOrmWrapper.forkManager(),
productsData
)
})
describe("list", () => {
it("list product type", async () => {
const typeResults = await service.list()
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
expect.objectContaining({
id: "type-2",
value: "Type 2",
}),
])
})
it("list product type by id", async () => {
const typeResults = await service.list({ id: data[0].type.id })
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
])
})
it("list product type by value matching string", async () => {
const typeResults = await service.list({ value: "Type 1" })
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
])
})
})
expect(productType.value).toEqual("UK")
describe("listAndCount", () => {
it("should return product type and count", async () => {
const [typeResults, count] = await service.listAndCount()
expect(count).toEqual(2)
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
value: "Type 1",
}),
expect.objectContaining({
id: "type-2",
value: "Type 2",
}),
])
})
it("should return product type and count when filtered", async () => {
const [typeResults, count] = await service.listAndCount({
id: data[0].type.id,
})
expect(count).toEqual(1)
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-1",
}),
])
})
it("should return product type and count when using skip and take", async () => {
const [typeResults, count] = await service.listAndCount(
{},
{ skip: 1, take: 1 }
)
expect(count).toEqual(2)
expect(typeResults).toEqual([
expect.objectContaining({
id: "type-2",
}),
])
})
it("should return requested fields", async () => {
const [typeResults, count] = await service.listAndCount(
{},
{
take: 1,
select: ["value"],
}
)
const serialized = JSON.parse(JSON.stringify(typeResults))
expect(count).toEqual(2)
expect(serialized).toEqual([
expect.objectContaining({
id: "type-1",
}),
])
})
})
describe("retrieve", () => {
const typeId = "type-1"
const typeValue = "Type 1"
it("should return type for the given id", async () => {
const type = await service.retrieve(typeId)
expect(type).toEqual(
expect.objectContaining({
id: typeId,
})
)
})
it("should throw an error when type with id does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductType 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("productType - id must be defined")
})
it("should return type based on config select param", async () => {
const type = await service.retrieve(typeId, {
select: ["id", "value"],
})
const serialized = JSON.parse(JSON.stringify(type))
expect(serialized).toEqual({
id: typeId,
value: typeValue,
})
})
})
describe("delete", () => {
const typeId = "type-1"
it("should delete the product type given an ID successfully", async () => {
await service.delete([typeId])
const types = await service.list({
id: typeId,
})
expect(types).toHaveLength(0)
})
})
describe("update", () => {
const typeId = "type-1"
it("should update the value of the type successfully", async () => {
await service.update([
{
id: typeId,
value: "UK",
},
])
const productType = await service.retrieve(typeId)
expect(productType.value).toEqual("UK")
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.update([
{
id: "does-not-exist",
value: "UK",
},
])
} catch (e) {
error = e
}
expect(error.message).toEqual(
'ProductType with id "does-not-exist" not found'
)
})
})
describe("create", () => {
it("should create a type successfully", async () => {
await service.create([
{
value: "UK",
},
])
const [productType] = await service.list({
value: "UK",
})
expect(productType.value).toEqual("UK")
})
})
})
})
},
})
@@ -1,12 +1,8 @@
import { ProductOption } from "@medusajs/client-types"
import { ProductTypes } from "@medusajs/types"
import { createMedusaContainer } from "@medusajs/utils"
import { Collection } from "@mikro-orm/core"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { Product, ProductTag, ProductVariant } from "@models"
import { ProductVariantService } from "@services"
import { asValue } from "awilix"
import ContainerLoader from "../../../../src/loaders/container"
import {
createOptions,
createProductAndTags,
@@ -14,313 +10,319 @@ import {
} from "../../../__fixtures__/product"
import { productsData, variantsData } from "../../../__fixtures__/product/data"
import { buildProductVariantOnlyData } from "../../../__fixtures__/variant/data/create-variant"
import { TestDatabase } from "../../../utils"
// TODO: fix tests
describe.skip("ProductVariant Service", () => {
let service: ProductVariantService
let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager
let variantOne: ProductVariant
let variantTwo: ProductVariant
let productOne: Product
const productVariantTestOne = "test-1"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
import { IProductModuleService } from "@medusajs/types"
beforeEach(async () => {
await TestDatabase.setupDatabase()
repositoryManager = await TestDatabase.forkManager()
jest.setTimeout(30000)
const container = createMedusaContainer()
container.register("manager", asValue(repositoryManager))
moduleIntegrationTestRunner({
moduleName: Modules.PRODUCT,
testSuite: ({
MikroOrmWrapper,
medusaApp,
}: SuiteOptions<IProductModuleService>) => {
describe.skip("ProductVariant Service", () => {
let variantOne: ProductVariant
let variantTwo: ProductVariant
let productOne: Product
const productVariantTestOne = "test-1"
let service: ProductVariantService
await ContainerLoader({ container })
service = container.resolve("productVariantService")
})
afterEach(async () => {
await TestDatabase.clearDatabase()
})
describe("list", () => {
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
beforeEach(() => {
service = medusaApp.modules["productService"].productVariantService_
})
variantOne = testManager.create(ProductVariant, {
id: productVariantTestOne,
title: "variant 1",
inventory_quantity: 10,
product: productOne,
})
describe("list", () => {
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
variantTwo = testManager.create(ProductVariant, {
id: "test-2",
title: "variant",
inventory_quantity: 10,
product: productOne,
})
await testManager.persistAndFlush([variantOne, variantTwo])
})
it("selecting by properties, scopes out the results", async () => {
const results = await service.list({
id: variantOne.id,
})
expect(results).toEqual([
expect.objectContaining({
id: variantOne.id,
title: "variant 1",
inventory_quantity: "10",
}),
])
})
it("passing a limit, scopes the result to the limit", async () => {
const results = await service.list(
{},
{
take: 1,
}
)
expect(results).toEqual([
expect.objectContaining({
id: variantOne.id,
}),
])
})
it("passing populate, scopes the results of the response", async () => {
const results = await service.list(
{
id: productVariantTestOne,
},
{
select: ["id", "title", "product.title"] as any,
relations: ["product"],
}
)
expect(results).toEqual([
expect.objectContaining({
id: productVariantTestOne,
title: "variant 1",
product: expect.objectContaining({
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
tags: expect.any(Collection<ProductTag>),
variants: expect.any(Collection<ProductVariant>),
}),
}),
])
status: ProductTypes.ProductStatus.PUBLISHED,
})
expect(JSON.parse(JSON.stringify(results))).toEqual([
{
id: productVariantTestOne,
title: "variant 1",
product: {
id: "product-1",
title: "product 1",
},
},
])
})
})
variantOne = testManager.create(ProductVariant, {
id: productVariantTestOne,
title: "variant 1",
inventory_quantity: 10,
product: productOne,
})
describe("relation: options", () => {
let products: Product[]
let variants: ProductVariant[]
let options: ProductOption[]
variantTwo = testManager.create(ProductVariant, {
id: "test-2",
title: "variant",
inventory_quantity: 10,
product: productOne,
})
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
await testManager.persistAndFlush([variantOne, variantTwo])
})
products = (await createProductAndTags(
testManager,
productsData
)) as Product[]
variants = (await createProductVariants(
testManager,
variantsData
)) as ProductVariant[]
it("selecting by properties, scopes out the results", async () => {
const results = await service.list({
id: variantOne.id,
})
options = await createOptions(testManager, [
{
id: "test-option-1",
title: "size",
product: products[0],
values: [
{ id: "value-1", value: "XS", variant: products[0].variants[0] },
{ id: "value-1", value: "XL", variant: products[0].variants[0] },
],
},
{
id: "test-option-2",
title: "color",
product: products[0],
value: "blue",
variant: products[0].variants[0],
},
])
})
expect(results).toEqual([
expect.objectContaining({
id: variantOne.id,
title: "variant 1",
inventory_quantity: "10",
}),
])
})
it("filter by options relation", async () => {
const variants = await service.list(
{ options: { id: ["value-1"] } },
{ relations: ["options"] }
)
it("passing a limit, scopes the result to the limit", async () => {
const results = await service.list(
{},
{
take: 1,
}
)
expect(JSON.parse(JSON.stringify(variants))).toEqual([
expect.objectContaining({
id: productVariantTestOne,
title: "variant title",
sku: "sku 1",
}),
])
})
})
expect(results).toEqual([
expect.objectContaining({
id: variantOne.id,
}),
])
})
describe("create", function () {
let products: Product[]
let productOptions!: ProductOption[]
it("passing populate, scopes the results of the response", async () => {
const results = await service.list(
{
id: productVariantTestOne,
},
{
select: ["id", "title", "product.title"] as any,
relations: ["product"],
}
)
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
expect(results).toEqual([
expect.objectContaining({
id: productVariantTestOne,
title: "variant 1",
product: expect.objectContaining({
id: "product-1",
title: "product 1",
tags: expect.any(Collection<ProductTag>),
variants: expect.any(Collection<ProductVariant>),
}),
}),
])
products = (await createProductAndTags(
testManager,
productsData
)) as Product[]
productOptions = await createOptions(testManager, [
{
id: "test-option-1",
title: "size",
product: products[0],
},
])
})
it("should create a variant", async () => {
const data = buildProductVariantOnlyData({
options: [
{
option: productOptions[0],
value: "XS",
},
],
expect(JSON.parse(JSON.stringify(results))).toEqual([
{
id: productVariantTestOne,
title: "variant 1",
product: {
id: "product-1",
title: "product 1",
},
},
])
})
})
const variants = await service.create(products[0].id, [data])
describe("relation: options", () => {
let products: Product[]
let variants: ProductVariant[]
let options: ProductOption[]
expect(variants).toHaveLength(1)
expect(variants[0].options).toHaveLength(1)
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
expect(JSON.parse(JSON.stringify(variants[0]))).toEqual(
expect.objectContaining({
id: expect.any(String),
title: data.title,
sku: data.sku,
inventory_quantity: 100,
allow_backorder: false,
manage_inventory: true,
variant_rank: 0,
product: expect.objectContaining({
id: products[0].id,
}),
options: expect.arrayContaining([
products = (await createProductAndTags(
testManager,
productsData
)) as Product[]
variants = (await createProductVariants(
testManager,
variantsData
)) as ProductVariant[]
options = await createOptions(testManager, [
{
id: "test-option-1",
title: "size",
product: products[0],
values: [
{
id: "value-1",
value: "XS",
variant: products[0].variants[0],
},
{
id: "value-1",
value: "XL",
variant: products[0].variants[0],
},
],
},
{
id: "test-option-2",
title: "color",
product: products[0],
value: "blue",
variant: products[0].variants[0],
},
])
})
it("filter by options relation", async () => {
const variants = await service.list(
{ options: { id: ["value-1"] } },
{ relations: ["options"] }
)
expect(JSON.parse(JSON.stringify(variants))).toEqual([
expect.objectContaining({
id: productVariantTestOne,
title: "variant title",
sku: "sku 1",
}),
])
})
})
describe("create", function () {
let products: Product[]
let productOptions!: ProductOption[]
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
products = (await createProductAndTags(
testManager,
productsData
)) as Product[]
productOptions = await createOptions(testManager, [
{
id: "test-option-1",
title: "size",
product: products[0],
},
])
})
it("should create a variant", async () => {
const data = buildProductVariantOnlyData({
options: [
{
option: productOptions[0],
value: "XS",
},
],
})
const variants = await service.create(products[0].id, [data])
expect(variants).toHaveLength(1)
expect(variants[0].options).toHaveLength(1)
expect(JSON.parse(JSON.stringify(variants[0]))).toEqual(
expect.objectContaining({
id: expect.any(String),
value: data.options![0].value,
}),
]),
title: data.title,
sku: data.sku,
inventory_quantity: 100,
allow_backorder: false,
manage_inventory: true,
variant_rank: 0,
product: expect.objectContaining({
id: products[0].id,
}),
options: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
value: data.options![0].value,
}),
]),
})
)
})
)
})
})
describe("retrieve", () => {
beforeEach(async () => {
testManager = await TestDatabase.forkManager()
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
status: ProductTypes.ProductStatus.PUBLISHED,
})
variantOne = testManager.create(ProductVariant, {
id: productVariantTestOne,
title: "variant 1",
inventory_quantity: 10,
product: productOne,
})
describe("retrieve", () => {
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
await testManager.persistAndFlush([variantOne])
})
it("should return the requested variant", async () => {
const result = await service.retrieve(variantOne.id)
expect(result).toEqual(
expect.objectContaining({
id: productVariantTestOne,
title: "variant 1",
})
)
})
it("should return requested attributes when requested through config", async () => {
const result = await service.retrieve(variantOne.id, {
select: ["id", "title", "product.title"] as any,
relations: ["product"],
})
expect(result).toEqual(
expect.objectContaining({
id: productVariantTestOne,
title: "variant 1",
product_id: "product-1",
product: expect.objectContaining({
productOne = testManager.create(Product, {
id: "product-1",
title: "product 1",
}),
status: ProductTypes.ProductStatus.PUBLISHED,
})
variantOne = testManager.create(ProductVariant, {
id: productVariantTestOne,
title: "variant 1",
inventory_quantity: 10,
product: productOne,
})
await testManager.persistAndFlush([variantOne])
})
)
it("should return the requested variant", async () => {
const result = await service.retrieve(variantOne.id)
expect(result).toEqual(
expect.objectContaining({
id: productVariantTestOne,
title: "variant 1",
})
)
})
it("should return requested attributes when requested through config", async () => {
const result = await service.retrieve(variantOne.id, {
select: ["id", "title", "product.title"] as any,
relations: ["product"],
})
expect(result).toEqual(
expect.objectContaining({
id: productVariantTestOne,
title: "variant 1",
product_id: "product-1",
product: expect.objectContaining({
id: "product-1",
title: "product 1",
}),
})
)
})
it("should throw an error when a variant with ID does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductVariant 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("productVariant - id must be defined")
})
})
})
it("should throw an error when a variant with ID does not exist", async () => {
let error
try {
await service.retrieve("does-not-exist")
} catch (e) {
error = e
}
expect(error.message).toEqual(
"ProductVariant 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("productVariant - id must be defined")
})
})
},
})
File diff suppressed because it is too large. Load diff
@@ -1,6 +0,0 @@
if (typeof process.env.DB_TEMP_NAME === "undefined") {
const tempName = parseInt(process.env.JEST_WORKER_ID || "1")
process.env.DB_TEMP_NAME = `medusa-integration-${tempName}`
}
process.env.MEDUSA_PRODUCT_DB_SCHEMA = "medusa-product"
@@ -1,22 +0,0 @@
const { dropDatabase } = require("pg-god")
const DB_HOST = process.env.DB_HOST ?? "localhost"
const DB_USERNAME = process.env.DB_USERNAME ?? "postgres"
const DB_PASSWORD = process.env.DB_PASSWORD ?? ""
const DB_NAME = process.env.DB_TEMP_NAME
const pgGodCredentials = {
user: DB_USERNAME,
password: DB_PASSWORD,
host: DB_HOST,
}
afterAll(async () => {
try {
await dropDatabase({ databaseName: DB_NAME }, pgGodCredentials)
} catch (e) {
console.error(
`This might fail if it is run during the unit tests since there is no database to drop. Otherwise, please check what is the issue. ${e.message}`
)
}
})
@@ -1,6 +0,0 @@
import { ModuleServiceInitializeOptions } from "@medusajs/types"
export const databaseOptions: ModuleServiceInitializeOptions["database"] = {
schema: "public",
clientUrl: "medusa-products-test",
}
@@ -1,95 +0,0 @@
import { TSMigrationGenerator } from "@mikro-orm/migrations"
import { MikroORM, Options, SqlEntityManager } from "@mikro-orm/postgresql"
import * as ProductModels from "@models"
import * as process from "process"
const DB_HOST = process.env.DB_HOST ?? "localhost"
const DB_USERNAME = process.env.DB_USERNAME ?? ""
const DB_PASSWORD = process.env.DB_PASSWORD
const DB_NAME = process.env.DB_TEMP_NAME
export const DB_URL = `postgres://${DB_USERNAME}${
DB_PASSWORD ? `:${DB_PASSWORD}` : ""
}@${DB_HOST}/${DB_NAME}`
const ORMConfig: Options = {
type: "postgresql",
clientUrl: DB_URL,
entities: Object.values(ProductModels),
schema: process.env.MEDUSA_PRODUCT_DB_SCHEMA,
debug: false,
migrations: {
path: "../../src/migrations",
pathTs: "../../src/migrations",
glob: "!(*.d).{js,ts}",
silent: true,
dropTables: true,
transactional: true,
allOrNothing: true,
safe: false,
generator: TSMigrationGenerator,
},
}
interface TestDatabase {
orm: MikroORM | null
manager: SqlEntityManager | null
setupDatabase(): Promise<void>
clearDatabase(): Promise<void>
getManager(): SqlEntityManager
forkManager(): Promise<SqlEntityManager>
getORM(): MikroORM
}
export const TestDatabase: TestDatabase = {
orm: null,
manager: null,
getManager() {
if (this.manager === null) {
throw new Error("manager entity not available")
}
return this.manager
},
async forkManager() {
if (this.manager === null) {
throw new Error("manager entity not available")
}
return await this.manager.fork()
},
getORM() {
if (this.orm === null) {
throw new Error("orm entity not available")
}
return this.orm
},
async setupDatabase() {
// Initializing the ORM
this.orm = await MikroORM.init(ORMConfig)
if (this.orm === null) {
throw new Error("ORM not configured")
}
this.manager = await this.orm.em
await this.orm.schema.refreshDatabase() // ensure db exists and is fresh
},
async clearDatabase() {
if (this.orm === null) {
throw new Error("ORM not configured")
}
await this.orm.close()
this.orm = null
this.manager = null
},
}
@@ -1,40 +0,0 @@
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
import { DB_URL } from "./database"
import { EventBusService } from "../__fixtures__/event-bus"
export function getInitModuleConfig(
additionalOptions: any = {},
injectedDependencies: null | Record<string, any> = null
) {
const moduleOptions = {
defaultAdapterOptions: {
database: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRODUCT_DB_SCHEMA,
},
},
...additionalOptions,
}
const modulesConfig_ = {
[Modules.PRODUCT]: {
definition: ModulesDefinition[Modules.PRODUCT],
options: moduleOptions,
},
}
const defaultInjectedDependencies = {
eventBusModuleService: new EventBusService(),
}
return {
injectedDependencies: injectedDependencies ?? defaultInjectedDependencies,
modulesConfig: modulesConfig_,
databaseConfig: {
clientUrl: DB_URL,
schema: process.env.MEDUSA_PRODUCT_DB_SCHEMA,
},
joinerConfig: [],
}
}
@@ -1,2 +0,0 @@
export * from "./database"
export * from "./get-init-module-config"
-2
View File
@@ -17,6 +17,4 @@ module.exports = {
testEnvironment: `node`,
moduleFileExtensions: [`js`, `ts`],
modulePathIgnorePatterns: ["dist/"],
setupFiles: ["<rootDir>/integration-tests/setup-env.js"],
setupFilesAfterEnv: ["<rootDir>/integration-tests/setup.js"],
}
@@ -693,7 +693,6 @@ export default class ProductModuleService<
@MedusaContext() sharedContext: Context = {}
): Promise<ProductTypes.ProductDTO[] | ProductTypes.ProductDTO> {
const input = Array.isArray(data) ? data : [data]
const products = await this.create_(input, sharedContext)
const createdProducts = await this.baseRepository_.serialize<