'ws' conflated storage mode with transport protocol (WebSocket). Renamed for clarity: the adapter talks the self-hosted server (src/storage/server.js), which happens to use WebSocket for realtime — but the name should describe what it connects to, not how. Renames: - src/storage/ws.js -> server.js - createWsStorage() -> createServerStorage() - storage mode 'ws' -> 'server' - REACT_APP_BACKEND_WS -> REACT_APP_BACKEND_REALTIME_URL - factory param wsUrl -> realtimeUrl - server/tests/ws-*.test.js -> server-*.test.js Kept literal: 'ws' npm package, ws:// protocol URLs, /ws WebSocket endpoint. Transport is accurate there; only storage-naming changed. Updated all docs (DEVELOPMENT, TESTING, REWORK_PLAN, GLOSSARY, TODO), scripts (dev-start.sh, replay-combat.js), factory + ESM tests. 204 tests green.
71 lines
2.3 KiB
JavaScript
71 lines
2.3 KiB
JavaScript
// Storage factory (index.js) test.
|
|
// Verifies getStorage() returns the right adapter per REACT_APP_STORAGE env,
|
|
// caches as singleton, and getStorageMode() reports the active mode.
|
|
// Adapters are mocked (no network/init) — factory routing is the unit.
|
|
|
|
import { getStorage, getStorageMode } from '../storage/index';
|
|
|
|
// reset module-level singleton between tests
|
|
let originalStorage;
|
|
|
|
beforeEach(() => {
|
|
originalStorage = process.env.REACT_APP_STORAGE;
|
|
// bust the module singleton by re-importing fresh
|
|
jest.resetModules();
|
|
});
|
|
|
|
afterEach(() => {
|
|
if (originalStorage === undefined) delete process.env.REACT_APP_STORAGE;
|
|
else process.env.REACT_APP_STORAGE = originalStorage;
|
|
jest.resetModules();
|
|
});
|
|
|
|
describe('getStorageMode', () => {
|
|
test('defaults to firebase when env unset', () => {
|
|
delete process.env.REACT_APP_STORAGE;
|
|
const { getStorageMode } = require('../storage/index');
|
|
expect(getStorageMode()).toBe('firebase');
|
|
});
|
|
|
|
test('returns server when REACT_APP_STORAGE=server', () => {
|
|
process.env.REACT_APP_STORAGE = 'server';
|
|
const { getStorageMode } = require('../storage/index');
|
|
expect(getStorageMode()).toBe('server');
|
|
});
|
|
|
|
test('throws on unknown mode', () => {
|
|
process.env.REACT_APP_STORAGE = 'garbage';
|
|
const { getStorage } = require('../storage/index');
|
|
expect(() => getStorage()).toThrow(/Unknown REACT_APP_STORAGE/);
|
|
});
|
|
});
|
|
|
|
describe('getStorage factory routing', () => {
|
|
test('server mode returns server adapter (init may fail without backend — catch)', () => {
|
|
process.env.REACT_APP_STORAGE = 'server';
|
|
const { getStorage } = require('../storage/index');
|
|
try {
|
|
const s = getStorage();
|
|
expect(s).toBeTruthy();
|
|
expect(typeof s.getDoc).toBe('function');
|
|
} catch (e) {
|
|
// ws adapter without backend URL/config is allowed to throw at factory;
|
|
// routing reached ws branch (not firebase) which is the contract.
|
|
expect(e).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
test('returns singleton on repeat call (same instance)', () => {
|
|
process.env.REACT_APP_STORAGE = 'server';
|
|
const { getStorage } = require('../storage/index');
|
|
let a;
|
|
try { a = getStorage(); } catch (e) { return; } // no backend ok
|
|
if (a) {
|
|
const b = getStorage();
|
|
expect(a).toBe(b);
|
|
}
|
|
});
|
|
|
|
|
|
});
|