diff --git a/demo/javascript-demo/client/index.html b/demo/javascript-demo/client/index.html index 12a5c05..5bacdd3 100644 --- a/demo/javascript-demo/client/index.html +++ b/demo/javascript-demo/client/index.html @@ -33,6 +33,7 @@

This is a demo app using Fullscript.js with a script tag

feature.mount("treatment-plan-iframe"); feature.on("treatmentPlan.activated", mockCallback); feature.on("patient.selected", mockCallback); + feature.on("order.checkoutStarted", mockCallback); } function mockCallback(data) { diff --git a/demo/react-demo/src/App.tsx b/demo/react-demo/src/App.tsx index 8891e84..86c14fc 100644 --- a/demo/react-demo/src/App.tsx +++ b/demo/react-demo/src/App.tsx @@ -18,6 +18,10 @@ const App = () => { console.log(payload); }; + const handleOrderCheckoutStarted = (payload: EventListenerPayload<"order.checkoutStarted">) => { + console.log(payload); + }; + const mountTreatmentPlan = () => { // ################ // publicKey: fullscript-js-test-public-key-prac @@ -40,6 +44,7 @@ const App = () => { feature.mount("treatment-plan-iframe"); feature.on("treatmentPlan.activated", handleTreatmentPlanActivated); feature.on("patient.selected", handlePatientSelected); + feature.on("order.checkoutStarted", handleOrderCheckoutStarted); }; return ( diff --git a/src/feature/eventType.ts b/src/feature/eventType.ts index 01d7b5e..52a7599 100644 --- a/src/feature/eventType.ts +++ b/src/feature/eventType.ts @@ -2,6 +2,7 @@ const EVENT_TYPES = { "treatmentPlan.activated": "treatmentPlan.activated", "patient.selected": "patient.selected", + "order.checkoutStarted": "order.checkoutStarted", }; type EventType = keyof typeof EVENT_TYPES; @@ -60,10 +61,25 @@ type TreatmentPlanPayload = { }; }; +type OrderPayload = { + order: { + id: string; + practitionerPay: boolean; + treatmentPlan: TreatmentPlanPayload["treatmentPlan"]; + }; +}; + +// Indexing with `E` means adding an entry to EVENT_TYPES without one here is a compile error +type EventPayloads = { + "treatmentPlan.activated": TreatmentPlanPayload; + "patient.selected": PatientPayload; + "order.checkoutStarted": OrderPayload; +}; + type EventListenerPayload = { id: string; type: E; - data: E extends "patient.selected" ? PatientPayload : TreatmentPlanPayload; + data: EventPayloads[E]; createdAt: string; clinicId: string; oauth: { @@ -84,6 +100,7 @@ export { EventListenerPayload, TreatmentPlanPayload, PatientPayload, + OrderPayload, EventType, EVENT_TYPES, }; diff --git a/src/feature/feature.spec.ts b/src/feature/feature.spec.ts index 4c27dca..3916880 100644 --- a/src/feature/feature.spec.ts +++ b/src/feature/feature.spec.ts @@ -2,6 +2,7 @@ import { Dispatcher, createDispatcher } from "../eventSystem"; import { FeatureType } from "../feature"; import { FullscriptOptions } from "../fullscript"; +import { EventType } from "./eventType"; import { FeatureOptions } from "./featureType"; let mockCreateIframe; @@ -153,44 +154,54 @@ describe("feature", () => { }); describe("dispatcher calls", () => { - it("calls registerEventListener on the dispatcher when on is called", () => { - return import("./feature").then(({ getFeature }) => { - const callback = jest.fn(); - const eventType = "treatmentPlan.activated"; - dispatcher.registerEventListener = jest.fn(); - const feature = getFeature( - mockFeatureType, - mockFeatureOptions, - mockFullscriptOptions, - dispatcher - ); - - feature.on(eventType, callback); - expect(dispatcher.registerEventListener).toHaveBeenCalledWith( - `${mockFrameId}.${eventType}`, - callback - ); - }); - }); - - it("calls unregisterEventListener on the dispatcher when off is called", () => { - return import("./feature").then(({ getFeature }) => { - const callback = jest.fn(); - const eventType = "treatmentPlan.activated"; - dispatcher.unregisterEventListener = jest.fn(); - const feature = getFeature( - mockFeatureType, - mockFeatureOptions, - mockFullscriptOptions, - dispatcher - ); - - feature.off(eventType, callback); - expect(dispatcher.unregisterEventListener).toHaveBeenCalledWith( - `${mockFrameId}.${eventType}`, - callback - ); - }); - }); + const eventTypes: EventType[] = [ + "treatmentPlan.activated", + "patient.selected", + "order.checkoutStarted", + ]; + + it.each(eventTypes)( + "calls registerEventListener on the dispatcher when on is called with %s", + eventType => { + return import("./feature").then(({ getFeature }) => { + const callback = jest.fn(); + dispatcher.registerEventListener = jest.fn(); + const feature = getFeature( + mockFeatureType, + mockFeatureOptions, + mockFullscriptOptions, + dispatcher + ); + + feature.on(eventType, callback); + expect(dispatcher.registerEventListener).toHaveBeenCalledWith( + `${mockFrameId}.${eventType}`, + callback + ); + }); + } + ); + + it.each(eventTypes)( + "calls unregisterEventListener on the dispatcher when off is called with %s", + eventType => { + return import("./feature").then(({ getFeature }) => { + const callback = jest.fn(); + dispatcher.unregisterEventListener = jest.fn(); + const feature = getFeature( + mockFeatureType, + mockFeatureOptions, + mockFullscriptOptions, + dispatcher + ); + + feature.off(eventType, callback); + expect(dispatcher.unregisterEventListener).toHaveBeenCalledWith( + `${mockFrameId}.${eventType}`, + callback + ); + }); + } + ); }); }); diff --git a/src/feature/index.ts b/src/feature/index.ts index 0b8833c..665302a 100644 --- a/src/feature/index.ts +++ b/src/feature/index.ts @@ -7,6 +7,7 @@ export type { EventListenerPayload, TreatmentPlanPayload, PatientPayload, + OrderPayload, EventType, } from "./eventType"; diff --git a/src/fullscriptJsValidator/fullscriptJsValidator.spec.ts b/src/fullscriptJsValidator/fullscriptJsValidator.spec.ts index 2f663aa..3d3f346 100644 --- a/src/fullscriptJsValidator/fullscriptJsValidator.spec.ts +++ b/src/fullscriptJsValidator/fullscriptJsValidator.spec.ts @@ -72,11 +72,14 @@ describe("fullscriptValidator", () => { }); describe("validateFeatureEventType", () => { - it("does not throw an error if the featureEventType is valid", () => { - expect(() => { - validateFeatureEventType("treatmentPlan.activated"); - }).not.toThrow(); - }); + it.each(["treatmentPlan.activated", "patient.selected", "order.checkoutStarted"])( + "does not throw an error if the featureEventType is %s", + eventType => { + expect(() => { + validateFeatureEventType(eventType); + }).not.toThrow(); + } + ); it("throws an error if the featureEventType is not treatmentPlan or a string", () => { const invalidEventType = "cancelled"; diff --git a/src/index.ts b/src/index.ts index b9b22fd..5d0d401 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ export type { EventListenerCallback, TreatmentPlanPayload, PatientPayload, + OrderPayload, PatientOptions, FeatureOptions, } from "./feature";