-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6652 from reactioncommerce/feat/promotions-add-du…
…plicate-promotion-endpoint feat/promotions add duplicate promotion endpoint
- Loading branch information
Showing
11 changed files
with
232 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
packages/api-plugin-promotions/src/mutations/duplicatePromotion.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import _ from "lodash"; | ||
import Random from "@reactioncommerce/random"; | ||
import validateTriggerParams from "./validateTriggerParams.js"; | ||
|
||
/** | ||
* @summary duplicate an existing promotion to a new one | ||
* @param {Object} context - the per-request application context | ||
* @param {String} promotionId - The ID of the promotion you want to duplicate | ||
* @return {Promise<{success: boolean, promotion: *}|{success: boolean, errors: [{message: string}]}>} - return the newly created promotion or an array of errors | ||
*/ | ||
export default async function duplicatePromotion(context, promotionId) { | ||
const { collections: { Promotions }, simpleSchemas: { Promotion: PromotionSchema } } = context; | ||
const now = new Date(); | ||
const existingPromotion = await Promotions.findOne({ _id: promotionId }); | ||
const newPromotion = _.cloneDeep(existingPromotion); | ||
newPromotion._id = Random.id(); | ||
newPromotion.createdAt = now; | ||
newPromotion.updatedAt = now; | ||
newPromotion.name = `Copy of ${existingPromotion.name}`; | ||
newPromotion.referenceId = await context.mutations.incrementSequence(context, newPromotion.shopId, "Promotions"); | ||
PromotionSchema.validate(newPromotion); | ||
validateTriggerParams(context, newPromotion); | ||
const results = await Promotions.insertOne(newPromotion); | ||
const { insertedCount } = results; | ||
if (!insertedCount) { | ||
return { | ||
success: false, | ||
errors: [{ | ||
message: "The record could not be inserted but no error was thrown" | ||
}] | ||
}; | ||
} | ||
return { | ||
success: true, | ||
promotion: newPromotion | ||
}; | ||
} |
69 changes: 69 additions & 0 deletions
69
packages/api-plugin-promotions/src/mutations/duplicatePromotion.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import mockCollection from "@reactioncommerce/api-utils/tests/mockCollection.js"; | ||
import mockContext from "@reactioncommerce/api-utils/tests/mockContext.js"; | ||
import SimpleSchema from "simpl-schema"; | ||
import { Promotion as PromotionSchema, Promotion, Trigger } from "../simpleSchemas.js"; | ||
import duplicatePromotion from "./duplicatePromotion.js"; | ||
import { ExistingOrderPromotion } from "./fixtures/orderPromotion.js"; | ||
|
||
const triggerKeys = ["offers"]; | ||
const promotionTypes = ["coupon"]; | ||
|
||
Trigger.extend({ | ||
triggerKey: { | ||
allowedValues: [...Trigger.getAllowedValuesForKey("triggerKey"), ...triggerKeys] | ||
} | ||
}); | ||
|
||
PromotionSchema.extend({ | ||
promotionType: { | ||
allowedValues: [...PromotionSchema.getAllowedValuesForKey("promotionType"), ...promotionTypes] | ||
} | ||
}); | ||
|
||
mockContext.collections.Promotions = mockCollection("Promotions"); | ||
const insertResults = { | ||
insertedCount: 1, | ||
insertedId: "myId" | ||
}; | ||
mockContext.collections.Promotions.insertOne = () => insertResults; | ||
mockContext.collections.Promotions.findOne = () => ExistingOrderPromotion; | ||
mockContext.mutations.incrementSequence = () => 1000000; | ||
|
||
mockContext.simpleSchemas = { | ||
Promotion | ||
}; | ||
|
||
export const OfferTriggerParameters = new SimpleSchema({ | ||
name: String, | ||
conditions: { | ||
type: Object, | ||
blackbox: true | ||
} | ||
}); | ||
|
||
const offerTrigger = { | ||
key: "offers", | ||
handler: () => {}, | ||
paramSchema: OfferTriggerParameters, | ||
type: "implicit" | ||
}; | ||
|
||
|
||
mockContext.promotions = { | ||
triggers: [ | ||
offerTrigger | ||
] | ||
}; | ||
|
||
|
||
test("duplicates existing promotions and creates new one", async () => { | ||
try { | ||
const { success, promotion } = await duplicatePromotion(mockContext, ExistingOrderPromotion._id); | ||
expect(success).toBeTruthy(); | ||
expect(promotion.name).toEqual("Copy of Order Promotion"); | ||
expect(promotion.referenceId).toEqual(1000000); | ||
expect(promotion._id).not.toEqual("orderPromotion"); | ||
} catch (error) { | ||
expect(error).toBeUndefined(); | ||
} | ||
}); |
77 changes: 77 additions & 0 deletions
77
packages/api-plugin-promotions/src/mutations/fixtures/orderPromotion.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
const now = new Date(); | ||
|
||
export const CreateOrderPromotion = { | ||
shopId: "testShop", | ||
promotionType: "coupon", | ||
name: "Order Promotion", | ||
label: "5 percent off your entire order when you spend more then $200", | ||
description: "5 percent off your entire order when you spend more then $200", | ||
enabled: true, | ||
triggers: [ | ||
{ | ||
triggerKey: "offers", | ||
triggerParameters: { | ||
name: "5 percent off your entire order when you spend more then $200", | ||
conditions: { | ||
any: [ | ||
{ | ||
fact: "cart", | ||
path: "$.merchandiseTotal", | ||
operator: "greaterThanInclusive", | ||
value: 200 | ||
} | ||
] | ||
} | ||
} | ||
} | ||
], | ||
actions: [ | ||
{ | ||
actionKey: "noop", | ||
actionParameters: {} | ||
} | ||
], | ||
startDate: now, | ||
endDate: new Date(now.getTime() + 1000 * 60 * 60 * 24 * 7), | ||
stackAbility: "none" | ||
}; | ||
|
||
export const ExistingOrderPromotion = { | ||
_id: "orderPromotion", | ||
referenceId: 1, | ||
shopId: "testShop", | ||
promotionType: "item-discount", | ||
triggerType: "implicit", | ||
name: "Order Promotion", | ||
label: "5 percent off your entire order when you spend more then $200", | ||
description: "5 percent off your entire order when you spend more then $200", | ||
enabled: true, | ||
triggers: [ | ||
{ | ||
triggerKey: "offers", | ||
triggerParameters: { | ||
name: "5 percent off your entire order when you spend more then $200", | ||
conditions: { | ||
any: [ | ||
{ | ||
fact: "cart", | ||
path: "$.merchandiseTotal", | ||
operator: "greaterThanInclusive", | ||
value: 200 | ||
} | ||
] | ||
} | ||
} | ||
} | ||
], | ||
actions: [ | ||
{ | ||
actionKey: "noop", | ||
actionParameters: {} | ||
} | ||
], | ||
startDate: now, | ||
endDate: new Date(now.getTime() + 1000 * 60 * 60 * 24 * 7), | ||
stackAbility: "none" | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
import applyExplicitPromotionToCart from "./applyExplicitPromotionToCart.js"; | ||
import createPromotion from "./createPromotion.js"; | ||
import updatePromotion from "./updatePromotion.js"; | ||
import duplicatePromotion from "./duplicatePromotion.js"; | ||
|
||
export default { | ||
applyExplicitPromotionToCart, | ||
createPromotion, | ||
updatePromotion | ||
updatePromotion, | ||
duplicatePromotion | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
packages/api-plugin-promotions/src/resolvers/Mutation/duplicatePromotion.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* @summary duplicate an existing promotion | ||
* @param {undefined} _ - unused | ||
* @param {Object} args - The arguments passed to the mutation | ||
* @param {Object} context - The application context | ||
* @return {Promise<boolean>} - true if success | ||
*/ | ||
export default async function duplicatePromotion(_, { input }, context) { | ||
const { promotionId, shopId } = input; | ||
await context.validatePermissions("reaction:legacy:promotions", "create", { shopId }); | ||
const duplicatePromotionResults = await context.mutations.duplicatePromotion(context, promotionId); | ||
return duplicatePromotionResults; | ||
} |
4 changes: 3 additions & 1 deletion
4
packages/api-plugin-promotions/src/resolvers/Mutation/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import updatePromotion from "./updatePromotion.js"; | ||
import createPromotion from "./createPromotion.js"; | ||
import duplicatePromotion from "./duplicatePromotion.js"; | ||
|
||
export default { | ||
updatePromotion, | ||
createPromotion | ||
createPromotion, | ||
duplicatePromotion | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters