From 696a1dc2f0e4dc124ae43e0fcd654574c9c07509 Mon Sep 17 00:00:00 2001 From: Jacob Kapitein Date: Tue, 2 Jul 2024 14:59:12 +0200 Subject: [PATCH 1/2] feat: add batch_status_update webhook support --- package-lock.json | 1 - src/enums/WebhookEvent.ts | 1 + src/models/Batch.ts | 8 +++++ src/models/WebhookRequest.ts | 18 ++++++++-- src/models/_interfaces/IBatch.ts | 4 +++ src/models/_interfaces/IWebhookRequest.ts | 10 +++++- test/PrintOne.spec.ts | 42 +++++++++++++++++++++++ 7 files changed, 80 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 75b7016..940c755 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "@print-one/print-one-js", "version": "1.3.0-next.2", - "hasInstallScript": true, "license": "MIT", "dependencies": { "@jest/test-sequencer": "^29.7.0", diff --git a/src/enums/WebhookEvent.ts b/src/enums/WebhookEvent.ts index 09ce717..9ece9f7 100644 --- a/src/enums/WebhookEvent.ts +++ b/src/enums/WebhookEvent.ts @@ -1,6 +1,7 @@ export const WebhookEvent = { order_status_update: "order_status_update", template_preview_rendered: "template_preview_rendered", + batch_status_update: "batch_status_update", } as const; export type WebhookEvent = (typeof WebhookEvent)[keyof typeof WebhookEvent]; diff --git a/src/models/Batch.ts b/src/models/Batch.ts index 8d9c20b..9c11955 100644 --- a/src/models/Batch.ts +++ b/src/models/Batch.ts @@ -72,6 +72,14 @@ export class Batch { return this._data.estimatedPrice; } + public get estimatedTax(): number { + return this._data.estimatedTax; + } + + public get sender(): Address { + return this._data.sender; + } + public get sendDate(): Date | undefined { return this._data.sendDate ? new Date(this._data.sendDate) : undefined; } diff --git a/src/models/WebhookRequest.ts b/src/models/WebhookRequest.ts index 75c25ca..f3ec552 100644 --- a/src/models/WebhookRequest.ts +++ b/src/models/WebhookRequest.ts @@ -1,10 +1,12 @@ import { + IBatchStatusUpdateWebhookRequest, IOrderStatusUpdateWebhookRequest, ITemplatePreviewRenderedWebhookRequest, IWebhookRequest, } from "~/models/_interfaces/IWebhookRequest"; -import { Protected } from "~/PrintOne"; +import { Batch } from "~/models/Batch"; import { Order } from "~/models/Order"; +import { Protected } from "~/PrintOne"; import { PreviewDetails } from "~/models/PreviewDetails"; abstract class AbstractWebhookRequest { @@ -26,7 +28,8 @@ abstract class AbstractWebhookRequest { export type WebhookRequest = | OrderStatusUpdateWebhookRequest - | TemplatePreviewRenderedWebhookRequest; + | TemplatePreviewRenderedWebhookRequest + | BatchStatusUpdateWebhookRequest; export function webhookRequestFactory( _protected: Protected, @@ -39,6 +42,8 @@ export function webhookRequestFactory( return new OrderStatusUpdateWebhookRequest(_protected, data); case "template_preview_rendered": return new TemplatePreviewRenderedWebhookRequest(_protected, data); + case "batch_status_update": + return new BatchStatusUpdateWebhookRequest(_protected, data); default: throw new Error(`Unknown webhook event: ${event}`); } @@ -61,3 +66,12 @@ export class TemplatePreviewRenderedWebhookRequest extends AbstractWebhookReques return new PreviewDetails(this._protected, this._data.data); } } + +export class BatchStatusUpdateWebhookRequest extends AbstractWebhookRequest< + Batch, + IBatchStatusUpdateWebhookRequest +> { + get data(): Batch { + return new Batch(this._protected, this._data.data); + } +} diff --git a/src/models/_interfaces/IBatch.ts b/src/models/_interfaces/IBatch.ts index 8c11411..0cf7726 100644 --- a/src/models/_interfaces/IBatch.ts +++ b/src/models/_interfaces/IBatch.ts @@ -1,3 +1,5 @@ +import { Address } from "~/models/Address"; + export type IBatch = { id: string; companyId: string; @@ -8,6 +10,8 @@ export type IBatch = { isBillable: boolean; templateId: string; estimatedPrice: number; + estimatedTax: number; + sender: Address; sendDate: string | null; status: string; orders: { diff --git a/src/models/_interfaces/IWebhookRequest.ts b/src/models/_interfaces/IWebhookRequest.ts index cbb32f3..37ee890 100644 --- a/src/models/_interfaces/IWebhookRequest.ts +++ b/src/models/_interfaces/IWebhookRequest.ts @@ -1,9 +1,11 @@ +import { IBatch } from "~/models/_interfaces/IBatch"; import { IOrder } from "~/models/_interfaces/IOrder"; import { IPreviewDetails } from "~/models/_interfaces/IPreviewDetails"; export type IWebhookRequest = | IOrderStatusUpdateWebhookRequest - | ITemplatePreviewRenderedWebhookRequest; + | ITemplatePreviewRenderedWebhookRequest + | IBatchStatusUpdateWebhookRequest; export type IOrderStatusUpdateWebhookRequest = { data: IOrder; @@ -16,3 +18,9 @@ export type ITemplatePreviewRenderedWebhookRequest = { event: "template_preview_rendered"; createdAt: string; }; + +export type IBatchStatusUpdateWebhookRequest = { + data: IBatch; + event: "batch_status_update"; + createdAt: string; +}; diff --git a/test/PrintOne.spec.ts b/test/PrintOne.spec.ts index 21cc486..4826216 100644 --- a/test/PrintOne.spec.ts +++ b/test/PrintOne.spec.ts @@ -23,6 +23,7 @@ import { BatchStatus } from "../src/enums/BatchStatus"; import { Webhook } from "~/models/Webhook"; import { WebhookEvent } from "~/enums/WebhookEvent"; import { + BatchStatusUpdateWebhookRequest, OrderStatusUpdateWebhookRequest, TemplatePreviewRenderedWebhookRequest, } from "~/models/WebhookRequest"; @@ -2015,6 +2016,47 @@ describe("validateWebhook", function () { expect(webhook.data).toEqual(expect.any(Order)); }); + it('should return BatchStatusUpdateWebhookRequest if event is "batch_status_update"', async function () { + // arrange + const body = JSON.stringify({ + data: { + id: "batch_1", + companyId: "2bd4c679-3d59-4a6f-a815-a60424746f8d", + name: "Test batch", + finish: "GLOSSY", + templateId: "tmpl_AyDg3PxvP5ydyGq3kSFfj", + status: "batch_created", + createdAt: "2024-06-03T13:14:46.501Z", + updatedAt: "2024-06-03T13:14:46.501Z", + sendDate: null, + isBillable: true, + estimatedPrice: 0, + orders: { + processing: 0, + success: 0, + failed: 0, + cancelled: 0, + }, + }, + event: "batch_status_update", + created_at: "2024-06-03T13:14:46.501Z", + }); + + const headers = { + "x-printone-hmac-sha256": "blmkCA9eG2fajvgpHx/RBirRO8rA4wRGf6gr1/v+V0g=", + }; + + // act + const webhook = await client.validateWebhook(body, headers, "secret"); + + // assert + expect(webhook).toBeDefined(); + expect(webhook).toEqual(expect.any(BatchStatusUpdateWebhookRequest)); + expect(webhook.event).toEqual(WebhookEvent.batch_status_update); + expect(webhook.createdAt).toEqual(expect.any(Date)); + expect(webhook.data).toEqual(expect.any(Batch)); + }); + it("should return TemplatePreviewRenderedWebhookRequest if event is template_preview_rendered", async function () { // arrange const body = JSON.stringify({ From 80c3ffe0e4bde365282949dac8dfaf450877c9a6 Mon Sep 17 00:00:00 2001 From: Jacob Kapitein Date: Tue, 2 Jul 2024 15:17:15 +0200 Subject: [PATCH 2/2] test: add missing field tests --- test/PrintOne.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/PrintOne.spec.ts b/test/PrintOne.spec.ts index 4826216..b860909 100644 --- a/test/PrintOne.spec.ts +++ b/test/PrintOne.spec.ts @@ -1553,6 +1553,8 @@ describe("getBatch", function () { expect(batch.templateId).toEqual(expect.any(String)); expect(batch.isBillable).toEqual(expect.any(Boolean)); expect(batch.estimatedPrice).toEqual(expect.any(Number)); + expect(batch.estimatedTax).toEqual(expect.any(Number)); + expect(batch.sender).toEqual(expect.any(Object)); expect(batch.sendDate).toEqual( expect.toBeOneOf([undefined, expect.any(Date)]), );