Skip to content

Commit

Permalink
Merge branch 'develop' into feat/oas-path-url
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-medusajs authored Feb 22, 2023
2 parents a7e85ed + 68496ff commit b7bce05
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-cobras-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---

fix(medusa): fixes bug for mpath incorrectly updated for nested categories
124 changes: 109 additions & 15 deletions integration-tests/api/__tests__/admin/product-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ describe("/admin/product-categories", () => {
describe("POST /admin/product-categories", () => {
beforeEach(async () => {
await adminSeeder(dbConnection)

productCategoryParent = await simpleProductCategoryFactory(dbConnection, {
name: "category parent",
handle: "category-parent",
})

productCategory = await simpleProductCategoryFactory(dbConnection, {
name: "category",
handle: "category",
parent_category: productCategoryParent,
})
})

afterEach(async () => {
Expand All @@ -267,11 +278,6 @@ describe("/admin/product-categories", () => {
})

it("successfully creates a product category", async () => {
productCategoryParent = await simpleProductCategoryFactory(dbConnection, {
name: "category parent",
handle: "category-parent",
})

const api = useApi()

const response = await api.post(
Expand All @@ -280,7 +286,7 @@ describe("/admin/product-categories", () => {
name: "test",
handle: "test",
is_internal: true,
parent_category_id: productCategoryParent.id,
parent_category_id: productCategory.id,
},
adminHeaders
)
Expand All @@ -296,13 +302,49 @@ describe("/admin/product-categories", () => {
created_at: expect.any(String),
updated_at: expect.any(String),
parent_category: expect.objectContaining({
id: productCategoryParent.id
id: productCategory.id
}),
category_children: []
}),
})
)
})

it("root parent returns children correctly on creating new category", async () => {
const api = useApi()

const response = await api.post(
`/admin/product-categories`,
{
name: "last descendant",
parent_category_id: productCategory.id,
},
adminHeaders
)
const lastDescendant = response.data.product_category

const parentResponse = await api.get(
`/admin/product-categories/${productCategoryParent.id}`,
adminHeaders
)

expect(parentResponse.data.product_category).toEqual(
expect.objectContaining({
id: productCategoryParent.id,
category_children: [
expect.objectContaining({
id: productCategory.id,
category_children: [
expect.objectContaining({
id: lastDescendant.id,
category_children: []
})
]
})
]
})
)
})
})

describe("DELETE /admin/product-categories/:id", () => {
Expand Down Expand Up @@ -381,14 +423,27 @@ describe("/admin/product-categories", () => {
beforeEach(async () => {
await adminSeeder(dbConnection)

productCategoryParent = await simpleProductCategoryFactory(dbConnection, {
name: "category parent",
handle: "category-parent",
})

productCategory = await simpleProductCategoryFactory(dbConnection, {
name: "skinny jeans",
handle: "skinny-jeans",
name: "category",
handle: "category",
parent_category: productCategoryParent,
})

productCategory2 = await simpleProductCategoryFactory(dbConnection, {
name: "sweater",
handle: "sweater",
productCategoryChild = await simpleProductCategoryFactory(dbConnection, {
name: "category child",
handle: "category-child",
parent_category: productCategory,
})

productCategoryChild2 = await simpleProductCategoryFactory(dbConnection, {
name: "category child 2",
handle: "category-child-2",
parent_category: productCategoryChild,
})
})

Expand Down Expand Up @@ -437,13 +492,13 @@ describe("/admin/product-categories", () => {
const api = useApi()

const response = await api.post(
`/admin/product-categories/${productCategory.id}`,
`/admin/product-categories/${productCategoryChild2.id}`,
{
name: "test",
handle: "test",
is_internal: true,
is_active: true,
parent_category_id: productCategory2.id,
parent_category_id: productCategory.id,
},
adminHeaders
)
Expand All @@ -459,13 +514,52 @@ describe("/admin/product-categories", () => {
created_at: expect.any(String),
updated_at: expect.any(String),
parent_category: expect.objectContaining({
id: productCategory2.id,
id: productCategory.id,
}),
category_children: []
}),
})
)
})

it("root parent returns children correctly on updating new category", async () => {
const api = useApi()

const response = await api.post(
`/admin/product-categories/${productCategoryChild2.id}`,
{
parent_category_id: productCategory.id,
},
adminHeaders
)
const lastDescendant = response.data.product_category

const parentResponse = await api.get(
`/admin/product-categories/${productCategoryParent.id}`,
adminHeaders
)

expect(parentResponse.data.product_category).toEqual(
expect.objectContaining({
id: productCategoryParent.id,
category_children: [
expect.objectContaining({
id: productCategory.id,
category_children: [
expect.objectContaining({
id: productCategoryChild.id,
category_children: []
}),
expect.objectContaining({
id: productCategoryChild2.id,
category_children: []
})
]
})
]
})
)
})
})

describe("POST /admin/product-categories/:id/products/batch", () => {
Expand Down
35 changes: 34 additions & 1 deletion packages/medusa/src/services/product-category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,17 @@ class ProductCategoryService extends TransactionBaseService {

/**
* Creates a product category
* @param productCategory - params used to create
* @param productCategoryInput - parameters to create a product category
* @return created product category
*/
async create(
productCategoryInput: CreateProductCategoryInput
): Promise<ProductCategory> {
return await this.atomicPhase_(async (manager) => {
const pcRepo = manager.withRepository(this.productCategoryRepo_)

await this.transformParentIdToEntity(productCategoryInput)

let productCategory = pcRepo.create(productCategoryInput)
productCategory = await pcRepo.save(productCategory)

Expand Down Expand Up @@ -157,6 +160,8 @@ class ProductCategoryService extends TransactionBaseService {
this.productCategoryRepo_
)

await this.transformParentIdToEntity(productCategoryInput)

let productCategory = await this.retrieve(productCategoryId)

for (const key in productCategoryInput) {
Expand Down Expand Up @@ -253,6 +258,34 @@ class ProductCategoryService extends TransactionBaseService {
)
})
}

/**
* Accepts an input object and transforms product_category_id
* into product_category entity.
* @param productCategoryInput - params used to create/update
* @return transformed productCategoryInput
*/
protected async transformParentIdToEntity(
productCategoryInput:
| CreateProductCategoryInput
| UpdateProductCategoryInput
): Promise<CreateProductCategoryInput | UpdateProductCategoryInput> {
// Typeorm only updates mpath when the category entity of the parent
// is passed into create/save. For this reason, everytime we create a
// category, we must fetch the entity and push to create
const parentCategoryId = productCategoryInput.parent_category_id

if (!parentCategoryId) {
return productCategoryInput
}

const parentCategory = await this.retrieve(parentCategoryId)

productCategoryInput.parent_category = parentCategory
delete productCategoryInput.parent_category_id

return productCategoryInput
}
}

export default ProductCategoryService
3 changes: 3 additions & 0 deletions packages/medusa/src/types/product-category.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Transform } from "class-transformer"
import { IsNotEmpty, IsOptional, IsString, IsBoolean } from "class-validator"
import { ProductCategory } from "../models"

export type CreateProductCategoryInput = {
name: string
handle?: string
is_internal?: boolean
is_active?: boolean
parent_category_id?: string | null
parent_category?: ProductCategory | null
}

export type UpdateProductCategoryInput = {
Expand All @@ -15,6 +17,7 @@ export type UpdateProductCategoryInput = {
is_internal?: boolean
is_active?: boolean
parent_category_id?: string | null
parent_category?: ProductCategory | null
}

export class AdminProductCategoriesReqBase {
Expand Down

0 comments on commit b7bce05

Please sign in to comment.