import { expect, test } from 'bun:test'; import { cp, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; import { Database } from 'bun:sqlite'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; 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 () => { const root = await mkdtemp(join(tmpdir(), 'eden-reference-readers-')); 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; universe.regions = { '10000001': { region_id: 10000001, name: 'The Forge' } }; universe.constellations = { '20000020': { constellation_id: 20000020, name: 'Kimotoro', region_id: 10000001 } }; universe.stations = { '60003761': { station_id: 60003761, system_id: 30000142, name: 'Jita IV - Moon 4 - Caldari Navy Assembly Plant', type_id: 587, owner_id: 1000035, position: { x: 1, y: 2, z: 3 } } }; (universe.systems as Record>)['30000142'].stations = [60003760]; await writeFile(universePath, JSON.stringify(universe)); const result = await new ReferenceCompiler({ directory, profile: 'fixture', sources: fixtureSources(sources) }).compile(); expect(result.status).toBe('success'); const reader = new SqliteReferenceRepository(directory, 'fixture'); try { expect(await reader.searchTypesByName(' trit ')).toEqual([{ id: 34, name: 'Tritanium', categoryId: 4, groupId: 18, published: true, volume: 0.01 }]); expect(await reader.searchTypes({ query: 'RIF', categoryId: 6 })).toEqual([{ id: 587, name: 'Rifter', categoryId: 6, groupId: 25, published: true, volume: 2500 }]); expect(await reader.categories([4])).toEqual([{ id: 4, name: 'Material', published: true }]); expect(await reader.groups({ categoryId: 4 })).toEqual([{ id: 18, categoryId: 4, name: 'Mineral', published: true }]); expect(await reader.regions({ query: 'forge' })).toEqual([{ id: 10000001, name: 'The Forge' }]); expect(await reader.systems({ regionId: 10000001 })).toEqual([{ id: 30000142, name: 'Jita', constellationId: 20000020, regionId: 10000001, x: -129064861735000000, y: 60755306910000000, z: 117469227060000000, securityStatus: 0.9459131360054016, securityClass: null }]); const stations = await reader.stations({ systemId: 30000142 }); expect(stations).toHaveLength(2); expect(stations).toEqual([ { id: 60003760, systemId: 30000142, systemName: 'Jita', regionId: 10000001, evidence: 'system_listed', sourceVerified: false, name: null, typeId: null, ownerId: null, x: null, y: null, z: null }, { id: 60003761, systemId: 30000142, systemName: 'Jita', regionId: 10000001, evidence: 'verified', sourceVerified: true, name: 'Jita IV - Moon 4 - Caldari Navy Assembly Plant', typeId: 587, ownerId: 1000035, x: 1, y: 2, z: 3 }, ]); const db = new Database(reader.databasePath, { readonly: true, strict: true }); try { expect(db.query<{ station_id: number }, []>('SELECT station_id FROM stations WHERE source_verified = 1 ORDER BY station_id LIMIT 1').get()?.station_id).toBe(60003761); } finally { db.close(); } expect(await reader.stations({ query: 'assembly' })).toEqual([stations[1]]); const pinned = reader.pin(); try { expect((await pinned.searchTypesByName('pyerite'))[0]?.id).toBe(35); } finally { pinned.close(); } } finally { reader.close(); } } finally { await rm(root, { recursive: true, force: true }); } }); test('readers reject empty type searches and preserve unknown station metadata', async () => { const root = await mkdtemp(join(tmpdir(), 'eden-reference-readers-')); try { const result = await new ReferenceCompiler({ directory: join(root, 'reference'), profile: 'fixture' }).compile(); expect(result.status).toBe('success'); const reader = new SqliteReferenceRepository(join(root, 'reference'), 'fixture'); try { await expect(reader.searchTypes({ query: ' ' })).rejects.toThrow('must contain letters or numbers'); expect(await reader.stations([999])).toEqual([]); await expect(reader.categories(Array.from({ length: 501 }, (_, index) => index))).rejects.toThrow('selection exceeds 500 IDs'); } finally { reader.close(); } } 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; 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'); try { await cp('fixtures/reference', sources, { recursive: true }); const universePath = join(sources, 'systems.json'); const universe = JSON.parse(await readFile(universePath, 'utf8')) as { systems: Record }; universe.systems['30000142'].stations = [60003760]; await writeFile(universePath, JSON.stringify(universe)); const result = await new ReferenceCompiler({ directory: join(root, 'reference'), profile: 'fixture', thresholds: { stationsMinimum: 1 }, sources: fixtureSources(sources) }).compile(); expect(result.status).toBe('failed'); expect(result.error).toContain('verified stations'); } finally { await rm(root, { recursive: true, force: true }); } });