feat(medusa): Add endpoint for retrieving a DiscountCondition (#1525)

This commit is contained in:
Oliver Windall Juhl
2022-05-17 11:17:17 +02:00
committed by GitHub
parent b02f2652be
commit a87e1cdf65
10 changed files with 450 additions and 42 deletions
@@ -1,7 +1,9 @@
import {
AdminDiscountConditionsRes,
AdminDiscountsDeleteRes,
AdminDiscountsListRes,
AdminDiscountsRes,
AdminGetDiscountsDiscountConditionsConditionParams,
AdminGetDiscountsParams,
AdminPostDiscountsDiscountConditions,
AdminPostDiscountsDiscountConditionsCondition,
@@ -187,6 +189,25 @@ class AdminDiscountsResource extends BaseResource {
const path = `/admin/discounts/${discountId}/conditions/${conditionId}`
return this.client.request("DELETE", path, {}, {}, customHeaders)
}
/**
* @description Gets a condition from a discount
*/
getCondition(
discountId: string,
conditionId: string,
query?: AdminGetDiscountsDiscountConditionsConditionParams,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminDiscountConditionsRes> {
let path = `/admin/discounts/${discountId}/conditions/${conditionId}`
if (query) {
const queryString = qs.stringify(query)
path = `/admin/discounts/${discountId}/conditions/${conditionId}?${queryString}`
}
return this.client.request("GET", path, {}, {}, customHeaders)
}
}
export default AdminDiscountsResource
+14 -1
View File
@@ -1,5 +1,5 @@
import { fixtures } from "../data"
import { rest } from "msw"
import { fixtures } from "../data"
export const adminHandlers = [
rest.post("/admin/collections/", (req, res, ctx) => {
@@ -784,6 +784,19 @@ export const adminHandlers = [
)
}),
rest.get("/admin/discounts/:id/conditions/:conditionId", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
discount_condition: {
...fixtures
.get("discount")
.rule.conditions.find(c => c.id === req.params.conditionId),
},
})
)
}),
rest.delete(
"/admin/discounts/:id/conditions/:conditionId",
(req, res, ctx) => {
@@ -1,7 +1,9 @@
import {
AdminDiscountConditionsRes,
AdminDiscountsListRes,
AdminDiscountsRes,
AdminGetDiscountParams,
AdminGetDiscountsDiscountConditionsConditionParams,
AdminGetDiscountsParams,
} from "@medusajs/medusa"
import { Response } from "@medusajs/medusa-js"
@@ -12,7 +14,16 @@ import { queryKeysFactory } from "../../utils/index"
const ADMIN_DISCOUNTS_QUERY_KEY = `admin_discounts` as const
export const adminDiscountKeys = queryKeysFactory(ADMIN_DISCOUNTS_QUERY_KEY)
export const adminDiscountKeys = {
...queryKeysFactory(ADMIN_DISCOUNTS_QUERY_KEY),
detailCondition(id: string, query?: any) {
return [
...this.detail(id),
"condition" as const,
{ ...(query || {}) },
] as const
},
}
type DiscountQueryKeys = typeof adminDiscountKeys
@@ -67,3 +78,22 @@ export const useAdminGetDiscountByCode = (
)
return { ...data, ...rest } as const
}
export const useAdminGetDiscountCondition = (
id: string,
conditionId: string,
query?: AdminGetDiscountsDiscountConditionsConditionParams,
options?: UseQueryOptionsWrapper<
Response<AdminDiscountConditionsRes>,
Error,
ReturnType<DiscountQueryKeys["detailCondition"]>
>
) => {
const { client } = useMedusa()
const { data, ...rest } = useQuery(
adminDiscountKeys.detailCondition(conditionId),
() => client.admin.discounts.getCondition(id, conditionId, query),
options
)
return { ...data, ...rest } as const
}
@@ -1,10 +1,11 @@
import { renderHook } from "@testing-library/react-hooks"
import { fixtures } from "../../../../mocks/data"
import {
useAdminDiscount,
useAdminDiscounts,
useAdminGetDiscountByCode,
useAdminGetDiscountCondition,
} from "../../../../src"
import { renderHook } from "@testing-library/react-hooks"
import { fixtures } from "../../../../mocks/data"
import { createWrapper } from "../../../utils"
describe("useAdminDiscounts hook", () => {
@@ -54,3 +55,26 @@ describe("useAdminDiscount hook", () => {
expect(result.current.discount).toEqual(discount)
})
})
describe("useAdminGetDiscountCondition hook", () => {
test("returns a discount condition", async () => {
const discount = fixtures.get("discount")
const { result, waitFor } = renderHook(
() =>
useAdminGetDiscountCondition(
discount.id,
discount.rule.conditions[0].id
),
{
wrapper: createWrapper(),
}
)
await waitFor(() => result.current.isSuccess)
expect(result.current.response.status).toEqual(200)
expect(result.current.discount_condition).toEqual(
discount.rule.conditions[0]
)
})
})
@@ -0,0 +1,90 @@
import { IsOptional, IsString } from "class-validator"
import { MedusaError } from "medusa-core-utils"
import {
defaultAdminDiscountConditionFields,
defaultAdminDiscountConditionRelations,
} from "."
import { DiscountCondition } from "../../../../models"
import { DiscountService } from "../../../../services"
import DiscountConditionService from "../../../../services/discount-condition"
import { getRetrieveConfig } from "../../../../utils/get-query-config"
import { validator } from "../../../../utils/validator"
/**
* @oas [get] /discounts/{discount_id}/conditions/{condition_id}
* operationId: "GetDiscountsDiscountConditionsCondition"
* summary: "Gets a DiscountCondition"
* x-authenticated: true
* parameters:
* - (path) discount_id=* {string} The id of the Discount.
* - (path) condition_id=* {string} The id of the DiscountCondition.
* query:
* - (query) expand {string} Comma separated list of relations to include in the results.
* - (query) fields {string} Comma separated list of fields to include in the results.
* description: "Gets a DiscountCondition"
* tags:
* - DiscountCondition
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount_condition:
* $ref: "#/components/schemas/discount_condition"
*/
export default async (req, res) => {
const { discount_id, condition_id } = req.params
const validatedParams = await validator(
AdminGetDiscountsDiscountConditionsConditionParams,
req.query
)
const discountService: DiscountService = req.scope.resolve("discountService")
const discount = await discountService.retrieve(discount_id, {
relations: ["rule", "rule.conditions"],
})
const existsOnDiscount = discount.rule.conditions.some(
(c) => c.id === condition_id
)
if (!existsOnDiscount) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Condition with id ${condition_id} does not belong to Discount with id ${discount_id}`
)
}
const config = getRetrieveConfig<DiscountCondition>(
defaultAdminDiscountConditionFields,
defaultAdminDiscountConditionRelations,
validatedParams?.fields?.split(",") as (keyof DiscountCondition)[],
validatedParams?.expand?.split(",")
)
const conditionService: DiscountConditionService = req.scope.resolve(
"discountConditionService"
)
const discountCondition = await conditionService.retrieve(
condition_id,
config
)
res.status(200).json({ discount_condition: discountCondition })
}
export class AdminGetDiscountsDiscountConditionsConditionParams {
@IsString()
@IsOptional()
expand?: string
@IsString()
@IsOptional()
fields?: string
}
@@ -1,6 +1,7 @@
import { Router } from "express"
import "reflect-metadata"
import { Discount } from "../../../.."
import { DiscountCondition } from "../../../../models"
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
import middlewares from "../../../middlewares"
@@ -50,6 +51,10 @@ export default (app) => {
)
// Discount condition management
route.get(
"/:discount_id/conditions/:condition_id",
middlewares.wrap(require("./get-condition").default)
)
route.post(
"/:discount_id/conditions/:condition_id",
middlewares.wrap(require("./update-condition").default)
@@ -91,10 +96,19 @@ export const defaultAdminDiscountsRelations = [
"rule.conditions",
]
export const defaultAdminDiscountConditionFields: (keyof DiscountCondition)[] =
["id", "type", "operator", "discount_rule_id", "created_at", "updated_at"]
export const defaultAdminDiscountConditionRelations = ["discount_rule"]
export type AdminDiscountsRes = {
discount: Discount
}
export type AdminDiscountConditionsRes = {
discount_condition: DiscountCondition
}
export type AdminDiscountsDeleteRes = DeleteResponse
export type AdminDiscountsListRes = PaginatedResponse & {
@@ -108,6 +122,7 @@ export * from "./create-dynamic-code"
export * from "./delete-condition"
export * from "./delete-discount"
export * from "./delete-dynamic-code"
export * from "./get-condition"
export * from "./get-discount"
export * from "./get-discount-by-code"
export * from "./list-discounts"