117 lines
4.1 KiB
TypeScript
117 lines
4.1 KiB
TypeScript
/**
|
|
* @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<typeof createBannerDOM>;
|
|
|
|
beforeEach(() => {
|
|
// Ensure a fresh DOM and storage for each test
|
|
document.body.innerHTML = '';
|
|
window.localStorage.clear();
|
|
dom = createBannerDOM();
|
|
|
|
const code = readFileSync(SCRIPT_PATH, 'utf8');
|
|
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');
|
|
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');
|
|
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);
|
|
});
|
|
});
|
|
|