Skip to content

Commit 4121999

Browse files
committed
refactor(wip): register module
1 parent 2c8dda8 commit 4121999

File tree

2 files changed

+54
-134
lines changed

2 files changed

+54
-134
lines changed

src/browser/register.ts

+8-21
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { getOptions, Options, normalize, logError } from "../common/util"
1+
import { getOptions, normalize, logError } from "../common/util"
22

33
import "./pages/error.css"
44
import "./pages/global.css"
55
import "./pages/login.css"
66

7-
export async function registerServiceWorker(navigator: Navigator, path: string, options: Options): Promise<void> {
7+
async function registerServiceWorker(): Promise<void> {
8+
const options = getOptions()
9+
const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`)
810
try {
911
await navigator.serviceWorker.register(path, {
1012
scope: (options.base ?? "") + "/",
@@ -15,23 +17,8 @@ export async function registerServiceWorker(navigator: Navigator, path: string,
1517
}
1618
}
1719

18-
interface HandleServiceWorkerRegistration {
19-
getOptions: () => Options
20-
normalize: (url: string, keepTrailing?: boolean) => string
21-
registerServiceWorker: (navigator: Navigator, path: string, options: Options) => Promise<void>
20+
if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
21+
registerServiceWorker()
22+
} else {
23+
console.error(`[Service Worker] navigator is undefined`)
2224
}
23-
24-
export function handleServiceWorkerRegistration({
25-
getOptions,
26-
normalize,
27-
registerServiceWorker,
28-
}: HandleServiceWorkerRegistration): void {
29-
if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
30-
const options = getOptions()
31-
const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`)
32-
registerServiceWorker(navigator, path, options)
33-
}
34-
}
35-
36-
// Written this way so that it's easier to test
37-
handleServiceWorkerRegistration({ getOptions, normalize, registerServiceWorker })

test/register.test.ts

+46-113
Original file line numberDiff line numberDiff line change
@@ -2,130 +2,63 @@ import { JSDOM } from "jsdom"
22
// Note: we need to import logger from the root
33
// because this is the logger used in logError in ../src/common/util
44
import { logger } from "../node_modules/@coder/logger"
5-
import { registerServiceWorker, handleServiceWorkerRegistration } from "../src/browser/register"
6-
import { Options } from "../src/common/util"
7-
const { window } = new JSDOM()
8-
global.window = (window as unknown) as Window & typeof globalThis
9-
global.document = window.document
10-
global.navigator = window.navigator
115

