feat: Add support for category deletion (#7679)
This commit is contained in:
@@ -639,18 +639,79 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Should be migrate to V2
|
describe("DELETE /admin/product-categories/:id", () => {
|
||||||
describe.skip("DELETE /admin/product-categories/:id", () => {
|
beforeEach(async () => {
|
||||||
it("returns successfully with an invalid ID", async () => {
|
productCategoryParent = (
|
||||||
const response = await api.delete(
|
await api.post(
|
||||||
`/admin/product-categories/invalid-id`,
|
"/admin/product-categories",
|
||||||
adminHeaders
|
{
|
||||||
)
|
name: "category parent",
|
||||||
|
description: "category parent",
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.product_category
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
productCategory = (
|
||||||
expect(response.data.id).toEqual("invalid-id")
|
await api.post(
|
||||||
expect(response.data.deleted).toBeTruthy()
|
"/admin/product-categories",
|
||||||
expect(response.data.object).toEqual("product-category")
|
{
|
||||||
|
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 () => {
|
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 () => {
|
it("deletes a product category with no children successfully", async () => {
|
||||||
const deleteResponse = await api
|
const deleteResponse = await api.delete(
|
||||||
.delete(
|
`/admin/product-categories/${productCategoryChild2.id}`,
|
||||||
`/admin/product-categories/${productCategory.id}`,
|
adminHeaders
|
||||||
adminHeaders
|
)
|
||||||
)
|
|
||||||
.catch((e) => e)
|
|
||||||
|
|
||||||
expect(deleteResponse.status).toEqual(200)
|
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.deleted).toBeTruthy()
|
||||||
expect(deleteResponse.data.object).toEqual("product-category")
|
expect(deleteResponse.data.object).toEqual("product_category")
|
||||||
|
|
||||||
const errorFetchingDeleted = await api
|
const errorFetchingDeleted = await api
|
||||||
.get(`/admin/product-categories/${productCategory.id}`, adminHeaders)
|
.get(
|
||||||
|
`/admin/product-categories/${productCategoryChild2.id}`,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
.catch((e) => e)
|
.catch((e) => e)
|
||||||
|
|
||||||
expect(errorFetchingDeleted.response.status).toEqual(404)
|
expect(errorFetchingDeleted.response.status).toEqual(404)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("deleting a product category reorders siblings accurately", async () => {
|
it("deleting a product category reorders siblings accurately", async () => {
|
||||||
const deleteResponse = await api
|
const deleteResponse = await api.delete(
|
||||||
.delete(
|
`/admin/product-categories/${productCategoryChild2.id}`,
|
||||||
`/admin/product-categories/${productCategory.id}`,
|
adminHeaders
|
||||||
adminHeaders
|
)
|
||||||
)
|
|
||||||
.catch((e) => e)
|
|
||||||
|
|
||||||
expect(deleteResponse.status).toEqual(200)
|
expect(deleteResponse.status).toEqual(200)
|
||||||
|
|
||||||
const siblingsResponse = await api
|
const siblingsResponse = await api
|
||||||
.get(
|
.get(
|
||||||
`/admin/product-categories?parent_category_id=${productCategoryParent.id}`,
|
`/admin/product-categories?parent_category_id=${productCategoryChild.id}`,
|
||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
.catch((e) => e)
|
.catch((e) => e)
|
||||||
|
|
||||||
expect(siblingsResponse.data.product_categories).toEqual([
|
expect(siblingsResponse.data.product_categories).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: productCategory1.id,
|
id: productCategoryChild3.id,
|
||||||
rank: 0,
|
|
||||||
}),
|
|
||||||
expect.objectContaining({
|
|
||||||
id: productCategory2.id,
|
|
||||||
rank: 1,
|
rank: 1,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1 +1,3 @@
|
|||||||
export * from "./create-product-category"
|
export * from "./create-product-category"
|
||||||
|
export * from "./update-product-category"
|
||||||
|
export * from "./delete-product-category"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export * from "./create-product-category"
|
export * from "./create-product-category"
|
||||||
export * from "./update-product-category"
|
export * from "./update-product-category"
|
||||||
|
export * from "./delete-product-category"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ProductCategoryWorkflow } from "@medusajs/types"
|
import { ProductCategoryWorkflow } from "@medusajs/types"
|
||||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
import { updateProductCategoryStep } from "../steps/update-product-category"
|
import { updateProductCategoryStep } from "../steps"
|
||||||
|
|
||||||
type WorkflowInputData =
|
type WorkflowInputData =
|
||||||
ProductCategoryWorkflow.UpdateProductCategoryWorkflowInput
|
ProductCategoryWorkflow.UpdateProductCategoryWorkflowInput
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import { updateProductCategoryWorkflow } from "@medusajs/core-flows"
|
import {
|
||||||
|
deleteProductCategoryWorkflow,
|
||||||
|
updateProductCategoryWorkflow,
|
||||||
|
} from "@medusajs/core-flows"
|
||||||
import { AdminProductCategoryResponse } from "@medusajs/types"
|
import { AdminProductCategoryResponse } from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
AuthenticatedMedusaRequest,
|
AuthenticatedMedusaRequest,
|
||||||
@@ -9,6 +12,7 @@ import {
|
|||||||
AdminProductCategoryParamsType,
|
AdminProductCategoryParamsType,
|
||||||
AdminUpdateProductCategoryType,
|
AdminUpdateProductCategoryType,
|
||||||
} from "../validators"
|
} from "../validators"
|
||||||
|
import { MedusaError } from "@medusajs/utils"
|
||||||
|
|
||||||
export const GET = async (
|
export const GET = async (
|
||||||
req: AuthenticatedMedusaRequest<AdminProductCategoryParamsType>,
|
req: AuthenticatedMedusaRequest<AdminProductCategoryParamsType>,
|
||||||
@@ -21,6 +25,13 @@ export const GET = async (
|
|||||||
req.remoteQueryConfig.fields
|
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 })
|
res.json({ product_category: category })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,3 +55,20 @@ export const POST = async (
|
|||||||
|
|
||||||
res.status(200).json({ product_category: category })
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ export const adminProductCategoryRoutesMiddlewares: MiddlewareRoute[] = [
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
method: ["DELETE"],
|
||||||
|
matcher: "/admin/product-categories/:id",
|
||||||
|
middlewares: [],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
method: ["POST"],
|
method: ["POST"],
|
||||||
matcher: "/admin/product-categories/:id/products",
|
matcher: "/admin/product-categories/:id/products",
|
||||||
|
|||||||
Reference in New Issue
Block a user