Files
dotcom-arcade/backend/src/services/StartupState.test.ts
T
Darkraise 74aa0cf067 feat(startup): serve the app while the server warms up
On a network share the database copy and cache pre-warm run for minutes,
and the listener only opened after all of it, so anyone who loaded the
page during that window got a connection error.

Open the port immediately after registering the static frontend, and
hold every route that needs the database behind a gate that answers 503
with a machine-readable marker and the current startup phase. The SPA
shell needs nothing the gate blocks, so the frontend renders a "server
is starting" screen on the login page's own background, polls /health,
and reloads once the server reports ready.

Move the database copy out of the entrypoint: it does the same freshness
check the application does, and doing it before node starts kept the port
closed for the longest part of startup. Distinguish a dead server from a
slow one by requiring the backend's own marker, since a proxy in front of
a stopped backend still answers.
2026-08-12 14:05:14 +07:00

42 lines
1.2 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from 'vitest';
vi.mock('../utils/logger', () => ({
logger: { info: vi.fn(), error: vi.fn(), debug: vi.fn(), warn: vi.fn() },
}));
import { StartupState } from './StartupState';
beforeEach(() => {
StartupState.reset();
});
describe('StartupState', () => {
it('starts not ready with an initial phase', () => {
expect(StartupState.isReady()).toBe(false);
expect(StartupState.getPhase()).toBe('Starting up');
});
it('reports the current phase while starting', () => {
StartupState.setPhase('Connecting to the Flashpoint database');
expect(StartupState.getPhase()).toBe('Connecting to the Flashpoint database');
expect(StartupState.isReady()).toBe(false);
});
it('reports ready once startup completes', () => {
StartupState.setPhase('Warming up game search');
StartupState.markReady();
expect(StartupState.isReady()).toBe(true);
expect(StartupState.getPhase()).toBe('Ready');
});
it('ignores late phase updates from background work', () => {
StartupState.markReady();
StartupState.setPhase('Installing Ruffle');
expect(StartupState.isReady()).toBe(true);
expect(StartupState.getPhase()).toBe('Ready');
});
});