/** * Unit test debugging utilities for Vitest */ import { createLocalVue } from "@vue/test-utils"; import BootstrapVue from "bootstrap-vue"; import { PiniaVuePlugin } from "pinia"; import { expect, vi } from "vitest"; import VueRouter from "vue-router"; import { localizationPlugin } from "@/components/plugins/localization"; import _short from "@/components/plugins/short"; import { vueRxShortcutPlugin } from "@/components/plugins/vueRxShortcuts"; import _l from "@/utils/localization"; function testLocalize(text) { if (text) { return `test_localized<${text}>`; } else { return text; } } // Gets a localVue with custom directives export function getLocalVue(instrumentLocalization = false) { const localVue = createLocalVue(); const mockedDirective = { bind(el, binding) { el.setAttribute("data-mock-directive", binding.value || el.title); }, }; localVue.use(PiniaVuePlugin); localVue.use(BootstrapVue); const l = instrumentLocalization ? testLocalize : _l; localVue.use(localizationPlugin, l); localVue.use(vueRxShortcutPlugin); localVue.directive("b-tooltip", mockedDirective); localVue.directive("b-popover", mockedDirective); return localVue; } export function suppressDebugConsole() { vi.spyOn(console, "debug").mockImplementation(() => {}); } export function suppressBootstrapVueWarnings() { const originalWarn = console.warn; vi.spyOn(console, "warn").mockImplementation((msg) => { if (!String(msg).includes("BootstrapVue warn")) { originalWarn(msg); } }); } export function suppressErrorForCustomIcons() { const originalError = console.error; vi.spyOn(console, "error").mockImplementation((msg) => { if (!String(msg).includes("Could not find one or more icon(s)")) { originalError(msg); } }); } export function suppressLucideVue2Deprecation() { const originalWarn = console.warn; vi.spyOn(console, "warn").mockImplementation((msg) => { if (!String(msg).includes("[Lucide Vue] This package will be deprecated")) { originalWarn(msg); } }); } export function suppressExpectedErrorMessages(expectedMessages = []) { const originalError = console.error; vi.spyOn(console, "error").mockImplementation((msg) => { if (!expectedMessages.some((expected) => String(msg).includes(expected))) { originalError(msg); } }); } function isTestLocalized(received) { return received && received.indexOf && received.indexOf("test_localized<") == 0; } // Custom matchers for localization testing expect.extend({ toBeLocalized(received) { const pass = isTestLocalized(received); if (pass) { return { message: () => `expected ${received} to be localized`, pass: true, }; } else { return { message: () => `expected ${received} to be localized`, pass: false, }; } }, toBeLocalizationOf(received, str) { let unlocalized; if (received.indexOf("test_localized<") == 0) { unlocalized = received.substr("test_localized<".length); unlocalized = unlocalized.substr(0, unlocalized.length - 1); } else { unlocalized = received; } const pass = testLocalize(str) == received; if (pass) { return { message: () => `expected ${unlocalized} to be localization of ${str}`, pass: true, }; } else if (!isTestLocalized(received)) { return { message: () => `expected ${received} to be localized`, pass: false, }; } else { return { message: () => `expected ${unlocalized} to be localization of ${str}`, pass: false, }; } }, }); export function dispatchEvent(wrapper, type, props = {}) { const event = new Event(type, { bubbles: true }); Object.assign(event, props); wrapper.element.dispatchEvent(event); } export function findViaNavigation(wrapper, component) { return wrapper.find(component.selector); } /** * Expect and mock out an API request to /api/configuration. In general, useConfig * and using tests/vitest/mockConfig is better since components since be talking to the API * directly in this way but some older components are not using the latest composables. */ export function expectConfigurationRequest(http, config) { return http.get("/api/configuration", ({ response }) => { return response(200).json(config); }); } /** * Return a new mocked out router attached to the specified localVue instance. */ export function injectTestRouter(localVue) { localVue.use(VueRouter); const router = new VueRouter(); return router; } /** * Waits n milliseconds and then promise resolves * Usage: await wait(500); */ export const wait = (n) => { return new Promise((resolve) => { setTimeout(() => { resolve(); }, n); }); }; export function mockUnprivilegedToolsRequest(server, http) { server.use( http.get("/api/unprivileged_tools", ({ response }) => { return response(200).json([]); }), ); }