fix(medusa): Prevent discount type updates (#1584)
This commit is contained in:
committed by
GitHub
parent
fa031fd28b
commit
083ab09361
@@ -161,7 +161,7 @@ describe("POST /admin/discounts", () => {
|
||||
|
||||
it("returns error", () => {
|
||||
expect(subject.body.message).toEqual(
|
||||
`type should not be empty, type must be a string`
|
||||
`Invalid rule type, must be one of "fixed", "percentage" or "free_shipping"`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -16,7 +16,6 @@ describe("POST /admin/discounts", () => {
|
||||
code: "10TOTALOFF",
|
||||
rule: {
|
||||
id: "1234",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
@@ -42,7 +41,6 @@ describe("POST /admin/discounts", () => {
|
||||
code: "10TOTALOFF",
|
||||
rule: {
|
||||
id: "1234",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
@@ -64,12 +62,9 @@ describe("POST /admin/discounts", () => {
|
||||
code: "10TOTALOFF",
|
||||
rule: {
|
||||
id: "1234",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
starts_at: "02/02/2021 13:45",
|
||||
is_dynamic: true,
|
||||
valid_duration: "PaMT2D",
|
||||
},
|
||||
adminSession: {
|
||||
@@ -92,60 +87,6 @@ describe("POST /admin/discounts", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("successful update with dynamic discount", () => {
|
||||
let subject
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
subject = await request(
|
||||
"POST",
|
||||
`/admin/discounts/${IdMap.getId("total10")}`,
|
||||
{
|
||||
payload: {
|
||||
code: "10TOTALOFF",
|
||||
rule: {
|
||||
id: "1234",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
starts_at: "02/02/2021 13:45",
|
||||
is_dynamic: true,
|
||||
valid_duration: "P1Y2M03DT04H05M",
|
||||
},
|
||||
adminSession: {
|
||||
jwt: {
|
||||
userId: IdMap.getId("admin_user"),
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("returns 200", () => {
|
||||
expect(subject.status).toEqual(200)
|
||||
})
|
||||
|
||||
it("calls service update", () => {
|
||||
expect(DiscountServiceMock.update).toHaveBeenCalledTimes(1)
|
||||
expect(DiscountServiceMock.update).toHaveBeenCalledWith(
|
||||
IdMap.getId("total10"),
|
||||
{
|
||||
code: "10TOTALOFF",
|
||||
rule: {
|
||||
id: "1234",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
starts_at: new Date("02/02/2021 13:45"),
|
||||
is_dynamic: true,
|
||||
valid_duration: "P1Y2M03DT04H05M",
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("fails on invalid date intervals", () => {
|
||||
let subject
|
||||
|
||||
@@ -159,7 +100,6 @@ describe("POST /admin/discounts", () => {
|
||||
code: "10TOTALOFF",
|
||||
rule: {
|
||||
id: "1234",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
IsDate,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsObject,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "."
|
||||
import { AllocationType, DiscountRuleType } from "../../../../models"
|
||||
import { Discount } from "../../../../models/discount"
|
||||
import { DiscountConditionOperator } from "../../../../models/discount-condition"
|
||||
import DiscountService from "../../../../services/discount"
|
||||
@@ -157,16 +159,18 @@ export class AdminPostDiscountsDiscountRule {
|
||||
@IsOptional()
|
||||
description?: string
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
type: string
|
||||
@IsEnum(DiscountRuleType, {
|
||||
message: `Invalid rule type, must be one of "fixed", "percentage" or "free_shipping"`,
|
||||
})
|
||||
type: DiscountRuleType
|
||||
|
||||
@IsNumber()
|
||||
value: number
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
allocation: string
|
||||
@IsEnum(AllocationType, {
|
||||
message: `Invalid allocation type, must be one of "total" or "item"`,
|
||||
})
|
||||
allocation: AllocationType
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { defaultAdminDiscountsRelations } from "."
|
||||
import { IsOptional, IsString } from "class-validator"
|
||||
import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "."
|
||||
import { Discount } from "../../../../models"
|
||||
import DiscountService from "../../../../services/discount"
|
||||
import { getRetrieveConfig } from "../../../../utils/get-query-config"
|
||||
import { validator } from "../../../../utils/validator"
|
||||
/**
|
||||
* @oas [get] /discounts/code/{code}
|
||||
* operationId: "GetDiscountsDiscountCode"
|
||||
@@ -23,11 +27,30 @@ import DiscountService from "../../../../services/discount"
|
||||
export default async (req, res) => {
|
||||
const { code } = req.params
|
||||
|
||||
const discountService: DiscountService = req.scope.resolve("discountService")
|
||||
const discount = await discountService.retrieveByCode(
|
||||
code,
|
||||
defaultAdminDiscountsRelations
|
||||
const validated = await validator(
|
||||
AdminGetDiscountsDiscountCodeParams,
|
||||
req.query
|
||||
)
|
||||
|
||||
const config = getRetrieveConfig<Discount>(
|
||||
defaultAdminDiscountsFields,
|
||||
defaultAdminDiscountsRelations,
|
||||
validated?.fields?.split(",") as (keyof Discount)[],
|
||||
validated?.expand?.split(",")
|
||||
)
|
||||
|
||||
const discountService: DiscountService = req.scope.resolve("discountService")
|
||||
const discount = await discountService.retrieveByCode(code, config)
|
||||
|
||||
res.status(200).json({ discount })
|
||||
}
|
||||
|
||||
export class AdminGetDiscountsDiscountCodeParams {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
expand?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
fields?: string
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
IsDate,
|
||||
IsEnum,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsObject,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
ValidateNested,
|
||||
} from "class-validator"
|
||||
import { defaultAdminDiscountsFields, defaultAdminDiscountsRelations } from "."
|
||||
import { AllocationType } from "../../../../models"
|
||||
import { Discount } from "../../../../models/discount"
|
||||
import { DiscountConditionOperator } from "../../../../models/discount-condition"
|
||||
import DiscountService from "../../../../services/discount"
|
||||
@@ -37,9 +39,6 @@ import { IsISO8601Duration } from "../../../../utils/validators/iso8601-duration
|
||||
* code:
|
||||
* type: string
|
||||
* description: A unique code that will be used to redeem the Discount
|
||||
* is_dynamic:
|
||||
* type: string
|
||||
* description: Whether the Discount should have multiple instances of itself, each with a different code. This can be useful for automatically generated codes that all have to follow a common set of rules.
|
||||
* rule:
|
||||
* description: The Discount Rule that defines how Discounts are calculated
|
||||
* oneOf:
|
||||
@@ -109,10 +108,6 @@ export class AdminPostDiscountsDiscountReq {
|
||||
@Type(() => AdminUpdateDiscountRule)
|
||||
rule?: AdminUpdateDiscountRule
|
||||
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
is_dynamic?: boolean
|
||||
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
is_disabled?: boolean
|
||||
@@ -156,16 +151,15 @@ export class AdminUpdateDiscountRule {
|
||||
@IsOptional()
|
||||
description?: string
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
type: string
|
||||
|
||||
@IsNumber()
|
||||
value: number
|
||||
@IsOptional()
|
||||
value?: number
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
allocation: string
|
||||
@IsOptional()
|
||||
@IsEnum(AllocationType, {
|
||||
message: `Invalid allocation type, must be one of "total" or "item"`,
|
||||
})
|
||||
allocation?: AllocationType
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
|
||||
Reference in New Issue
Block a user