/** * @vitest-environment jsdom */ import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; const __dirname = dirname(fileURLToPath(import.meta.url)); const SCRIPT_PATH = join(__dirname, '../../static/assets/js/cookie-consent.js'); function createBannerDOM() { const banner = document.createElement('div'); banner.id = 'cookie-banner'; const acceptBtn = document.createElement('button'); acceptBtn.type = 'button'; acceptBtn.dataset.consent = 'accept'; const rejectBtn = document.createElement('button'); rejectBtn.type = 'button'; rejectBtn.dataset.consent = 'reject'; banner.appendChild(acceptBtn); banner.appendChild(rejectBtn); document.body.appendChild(banner); return { banner, acceptBtn, rejectBtn }; } describe('cookie-consent.js', () => { const STORAGE_KEY = 'mifi-ventures-cookie-consent'; let dom: ReturnType; beforeEach(() => { // Ensure a fresh DOM and storage for each test document.body.innerHTML = ''; window.localStorage.clear(); dom = createBannerDOM(); const code = readFileSync(SCRIPT_PATH, 'utf8'); // eslint-disable-next-line no-eval eval(code); document.dispatchEvent(new Event('DOMContentLoaded')); }); afterEach(() => { dom.banner.remove(); vi.restoreAllMocks(); window.localStorage.clear(); }); it('shows banner when no preference is stored', () => { expect(dom.banner.classList.contains('is-visible')).toBe(true); }); it('hides banner and loads analytics when preference is "accept"', () => { document.body.innerHTML = ''; window.localStorage.setItem(STORAGE_KEY, 'accept'); dom = createBannerDOM(); const appendChildSpy = vi.spyOn(document.head, 'appendChild'); const code = readFileSync(SCRIPT_PATH, 'utf8'); // eslint-disable-next-line no-eval eval(code); document.dispatchEvent(new Event('DOMContentLoaded')); expect(dom.banner.classList.contains('is-visible')).toBe(false); expect(appendChildSpy).toHaveBeenCalled(); const urls = appendChildSpy.mock.calls .map((args) => (args[0] as HTMLScriptElement).src) .filter(Boolean); expect(urls.some((src) => src.includes('googletagmanager.com'))).toBe(true); }); it('hides banner when preference is "reject" and does not load analytics', () => { document.body.innerHTML = ''; window.localStorage.setItem(STORAGE_KEY, 'reject'); dom = createBannerDOM(); const appendChildSpy = vi.spyOn(document.head, 'appendChild'); const code = readFileSync(SCRIPT_PATH, 'utf8'); // eslint-disable-next-line no-eval eval(code); document.dispatchEvent(new Event('DOMContentLoaded')); expect(dom.banner.classList.contains('is-visible')).toBe(false); const urls = appendChildSpy.mock.calls .map((args) => (args[0] as HTMLScriptElement).src) .filter(Boolean); expect(urls.some((src) => src.includes('googletagmanager.com'))).toBe(false); }); it('stores "accept" in localStorage, hides banner, and loads analytics on accept click', () => { const appendChildSpy = vi.spyOn(document.head, 'appendChild'); dom.acceptBtn.click(); expect(window.localStorage.getItem(STORAGE_KEY)).toBe('accept'); expect(dom.banner.classList.contains('is-visible')).toBe(false); expect(appendChildSpy).toHaveBeenCalled(); }); it('stores "reject" in localStorage and hides banner on reject click', () => { const appendChildSpy = vi.spyOn(document.head, 'appendChild'); dom.rejectBtn.click(); expect(window.localStorage.getItem(STORAGE_KEY)).toBe('reject'); expect(dom.banner.classList.contains('is-visible')).toBe(false); const urls = appendChildSpy.mock.calls .map((args) => (args[0] as HTMLScriptElement).src) .filter(Boolean); expect(urls.some((src) => src.includes('googletagmanager.com'))).toBe(false); }); });