Archived
1
0

refactor: clean up testing files

This commit is contained in:
Joe Previte
2021-07-12 16:54:19 -07:00
parent a5cf01840a
commit fc16f7e06d
5 changed files with 15 additions and 17 deletions

View File

@ -0,0 +1,90 @@
import { JSDOM } from "jsdom"
import { LocationLike } from "../../util.test"
describe("login", () => {
describe("there is an element with id 'base'", () => {
beforeEach(() => {
const dom = new JSDOM()
global.document = dom.window.document
const location: LocationLike = {
pathname: "/healthz",
origin: "http://localhost:8080",
}
global.location = location as Location
})
afterEach(() => {
// Reset the global.document
global.document = undefined as any as Document
global.location = undefined as any as Location
})
it("should set the value to options.base", () => {
// Mock getElementById
const spy = jest.spyOn(document, "getElementById")
// Create a fake element and set the attribute
const mockElement = document.createElement("input")
mockElement.setAttribute("id", "base")
const expected = {
base: "./hello-world",
csStaticBase: "./static/development/Users/jp/Dev/code-server",
logLevel: 2,
disableTelemetry: false,
disableUpdateCheck: false,
}
mockElement.setAttribute("data-settings", JSON.stringify(expected))
document.body.appendChild(mockElement)
spy.mockImplementation(() => mockElement)
// Load file
require("../../../../src/browser/pages/login")
const el: HTMLInputElement | null = document.querySelector("input#base")
expect(el?.value).toBe("/hello-world")
})
})
describe("there is not an element with id 'base'", () => {
let spy: jest.SpyInstance
beforeAll(() => {
// This is important because we're manually requiring the file
// If you don't call this before all tests
// the module registry from other tests may cause side effects.
jest.resetModuleRegistry()
})
beforeEach(() => {
const dom = new JSDOM()
global.document = dom.window.document
spy = jest.spyOn(document, "getElementById")
const location: LocationLike = {
pathname: "/healthz",
origin: "http://localhost:8080",
}
global.location = location as Location
})
afterEach(() => {
spy.mockClear()
jest.resetModules()
// Reset the global.document
global.document = undefined as any as Document
global.location = undefined as any as Location
})
afterAll(() => {
jest.restoreAllMocks()
})
it("should do nothing", () => {
spy.mockImplementation(() => null)
// Load file
require("../../../../src/browser/pages/login")
// It's called once by getOptions in the top of the file
// and then another to get the base element
expect(spy).toHaveBeenCalledTimes(2)
})
})
})

View File

