feature/IO-2433-esignature - Add in Notifications
This commit is contained in:
231
server/notifications/dispatchJobWatcherNotification.test.js
Normal file
231
server/notifications/dispatchJobWatcherNotification.test.js
Normal file
@@ -0,0 +1,231 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { createRequire } from "node:module";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const mock = require("mock-require");
|
||||
|
||||
const graphClientModuleId = require.resolve("../graphql-client/graphql-client");
|
||||
const queriesModuleId = require.resolve("../graphql-client/queries");
|
||||
const emailQueueModuleId = require.resolve("./queues/emailQueue");
|
||||
const appQueueModuleId = require.resolve("./queues/appQueue");
|
||||
const fcmQueueModuleId = require.resolve("./queues/fcmQueue");
|
||||
const dispatcherModuleId = require.resolve("./dispatchJobWatcherNotification");
|
||||
|
||||
const dispatchEmailsToQueueMock = vi.fn();
|
||||
const dispatchAppsToQueueMock = vi.fn();
|
||||
const dispatchFcmsToQueueMock = vi.fn();
|
||||
|
||||
const loadDispatcher = ({ requestMock }) => {
|
||||
mock.stopAll();
|
||||
dispatchEmailsToQueueMock.mockReset();
|
||||
dispatchAppsToQueueMock.mockReset();
|
||||
dispatchFcmsToQueueMock.mockReset();
|
||||
|
||||
mock(graphClientModuleId, { client: { request: requestMock } });
|
||||
mock(queriesModuleId, {
|
||||
GET_JOB_WATCHERS: "GET_JOB_WATCHERS",
|
||||
GET_NOTIFICATION_ASSOCIATIONS: "GET_NOTIFICATION_ASSOCIATIONS"
|
||||
});
|
||||
mock(emailQueueModuleId, { dispatchEmailsToQueue: dispatchEmailsToQueueMock });
|
||||
mock(appQueueModuleId, { dispatchAppsToQueue: dispatchAppsToQueueMock });
|
||||
mock(fcmQueueModuleId, { dispatchFcmsToQueue: dispatchFcmsToQueueMock });
|
||||
|
||||
delete require.cache[dispatcherModuleId];
|
||||
|
||||
return require(dispatcherModuleId);
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
mock.stopAll();
|
||||
delete require.cache[dispatcherModuleId];
|
||||
});
|
||||
|
||||
describe("dispatchJobWatcherNotification", () => {
|
||||
it("dispatches queue payloads using watcher settings plus fallback defaults for extra recipients", async () => {
|
||||
const requestMock = vi.fn(async (query) => {
|
||||
if (query === "GET_JOB_WATCHERS") {
|
||||
return {
|
||||
job_watchers: [
|
||||
{
|
||||
user_email: "watcher@example.com",
|
||||
user: {
|
||||
employee: {
|
||||
id: "emp-1",
|
||||
first_name: "Pat",
|
||||
last_name: "Lee"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
job: {
|
||||
ro_number: "RO-123",
|
||||
bodyshop: {
|
||||
id: "shop-1",
|
||||
shopname: "ImEX",
|
||||
timezone: "America/Toronto"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (query === "GET_NOTIFICATION_ASSOCIATIONS") {
|
||||
return {
|
||||
associations: [
|
||||
{
|
||||
id: "assoc-1",
|
||||
useremail: "watcher@example.com",
|
||||
notification_settings: {
|
||||
"esign-document-opened": {
|
||||
app: true,
|
||||
email: false,
|
||||
fcm: true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "assoc-2",
|
||||
useremail: "creator@example.com",
|
||||
notification_settings: {}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
const { dispatchJobWatcherNotification } = loadDispatcher({ requestMock });
|
||||
const logger = { log: vi.fn() };
|
||||
|
||||
const result = await dispatchJobWatcherNotification({
|
||||
jobId: "job-1",
|
||||
scenarioKey: "esign-document-opened",
|
||||
key: "notifications.job.esignDocumentOpened",
|
||||
body: '"Repair Authorization" has been opened.',
|
||||
variables: { documentId: "123" },
|
||||
extraRecipientEmails: ["creator@example.com"],
|
||||
defaultChannelPreferences: {
|
||||
app: true,
|
||||
email: false,
|
||||
fcm: false
|
||||
},
|
||||
logger
|
||||
});
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(requestMock).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(dispatchEmailsToQueueMock).not.toHaveBeenCalled();
|
||||
|
||||
expect(dispatchAppsToQueueMock).toHaveBeenCalledTimes(1);
|
||||
expect(dispatchAppsToQueueMock.mock.calls[0][0]).toEqual({
|
||||
appsToDispatch: [
|
||||
expect.objectContaining({
|
||||
jobId: "job-1",
|
||||
jobRoNumber: "RO-123",
|
||||
bodyShopId: "shop-1",
|
||||
scenarioKey: "esign-document-opened",
|
||||
key: "notifications.job.esignDocumentOpened",
|
||||
recipients: [
|
||||
{
|
||||
user: "watcher@example.com",
|
||||
bodyShopId: "shop-1",
|
||||
employeeId: "emp-1",
|
||||
associationId: "assoc-1"
|
||||
},
|
||||
{
|
||||
user: "creator@example.com",
|
||||
bodyShopId: "shop-1",
|
||||
employeeId: null,
|
||||
associationId: "assoc-2"
|
||||
}
|
||||
]
|
||||
})
|
||||
],
|
||||
logger
|
||||
});
|
||||
|
||||
expect(dispatchFcmsToQueueMock).toHaveBeenCalledTimes(1);
|
||||
expect(dispatchFcmsToQueueMock.mock.calls[0][0]).toEqual({
|
||||
fcmsToDispatch: [
|
||||
expect.objectContaining({
|
||||
jobId: "job-1",
|
||||
scenarioKey: "esign-document-opened",
|
||||
recipients: [
|
||||
{
|
||||
user: "watcher@example.com",
|
||||
bodyShopId: "shop-1",
|
||||
employeeId: "emp-1",
|
||||
associationId: "assoc-1"
|
||||
}
|
||||
]
|
||||
})
|
||||
],
|
||||
logger
|
||||
});
|
||||
});
|
||||
|
||||
it("returns false when no recipients have any enabled channels", async () => {
|
||||
const requestMock = vi.fn(async (query) => {
|
||||
if (query === "GET_JOB_WATCHERS") {
|
||||
return {
|
||||
job_watchers: [
|
||||
{
|
||||
user_email: "watcher@example.com",
|
||||
user: {
|
||||
employee: {
|
||||
id: "emp-1",
|
||||
first_name: "Pat",
|
||||
last_name: "Lee"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
job: {
|
||||
ro_number: "RO-123",
|
||||
bodyshop: {
|
||||
id: "shop-1",
|
||||
shopname: "ImEX",
|
||||
timezone: "America/Toronto"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (query === "GET_NOTIFICATION_ASSOCIATIONS") {
|
||||
return {
|
||||
associations: [
|
||||
{
|
||||
id: "assoc-1",
|
||||
useremail: "watcher@example.com",
|
||||
notification_settings: {
|
||||
"esign-document-opened": {
|
||||
app: false,
|
||||
email: false,
|
||||
fcm: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
const { dispatchJobWatcherNotification } = loadDispatcher({ requestMock });
|
||||
|
||||
const result = await dispatchJobWatcherNotification({
|
||||
jobId: "job-1",
|
||||
scenarioKey: "esign-document-opened",
|
||||
key: "notifications.job.esignDocumentOpened",
|
||||
body: '"Repair Authorization" has been opened.',
|
||||
logger: { log: vi.fn() }
|
||||
});
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(dispatchEmailsToQueueMock).not.toHaveBeenCalled();
|
||||
expect(dispatchAppsToQueueMock).not.toHaveBeenCalled();
|
||||
expect(dispatchFcmsToQueueMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user