feat: Add support for category deletion (#7679)

This commit is contained in:
Stevche Radevski
2024-06-11 16:49:42 +02:00
committed by GitHub
parent dd0b9f0805
commit 0e731dbad0
8 changed files with 164 additions and 35 deletions

View File

@@ -639,18 +639,79 @@ medusaIntegrationTestRunner({
})
})
// TODO: Should be migrate to V2
describe.skip("DELETE /admin/product-categories/:id", () => {
it("returns successfully with an invalid ID", async () => {
const response = await api.delete(
`/admin/product-categories/invalid-id`,
adminHeaders
)
describe("DELETE /admin/product-categories/:id", () => {
beforeEach(async () => {
productCategoryParent = (
await api.post(
"/admin/product-categories",
{
name: "category parent",
description: "category parent",
},
adminHeaders
)
).data.product_category
expect(response.status).toEqual(200)
expect(response.data.id).toEqual("invalid-id")
expect(response.data.deleted).toBeTruthy()
expect(response.data.object).toEqual("product-category")
productCategory = (
await api.post(
"/admin/product-categories",
{
name: "category-0",
parent_category_id: productCategoryParent.id,
rank: 0,
description: "category-0",
},
adminHeaders
)
).data.product_category
productCategoryChild = (
await api.post(
"/admin/product-categories",
{
name: "category child",
parent_category_id: productCategory.id,
rank: 0,
description: "category child",
},
adminHeaders
)
).data.product_category
productCategoryChild2 = (
await api.post(
"/admin/product-categories",
{
name: "category child 2",
parent_category_id: productCategoryChild.id,
rank: 2,
description: "category child 2",
},
adminHeaders
)
).data.product_category
productCategoryChild3 = (
await api.post(
"/admin/product-categories",
{
name: "category child 3",
parent_category_id: productCategoryChild.id,
rank: 2,
description: "category child 3",
},
adminHeaders
)
).data.product_category
})
// BREAKING: In v1 we would return 200 on an invalid ID, in v2 we return 404
it("returns successfully with an invalid ID", async () => {
const err = await api
.delete(`/admin/product-categories/invalid-id`, adminHeaders)
.catch((e) => e)
expect(err.response.status).toEqual(404)
})
it("throws a not allowed error for a category with children", async () => {
@@ -669,49 +730,43 @@ medusaIntegrationTestRunner({
})
it("deletes a product category with no children successfully", async () => {
const deleteResponse = await api
.delete(
`/admin/product-categories/${productCategory.id}`,
adminHeaders
)
.catch((e) => e)
const deleteResponse = await api.delete(
`/admin/product-categories/${productCategoryChild2.id}`,
adminHeaders
)
expect(deleteResponse.status).toEqual(200)
expect(deleteResponse.data.id).toEqual(productCategory.id)
expect(deleteResponse.data.id).toEqual(productCategoryChild2.id)
expect(deleteResponse.data.deleted).toBeTruthy()
expect(deleteResponse.data.object).toEqual("product-category")
expect(deleteResponse.data.object).toEqual("product_category")
const errorFetchingDeleted = await api
.get(`/admin/product-categories/${productCategory.id}`, adminHeaders)
.get(
`/admin/product-categories/${productCategoryChild2.id}`,
adminHeaders
)
.catch((e) => e)
expect(errorFetchingDeleted.response.status).toEqual(404)
})
it("deleting a product category reorders siblings accurately", async () => {
const deleteResponse = await api
.delete(
`/admin/product-categories/${productCategory.id}`,
adminHeaders
)
.catch((e) => e)
const deleteResponse = await api.delete(
`/admin/product-categories/${productCategoryChild2.id}`,
adminHeaders
)
expect(deleteResponse.status).toEqual(200)
const siblingsResponse = await api
.get(
`/admin/product-categories?parent_category_id=${productCategoryParent.id}`,
`/admin/product-categories?parent_category_id=${productCategoryChild.id}`,
adminHeaders
)
.catch((e) => e)
expect(siblingsResponse.data.product_categories).toEqual([
expect.objectContaining({
id: productCategory1.id,
rank: 0,
}),
expect.objectContaining({
id: productCategory2.id,
id: productCategoryChild3.id,
rank: 1,
}),
])

View File

@@ -0,0 +1,28 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { IProductModuleService } from "@medusajs/types"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
export const deleteProductCategoryStepId = "delete-product-category"
export const deleteProductCategoryStep = createStep(
deleteProductCategoryStepId,
async (id: string, { container }) => {
const service = container.resolve<IProductModuleService>(
ModuleRegistrationName.PRODUCT
)
await service.deleteCategory(id)
return new StepResponse(void 0, id)
},
async (prevId, { container }) => {
if (!prevId) {
return
}
const service = container.resolve<IProductModuleService>(
ModuleRegistrationName.PRODUCT
)
// TODO: There is no soft delete support for categories yet
// await service.restoreCategory(prevId)
}
)

View File

@@ -1 +1,3 @@
export * from "./create-product-category"
export * from "./update-product-category"
export * from "./delete-product-category"

View File

@@ -0,0 +1,10 @@
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { deleteProductCategoryStep } from "../steps"
export const deleteProductCategoryWorkflowId = "delete-product-category"
export const deleteProductCategoryWorkflow = createWorkflow(
deleteProductCategoryWorkflowId,
(input: WorkflowData<string>) => {
return deleteProductCategoryStep(input)
}
)

View File

@@ -1,2 +1,3 @@
export * from "./create-product-category"
export * from "./update-product-category"
export * from "./delete-product-category"

View File

@@ -1,6 +1,6 @@
import { ProductCategoryWorkflow } from "@medusajs/types"
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { updateProductCategoryStep } from "../steps/update-product-category"
import { updateProductCategoryStep } from "../steps"
type WorkflowInputData =
ProductCategoryWorkflow.UpdateProductCategoryWorkflowInput

View File

@@ -1,4 +1,7 @@
import { updateProductCategoryWorkflow } from "@medusajs/core-flows"
import {
deleteProductCategoryWorkflow,
updateProductCategoryWorkflow,
} from "@medusajs/core-flows"
import { AdminProductCategoryResponse } from "@medusajs/types"
import {
AuthenticatedMedusaRequest,
@@ -9,6 +12,7 @@ import {
AdminProductCategoryParamsType,
AdminUpdateProductCategoryType,
} from "../validators"
import { MedusaError } from "@medusajs/utils"
export const GET = async (
req: AuthenticatedMedusaRequest<AdminProductCategoryParamsType>,
@@ -21,6 +25,13 @@ export const GET = async (
req.remoteQueryConfig.fields
)
if (!category) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Product category with id: ${req.params.id} was not found`
)
}
res.json({ product_category: category })
}
@@ -44,3 +55,20 @@ export const POST = async (
res.status(200).json({ product_category: category })
}
export const DELETE = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const id = req.params.id
await deleteProductCategoryWorkflow(req.scope).run({
input: id,
})
res.status(200).json({
id,
object: "product_category",
deleted: true,
})
}

View File

@@ -53,6 +53,11 @@ export const adminProductCategoryRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["DELETE"],
matcher: "/admin/product-categories/:id",
middlewares: [],
},
{
method: ["POST"],
matcher: "/admin/product-categories/:id/products",