import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { JSDOM } from 'jsdom'; import { serviceTile } from '../../public/components/service_tile.js'; // Provide a DOM via jsdom WITHOUT switching this file to the `jsdom` vitest // environment — a second environment makes vitest run a parallel worker pool that // collides with the DB-backed node tests on the shared test database. We set the // globals dom.js needs (document/Node) for this file only and tear them down after. beforeAll(() => { const dom = new JSDOM('', { url: 'http://localhost/' }); global.window = dom.window; global.document = dom.window.document; global.Node = dom.window.Node; global.location = dom.window.location; // safeHref() resolves against location.origin }); afterAll(() => { delete global.window; delete global.document; delete global.Node; delete global.location; }); const base = { id: 'gramps', name: 'Gramps', host: 'ct109', icon: 'gramps', status: 'ok', url: 'http://192.168.1.99', external: 'https://gramps.hynesy.com' }; describe('serviceTile', () => { it('local: primary link is the LAN url, alt link is the domain', () => { const t = serviceTile(base, false); expect(t.querySelector('.tile-link').getAttribute('href')).toBe('http://192.168.1.99/'); expect(t.querySelector('.tile-alt').getAttribute('href')).toBe('https://gramps.hynesy.com/'); expect(t.querySelectorAll('a').length).toBe(2); }); it('remote: primary is the domain, alt is the LAN url', () => { const t = serviceTile(base, true); expect(t.querySelector('.tile-link').getAttribute('href')).toBe('https://gramps.hynesy.com/'); expect(t.querySelector('.tile-alt').getAttribute('href')).toBe('http://192.168.1.99/'); expect(t.classList.contains('lan-only')).toBe(false); }); it('remote + no external: lan-only, no alt, badge present', () => { const t = serviceTile({ ...base, external: undefined }, true); expect(t.classList.contains('lan-only')).toBe(true); expect(t.querySelector('.tile-alt')).toBeNull(); expect(t.querySelector('.tile-lan')).not.toBeNull(); }); });