diff --git a/ci/dev/lint.sh b/ci/dev/lint.sh index c4875ff1d710..9ba576e002c8 100755 --- a/ci/dev/lint.sh +++ b/ci/dev/lint.sh @@ -6,7 +6,7 @@ main() { eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js" | grep -v "lib/vscode") stylelint $(git ls-files "*.css" | grep -v "lib/vscode") - tsc --noEmit + tsc --noEmit --skipLibCheck shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090,SC2002 $(git ls-files "*.sh" | grep -v "lib/vscode") if command -v helm && helm kubeval --help > /dev/null; then helm kubeval ci/helm-chart diff --git a/src/browser/serviceWorker.ts b/src/browser/serviceWorker.ts index 1bee59bfb3c6..25765a1a4a68 100644 --- a/src/browser/serviceWorker.ts +++ b/src/browser/serviceWorker.ts @@ -1,11 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ self.addEventListener("install", () => { - console.log("[Service Worker] install") + console.log("[Service Worker] installed") }) self.addEventListener("activate", (event: any) => { event.waitUntil((self as any).clients.claim()) + console.log("[Service Worker] activated") }) self.addEventListener("fetch", () => { diff --git a/test/emitter.test.ts b/test/emitter.test.ts index 8ff5106a45b1..001b13e0d18a 100644 --- a/test/emitter.test.ts +++ b/test/emitter.test.ts @@ -1,9 +1,10 @@ // Note: we need to import logger from the root // because this is the logger used in logError in ../src/common/util import { logger } from "../node_modules/@coder/logger" + import { Emitter } from "../src/common/emitter" -describe("Emitter", () => { +describe("emitter", () => { let spy: jest.SpyInstance beforeEach(() => { @@ -59,6 +60,25 @@ describe("Emitter", () => { emitter.dispose() }) + it("should log an error if something goes wrong", async () => { + const HELLO_WORLD = "HELLO_WORLD" + const mockCallback = jest.fn(() => "Mock function called") + const message = "You don't have access to that folder." + + const emitter = new Emitter<{ event: string; callback: () => void }>() + + const onHelloWorld = ({ event, callback }: { event: string; callback: () => void }): void => { + if (event === HELLO_WORLD) { + callback() + throw new Error(message) + } + } + + emitter.event(onHelloWorld) + + await emitter.emit({ event: HELLO_WORLD, callback: mockCallback }) + }) + it("should log an error if something goes wrong", async () => { const HELLO_WORLD = "HELLO_WORLD" const mockCallback = jest.fn(() => "Mock function called") diff --git a/test/serviceWorker.test.ts b/test/serviceWorker.test.ts new file mode 100644 index 000000000000..7933d1f42daf --- /dev/null +++ b/test/serviceWorker.test.ts @@ -0,0 +1,92 @@ +interface MockEvent { + claim: jest.Mock + waitUntil?: jest.Mock +} + +interface Listener { + event: string + cb: (event?: MockEvent) => void +} + +describe("serviceWorker", () => { + let listeners: Listener[] = [] + let spy: jest.SpyInstance + let claimSpy: jest.Mock + let waitUntilSpy: jest.Mock + + function emit(event: string) { + listeners + .filter((listener) => listener.event === event) + .forEach((listener) => { + switch (event) { + case "activate": + listener.cb({ + claim: jest.fn(), + waitUntil: jest.fn(() => waitUntilSpy()), + }) + break + default: + listener.cb() + } + }) + } + + beforeEach(() => { + claimSpy = jest.fn() + spy = jest.spyOn(console, "log") + waitUntilSpy = jest.fn() + + Object.assign(global, { + self: global, + addEventListener: (event: string, cb: () => void) => { + listeners.push({ event, cb }) + }, + clients: { + claim: claimSpy.mockResolvedValue("claimed"), + }, + }) + }) + + afterEach(() => { + jest.restoreAllMocks() + jest.resetModules() + spy.mockClear() + claimSpy.mockClear() + + // Clear all the listeners + listeners = [] + }) + + it("should add 3 listeners: install, activate and fetch", () => { + require("../src/browser/serviceWorker.ts") + const listenerEventNames = listeners.map((listener) => listener.event) + + expect(listeners).toHaveLength(3) + expect(listenerEventNames).toContain("install") + expect(listenerEventNames).toContain("activate") + expect(listenerEventNames).toContain("fetch") + }) + + it("should call the proper callbacks for 'install'", async () => { + require("../src/browser/serviceWorker.ts") + emit("install") + expect(spy).toHaveBeenCalledWith("[Service Worker] installed") + expect(spy).toHaveBeenCalledTimes(1) + }) + + it("should do nothing when 'fetch' is called", async () => { + require("../src/browser/serviceWorker.ts") + emit("fetch") + expect(spy).not.toHaveBeenCalled() + }) + + it("should call the proper callbacks for 'activate'", async () => { + require("../src/browser/serviceWorker.ts") + emit("activate") + + // Activate serviceWorker + expect(spy).toHaveBeenCalledWith("[Service Worker] activated") + expect(waitUntilSpy).toHaveBeenCalled() + expect(claimSpy).toHaveBeenCalled() + }) +})