Skip to content

Commit

Permalink
Merge pull request #27 from Print-one/feat/PO-2040-coupon-code-used-w…
Browse files Browse the repository at this point in the history
…ebhook-event
  • Loading branch information
PaulRill00 authored Aug 7, 2024
2 parents e97b054 + ba28867 commit 1f9aa51
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/enums/WebhookEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const WebhookEvent = {
order_status_update: "order_status_update",
template_preview_rendered: "template_preview_rendered",
batch_status_update: "batch_status_update",
coupon_code_used: "coupon_code_used",
} as const;

export type WebhookEvent = (typeof WebhookEvent)[keyof typeof WebhookEvent];
16 changes: 15 additions & 1 deletion src/models/WebhookRequest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
IBatchStatusUpdateWebhookRequest,
ICouponCodeUsedWebhookRequest,
IOrderStatusUpdateWebhookRequest,
ITemplatePreviewRenderedWebhookRequest,
IWebhookRequest,
Expand All @@ -8,6 +9,7 @@ import { Batch } from "~/models/Batch";
import { Order } from "~/models/Order";
import { Protected } from "~/PrintOne";
import { PreviewDetails } from "~/models/PreviewDetails";
import { CouponCode } from "~/models/CouponCode";

abstract class AbstractWebhookRequest<T, E extends IWebhookRequest> {
constructor(
Expand All @@ -29,7 +31,8 @@ abstract class AbstractWebhookRequest<T, E extends IWebhookRequest> {
export type WebhookRequest =
| OrderStatusUpdateWebhookRequest
| TemplatePreviewRenderedWebhookRequest
| BatchStatusUpdateWebhookRequest;
| BatchStatusUpdateWebhookRequest
| CouponCodeUsedWebhookRequest;

export function webhookRequestFactory(
_protected: Protected,
Expand All @@ -44,6 +47,8 @@ export function webhookRequestFactory(
return new TemplatePreviewRenderedWebhookRequest(_protected, data);
case "batch_status_update":
return new BatchStatusUpdateWebhookRequest(_protected, data);
case "coupon_code_used":
return new CouponCodeUsedWebhookRequest(_protected, data);
default:
throw new Error(`Unknown webhook event: ${event}`);
}
Expand Down Expand Up @@ -75,3 +80,12 @@ export class BatchStatusUpdateWebhookRequest extends AbstractWebhookRequest<
return new Batch(this._protected, this._data.data);
}
}

export class CouponCodeUsedWebhookRequest extends AbstractWebhookRequest<
CouponCode,
ICouponCodeUsedWebhookRequest
> {
get data(): CouponCode {
return new CouponCode(this._protected, this._data.data);
}
}
37 changes: 22 additions & 15 deletions src/models/_interfaces/IWebhookRequest.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
import { IBatch } from "~/models/_interfaces/IBatch";
import { IOrder } from "~/models/_interfaces/IOrder";
import { IPreviewDetails } from "~/models/_interfaces/IPreviewDetails";
import { ICouponCode } from "~/models/_interfaces/ICouponCode";

export type IWebhookRequest =
| IOrderStatusUpdateWebhookRequest
| ITemplatePreviewRenderedWebhookRequest
| IBatchStatusUpdateWebhookRequest;
| IBatchStatusUpdateWebhookRequest
| ICouponCodeUsedWebhookRequest;

export type IOrderStatusUpdateWebhookRequest = {
data: IOrder;
event: "order_status_update";
type IWebhookBaseRequest<TEvent extends string, TData> = {
data: TData;
event: TEvent;
createdAt: string;
};

export type ITemplatePreviewRenderedWebhookRequest = {
data: IPreviewDetails;
event: "template_preview_rendered";
createdAt: string;
};

export type IBatchStatusUpdateWebhookRequest = {
data: IBatch;
event: "batch_status_update";
createdAt: string;
};
export type IOrderStatusUpdateWebhookRequest = IWebhookBaseRequest<
"order_status_update",
IOrder
>;
export type ITemplatePreviewRenderedWebhookRequest = IWebhookBaseRequest<
"template_preview_rendered",
IPreviewDetails
>;
export type IBatchStatusUpdateWebhookRequest = IWebhookBaseRequest<
"batch_status_update",
IBatch
>;
export type ICouponCodeUsedWebhookRequest = IWebhookBaseRequest<
"coupon_code_used",
ICouponCode
>;
31 changes: 31 additions & 0 deletions test/PrintOne.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
PreviewDetails,
Template,
Coupon,
CouponCode,
} from "../src";
import "jest-extended";
import * as fs from "fs";
Expand All @@ -27,6 +28,7 @@ import {
BatchStatusUpdateWebhookRequest,
OrderStatusUpdateWebhookRequest,
TemplatePreviewRenderedWebhookRequest,
CouponCodeUsedWebhookRequest,
} from "~/models/WebhookRequest";

let template: Template = null as unknown as Template;
Expand Down Expand Up @@ -2242,6 +2244,35 @@ describe("validateWebhook", function () {
expect(webhook.data).toEqual(expect.any(PreviewDetails));
});

it("should return CouponCodeUsedWebhookRequest if event is coupon_code_used", async function () {
// arrange
const body = JSON.stringify({
data: {
id: "cpc_123456789",
couponId: "co_123456789",
code: "some-coupon-code",
used: false,
usedAt: null,
orderId: null,
},
event: "coupon_code_used",
created_at: "2024-06-25T07:28:17.487Z",
});
const headers = {
"x-printone-hmac-sha256": "71jF20za0eDB/2NSLhlr9W1HCHqwhZuZPz7mOdL0mGg=",
};

// act
const webhook = await client.validateWebhook(body, headers, "secret");

// assert
expect(webhook).toBeDefined();
expect(webhook).toEqual(expect.any(CouponCodeUsedWebhookRequest));
expect(webhook.event).toEqual(WebhookEvent.coupon_code_used);
expect(webhook.createdAt).toEqual(expect.any(Date));
expect(webhook.data).toEqual(expect.any(CouponCode));
});

it("should throw an error if event is not valid", async function () {
// arrange
jest.spyOn(client, "isValidWebhook").mockReturnValue(false);
Expand Down

0 comments on commit 1f9aa51

Please sign in to comment.