Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
import { actionTypes as at } from "common/Actions.mjs";
import { mockServices, stubGlobals } from "test/jest/test-utils";
describe("System Tick Feed", () => {
let SYSTEM_TICK_INTERVAL;
let SystemTickFeed;
let restoreChromeUtils;
let restoreGlobals;
let instance;
// SystemTickFeed.sys.mjs pulls setInterval/clearInterval through
// ChromeUtils.defineESModuleGetters at load time. Pointing the lazy holder's
// prototype at globalThis makes those resolve to whatever timers are
// installed when they are called, so jest's fake timers are picked up.
beforeAll(async () => {
restoreChromeUtils = stubGlobals({
ChromeUtils: {
defineESModuleGetters: object => {
Object.setPrototypeOf(object, globalThis);
return globalThis;
},
idleDispatch: f => f(),
},
});
({ SYSTEM_TICK_INTERVAL, SystemTickFeed } =
await import("lib/SystemTickFeed.sys.mjs"));
});
afterAll(() => {
restoreChromeUtils();
});
beforeEach(() => {
jest.useFakeTimers();
restoreGlobals = stubGlobals({
Cc: {
"@mozilla.org/widget/useridleservice;1": {
getService: () => ({ idleTime: 0 }),
},
},
Ci: { nsIUserIdleService: "nsIUserIdleService" },
Services: mockServices(["obs"]),
});
instance = new SystemTickFeed();
instance.store = {
getState() {
return {};
},
dispatch: jest.fn(),
};
});
afterEach(() => {
restoreGlobals();
jest.useRealTimers();
});
it("should create a SystemTickFeed", () => {
expect(instance).toBeInstanceOf(SystemTickFeed);
});
it("should fire SYSTEM_TICK events at configured interval", () => {
instance.onAction({ type: at.INIT });
jest.advanceTimersByTime(SYSTEM_TICK_INTERVAL * 2);
expect(instance.store.dispatch).toHaveBeenCalledTimes(2);
expect(instance.store.dispatch).toHaveBeenNthCalledWith(1, {
type: at.SYSTEM_TICK,
});
expect(instance.store.dispatch).toHaveBeenNthCalledWith(2, {
type: at.SYSTEM_TICK,
});
});
it("should not fire SYSTEM_TICK events after UNINIT", () => {
instance.onAction({ type: at.UNINIT });
jest.advanceTimersByTime(SYSTEM_TICK_INTERVAL * 2);
expect(instance.store.dispatch).not.toHaveBeenCalled();
});
it("should not fire SYSTEM_TICK events while the user is away", () => {
instance.onAction({ type: at.INIT });
instance._idleService = { idleTime: SYSTEM_TICK_INTERVAL + 1 };
jest.advanceTimersByTime(SYSTEM_TICK_INTERVAL * 3);
expect(instance.store.dispatch).not.toHaveBeenCalled();
instance.onAction({ type: at.UNINIT });
});
it("should fire SYSTEM_TICK immediately when the user is active again", () => {
instance.onAction({ type: at.INIT });
instance._idleService = { idleTime: SYSTEM_TICK_INTERVAL + 1 };
jest.advanceTimersByTime(SYSTEM_TICK_INTERVAL * 3);
instance.observe();
expect(instance.store.dispatch).toHaveBeenCalledTimes(1);
expect(instance.store.dispatch).toHaveBeenCalledWith({
type: at.SYSTEM_TICK,
});
instance.onAction({ type: at.UNINIT });
});
});