// DisplayView.characterization.test.js // Lock DisplayView uses storage adapter (subscribeDoc), NOT raw SDK onSnapshot(doc(db)). // Blind spot caught: M2 refactor missed DisplayView; raw SDK + ws stub db = crash. // Test asserts adapter recorder shows subscribeDoc calls when player view boots. import React from 'react'; import { render, waitFor } from '@testing-library/react'; import '@testing-library/jest-dom'; import App from './App'; import { MOCK_DB } from './__mocks__/firebase/_mock-db'; import { getAdapterCalls, resetAdapterCalls } from './storage/firebase'; // Seed activeDisplay + campaign + encounter so DisplayView has data to subscribe to. function seedActiveDisplay() { const campaignPath = 'artifacts/ttrpg-initiative-tracker-default/public/data/campaigns/c1'; const encounterPath = 'artifacts/ttrpg-initiative-tracker-default/public/data/campaigns/c1/encounters/e1'; const activeDisplayPath = 'artifacts/ttrpg-initiative-tracker-default/public/data/activeDisplay/status'; MOCK_DB.set(campaignPath, { name: 'Camp', playerDisplayBackgroundUrl: '' }); MOCK_DB.set(encounterPath, { name: 'Enc', participants: [], isStarted: true }); MOCK_DB.set(activeDisplayPath, { activeCampaignId: 'c1', activeEncounterId: 'e1', hidePlayerHp: false }); } describe('DisplayView characterization', () => { beforeEach(() => { window.history.replaceState({}, '', '/display'); global.alert = jest.fn(); window.open = jest.fn(); resetAdapterCalls(); }); afterEach(() => { window.history.replaceState({}, '', '/'); }); test('DisplayView subscribes via adapter.subscribeDoc (not raw SDK)', async () => { seedActiveDisplay(); render(); // wait for DisplayView to mount and attempt subscriptions await waitFor(() => { const subs = getAdapterCalls().filter(c => c.fn === 'subscribeDoc'); expect(subs.length).toBeGreaterThanOrEqual(1); }, { timeout: 3000 }); // must subscribe to campaign doc (for background url) and encounter doc const docSubs = getAdapterCalls().filter(c => c.fn === 'subscribeDoc').map(c => c.path); expect(docSubs.some(p => p.includes('/campaigns/c1'))).toBe(true); expect(docSubs.some(p => p.includes('/encounters/e1'))).toBe(true); }); test('DisplayView also subscribes to activeDisplay status doc via adapter', async () => { seedActiveDisplay(); render(); await waitFor(() => { const subs = getAdapterCalls().filter(c => c.fn === 'subscribeDoc' && c.path.includes('activeDisplay')); expect(subs.length).toBeGreaterThanOrEqual(1); }, { timeout: 3000 }); }); });