// The bridge to the dashboard: only the expected origin, only this version, // and the editor says when it listens. import { describe, expect, it } from 'vitest'; import { BRIDGE_VERSION, startBridge } from '../src/bridge/dashboardBridge.js'; function fakeWindow() { const posted: [unknown, string][] = []; const listeners = new Set<(event: { origin: string; data: unknown }) => void>(); return { posted, window: { parent: { postMessage: (message: unknown, origin: string) => posted.push([message, origin]) }, addEventListener: (_: 'message', listener: (event: { origin: string; data: unknown }) => void) => listeners.add(listener), removeEventListener: (_: 'message', listener: (event: { origin: string; data: unknown }) => void) => listeners.delete(listener), }, send: (origin: string, data: unknown) => { for (const listener of listeners) listener({ origin, data }); }, listening: () => listeners.size, }; } describe('the bridge to the dashboard', () => { it('says it is ready, to the dashboard only', () => { const fake = fakeWindow(); startBridge(fake.window, 'https://dashboard.example', { onLocale: () => {}, onTheme: () => {} }); expect(fake.posted).toEqual([[{ v: BRIDGE_VERSION, type: 'ready' }, 'https://dashboard.example']]); }); it('takes language and colours from the dashboard, and nothing from elsewhere', () => { const fake = fakeWindow(); const got: unknown[] = []; const stop = startBridge(fake.window, 'https://dashboard.example', { onLocale: (locale) => got.push(['locale', locale]), onTheme: (theme, tokens) => got.push(['theme', theme, tokens]), }); fake.send('https://evil.example', { v: 1, type: 'setLocale', locale: 'en' }); fake.send('https://dashboard.example', { v: 2, type: 'setLocale', locale: 'en' }); fake.send('https://dashboard.example', { v: 1, type: 'setLocale', locale: 7 }); fake.send('https://dashboard.example', { v: 1, type: 'setTheme', theme: 'pink' }); fake.send('https://dashboard.example', null); expect(got).toEqual([]); fake.send('https://dashboard.example', { v: 1, type: 'setLocale', locale: 'en-GB' }); fake.send('https://dashboard.example', { v: 1, type: 'setTheme', theme: 'dark', tokens: { '--accent': '#123456', color: 'red', '--bad': 3 } }); expect(got).toEqual([ ['locale', 'en-GB'], ['theme', 'dark', { '--accent': '#123456' }], ]); stop(); expect(fake.listening()).toBe(0); }); });