@ -6,7 +6,7 @@ import {
getNlsConfiguration,
nlsConfigElementId,
setBodyBackgroundToThemeBackgroundColor,
} from "../../../src/browser/pages/vscode"
} from "../../../../src/browser/pages/vscode"
describe("vscode", () => {
describe("getNlsConfiguration", () => {

View File

@ -0,0 +1,183 @@
import { JSDOM } from "jsdom"
import { registerServiceWorker } from "../../../src/browser/register"
import { createLoggerMock } from "../../utils/helpers"
import { LocationLike } from "../util.test"
describe("register", () => {
describe("when navigator and serviceWorker are defined", () => {
const mockRegisterFn = jest.fn()
beforeAll(() => {
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
Object.defineProperty(global.navigator, "serviceWorker", {
value: {
register: mockRegisterFn,
},
})
})
const loggerModule = createLoggerMock()
beforeEach(() => {
jest.clearAllMocks()
jest.mock("@coder/logger", () => loggerModule)
})
afterEach(() => {
jest.resetModules()
})
afterAll(() => {
jest.restoreAllMocks()
// We don't want these to stay around because it can affect other tests
global.window = undefined as unknown as Window & typeof globalThis
global.document = undefined as unknown as Document & typeof globalThis
global.navigator = undefined as unknown as Navigator & typeof globalThis
global.location = undefined as unknown as Location & typeof globalThis
})
it("test should have access to browser globals from beforeAll", () => {
expect(typeof global.window).not.toBeFalsy()
expect(typeof global.document).not.toBeFalsy()
expect(typeof global.navigator).not.toBeFalsy()
expect(typeof global.location).not.toBeFalsy()
})
it("should register a ServiceWorker", () => {
// Load service worker like you would in the browser
require("../../../src/browser/register")
expect(mockRegisterFn).toHaveBeenCalled()
expect(mockRegisterFn).toHaveBeenCalledTimes(1)
})
it("should log an error if something doesn't work", () => {
const message = "Can't find browser"
const error = new Error(message)
mockRegisterFn.mockImplementation(() => {
throw error
})
// Load service worker like you would in the browser
require("../../../src/browser/register")
expect(mockRegisterFn).toHaveBeenCalled()
expect(loggerModule.logger.error).toHaveBeenCalled()
expect(loggerModule.logger.error).toHaveBeenCalledTimes(1)
expect(loggerModule.logger.error).toHaveBeenCalledWith(
`[Service Worker] registration: ${error.message} ${error.stack}`,
)
})
})
describe("when navigator and serviceWorker are NOT defined", () => {
const loggerModule = createLoggerMock()
beforeEach(() => {
jest.clearAllMocks()
jest.mock("@coder/logger", () => loggerModule)
})
afterAll(() => {
jest.restoreAllMocks()
})
it("should log an error", () => {
// Load service worker like you would in the browser
require("../../../src/browser/register")
expect(loggerModule.logger.error).toHaveBeenCalled()
expect(loggerModule.logger.error).toHaveBeenCalledTimes(1)
expect(loggerModule.logger.error).toHaveBeenCalledWith("[Service Worker] navigator is undefined")
})
})
describe("registerServiceWorker", () => {
let serviceWorkerPath: string
let serviceWorkerScope: string
const mockFn = jest.fn((path: string, options: { scope: string }) => {
serviceWorkerPath = path
serviceWorkerScope = options.scope
return undefined
})
beforeAll(() => {
const location: LocationLike = {
pathname: "",
origin: "http://localhost:8080",
}
const { window } = new JSDOM()
global.window = window as unknown as Window & typeof globalThis
global.document = window.document
global.navigator = window.navigator
global.location = location as Location
Object.defineProperty(global.navigator, "serviceWorker", {
value: {
register: mockFn,
},
})
})
afterEach(() => {
mockFn.mockClear()
jest.resetModules()
})
afterAll(() => {
jest.restoreAllMocks()
// We don't want these to stay around because it can affect other tests
global.window = undefined as unknown as Window & typeof globalThis
global.document = undefined as unknown as Document & typeof globalThis
global.navigator = undefined as unknown as Navigator & typeof globalThis
global.location = undefined as unknown as Location & typeof globalThis
})
it("should register when options.base is undefined", async () => {
// Mock getElementById
const csStaticBasePath = "/static/development/Users/jp/Dev/code-server"
const spy = jest.spyOn(document, "getElementById")
// Create a fake element and set the attribute
const mockElement = document.createElement("div")
mockElement.id = "coder-options"
mockElement.setAttribute(
"data-settings",
`{"csStaticBase":"${csStaticBasePath}","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}`,
)
// Return mockElement from the spy
// this way, when we call "getElementById"
// it returns the element
spy.mockImplementation(() => mockElement)
await registerServiceWorker()
expect(mockFn).toBeCalled()
expect(serviceWorkerPath).toMatch(`${csStaticBasePath}/dist/serviceWorker.js`)
expect(serviceWorkerScope).toMatch("/")
})
it("should register when options.base is defined", async () => {
const csStaticBasePath = "/static/development/Users/jp/Dev/code-server"
const spy = jest.spyOn(document, "getElementById")
// Create a fake element and set the attribute
const mockElement = document.createElement("div")
mockElement.id = "coder-options"
mockElement.setAttribute(
"data-settings",
`{"base":"proxy/","csStaticBase":"${csStaticBasePath}","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}`,
)
// Return mockElement from the spy
// this way, when we call "getElementById"
// it returns the element
spy.mockImplementation(() => mockElement)
await registerServiceWorker()
expect(mockFn).toBeCalled()
expect(serviceWorkerPath).toMatch(`/dist/serviceWorker.js`)
expect(serviceWorkerScope).toMatch("/")
})
})
})

View File

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