feat: Revamp of product categories (#7695)

* feat: Normalize the categories interface to match standards

* feat: Revamp the product category implementation

* fix: Adjustments to code and tests around product categories
This commit is contained in:
Stevche Radevski
2024-06-13 09:10:12 +02:00
committed by GitHub
parent fbd8eef18b
commit d862d03de0
35 changed files with 1135 additions and 874 deletions
@@ -66,126 +66,126 @@ export const productCategoriesRankData = [
},
]
export const eletronicsCategoriesData = eval(`[
export const eletronicsCategoriesData = [
{
id: "electronics",
name: "Electronics",
parent_category_id: null,
},
{
id: "computers",
name: "Computers & Accessories",
parent_category_id: "electronics",
},
{
id: "desktops",
name: "Desktops",
parent_category_id: "computers",
},
{
id: "gaming-desktops",
name: "Gaming Desktops",
parent_category_id: "desktops",
},
{
id: "office-desktops",
name: "Office Desktops",
parent_category_id: "desktops",
},
{
id: "laptops",
name: "Laptops",
parent_category_id: "computers",
},
{
id: "gaming-laptops",
name: "Gaming Laptops",
parent_category_id: "laptops",
},
{
id: "budget-gaming",
name: "Budget Gaming Laptops",
parent_category_id: "gaming-laptops",
},
{
id: "high-performance",
name: "High Performance Gaming Laptops",
parent_category_id: "gaming-laptops",
},
{
id: "vr-ready",
name: "VR-Ready High Performance Gaming Laptops",
parent_category_id: "high-performance",
},
{
id: "4k-gaming",
name: "4K Gaming Laptops",
parent_category_id: "high-performance",
},
{
id: "ultrabooks",
name: "Ultrabooks",
parent_category_id: "laptops",
},
{
id: "thin-light",
name: "Thin & Light Ultrabooks",
parent_category_id: "ultrabooks",
},
{
id: "convertible-ultrabooks",
name: "Convertible Ultrabooks",
parent_category_id: "ultrabooks",
},
{
id: "touchscreen-ultrabooks",
name: "Touchscreen Ultrabooks",
parent_category_id: "convertible-ultrabooks",
},
{
id: "detachable-ultrabooks",
name: "Detachable Ultrabooks",
parent_category_id: "convertible-ultrabooks",
},
{
id: "mobile",
name: "Mobile Phones & Accessories",
parent_category_id: "electronics",
},
{
id: "smartphones",
name: "Smartphones",
parent_category_id: "mobile",
},
{
id: "android-phones",
name: "Android Phones",
parent_category_id: "smartphones",
},
{
id: "flagship-phones",
name: "Flagship Smartphones",
parent_category_id: "android-phones",
},
{
id: "budget-phones",
name: "Budget Smartphones",
parent_category_id: "android-phones",
},
{
id: "iphones",
name: "iPhones",
parent_category_id: "smartphones",
},
{
id: "pro-phones",
name: "Pro Models",
parent_category_id: "iphones",
},
{
id: "mini-phones",
name: "Mini Models",
parent_category_id: "iphones",
},
]`)
{
id: "computers",
name: "Computers & Accessories",
parent_category_id: "electronics",
},
{
id: "desktops",
name: "Desktops",
parent_category_id: "computers",
},
{
id: "gaming-desktops",
name: "Gaming Desktops",
parent_category_id: "desktops",
},
{
id: "office-desktops",
name: "Office Desktops",
parent_category_id: "desktops",
},
{
id: "laptops",
name: "Laptops",
parent_category_id: "computers",
},
{
id: "gaming-laptops",
name: "Gaming Laptops",
parent_category_id: "laptops",
},
{
id: "budget-gaming",
name: "Budget Gaming Laptops",
parent_category_id: "gaming-laptops",
},
{
id: "high-performance",
name: "High Performance Gaming Laptops",
parent_category_id: "gaming-laptops",
},
{
id: "vr-ready",
name: "VR-Ready High Performance Gaming Laptops",
parent_category_id: "high-performance",
},
{
id: "4k-gaming",
name: "4K Gaming Laptops",
parent_category_id: "high-performance",
},
{
id: "ultrabooks",
name: "Ultrabooks",
parent_category_id: "laptops",
},
{
id: "thin-light",
name: "Thin & Light Ultrabooks",
parent_category_id: "ultrabooks",
},
{
id: "convertible-ultrabooks",
name: "Convertible Ultrabooks",
parent_category_id: "ultrabooks",
},
{
id: "touchscreen-ultrabooks",
name: "Touchscreen Ultrabooks",
parent_category_id: "convertible-ultrabooks",
},
{
id: "detachable-ultrabooks",
name: "Detachable Ultrabooks",
parent_category_id: "convertible-ultrabooks",
},
{
id: "mobile",
name: "Mobile Phones & Accessories",
parent_category_id: "electronics",
},
{
id: "smartphones",
name: "Smartphones",
parent_category_id: "mobile",
},
{
id: "android-phones",
name: "Android Phones",
parent_category_id: "smartphones",
},
{
id: "flagship-phones",
name: "Flagship Smartphones",
parent_category_id: "android-phones",
},
{
id: "budget-phones",
name: "Budget Smartphones",
parent_category_id: "android-phones",
},
{
id: "iphones",
name: "iPhones",
parent_category_id: "smartphones",
},
{
id: "pro-phones",
name: "Pro Models",
parent_category_id: "iphones",
},
{
id: "mini-phones",
name: "Mini Models",
parent_category_id: "iphones",
},
]
@@ -1,31 +0,0 @@
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { ProductCategory } from "@models"
export async function createProductCategories(
manager: SqlEntityManager,
categoriesData: any[]
): Promise<ProductCategory[]> {
const categories: ProductCategory[] = []
for (let categoryData of categoriesData) {
let categoryDataClone = { ...categoryData }
let parentCategory: ProductCategory | null = null
const parentCategoryId = categoryDataClone.parent_category_id as string
delete categoryDataClone.parent_category_id
if (parentCategoryId) {
parentCategory = await manager.findOne(ProductCategory, parentCategoryId)
}
const category = manager.create(ProductCategory, {
...categoryDataClone,
parent_category: parentCategory,
})
categories.push(category)
}
await manager.persistAndFlush(categories)
return categories
}
@@ -2,7 +2,6 @@ import { ProductCategoryService } from "@services"
import { Modules } from "@medusajs/modules-sdk"
import { moduleIntegrationTestRunner } from "medusa-test-utils"
import { createProductCategories } from "../__fixtures__/product-category"
import {
eletronicsCategoriesData,
productCategoriesData,
@@ -28,10 +27,9 @@ moduleIntegrationTestRunner<Service>({
describe("list", () => {
beforeEach(async () => {
await createProductCategories(
MikroOrmWrapper.forkManager(),
productCategoriesData
)
for (const entry of productCategoriesData) {
await service.create([entry])
}
})
it("lists all product categories", async () => {
@@ -131,33 +129,33 @@ moduleIntegrationTestRunner<Service>({
expect.objectContaining({
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
category_children: [
expect.objectContaining({
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
category_children: [
expect.objectContaining({
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
category_children: [],
}),
expect.objectContaining({
id: "category-1-b",
handle: "category-1-b",
mpath: "category-0.category-1.category-1-b.",
mpath: "category-0.category-1.category-1-b",
parent_category_id: "category-1",
category_children: [
expect.objectContaining({
id: "category-1-b-1",
handle: "category-1-b-1",
mpath:
"category-0.category-1.category-1-b.category-1-b-1.",
"category-0.category-1.category-1-b.category-1-b-1",
parent_category_id: "category-1-b",
category_children: [],
}),
@@ -189,20 +187,20 @@ moduleIntegrationTestRunner<Service>({
{
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
category_children: [],
},
{
id: "category-1-b",
handle: "category-1-b",
mpath: "category-0.category-1.category-1-b.",
mpath: "category-0.category-1.category-1-b",
parent_category_id: "category-1",
category_children: [
expect.objectContaining({
id: "category-1-b-1",
handle: "category-1-b-1",
mpath: "category-0.category-1.category-1-b.category-1-b-1.",
mpath: "category-0.category-1.category-1-b.category-1-b-1",
parent_category_id: "category-1-b",
category_children: [],
}),
@@ -212,10 +210,9 @@ moduleIntegrationTestRunner<Service>({
})
it("includes the entire list of parents when include_ancestors_tree is true", async () => {
await createProductCategories(
MikroOrmWrapper.forkManager(),
eletronicsCategoriesData
)
for (const entry of eletronicsCategoriesData) {
await service.create([entry])
}
const productCategoryResults = await service.list(
{
@@ -236,34 +233,34 @@ moduleIntegrationTestRunner<Service>({
id: "4k-gaming",
handle: "4k-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.high-performance.4k-gaming.",
"electronics.computers.laptops.gaming-laptops.high-performance.4k-gaming",
parent_category_id: "high-performance",
parent_category: {
id: "high-performance",
parent_category_id: "gaming-laptops",
handle: "high-performance-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.high-performance.",
"electronics.computers.laptops.gaming-laptops.high-performance",
parent_category: {
id: "gaming-laptops",
handle: "gaming-laptops",
mpath: "electronics.computers.laptops.gaming-laptops.",
mpath: "electronics.computers.laptops.gaming-laptops",
parent_category_id: "laptops",
parent_category: {
id: "laptops",
parent_category_id: "computers",
handle: "laptops",
mpath: "electronics.computers.laptops.",
mpath: "electronics.computers.laptops",
parent_category: {
id: "computers",
handle: "computers-&-accessories",
mpath: "electronics.computers.",
mpath: "electronics.computers",
parent_category_id: "electronics",
parent_category: {
id: "electronics",
parent_category_id: null,
handle: "electronics",
mpath: "electronics.",
mpath: "electronics",
parent_category: null,
},
},
@@ -275,10 +272,9 @@ moduleIntegrationTestRunner<Service>({
})
it("includes the entire list of descendants when include_descendants_tree is true", async () => {
await createProductCategories(
MikroOrmWrapper.forkManager(),
eletronicsCategoriesData
)
for (const entry of eletronicsCategoriesData) {
await service.create([entry])
}
const productCategoryResults = await service.list(
{
@@ -298,14 +294,14 @@ moduleIntegrationTestRunner<Service>({
{
id: "gaming-laptops",
handle: "gaming-laptops",
mpath: "electronics.computers.laptops.gaming-laptops.",
mpath: "electronics.computers.laptops.gaming-laptops",
parent_category_id: "laptops",
category_children: [
{
id: "budget-gaming",
handle: "budget-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.budget-gaming.",
"electronics.computers.laptops.gaming-laptops.budget-gaming",
parent_category_id: "gaming-laptops",
category_children: [],
},
@@ -313,14 +309,14 @@ moduleIntegrationTestRunner<Service>({
id: "high-performance",
handle: "high-performance-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.high-performance.",
"electronics.computers.laptops.gaming-laptops.high-performance",
parent_category_id: "gaming-laptops",
category_children: expect.arrayContaining([
{
id: "4k-gaming",
handle: "4k-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.high-performance.4k-gaming.",
"electronics.computers.laptops.gaming-laptops.high-performance.4k-gaming",
parent_category_id: "high-performance",
category_children: [],
},
@@ -328,7 +324,7 @@ moduleIntegrationTestRunner<Service>({
id: "vr-ready",
handle: "vr-ready-high-performance-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.high-performance.vr-ready.",
"electronics.computers.laptops.gaming-laptops.high-performance.vr-ready",
parent_category_id: "high-performance",
category_children: [],
},
@@ -340,10 +336,9 @@ moduleIntegrationTestRunner<Service>({
})
it("includes the entire list of descendants an parents when include_descendants_tree and include_ancestors_tree are true", async () => {
await createProductCategories(
MikroOrmWrapper.forkManager(),
eletronicsCategoriesData
)
for (const entry of eletronicsCategoriesData) {
await service.create([entry])
}
const productCategoryResults = await service.list(
{
@@ -364,22 +359,22 @@ moduleIntegrationTestRunner<Service>({
{
id: "gaming-laptops",
handle: "gaming-laptops",
mpath: "electronics.computers.laptops.gaming-laptops.",
mpath: "electronics.computers.laptops.gaming-laptops",
parent_category_id: "laptops",
parent_category: {
id: "laptops",
handle: "laptops",
mpath: "electronics.computers.laptops.",
mpath: "electronics.computers.laptops",
parent_category_id: "computers",
parent_category: {
id: "computers",
handle: "computers-&-accessories",
mpath: "electronics.computers.",
mpath: "electronics.computers",
parent_category_id: "electronics",
parent_category: {
id: "electronics",
handle: "electronics",
mpath: "electronics.",
mpath: "electronics",
parent_category_id: null,
parent_category: null,
},
@@ -390,14 +385,14 @@ moduleIntegrationTestRunner<Service>({
id: "budget-gaming",
handle: "budget-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.budget-gaming.",
"electronics.computers.laptops.gaming-laptops.budget-gaming",
parent_category_id: "gaming-laptops",
},
{
id: "high-performance",
handle: "high-performance-gaming-laptops",
mpath:
"electronics.computers.laptops.gaming-laptops.high-performance.",
"electronics.computers.laptops.gaming-laptops.high-performance",
parent_category_id: "gaming-laptops",
},
],
@@ -424,17 +419,17 @@ moduleIntegrationTestRunner<Service>({
{
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
parent_category: {
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
parent_category: {
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
parent_category: null,
},
@@ -443,17 +438,17 @@ moduleIntegrationTestRunner<Service>({
{
id: "category-1-b",
handle: "category-1-b",
mpath: "category-0.category-1.category-1-b.",
mpath: "category-0.category-1.category-1-b",
parent_category_id: "category-1",
parent_category: {
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
parent_category: {
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
parent_category: null,
},
@@ -482,17 +477,17 @@ moduleIntegrationTestRunner<Service>({
{
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
parent_category: {
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
parent_category: {
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
parent_category: null,
},
@@ -502,17 +497,17 @@ moduleIntegrationTestRunner<Service>({
{
id: "category-1-b",
handle: "category-1-b",
mpath: "category-0.category-1.category-1-b.",
mpath: "category-0.category-1.category-1-b",
parent_category_id: "category-1",
parent_category: {
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
parent_category: {
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
parent_category: null,
},
@@ -521,7 +516,7 @@ moduleIntegrationTestRunner<Service>({
{
id: "category-1-b-1",
handle: "category-1-b-1",
mpath: "category-0.category-1.category-1-b.category-1-b-1.",
mpath: "category-0.category-1.category-1-b.category-1-b-1",
parent_category_id: "category-1-b",
},
],
@@ -549,19 +544,19 @@ moduleIntegrationTestRunner<Service>({
expect.objectContaining({
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
category_children: [
expect.objectContaining({
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
category_children: [
expect.objectContaining({
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
category_children: [],
}),
@@ -577,10 +572,9 @@ moduleIntegrationTestRunner<Service>({
const categoryOneId = "category-1"
beforeEach(async () => {
await createProductCategories(
MikroOrmWrapper.forkManager(),
productCategoriesData
)
for (const entry of productCategoriesData) {
await service.create([entry])
}
})
it("should return category for the given id", async () => {
@@ -659,10 +653,9 @@ moduleIntegrationTestRunner<Service>({
describe("listAndCount", () => {
beforeEach(async () => {
await createProductCategories(
MikroOrmWrapper.forkManager(),
productCategoriesData
)
for (const entry of productCategoriesData) {
await service.create([entry])
}
})
it("should return categories and count based on take and skip", async () => {
@@ -800,33 +793,33 @@ moduleIntegrationTestRunner<Service>({
expect.objectContaining({
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
category_children: [
expect.objectContaining({
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
category_children: [
expect.objectContaining({
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
category_children: [],
}),
expect.objectContaining({
id: "category-1-b",
handle: "category-1-b",
mpath: "category-0.category-1.category-1-b.",
mpath: "category-0.category-1.category-1-b",
parent_category_id: "category-1",
category_children: [
expect.objectContaining({
id: "category-1-b-1",
handle: "category-1-b-1",
mpath:
"category-0.category-1.category-1-b.category-1-b-1.",
"category-0.category-1.category-1-b.category-1-b-1",
parent_category_id: "category-1-b",
category_children: [],
}),
@@ -861,19 +854,19 @@ moduleIntegrationTestRunner<Service>({
expect.objectContaining({
id: "category-0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
category_children: [
expect.objectContaining({
id: "category-1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: "category-0",
category_children: [
expect.objectContaining({
id: "category-1-a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: "category-1",
category_children: [],
}),
@@ -887,10 +880,12 @@ moduleIntegrationTestRunner<Service>({
describe("create", () => {
it("should create a category successfully", async () => {
await service.create({
name: "New Category",
parent_category_id: null,
})
await service.create([
{
name: "New Category",
parent_category_id: null,
},
])
const [productCategory] = await service.list(
{
@@ -910,16 +905,17 @@ moduleIntegrationTestRunner<Service>({
})
it("should append rank from an existing category depending on parent", async () => {
await service.create({
name: "New Category",
parent_category_id: null,
rank: 0,
})
await service.create({
name: "New Category 2",
parent_category_id: null,
})
await service.create([
{
name: "New Category",
parent_category_id: null,
rank: 0,
},
{
name: "New Category 2",
parent_category_id: null,
},
])
const [productCategoryNew] = await service.list(
{
@@ -930,17 +926,19 @@ moduleIntegrationTestRunner<Service>({
}
)
expect(productCategoryNew).toEqual(
expect(JSON.parse(JSON.stringify(productCategoryNew))).toEqual(
expect.objectContaining({
name: "New Category 2",
rank: 1,
})
)
await service.create({
name: "New Category 2.1",
parent_category_id: productCategoryNew.id,
})
await service.create([
{
name: "New Category 2.1",
parent_category_id: productCategoryNew.id,
},
])
const [productCategoryWithParent] = await service.list(
{
@@ -971,10 +969,10 @@ moduleIntegrationTestRunner<Service>({
let categories
beforeEach(async () => {
categories = await createProductCategories(
MikroOrmWrapper.forkManager(),
productCategoriesRankData
)
categories = []
for (const entry of productCategoriesRankData) {
categories.push((await service.create([entry]))[0])
}
productCategoryZero = categories[0]
productCategoryOne = categories[1]
@@ -985,9 +983,12 @@ moduleIntegrationTestRunner<Service>({
})
it("should update the name of the category successfully", async () => {
await service.update(productCategoryZero.id, {
name: "New Category",
})
await service.update([
{
id: productCategoryZero.id,
name: "New Category",
},
])
const productCategory = await service.retrieve(
productCategoryZero.id,
@@ -1003,9 +1004,12 @@ moduleIntegrationTestRunner<Service>({
let error
try {
await service.update("does-not-exist", {
name: "New Category",
})
await service.update([
{
id: "does-not-exist",
name: "New Category",
},
])
} catch (e) {
error = e
}
@@ -1016,9 +1020,12 @@ moduleIntegrationTestRunner<Service>({
})
it("should reorder rank successfully in the same parent", async () => {
await service.update(productCategoryTwo.id, {
rank: 0,
})
await service.update([
{
id: productCategoryTwo.id,
rank: 0,
},
])
const productCategories = await service.list(
{
@@ -1048,10 +1055,13 @@ moduleIntegrationTestRunner<Service>({
})
it("should reorder rank successfully when changing parent", async () => {
await service.update(productCategoryTwo.id, {
rank: 0,
parent_category_id: productCategoryZero.id,
})
await service.update([
{
id: productCategoryTwo.id,
rank: 0,
parent_category_id: productCategoryZero.id,
},
])
const productCategories = await service.list(
{
@@ -1085,10 +1095,13 @@ moduleIntegrationTestRunner<Service>({
})
it("should reorder rank successfully when changing parent and in first position", async () => {
await service.update(productCategoryTwo.id, {
rank: 0,
parent_category_id: productCategoryZero.id,
})
await service.update([
{
id: productCategoryTwo.id,
rank: 0,
parent_category_id: productCategoryZero.id,
},
])
const productCategories = await service.list(
{
@@ -1129,10 +1142,10 @@ moduleIntegrationTestRunner<Service>({
let categories
beforeEach(async () => {
categories = await createProductCategories(
MikroOrmWrapper.forkManager(),
productCategoriesRankData
)
categories = []
for (const entry of productCategoriesRankData) {
categories.push((await service.create([entry]))[0])
}
productCategoryZero = categories[0]
productCategoryOne = categories[1]
@@ -1143,7 +1156,7 @@ moduleIntegrationTestRunner<Service>({
let error
try {
await service.delete("does-not-exist")
await service.delete(["does-not-exist"])
} catch (e) {
error = e
}
@@ -1157,7 +1170,7 @@ moduleIntegrationTestRunner<Service>({
let error
try {
await service.delete(productCategoryZero.id)
await service.delete([productCategoryZero.id])
} catch (e) {
error = e
}
@@ -1168,7 +1181,7 @@ moduleIntegrationTestRunner<Service>({
})
it("should reorder siblings rank successfully on deleting", async () => {
await service.delete(productCategoryOne.id)
await service.delete([productCategoryOne.id])
const productCategories = await service.list(
{
@@ -6,7 +6,6 @@ import {
MockEventBusService,
moduleIntegrationTestRunner,
} from "medusa-test-utils"
import { createProductCategories } from "../../__fixtures__/product-category"
import { productCategoriesRankData } from "../../__fixtures__/product-category/data"
jest.setTimeout(30000)
@@ -52,18 +51,12 @@ moduleIntegrationTestRunner<IProductModuleService>({
},
]
productCategories = await createProductCategories(
testManager,
productCategoriesData
)
productCategories = []
for (const entry of productCategoriesData) {
productCategories.push(await service.createCategories(entry))
}
productCategoryOne = productCategories[0]
productCategoryTwo = productCategories[1]
await testManager.persistAndFlush([
productCategoryOne,
productCategoryTwo,
])
})
afterEach(async () => {
@@ -260,7 +253,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
describe("createCategory", () => {
it("should create a category successfully", async () => {
await service.createCategory({
await service.createCategories({
name: "New Category",
parent_category_id: productCategoryOne.id,
})
@@ -285,26 +278,28 @@ moduleIntegrationTestRunner<IProductModuleService>({
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
const category = await service.createCategory({
const category = await service.createCategories({
name: "New Category",
parent_category_id: productCategoryOne.id,
})
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith({
data: { id: category.id },
eventName: "product-category.created",
})
expect(eventBusSpy).toHaveBeenCalledWith([
expect.objectContaining({
data: { id: category.id },
eventName: "productService.product-category.created",
}),
])
})
it("should append rank from an existing category depending on parent", async () => {
await service.createCategory({
await service.createCategories({
name: "New Category",
parent_category_id: productCategoryOne.id,
rank: 0,
})
await service.createCategory({
await service.createCategories({
name: "New Category 2",
parent_category_id: productCategoryOne.id,
})
@@ -325,7 +320,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
})
)
await service.createCategory({
await service.createCategories({
name: "New Category 2.1",
parent_category_id: productCategoryNew.id,
})
@@ -359,12 +354,10 @@ moduleIntegrationTestRunner<IProductModuleService>({
let categories
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
categories = await createProductCategories(
testManager,
productCategoriesRankData
)
categories = []
for (const entry of productCategoriesRankData) {
categories.push(await service.createCategories(entry))
}
productCategoryZero = categories[0]
productCategoryOne = categories[1]
@@ -376,19 +369,23 @@ moduleIntegrationTestRunner<IProductModuleService>({
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
await service.updateCategory(productCategoryZero.id, {
eventBusSpy.mockClear()
await service.updateCategories(productCategoryZero.id, {
name: "New Category",
})
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith({
data: { id: productCategoryZero.id },
eventName: "product-category.updated",
})
expect(eventBusSpy).toHaveBeenCalledWith([
expect.objectContaining({
data: { id: productCategoryZero.id },
eventName: "productService.product-category.updated",
}),
])
})
it("should update the name of the category successfully", async () => {
await service.updateCategory(productCategoryZero.id, {
await service.updateCategories(productCategoryZero.id, {
name: "New Category",
})
@@ -406,7 +403,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
let error
try {
await service.updateCategory("does-not-exist", {
await service.updateCategories("does-not-exist", {
name: "New Category",
})
} catch (e) {
@@ -414,12 +411,12 @@ moduleIntegrationTestRunner<IProductModuleService>({
}
expect(error.message).toEqual(
`ProductCategory not found ({ id: 'does-not-exist' })`
`ProductCategory with id: does-not-exist was not found`
)
})
it("should reorder rank successfully in the same parent", async () => {
await service.updateCategory(productCategoryTwo.id, {
await service.updateCategories(productCategoryTwo.id, {
rank: 0,
})
@@ -451,7 +448,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
})
it("should reorder rank successfully when changing parent", async () => {
await service.updateCategory(productCategoryTwo.id, {
await service.updateCategories(productCategoryTwo.id, {
rank: 0,
parent_category_id: productCategoryZero.id,
})
@@ -488,7 +485,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
})
it("should reorder rank successfully when changing parent and in first position", async () => {
await service.updateCategory(productCategoryTwo.id, {
await service.updateCategories(productCategoryTwo.id, {
rank: 0,
parent_category_id: productCategoryZero.id,
})
@@ -532,34 +529,37 @@ moduleIntegrationTestRunner<IProductModuleService>({
let categories
beforeEach(async () => {
const testManager = await MikroOrmWrapper.forkManager()
categories = await createProductCategories(
testManager,
productCategoriesRankData
)
categories = []
for (const entry of productCategoriesRankData) {
categories.push(await service.createCategories(entry))
}
productCategoryZero = categories[0]
productCategoryOne = categories[1]
productCategoryTwo = categories[2]
})
// TODO: Normalize delete events as well
it("should emit events through event bus", async () => {
const eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
await service.deleteCategory(productCategoryOne.id)
eventBusSpy.mockClear()
await service.deleteCategories([productCategoryOne.id])
expect(eventBusSpy).toHaveBeenCalledTimes(1)
expect(eventBusSpy).toHaveBeenCalledWith({
data: { id: productCategoryOne.id },
eventName: "product-category.deleted",
})
expect(eventBusSpy).toHaveBeenCalledWith([
expect.objectContaining({
data: { id: productCategoryOne.id },
eventName: "product-category.deleted",
}),
])
})
it("should throw an error when an id does not exist", async () => {
let error
try {
await service.deleteCategory("does-not-exist")
await service.deleteCategories(["does-not-exist"])
} catch (e) {
error = e
}
@@ -573,7 +573,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
let error
try {
await service.deleteCategory(productCategoryZero.id)
await service.deleteCategories([productCategoryZero.id])
} catch (e) {
error = e
}
@@ -584,7 +584,7 @@ moduleIntegrationTestRunner<IProductModuleService>({
})
it("should reorder siblings rank successfully on deleting", async () => {
await service.deleteCategory(productCategoryOne.id)
await service.deleteCategories([productCategoryOne.id])
const productCategories = await service.listCategories(
{
@@ -1,5 +1,5 @@
import { Modules } from "@medusajs/modules-sdk"
import { IProductModuleService } from "@medusajs/types"
import { IProductModuleService, ProductCategoryDTO } from "@medusajs/types"
import { kebabCase, ProductStatus } from "@medusajs/utils"
import {
Product,
@@ -18,7 +18,6 @@ import {
createCollections,
createTypes,
} from "../../__fixtures__/product"
import { createProductCategories } from "../../__fixtures__/product-category"
jest.setTimeout(300000)
@@ -101,10 +100,10 @@ moduleIntegrationTestRunner<IProductModuleService>({
productTypeOne = types[0]
productTypeTwo = types[1]
const categories = await createProductCategories(
testManager,
productCategoriesData
)
const categories: ProductCategoryDTO[] = []
for (const entry of productCategoriesData) {
categories.push(await service.createCategories(entry))
}
productCategoryOne = categories[0]
productCategoryTwo = categories[1]
@@ -12,9 +12,8 @@ import { Modules } from "@medusajs/modules-sdk"
import { IProductModuleService, ProductDTO } from "@medusajs/types"
import { kebabCase, ProductStatus } from "@medusajs/utils"
import { SqlEntityManager } from "@mikro-orm/postgresql"
import { ProductService } from "@services"
import { ProductService, ProductCategoryService } from "@services"
import { moduleIntegrationTestRunner } from "medusa-test-utils"
import { createProductCategories } from "../__fixtures__/product-category"
import {
categoriesData,
productsData,
@@ -25,15 +24,18 @@ jest.setTimeout(30000)
type Service = IProductModuleService & {
productService_: ProductService
productCategoryService_: ProductCategoryService
}
moduleIntegrationTestRunner<Service>({
moduleName: Modules.PRODUCT,
testSuite: ({ MikroOrmWrapper, service: moduleService }) => {
let service: ProductService
let categoryService: ProductCategoryService
beforeEach(() => {
service = moduleService.productService_
categoryService = moduleService.productCategoryService_
})
describe("Product Service", () => {
@@ -351,10 +353,11 @@ moduleIntegrationTestRunner<Service>({
products = await createProductAndTags(testManager, productsData)
workingProduct = products.find((p) => p.id === "test-1") as Product
categories = await createProductCategories(
testManager,
categoriesData
)
categories = []
for (const entry of categoriesData) {
categories.push((await categoryService.create([entry]))[0])
}
workingCategory = (await testManager.findOne(
ProductCategory,
"category-1"
@@ -400,21 +403,21 @@ moduleIntegrationTestRunner<Service>({
id: "category-0",
name: "category 0",
handle: "category-0",
mpath: "category-0.",
mpath: "category-0",
parent_category_id: null,
},
{
id: "category-1",
name: "category 1",
handle: "category-1",
mpath: "category-0.category-1.",
mpath: "category-0.category-1",
parent_category_id: null,
},
{
id: "category-1-a",
name: "category 1 a",
handle: "category-1-a",
mpath: "category-0.category-1.category-1-a.",
mpath: "category-0.category-1.category-1-a",
parent_category_id: null,
},
])