// Firebase adapter contract test. // Runs the SAME storage contract as ws (src/storage/contract.js) // against createFirebaseStorage. The SDK is mocked via src/__mocks__/firebase/*, // so this proves the adapter translates contract calls -> SDK calls correctly // (path handling, merge semantics, subscribe) without hitting network. import { initFirebase, createFirebaseStorage } from '../storage/firebase'; import { runStorageContract } from '../storage/contract'; import { resetMockDb, MOCK_DB } from '../__mocks__/firebase/_mock-db'; import { orderBy, limit } from '../__mocks__/firebase/firestore'; // Firebase mock DB is shared global state. Reset before each factory so // contract tests are isolated. runStorageContract('firebase', () => { resetMockDb(); const ok = initFirebase(); if (!ok) throw new Error('initFirebase failed under mocked env'); return createFirebaseStorage(); }); // Firebase-only: queryConstraints (orderBy + limit) must flow through // subscribeCollection. main App passes LOG_QUERY = [orderBy('timestamp','desc'), // limit(500)] for the combat log. Adapter forwards them to the SDK; this proves // the whole chain sorts + caps, not just dumps raw. describe('firebase adapter: queryConstraints', () => { let storage; beforeEach(() => { resetMockDb(); initFirebase(); storage = createFirebaseStorage(); }); test('subscribeCollection honors orderBy desc', async () => { MOCK_DB.set('logs/a', { message: 'A', timestamp: 100 }); MOCK_DB.set('logs/b', { message: 'B', timestamp: 300 }); MOCK_DB.set('logs/c', { message: 'C', timestamp: 200 }); const result = await new Promise((resolve) => { storage.subscribeCollection('logs', resolve, [orderBy('timestamp', 'desc')]); }); expect(result.map(d => d.message)).toEqual(['B', 'C', 'A']); }); test('subscribeCollection honors limit', async () => { for (let i = 0; i < 5; i++) { MOCK_DB.set(`logs/l${i}`, { message: `L${i}`, timestamp: i }); } const result = await new Promise((resolve) => { storage.subscribeCollection('logs', resolve, [orderBy('timestamp', 'desc'), limit(3)]); }); expect(result).toHaveLength(3); expect(result.map(d => d.message)).toEqual(['L4', 'L3', 'L2']); }); });