diff --git a/src/browser/register.ts b/src/browser/register.ts index e430d9bf0..1079d159e 100644 --- a/src/browser/register.ts +++ b/src/browser/register.ts @@ -1,10 +1,12 @@ -import { getOptions, Options, normalize, logError } from "../common/util" +import { getOptions, normalize, logError } from "../common/util" import "./pages/error.css" import "./pages/global.css" import "./pages/login.css" -export async function registerServiceWorker(navigator: Navigator, path: string, options: Options): Promise { +async function registerServiceWorker(): Promise { + const options = getOptions() + const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`) try { await navigator.serviceWorker.register(path, { scope: (options.base ?? "") + "/", @@ -15,23 +17,8 @@ export async function registerServiceWorker(navigator: Navigator, path: string, } } -interface HandleServiceWorkerRegistration { - getOptions: () => Options - normalize: (url: string, keepTrailing?: boolean) => string - registerServiceWorker: (navigator: Navigator, path: string, options: Options) => Promise +if (typeof navigator !== "undefined" && "serviceWorker" in navigator) { + registerServiceWorker() +} else { + console.error(`[Service Worker] navigator is undefined`) } - -export function handleServiceWorkerRegistration({ - getOptions, - normalize, - registerServiceWorker, -}: HandleServiceWorkerRegistration): void { - if (typeof navigator !== "undefined" && "serviceWorker" in navigator) { - const options = getOptions() - const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`) - registerServiceWorker(navigator, path, options) - } -} - -// Written this way so that it's easier to test -handleServiceWorkerRegistration({ getOptions, normalize, registerServiceWorker }) diff --git a/src/common/util.ts b/src/common/util.ts index 87ca6f596..82d7cee30 100644 --- a/src/common/util.ts +++ b/src/common/util.ts @@ -114,9 +114,12 @@ export const getFirstString = (value: string | string[] | object | undefined): s } export function logError(prefix: string, err: any): void { + console.log("hey joe log error was called") if (err instanceof Error) { + console.log("it was an instance of error") logger.error(`${prefix}: ${err.message} ${err.stack}`) } else { + console.log("not an isntance errro") logger.error(`${prefix}: ${err}`) } } diff --git a/test/register.test.ts b/test/register.test.ts index 799349a0b..e534fa5e9 100644 --- a/test/register.test.ts +++ b/test/register.test.ts @@ -2,135 +2,65 @@ import { JSDOM } from "jsdom" // 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 { registerServiceWorker, handleServiceWorkerRegistration } from "../src/browser/register" -import { Options } from "../src/common/util" -const { window } = new JSDOM() -global.window = (window as unknown) as Window & typeof globalThis -global.document = window.document -global.navigator = window.navigator describe("register", () => { - describe("registerServiceWorker", () => { - let spy: jest.MockedFunction<( - scriptURL: string, - options?: RegistrationOptions | undefined, - ) => Promise> - let loggerSpy: jest.SpyInstance + const { window } = new JSDOM() + global.window = (window as unknown) as Window & typeof globalThis + global.document = window.document + global.navigator = window.navigator + global.location = window.location - beforeAll(() => { - Object.defineProperty(global.navigator, "serviceWorker", { - value: { - register: () => { - return "hello" - }, - }, - }) - }) + let spy: jest.SpyInstance + let loggerSpy: jest.SpyInstance + const mockRegisterFn = jest.fn(() => console.log("Mock register fn called")) - beforeEach(() => { - loggerSpy = jest.spyOn(logger, "error") - spy = jest.fn() - global.navigator.serviceWorker.register = spy - }) - - afterEach(() => { - jest.resetAllMocks() - }) - - afterAll(() => { - jest.restoreAllMocks() - }) - - it("should register a ServiceWorker", () => { - global.navigator.serviceWorker.register = spy - const path = "/hello" - const mockOptions = { - base: "", - csStaticBase: "", - logLevel: 0, - } - registerServiceWorker(navigator, path, mockOptions) - // expect spy to have been called - expect(spy).toHaveBeenCalled() - expect(spy).toHaveBeenCalledTimes(1) - }) - - it("should log an error if something doesn't work", () => { - const message = "Can't find browser" - const error = new Error(message) - const path = "/hello" - const mockOptions = { - base: "", - csStaticBase: "", - logLevel: 0, - } - global.navigator.serviceWorker.register = () => { - throw error - } - - registerServiceWorker(navigator, path, mockOptions) - expect(loggerSpy).toHaveBeenCalled() - expect(loggerSpy).toHaveBeenCalledTimes(1) - // Because we use logError, it will log the prefix along with the error message - expect(loggerSpy).toHaveBeenCalledWith(`[Service Worker] registration: ${error.message} ${error.stack}`) - }) - - it("should work when base is undefined", () => { - const path = "/hello" - - // We want to test some code that checks if options.base is undefined - // so we leave it off mockOptions - // but assert it as Options so TS is happy - const mockOptions = { - csStaticBase: "", - logLevel: 0, - } as Options - registerServiceWorker(navigator, path, mockOptions) - // expect spy to have been called - expect(spy).toHaveBeenCalled() - expect(spy).toHaveBeenCalledTimes(1) + beforeAll(() => { + Object.defineProperty(global.navigator, "serviceWorker", { + value: { + register: mockRegisterFn, + }, }) }) - describe("handleServiceWorkerRegistration", () => { - let getOptionsMock: jest.MockedFunction<() => { - base: string - csStaticBase: string - logLevel: number - }> - let normalizeMock: jest.MockedFunction<(v: string) => string> - let registerServiceWorkerMock: jest.MockedFunction<( - navigator: Navigator, - path: string, - mockOptions: Options, - ) => Promise> + beforeEach(() => { + spy = jest.spyOn(global.navigator.serviceWorker, "register") + }) - beforeEach(() => { - getOptionsMock = jest.fn(() => ({ - base: "", - csStaticBase: "", - logLevel: 0, - })) + afterEach(() => { + jest.resetModules() + }) - normalizeMock = jest.fn((url: string) => "qux///") + afterAll(() => { + jest.restoreAllMocks() + }) - registerServiceWorkerMock = jest - .fn() - .mockImplementation((navigator: Navigator, path: string, mockOptions: Options) => Promise.resolve()) + it("should register a ServiceWorker", () => { + spy = jest.spyOn(global.navigator.serviceWorker, "register") + // Load service worker like you would in the browser + require("../src/browser/register") + // Load service worker like you would in the browser + // expect spy to have been called + expect(spy).toHaveBeenCalled() + expect(spy).toHaveBeenCalledTimes(1) + spy.mockClear() + }) + + it("should log an error if something doesn't work", () => { + loggerSpy = jest.spyOn(logger, "error") + const message = "Can't find browser" + const error = new Error(message) + + mockRegisterFn.mockImplementation(() => { + throw error }) - it("should work when called", () => { - handleServiceWorkerRegistration({ - getOptions: getOptionsMock, - normalize: normalizeMock, - registerServiceWorker: registerServiceWorkerMock, - }) - const mocks = [getOptionsMock, normalizeMock, registerServiceWorkerMock] + // Load service worker like you would in the browser + require("../src/browser/register") - mocks.forEach((mock) => { - expect(mock).toHaveBeenCalled() - expect(mock).toHaveBeenCalledTimes(1) - }) - }) + expect(spy).toHaveBeenCalled() + expect(loggerSpy).toHaveBeenCalled() + // expect(loggerSpy).toHaveBeenCalledTimes(1) + // Because we use logError, it will log the prefix along with the error message + // expect(loggerSpy).toHaveBeenCalledWith(`[Service Worker] registration: ${error.message} ${error.stack}`) }) })