import assert from 'node:assert/strict'; import {readFile} from 'node:fs/promises'; import test from 'node:test'; import vm from 'node:vm'; const source = await readFile(new URL('./hop-native.js', import.meta.url), 'utf8'); function page({search = '', signedIn = false, fetchResult} = {}) { const dataset = {}; const publicHomeLink = { classList: {toggle() {}}, href: 'https://hop.test/', }; let currentMainReplaced = false; const currentMain = { replaceWith() { currentMainReplaced = true; }, }; const publicMain = { parentElement: {querySelectorAll: () => []}, }; const document = { documentElement: {dataset}, title: 'Dashboard', addEventListener() {}, querySelector(selector) { if (selector === 'meta[name="hop-signed-user-id"]') return signedIn ? {} : null; if (selector === '[data-hop-public-home-link]') return signedIn ? publicHomeLink : null; if (selector === '[role="main"]') return currentMain; return null; }, querySelectorAll() { return []; }, }; const context = { console: {error() {}}, document, DOMParser: class { parseFromString() { return { title: 'Hop', querySelector: (selector) => selector === '#hop-main' ? publicMain : null, }; } }, fetch: fetchResult || (() => Promise.resolve({ok: true, text: () => Promise.resolve('
')})), MutationObserver: class { observe() {} }, URL, URLSearchParams, window: { location: {href: `https://hop.test/${search}`, origin: 'https://hop.test', pathname: '/', search}, requestAnimationFrame() {}, }, }; vm.runInNewContext(source, context); return {dataset, get currentMainReplaced() { return currentMainReplaced; }}; } async function settle() { await new Promise((resolve) => setImmediate(resolve)); } test('keeps the authenticated dashboard hidden until the public homepage is ready', async () => { let finishFetch; const fetchResult = () => new Promise((resolve) => { finishFetch = resolve; }); const result = page({search: '?hop=home', signedIn: true, fetchResult}); assert.equal(result.dataset.hopPublicHome, 'loading'); assert.equal(result.dataset.hopNative, undefined); assert.equal(result.currentMainReplaced, false); finishFetch({ok: true, text: () => Promise.resolve('
')}); await settle(); assert.equal(result.dataset.hopPublicHome, 'rendered'); assert.equal(result.dataset.hopNative, 'true'); assert.equal(result.currentMainReplaced, true); }); test('reveals the existing page when the public homepage request fails', async () => { const result = page({ search: '?hop=home', signedIn: true, fetchResult: () => Promise.reject(new Error('offline')), }); assert.equal(result.dataset.hopNative, undefined); await settle(); assert.equal(result.dataset.hopPublicHome, 'failed'); assert.equal(result.dataset.hopNative, 'true'); assert.equal(result.currentMainReplaced, false); }); test('reveals ordinary pages immediately', () => { const result = page({signedIn: true}); assert.equal(result.dataset.hopNative, 'true'); });