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:
+118
-118
@@ -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(
|
||||
{
|
||||
|
||||
+51
-51
@@ -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(
|
||||
{
|
||||
|
||||
+5
-6
@@ -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,
|
||||
},
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user