126
describe("register", () => {
13-
describe("registerServiceWorker", () => {
14-
let spy: jest.SpyInstance
15-
let loggerSpy: jest.SpyInstance
16-
17-
beforeAll(() => {
18-
Object.defineProperty(global.navigator, "serviceWorker", {
19-
value: {
20-
register: () => {
21-
return "hello"
22-
},
7+
const { window } = new JSDOM()
8+
global.window = (window as unknown) as Window & typeof globalThis
9+
global.document = window.document
10+
global.navigator = window.navigator
11+
global.location = window.location
12+
13+
let spy: jest.SpyInstance
14+
let loggerSpy: jest.SpyInstance
15+
16+
beforeAll(() => {
17+
Object.defineProperty(global.navigator, "serviceWorker", {
18+
value: {
19+
register: () => {
20+
return "hello"
2321
},
24-
})
25-
})
26-
27-
beforeEach(() => {
28-
loggerSpy = jest.spyOn(logger, "error")
29-
spy = jest.spyOn(global.navigator.serviceWorker, "register")
30-
})
31-
32-
afterEach(() => {
33-
jest.resetAllMocks()
34-
})
35-
36-
afterAll(() => {
37-
jest.restoreAllMocks()
38-
})
39-
40-
it("should register a ServiceWorker", () => {
41-
const path = "/hello"
42-
const mockOptions = {
43-
base: "",
44-
csStaticBase: "",
45-
logLevel: 0,
46-
}
47-
registerServiceWorker(navigator, path, mockOptions)
48-
// expect spy to have been called
49-
expect(spy).toHaveBeenCalled()
50-
expect(spy).toHaveBeenCalledTimes(1)
51-
})
52-
53-
it("should log an error if something doesn't work", () => {
54-
const message = "Can't find browser"
55-
const error = new Error(message)
56-
const path = "/hello"
57-
const mockOptions = {
58-
base: "",
59-
csStaticBase: "",
60-
logLevel: 0,
61-
}
62-
global.navigator.serviceWorker.register = () => {
63-
throw error
64-
}
65-
66-
registerServiceWorker(navigator, path, mockOptions)
67-
expect(loggerSpy).toHaveBeenCalled()
68-
expect(loggerSpy).toHaveBeenCalledTimes(1)
69-
// Because we use logError, it will log the prefix along with the error message
70-
expect(loggerSpy).toHaveBeenCalledWith(`[Service Worker] registration: ${error.message} ${error.stack}`)
22+
},
7123
})
24+
})
7225

73-
it("should work when base is undefined", () => {
74-
const path = "/hello"
75-
76-
// We want to test some code that checks if options.base is undefined
77-
// so we leave it off mockOptions
78-
// but assert it as Options so TS is happy
79-
const mockOptions = {
80-
csStaticBase: "",
81-
logLevel: 0,
82-
} as Options
83-
registerServiceWorker(navigator, path, mockOptions)
84-
// expect spy to have been called
85-
expect(spy).toHaveBeenCalled()
86-
expect(spy).toHaveBeenCalledTimes(1)
87-
})
26+
beforeEach(() => {
27+
spy = jest.spyOn(global.navigator.serviceWorker, "register")
28+
loggerSpy = jest.spyOn(logger, "error")
8829
})
8930

90-
describe("handleServiceWorkerRegistration", () => {
91-
let getOptionsMock: jest.MockedFunction<() => {
92-
base: string
93-
csStaticBase: string
94-
logLevel: number
95-
}>
96-
let normalizeMock: jest.MockedFunction<(v: string) => string>
97-
let registerServiceWorkerMock: jest.MockedFunction<(
98-
navigator: Navigator,
99-
path: string,
100-
mockOptions: Options,
101-
) => Promise<void>>
31+
afterEach(() => {
32+
jest.resetModules()
33+
jest.resetAllMocks()
34+
})
10235

103-
beforeEach(() => {
104-
getOptionsMock = jest.fn(() => ({
105-
base: "",
106-
csStaticBase: "",
107-
logLevel: 0,
108-
}))
36+
afterAll(() => {
37+
jest.restoreAllMocks()
38+
})
10939

110-
normalizeMock = jest.fn((url: string) => "qux///")
40+
it("should register a ServiceWorker", () => {
41+
// Load service worker like you would in the browser
42+
require("../src/browser/register")
43+
// Load service worker like you would in the browser
44+
// expect spy to have been called
45+
expect(spy).toHaveBeenCalled()
46+
expect(spy).toHaveBeenCalledTimes(1)
47+
})
11148

112-
registerServiceWorkerMock = jest
113-
.fn()
114-
.mockImplementation((navigator: Navigator, path: string, mockOptions: Options) => Promise.resolve())
115-
})
116-
it("should work when called", () => {
117-
handleServiceWorkerRegistration({
118-
getOptions: getOptionsMock,
119-
normalize: normalizeMock,
120-
registerServiceWorker: registerServiceWorkerMock,
121-
})
49+
it("should log an error if something doesn't work", () => {
50+
const message = "Can't find browser"
51+
const error = new Error(message)
52+
global.navigator.serviceWorker.register = () => {
53+
throw error
54+
}
12255

123-
const mocks = [getOptionsMock, normalizeMock, registerServiceWorkerMock]
56+
// Load service worker like you would in the browser
57+
require("../src/browser/register")
12458

125-
mocks.forEach((mock) => {
126-
expect(mock).toHaveBeenCalled()
127-
expect(mock).toHaveBeenCalledTimes(1)
128-
})
129-
})
59+
expect(loggerSpy).toHaveBeenCalled()
60+
expect(loggerSpy).toHaveBeenCalledTimes(1)
61+
// Because we use logError, it will log the prefix along with the error message
62+
expect(loggerSpy).toHaveBeenCalledWith(`[Service Worker] registration: ${error.message} ${error.stack}`)
13063
})
13164
})

0 commit comments

Comments
 (0)