diff --git a/.changeset/slimy-ants-shave.md b/.changeset/slimy-ants-shave.md new file mode 100644 index 00000000000..4bdaaf62542 --- /dev/null +++ b/.changeset/slimy-ants-shave.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +Improve condtions filtering in discount rules to prevent sending empty conditions diff --git a/src/discounts/models/CatalogRule/preparePredicate.test.ts b/src/discounts/models/CatalogRule/preparePredicate.test.ts new file mode 100644 index 00000000000..aef0f1e80f8 --- /dev/null +++ b/src/discounts/models/CatalogRule/preparePredicate.test.ts @@ -0,0 +1,60 @@ +import { Condition } from "../Condition"; +import { prepareCataloguePredicate } from "./preparePredicate"; + +describe("prepareCataloguePredicate", () => { + it("should return empty object when conditions are empty", () => { + const conditions: Condition[] = []; + + const result = prepareCataloguePredicate(conditions); + + expect(result).toEqual({}); + }); + + it("should return object with filtered conditions", () => { + const conditions = [ + { + id: "", + type: "is", + value: null, + }, + { + id: "product", + type: "is", + value: [], + }, + { + id: "category", + type: "is", + value: [ + { label: "1", value: "1" }, + { label: "2", value: "2" }, + ], + }, + { + id: "collection", + type: "is", + value: [ + { label: "3", value: "3" }, + { label: "4", value: "4" }, + ], + }, + ] as Condition[]; + + const result = prepareCataloguePredicate(conditions); + + expect(result).toEqual({ + OR: [ + { + categoryPredicate: { + ids: ["1", "2"], + }, + }, + { + collectionPredicate: { + ids: ["3", "4"], + }, + }, + ], + }); + }); +}); diff --git a/src/discounts/models/CatalogRule/preparePredicate.ts b/src/discounts/models/CatalogRule/preparePredicate.ts index 0d2017dc77a..8000c34b9f6 100644 --- a/src/discounts/models/CatalogRule/preparePredicate.ts +++ b/src/discounts/models/CatalogRule/preparePredicate.ts @@ -7,7 +7,13 @@ export function prepareCataloguePredicate( ): CataloguePredicateInput { const ruleConditions = conditions .map(condition => { - if (!condition.id || !condition?.value?.length) { + if (!condition.id) { + return undefined; + } + + if (Array.isArray(condition.value) && condition.value.length === 0) { + return undefined; + } else if (!condition.value) { return undefined; } diff --git a/src/discounts/models/OrderRule/prepareConditions.test.ts b/src/discounts/models/OrderRule/prepareConditions.test.ts index 2fe66ccd8b6..2eb8293b048 100644 --- a/src/discounts/models/OrderRule/prepareConditions.test.ts +++ b/src/discounts/models/OrderRule/prepareConditions.test.ts @@ -3,7 +3,7 @@ import { OrderPredicateAPI } from "@dashboard/discounts/types"; import { prepareOrderConditions } from "./prepareConditions"; describe("prepareOrderConditions", () => { - it("should return empty array when cataloguePredicate is empty", () => { + it("should return empty array when orderPredicate is empty", () => { const orderPredicate = {} as OrderPredicateAPI; const result = prepareOrderConditions(orderPredicate); @@ -11,7 +11,7 @@ describe("prepareOrderConditions", () => { expect(result).toEqual([]); }); - it("should return array of conditions when cataloguePredicate is not empty", () => { + it("should return array of conditions when orderPredicate is not empty", () => { const orderPredicate = { discountedObjectPredicate: { AND: [ diff --git a/src/discounts/models/OrderRule/preparePredicate.test.ts b/src/discounts/models/OrderRule/preparePredicate.test.ts new file mode 100644 index 00000000000..84bc2915388 --- /dev/null +++ b/src/discounts/models/OrderRule/preparePredicate.test.ts @@ -0,0 +1,64 @@ +import { Condition } from "../Condition"; +import { prepareOrderPredicate } from "./preparePredicate"; + +describe("prepareOrderPredicate", () => { + it("should return empty object when conditions are empty", () => { + const conditions: Condition[] = []; + + const result = prepareOrderPredicate(conditions); + + expect(result).toEqual({ + discountedObjectPredicate: {}, + }); + }); + + it("should return object with filtered conditions", () => { + const conditions = [ + { + id: "", + type: "is", + value: null, + }, + { + id: "baseTotalPrice", + type: "is", + value: "1", + }, + { + id: "", + type: "is", + value: null, + }, + { + id: "baseSubtotalPrice", + type: "range", + value: { + gte: "50", + lte: "100", + }, + }, + ] as Condition[]; + + const result = prepareOrderPredicate(conditions); + + expect(result).toEqual({ + discountedObjectPredicate: { + OR: [ + { + baseTotalPrice: { + eq: "1", + }, + }, + { + baseSubtotalPrice: { + eq: { + gte: "50", + lte: "100", + }, + }, + }, + ], + }, + }); + }); +}); diff --git a/src/discounts/models/OrderRule/preparePredicate.ts b/src/discounts/models/OrderRule/preparePredicate.ts index 5d33a145a9f..4a2358c04ce 100644 --- a/src/discounts/models/OrderRule/preparePredicate.ts +++ b/src/discounts/models/OrderRule/preparePredicate.ts @@ -11,7 +11,17 @@ export function prepareOrderPredicate( ): OrderPredicateInput { const ruleConditions = conditions .map(condition => { - if (!condition.type) { + if (!condition.id) { + return undefined; + } + + if (!condition.id) { + return undefined; + } + + if (Array.isArray(condition.value) && condition.value.length === 0) { + return undefined; + } else if (!condition.value) { return undefined; }