mirror of
https://github.com/brendan-ch/project-inter-server.git
synced 2026-04-17 16:00:32 +00:00
151 lines
5.4 KiB
TypeScript
151 lines
5.4 KiB
TypeScript
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
|
|
import http2 from "http2";
|
|
import { EventEmitter } from "node:events";
|
|
import {
|
|
AppleNotificationSender,
|
|
NotificationAlertArguments
|
|
} from "../../../src/notifications/senders/AppleNotificationSender";
|
|
import { ETANotificationScheduler } from "../../../src/notifications/schedulers/ETANotificationScheduler";
|
|
|
|
jest.mock("http2");
|
|
|
|
const sampleKeyBase64 = "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR1RBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJIa3dkd0lCQVFRZ3NybVNBWklhZ09mQ1A4c0IKV2kyQ0JYRzFPbzd2MWJpc3BJWkN3SXI0UkRlZ0NnWUlLb1pJemowREFRZWhSQU5DQUFUWkh4VjJ3UUpMTUJxKwp5YSt5ZkdpM2cyWlV2NmhyZmUrajA4eXRla1BIalhTMHF6Sm9WRUx6S0hhNkVMOVlBb1pEWEJ0QjZoK2ZHaFhlClNPY09OYmFmCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K";
|
|
|
|
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("AppleNotificationSender", () => {
|
|
let notificationSender: AppleNotificationSender;
|
|
|
|
beforeEach(() => {
|
|
notificationSender = new AppleNotificationSender();
|
|
|
|
// 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,
|
|
};
|
|
});
|
|
|
|
beforeEach(() => {
|
|
mockHttp2Connect(200);
|
|
});
|
|
|
|
describe("reloadAPNsTokenIfTimePassed", () => {
|
|
it("reloads the token if token hasn't been generated yet", async () => {
|
|
notificationSender.reloadAPNsTokenIfTimePassed();
|
|
expect(notificationSender.lastRefreshedTimeMs).toBeDefined();
|
|
});
|
|
|
|
it("doesn't reload the token if last refreshed time is recent", async () => {
|
|
notificationSender.reloadAPNsTokenIfTimePassed();
|
|
const lastRefreshedTimeMs = notificationSender.lastRefreshedTimeMs;
|
|
|
|
notificationSender.reloadAPNsTokenIfTimePassed();
|
|
// Expect no change to have occurred
|
|
expect(lastRefreshedTimeMs).toEqual(notificationSender.lastRefreshedTimeMs);
|
|
});
|
|
});
|
|
|
|
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 = AppleNotificationSender.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 = AppleNotificationSender.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("sendNotificationImmediately", () => {
|
|
it('makes the connection to the http server if the notification should be sent', async () => {
|
|
const notificationArguments: NotificationAlertArguments = {
|
|
title: 'Test notification',
|
|
body: 'This notification will send',
|
|
}
|
|
|
|
const result = await notificationSender.sendNotificationImmediately('1', notificationArguments);
|
|
|
|
expect(http2.connect).toHaveBeenCalled();
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it('throws an error if the bundle ID is not set correctly', async () => {
|
|
process.env = {
|
|
...process.env,
|
|
APNS_BUNDLE_ID: undefined,
|
|
}
|
|
const notificationArguments: NotificationAlertArguments = {
|
|
title: 'Test notification',
|
|
body: 'This notification will not send',
|
|
}
|
|
|
|
await expect(async () => {
|
|
await notificationSender.sendNotificationImmediately('1', notificationArguments);
|
|
}).rejects.toThrow();
|
|
});
|
|
|
|
it('returns false if there is an error sending the notification', async () => {
|
|
mockHttp2Connect(403);
|
|
|
|
const notificationArguments: NotificationAlertArguments = {
|
|
title: 'Test notification',
|
|
body: 'This notification will not send',
|
|
}
|
|
|
|
const result = await notificationSender.sendNotificationImmediately('1', notificationArguments);
|
|
|
|
expect(http2.connect).toHaveBeenCalled();
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it('does not send notification if shouldActuallySendNotifications is false', async () => {
|
|
notificationSender = new AppleNotificationSender(false);
|
|
|
|
const notificationArguments: NotificationAlertArguments = {
|
|
title: 'Test notification',
|
|
body: 'This notification should not send',
|
|
}
|
|
|
|
const result = await notificationSender.sendNotificationImmediately('1', notificationArguments);
|
|
|
|
expect(http2.connect).not.toHaveBeenCalled();
|
|
expect(result).toBe(true);
|
|
});
|
|
});
|
|
});
|