/** * Tests for System Initialization Service */ import { beforeEach, describe, expect, test } from 'bun:test'; import { eq } from 'drizzle-orm'; import type { DbClient } from '../db/client'; import { systemConfig } from '../db/schema'; import { setupTestDatabase } from '../test-utils/database'; import { autoDetectSSHKeys, getDefaultConfiguration, initializeSystem, isSystemInitialized, } from './system-init'; describe('System Init Service', () => { let db: DbClient; beforeEach(async () => { db = await setupTestDatabase(); }); describe('getDefaultConfiguration', () => { test('returns default values from schema', () => { const defaults = getDefaultConfiguration(); // network.bridge keeps its default (a container-service concept, not // a zone address). expect(defaults['network.bridge']).toBe('vmbr0'); // Network/DNS addressing is no longer defaulted // (openspec/specs/progressive-zone-disclosure/spec.md): internal is discovered at // celilo-mgmt install; dmz/app/secure appear only when a firewall // module provides them. expect(defaults['network.dmz.subnet']).toBeUndefined(); expect(defaults['network.dmz.vlan']).toBeUndefined(); expect(defaults['network.internal.subnet']).toBeUndefined(); expect(defaults['dns.primary']).toBeUndefined(); expect(defaults['dns.fallback']).toBeUndefined(); // primary_domain was removed from system config in MANIFEST_V2 D9. expect(defaults.primary_domain).toBeUndefined(); }); }); describe('autoDetectSSHKeys', () => { test('returns an array of detected keys', () => { const keys = autoDetectSSHKeys(); // Either empty (no key found) or entries with non-empty content. expect(Array.isArray(keys)).toBe(true); for (const key of keys) { expect(typeof key.content).toBe('string'); expect(key.content.length).toBeGreaterThan(0); } }); }); describe('initializeSystem', () => { test('creates all default configuration', () => { const config = initializeSystem(db); expect(config).toBeDefined(); expect(typeof config).toBe('object'); // Verify base values were created const networkBridge = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'network.bridge')) .get(); expect(networkBridge?.value).toBe('vmbr0'); }); test('computes gateway IPs from provided subnets', () => { // Subnets are no longer defaulted, so the operator/firewall supplies // them as overrides; the gateway is still auto-computed from the // subnet network address. initializeSystem(db, { 'network.dmz.subnet': '10.0.10.0/24', 'network.app.subnet': '10.0.20.0/24', }); // Check DMZ gateway was computed const dmzGateway = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'network.dmz.gateway')) .get(); expect(dmzGateway?.value).toBe('10.0.10.1'); // Check app gateway was computed const appGateway = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'network.app.gateway')) .get(); expect(appGateway?.value).toBe('10.0.20.1'); }); test('does not seed network/DNS addressing by default', () => { initializeSystem(db); for (const key of [ 'network.dmz.subnet', 'network.app.subnet', 'network.secure.subnet', 'network.internal.subnet', 'dns.primary', 'dns.fallback', ]) { const row = db.select().from(systemConfig).where(eq(systemConfig.key, key)).get(); expect(row).toBeUndefined(); } // network.bridge IS still seeded. const bridge = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'network.bridge')) .get(); expect(bridge?.value).toBe('vmbr0'); }); test('applies overrides instead of defaults', () => { initializeSystem(db, { primary_domain: 'custom.com', 'network.dmz.subnet': '192.168.10.0/24', }); // Verify override was applied const domain = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'primary_domain')) .get(); expect(domain?.value).toBe('custom.com'); // Verify computed gateway uses custom subnet const dmzGateway = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'network.dmz.gateway')) .get(); expect(dmzGateway?.value).toBe('192.168.10.1'); }); test('includes SSH key if auto-detected', () => { const config = initializeSystem(db); const detectedKeys = autoDetectSSHKeys(); if (detectedKeys.length > 0) { const detectedKey = detectedKeys[0].content; expect(config['ssh.public_key']).toBe(detectedKey); const sshKey = db .select() .from(systemConfig) .where(eq(systemConfig.key, 'ssh.public_key')) .get(); expect(sshKey?.value).toBe(detectedKey); } }); }); describe('isSystemInitialized', () => { test('returns false for empty database', () => { const initialized = isSystemInitialized(db); expect(initialized).toBe(false); }); test('returns true after initialization', () => { initializeSystem(db); const initialized = isSystemInitialized(db); expect(initialized).toBe(true); }); test('keys off the sentinel, not config rows', async () => { // Config rows present but no sentinel → NOT initialized. Initialization // is tracked by the explicit `system.initialized` marker // (openspec/specs/progressive-zone-disclosure/spec.md), not by any network row. db.insert(systemConfig).values({ key: 'network.dmz.subnet', value: '10.0.0.0/24' }).run(); db.insert(systemConfig).values({ key: 'ssh.public_key', value: 'ssh-rsa AAAA...' }).run(); expect(isSystemInitialized(db)).toBe(false); db.insert(systemConfig).values({ key: 'system.initialized', value: 'true' }).run(); expect(isSystemInitialized(db)).toBe(true); }); }); });