fix(reference): verify station coverage and rollback inputs
This commit is contained in:
@@ -2,7 +2,7 @@ import { expect, test } from 'bun:test';
|
||||
import { cp, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { ReferenceCompiler, SqliteReferenceRepository } from '../src/lib/server/reference';
|
||||
import { ReferenceCompiler, SqliteReferenceRepository, readReferenceManifest } from '../src/lib/server/reference';
|
||||
import { fixtureSources } from '../src/lib/server/reference/sources';
|
||||
|
||||
test('reference readers search normalized types and expose group/category/system/region/station joins', async () => {
|
||||
@@ -57,6 +57,31 @@ test('readers reject empty type searches and preserve unknown station metadata',
|
||||
} finally { await rm(root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('offline production-profile candidate records verified station counts', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'eden-reference-production-stations-'));
|
||||
const sources = join(root, 'fixtures');
|
||||
const directory = join(root, 'reference');
|
||||
try {
|
||||
await cp('fixtures/reference', sources, { recursive: true });
|
||||
const universePath = join(sources, 'systems.json');
|
||||
const universe = JSON.parse(await readFile(universePath, 'utf8')) as Record<string, unknown>;
|
||||
universe.regions = { '10000001': { region_id: 10000001, name: 'The Forge' } };
|
||||
universe.constellations = { '20000020': { constellation_id: 20000020, name: 'Kimotoro', region_id: 10000001 } };
|
||||
universe.stations = { '60003760': { station_id: 60003760, system_id: 30000142, type_id: 587, owner_id: 1000035, position: { x: 1, y: 2, z: 3 } } };
|
||||
await writeFile(universePath, JSON.stringify(universe));
|
||||
const result = await new ReferenceCompiler({ directory, profile: 'production', thresholds: { systemsMinimum: 1, stationsMinimum: 1 }, sources: fixtureSources(sources) }).compile();
|
||||
expect(result.status).toBe('success');
|
||||
const manifest = await readReferenceManifest(directory);
|
||||
expect(manifest.active?.profile).toBe('production');
|
||||
expect(manifest.active?.counts.stations).toBe(1);
|
||||
expect(manifest.active?.counts.verified_stations).toBe(1);
|
||||
expect(manifest.active?.stationCoverage).toBe('incomplete');
|
||||
const reader = new SqliteReferenceRepository(directory, 'production');
|
||||
try { expect((await reader.stations([60003760]))[0]?.sourceVerified).toBe(true); }
|
||||
finally { reader.close(); }
|
||||
} finally { await rm(root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('unknown system station IDs cannot satisfy verified production station coverage', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'eden-reference-station-gate-'));
|
||||
const sources = join(root, 'fixtures');
|
||||
|
||||
@@ -321,6 +321,25 @@ describe('fixture reference compiler', () => {
|
||||
} finally { await rm(root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('rejects incomplete PREVIOUS count metadata before rollback', async () => {
|
||||
const { root, sources } = await fixtureDirectory();
|
||||
const directory = join(root, 'reference');
|
||||
try {
|
||||
const first = await new ReferenceCompiler({ directory, profile: 'fixture', sources: fixtureSources(sources) }).compile();
|
||||
expect(first.status).toBe('success');
|
||||
if (first.status !== 'success') throw new Error('initial fixture build did not publish');
|
||||
await writeFile(join(sources, 'reference-data.json'), `${await readFile(join(sources, 'reference-data.json'), 'utf8')}\n`);
|
||||
const second = await new ReferenceCompiler({ directory, profile: 'fixture', sources: fixtureSources(sources) }).compile();
|
||||
expect(second.status).toBe('success');
|
||||
const manifest = await readReferenceManifest(directory);
|
||||
if (!manifest.previous) throw new Error('fixture build did not retain PREVIOUS');
|
||||
const malformed = { ...manifest, previous: { ...manifest.previous, counts: Object.fromEntries(Object.entries(manifest.previous.counts).filter(([key]) => key !== 'stations')) } };
|
||||
await writeFile(join(directory, 'manifest.json'), `${JSON.stringify(malformed)}\n`);
|
||||
await expect(new ReferenceCompiler({ directory, profile: 'fixture', sources: fixtureSources(sources) }).rollback()).rejects.toThrow(/missing count metadata/);
|
||||
expect((await readReferenceManifest(directory)).active?.version).toBe(manifest.active?.version);
|
||||
} finally { await rm(root, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('recovers a validated orphan database after manifest publication crash', async () => {
|
||||
const { root, sources } = await fixtureDirectory();
|
||||
const directory = join(root, 'reference');
|
||||
|
||||
Reference in New Issue
Block a user