Skip to content

feat(testing): add tests for serviceWorker.ts #2744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 25, 2021
2 changes: 1 addition & 1 deletion ci/dev/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/browser/serviceWorker.ts
Original file line number Diff line number Diff line change
@@ -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", () => {
Expand Down
22 changes: 21 additions & 1 deletion test/emitter.test.ts
Original file line number Diff line number Diff line change
@@ -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(() => {
Expand Down Expand Up @@ -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")
Expand Down
92 changes: 92 additions & 0 deletions test/serviceWorker.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
interface MockEvent {
claim: jest.Mock<any, any>
waitUntil?: jest.Mock<any, any>
}

interface Listener {
event: string
cb: (event?: MockEvent) => void
}

describe("serviceWorker", () => {
let listeners: Listener[] = []
let spy: jest.SpyInstance
let claimSpy: jest.Mock<any, any>
let waitUntilSpy: jest.Mock<any, any>

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()
})
})