[PM-6426] Adding jest tests to the ForegroundTaskSchedulerService and the BackgroundTaskSchedulerService
This commit is contained in:
parent
fae0f65ab2
commit
2f769eb4d7
|
@ -0,0 +1,127 @@
|
||||||
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
import { ScheduledTaskNames } from "@bitwarden/common/platform/enums/scheduled-task-name.enum";
|
||||||
|
import { GlobalState, StateProvider } from "@bitwarden/common/platform/state";
|
||||||
|
|
||||||
|
import { createPortSpyMock } from "../../../autofill/spec/autofill-mocks";
|
||||||
|
import {
|
||||||
|
flushPromises,
|
||||||
|
sendPortMessage,
|
||||||
|
triggerPortOnDisconnectEvent,
|
||||||
|
triggerRuntimeOnConnectEvent,
|
||||||
|
} from "../../../autofill/spec/testing-utils";
|
||||||
|
import {
|
||||||
|
BrowserTaskSchedulerPortActions,
|
||||||
|
BrowserTaskSchedulerPortName,
|
||||||
|
} from "../abstractions/browser-task-scheduler.service";
|
||||||
|
|
||||||
|
import { BackgroundTaskSchedulerService } from "./background-task-scheduler.service";
|
||||||
|
|
||||||
|
describe("BackgroundTaskSchedulerService", () => {
|
||||||
|
let logService: MockProxy<LogService>;
|
||||||
|
let stateProvider: MockProxy<StateProvider>;
|
||||||
|
let globalStateMock: MockProxy<GlobalState<any>>;
|
||||||
|
let portMock: chrome.runtime.Port;
|
||||||
|
let backgroundTaskSchedulerService: BackgroundTaskSchedulerService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
logService = mock<LogService>();
|
||||||
|
globalStateMock = mock<GlobalState<any>>({
|
||||||
|
state$: mock<Observable<any>>(),
|
||||||
|
update: jest.fn((callback) => callback([], {} as any)),
|
||||||
|
});
|
||||||
|
stateProvider = mock<StateProvider>({
|
||||||
|
getGlobal: jest.fn(() => globalStateMock),
|
||||||
|
});
|
||||||
|
portMock = createPortSpyMock(BrowserTaskSchedulerPortName);
|
||||||
|
backgroundTaskSchedulerService = new BackgroundTaskSchedulerService(logService, stateProvider);
|
||||||
|
jest.spyOn(globalThis, "setTimeout");
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("ports on connect", () => {
|
||||||
|
it("ignores port connections that do not have the correct task scheduler port name", () => {
|
||||||
|
const portMockWithDifferentName = createPortSpyMock("different-name");
|
||||||
|
triggerRuntimeOnConnectEvent(portMockWithDifferentName);
|
||||||
|
|
||||||
|
expect(portMockWithDifferentName.onMessage.addListener).not.toHaveBeenCalled();
|
||||||
|
expect(portMockWithDifferentName.onDisconnect.addListener).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets up onMessage and onDisconnect listeners for connected ports", () => {
|
||||||
|
triggerRuntimeOnConnectEvent(portMock);
|
||||||
|
|
||||||
|
expect(portMock.onMessage.addListener).toHaveBeenCalled();
|
||||||
|
expect(portMock.onDisconnect.addListener).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("ports on disconnect", () => {
|
||||||
|
it("removes the port from the set of connected ports", () => {
|
||||||
|
triggerRuntimeOnConnectEvent(portMock);
|
||||||
|
expect(backgroundTaskSchedulerService["ports"].size).toBe(1);
|
||||||
|
|
||||||
|
triggerPortOnDisconnectEvent(portMock);
|
||||||
|
expect(backgroundTaskSchedulerService["ports"].size).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("port message handlers", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
triggerRuntimeOnConnectEvent(portMock);
|
||||||
|
backgroundTaskSchedulerService.registerTaskHandler(
|
||||||
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
jest.fn(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets a setTimeout backup alarm", async () => {
|
||||||
|
sendPortMessage(portMock, {
|
||||||
|
action: BrowserTaskSchedulerPortActions.setTimeout,
|
||||||
|
taskName: ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
delayInMs: 1000,
|
||||||
|
});
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(globalThis.setTimeout).toHaveBeenCalled();
|
||||||
|
expect(chrome.alarms.create).toHaveBeenCalledWith(
|
||||||
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
{ delayInMinutes: 0.5 },
|
||||||
|
expect.any(Function),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets a setInterval backup alarm", async () => {
|
||||||
|
sendPortMessage(portMock, {
|
||||||
|
action: BrowserTaskSchedulerPortActions.setInterval,
|
||||||
|
taskName: ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
intervalInMs: 600000,
|
||||||
|
});
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(chrome.alarms.create).toHaveBeenCalledWith(
|
||||||
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
{ delayInMinutes: 10, periodInMinutes: 10 },
|
||||||
|
expect.any(Function),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("clears a scheduled alarm", async () => {
|
||||||
|
sendPortMessage(portMock, {
|
||||||
|
action: BrowserTaskSchedulerPortActions.clearAlarm,
|
||||||
|
alarmName: ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
});
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(chrome.alarms.clear).toHaveBeenCalledWith(
|
||||||
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
expect.any(Function),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -25,6 +25,10 @@ export class BackgroundTaskSchedulerService extends BrowserTaskSchedulerServiceI
|
||||||
* @param port - The port that was connected.
|
* @param port - The port that was connected.
|
||||||
*/
|
*/
|
||||||
private handlePortOnConnect = (port: chrome.runtime.Port) => {
|
private handlePortOnConnect = (port: chrome.runtime.Port) => {
|
||||||
|
if (port.name !== BrowserTaskSchedulerPortName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.ports.add(port);
|
this.ports.add(port);
|
||||||
port.onMessage.addListener(this.handlePortMessage);
|
port.onMessage.addListener(this.handlePortMessage);
|
||||||
port.onDisconnect.addListener(this.handlePortOnDisconnect);
|
port.onDisconnect.addListener(this.handlePortOnDisconnect);
|
||||||
|
@ -50,10 +54,6 @@ export class BackgroundTaskSchedulerService extends BrowserTaskSchedulerServiceI
|
||||||
message: BrowserTaskSchedulerPortMessage,
|
message: BrowserTaskSchedulerPortMessage,
|
||||||
port: chrome.runtime.Port,
|
port: chrome.runtime.Port,
|
||||||
) => {
|
) => {
|
||||||
if (port.name !== BrowserTaskSchedulerPortName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.action === BrowserTaskSchedulerPortActions.setTimeout) {
|
if (message.action === BrowserTaskSchedulerPortActions.setTimeout) {
|
||||||
super.setTimeout(message.taskName, message.delayInMs);
|
super.setTimeout(message.taskName, message.delayInMs);
|
||||||
return;
|
return;
|
||||||
|
@ -65,8 +65,7 @@ export class BackgroundTaskSchedulerService extends BrowserTaskSchedulerServiceI
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.action === BrowserTaskSchedulerPortActions.clearAlarm) {
|
if (message.action === BrowserTaskSchedulerPortActions.clearAlarm) {
|
||||||
void super.clearScheduledAlarm(message.alarmName);
|
super.clearScheduledAlarm(message.alarmName).catch((error) => this.logService.error(error));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
import { ScheduledTaskNames } from "@bitwarden/common/platform/enums/scheduled-task-name.enum";
|
||||||
|
import { GlobalState, StateProvider } from "@bitwarden/common/platform/state";
|
||||||
|
|
||||||
|
import { createPortSpyMock } from "../../../autofill/spec/autofill-mocks";
|
||||||
|
import { flushPromises } from "../../../autofill/spec/testing-utils";
|
||||||
|
import {
|
||||||
|
BrowserTaskSchedulerPortActions,
|
||||||
|
BrowserTaskSchedulerPortName,
|
||||||
|
} from "../abstractions/browser-task-scheduler.service";
|
||||||
|
|
||||||
|
import { ForegroundTaskSchedulerService } from "./foreground-task-scheduler.service";
|
||||||
|
|
||||||
|
describe("ForegroundTaskSchedulerService", () => {
|
||||||
|
let logService: MockProxy<LogService>;
|
||||||
|
let stateProvider: MockProxy<StateProvider>;
|
||||||
|
let globalStateMock: MockProxy<GlobalState<any>>;
|
||||||
|
let portMock: chrome.runtime.Port;
|
||||||
|
let foregroundTaskSchedulerService: ForegroundTaskSchedulerService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
logService = mock<LogService>();
|
||||||
|
globalStateMock = mock<GlobalState<any>>({
|
||||||
|
state$: mock<Observable<any>>(),
|
||||||
|
update: jest.fn((callback) => callback([], {} as any)),
|
||||||
|
});
|
||||||
|
stateProvider = mock<StateProvider>({
|
||||||
|
getGlobal: jest.fn(() => globalStateMock),
|
||||||
|
});
|
||||||
|
portMock = createPortSpyMock(BrowserTaskSchedulerPortName);
|
||||||
|
foregroundTaskSchedulerService = new ForegroundTaskSchedulerService(logService, stateProvider);
|
||||||
|
foregroundTaskSchedulerService["port"] = portMock;
|
||||||
|
foregroundTaskSchedulerService.registerTaskHandler(
|
||||||
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
jest.fn(),
|
||||||
|
);
|
||||||
|
jest.spyOn(globalThis, "setTimeout");
|
||||||
|
jest.spyOn(globalThis, "setInterval");
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets a timeout for a task and sends a message to the background to set up a backup timeout alarm", async () => {
|
||||||
|
foregroundTaskSchedulerService.setTimeout(ScheduledTaskNames.loginStrategySessionTimeout, 1000);
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(globalThis.setTimeout).toHaveBeenCalledWith(expect.any(Function), 1000);
|
||||||
|
expect(chrome.alarms.create).toHaveBeenCalledWith(
|
||||||
|
"loginStrategySessionTimeout",
|
||||||
|
{ delayInMinutes: 0.5 },
|
||||||
|
expect.any(Function),
|
||||||
|
);
|
||||||
|
expect(portMock.postMessage).toHaveBeenCalledWith({
|
||||||
|
action: BrowserTaskSchedulerPortActions.setTimeout,
|
||||||
|
taskName: ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
delayInMs: 1000,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets an interval for a task and sends a message to the background to set up a backup interval alarm", async () => {
|
||||||
|
foregroundTaskSchedulerService.setInterval(
|
||||||
|
ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
1000,
|
||||||
|
);
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(globalThis.setInterval).toHaveBeenCalledWith(expect.any(Function), 1000);
|
||||||
|
expect(portMock.postMessage).toHaveBeenCalledWith({
|
||||||
|
action: BrowserTaskSchedulerPortActions.setInterval,
|
||||||
|
taskName: ScheduledTaskNames.loginStrategySessionTimeout,
|
||||||
|
intervalInMs: 1000,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue