// Session 45 — Phase 4: the ticker polls /api/ticker (snapshot exhaust). const fs = require('fs'); const path = require('path'); const WEB = path.join(__dirname, '..', '..', 'web', 'src'); const read = (rel) => fs.readFileSync(path.join(WEB, rel), 'utf8'); describe('Ticker live wiring', () => { const src = read('components/vyndr/Ticker.tsx'); it('fetches from /api/ticker (not purely hardcoded)', () => { expect(src).toContain("fetch('/api/ticker'"); expect(src).toContain('setInterval(load'); }); it('polls every 30s by default', () => { expect(src).toContain('pollMs = 30_000'); }); it('falls back to the passed items + keeps current on failure (never blanks)', () => { expect(src).toContain('feed && feed.length > 0 ? feed : items'); expect(src).toContain('keep the current items on failure'); }); it('colors event tags (A+/MOVE/SCAN/ALERT)', () => { expect(src).toContain("MOVE: 'var(--amber)'"); expect(src).toContain("ALERT: 'var(--text-0)'"); }); }); describe('Ticker Next proxy', () => { it('exists and forwards to the backend', () => { const proxy = read('app/api/ticker/route.ts'); expect(proxy).toContain('/api/ticker'); expect(proxy).toContain('BACKEND_URL'); }); });