diff --git a/test/notifications/schedulers/ETANotificationSchedulerTests.ts b/test/notifications/schedulers/ETANotificationSchedulerTests.test.ts similarity index 69% rename from test/notifications/schedulers/ETANotificationSchedulerTests.ts rename to test/notifications/schedulers/ETANotificationSchedulerTests.test.ts index 3fb738b..60262c8 100644 --- a/test/notifications/schedulers/ETANotificationSchedulerTests.ts +++ b/test/notifications/schedulers/ETANotificationSchedulerTests.test.ts @@ -4,11 +4,16 @@ import { UnoptimizedInMemoryRepository } from "../../../src/repositories/Unoptim import http2 from "http2"; import { IEta, IShuttle, IStop } from "../../../src/entities/entities"; import { addMockShuttleToRepository, addMockStopToRepository } from "../../testHelpers/repositorySetupHelpers"; -import EventEmitter = require("node:events"); +import { AppleNotificationSender } from "../../../src/notifications/senders/AppleNotificationSender"; jest.mock("http2"); +jest.mock("../../../src/notifications/senders/AppleNotificationSender"); -const sampleKeyBase64 = "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR1RBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJIa3dkd0lCQVFRZ3NybVNBWklhZ09mQ1A4c0IKV2kyQ0JYRzFPbzd2MWJpc3BJWkN3SXI0UkRlZ0NnWUlLb1pJemowREFRZWhSQU5DQUFUWkh4VjJ3UUpMTUJxKwp5YSt5ZkdpM2cyWlV2NmhyZmUrajA4eXRla1BIalhTMHF6Sm9WRUx6S0hhNkVMOVlBb1pEWEJ0QjZoK2ZHaFhlClNPY09OYmFmCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"; +const MockAppleNotificationSender = AppleNotificationSender as jest.MockedClass; + +function mockNotificationSenderMethods(shouldSimulateNotificationSend: boolean) { + MockAppleNotificationSender.prototype.sendNotificationImmediately = jest.fn(async () => shouldSimulateNotificationSend); +} /** * Wait for a condition to become true until the timeout @@ -35,25 +40,6 @@ async function waitForMilliseconds(ms: number): Promise { await new Promise((resolve) => setTimeout(resolve, ms)); } -function mockHttp2Connect(status: number) { - class MockClient extends EventEmitter { - request = jest.fn((headers: any) => { - const mockRequest: any = new EventEmitter(); - mockRequest.setEncoding = jest.fn(); - mockRequest.write = jest.fn(); - mockRequest.end = jest.fn(() => { - setTimeout(() => { - mockRequest.emit('response', { ':status': status }); - }, 10); - }); - return mockRequest; - }); - - close() {}; - } - - (http2.connect as jest.Mock) = jest.fn(() => new MockClient()); -} describe("ETANotificationScheduler", () => { let repository: UnoptimizedInMemoryRepository @@ -61,38 +47,13 @@ describe("ETANotificationScheduler", () => { beforeEach(() => { repository = new UnoptimizedInMemoryRepository(); - notificationService = new ETANotificationScheduler(repository); - // Ensure that tests don't hit the server - process.env = { - ...process.env, - APNS_KEY_ID: "1", - APNS_TEAM_ID: "1", - APNS_BUNDLE_ID: "dev.bchen.ProjectInter", - APNS_PRIVATE_KEY: sampleKeyBase64, - }; + mockNotificationSenderMethods(true); + + const appleNotificationSender = new MockAppleNotificationSender(false); + notificationService = new ETANotificationScheduler(repository, appleNotificationSender); }); - beforeEach(() => { - mockHttp2Connect(200); - }); - - describe("reloadAPNsTokenIfTimePassed", () => { - it("reloads the token if token hasn't been generated yet", async () => { - notificationService.reloadAPNsTokenIfTimePassed(); - expect(notificationService.lastRefreshedTimeMs).toBeDefined(); - }); - - it("doesn't reload the token if last refreshed time is recent", async () => { - notificationService.reloadAPNsTokenIfTimePassed(); - const lastRefreshedTimeMs = notificationService.lastRefreshedTimeMs; - - notificationService.reloadAPNsTokenIfTimePassed(); - // Expect no change to have occurred - expect(lastRefreshedTimeMs).toEqual(notificationService.lastRefreshedTimeMs); - }); - }) - function generateNotificationDataAndEta(shuttle: IShuttle, stop: IStop) { const eta: IEta = { shuttleId: shuttle.id, @@ -173,7 +134,12 @@ describe("ETANotificationScheduler", () => { const shuttle = await addMockShuttleToRepository(repository, "1"); const stop = await addMockStopToRepository(repository, "1"); const { eta, notificationData1 } = generateNotificationDataAndEta(shuttle, stop) - mockHttp2Connect(403); + + mockNotificationSenderMethods(false); + notificationService = new ETANotificationScheduler( + repository, + new MockAppleNotificationSender(), + ) // Act await notificationService.scheduleNotification(notificationData1); @@ -188,29 +154,6 @@ describe("ETANotificationScheduler", () => { }); }); - describe('getAPNsFullUrlToUse', () => { - it('should return the production URL when APNS_IS_PRODUCTION is set to "1"', () => { - process.env.APNS_IS_PRODUCTION = "1"; - const deviceId = 'testDeviceId'; - const result = ETANotificationScheduler.getAPNsFullUrlToUse(deviceId); - - const { fullUrl, host, path } = result; - expect(fullUrl).toBe(`https://api.push.apple.com/3/device/${deviceId}`); - expect(host).toBe("https://api.push.apple.com"); - expect(path).toBe(`/3/device/${deviceId}`); - }); - - it('should return the sandbox URL when APNS_IS_PRODUCTION is set to something other than 1', () => { - process.env.APNS_IS_PRODUCTION = "0"; - const deviceId = 'testDeviceId'; - const result = ETANotificationScheduler.getAPNsFullUrlToUse(deviceId); - - const { fullUrl, host, path } = result; - expect(fullUrl).toBe(`https://api.development.push.apple.com/3/device/${deviceId}`); - expect(host).toBe("https://api.development.push.apple.com"); - expect(path).toBe(`/3/device/${deviceId}`); - }); - }); describe("cancelNotification", () => { it("stops notification from sending to given shuttle/stop ID", async () => { @@ -236,7 +179,7 @@ describe("ETANotificationScheduler", () => { // Arrange const shuttle1 = await addMockShuttleToRepository(repository, "1"); const stop = await addMockStopToRepository(repository, "1"); - const { eta, notificationData1 } = generateNotificationDataAndEta(shuttle1, stop); + const { notificationData1 } = generateNotificationDataAndEta(shuttle1, stop); await notificationService.scheduleNotification(notificationData1); const shuttle2 = {