'use strict'; /** * Regression tests for config-schema.js KNOWN_KEYS — DC-091. * * Bug: license-manager.js persists config.licenseBackup (activation * restore-on-restart) and src/config/migrations.js stamps config._version, * but neither key was in KNOWN_KEYS — so every startup logged * `Unknown config key "licenseBackup" / "_version" — possible typo?` * false positives (verified in live dashcaddy-api container logs, * 2026-08-22T23:53:54Z restart). * * These tests pin: (1) the live production config key set validates with * zero unknown-key warnings, (2) genuine typos still warn, (3) the schema * stays in sync with the first-party writer keys. */ const { validateConfig } = require('../src/utilities/config-schema'); describe('config-schema KNOWN_KEYS vs first-party writers (DC-091)', () => { // Exact key set of the live production config.json (DNS2, verified // 2026-08-23). If a new key appears here, teach KNOWN_KEYS about it — // or fix the writer if it's a typo. const LIVE_CONFIG_KEYS = [ '_version', 'configurationType', 'customFavicon', 'customLogo', 'dashboardHost', 'dashboardTitle', 'dns', 'dnsServers', 'language', 'license', 'licenseBackup', 'logoPosition', 'pylon', 'setupComplete', 'timestamp', 'tld', 'updatedAt' ]; test('live production config key set produces zero unknown-key warnings', () => { const config = {}; for (const key of LIVE_CONFIG_KEYS) { // Minimal valid-ish values; validateConfig only cares about shape // for these keys, and unknown-key detection is the target here. config[key] = key === '_version' ? 2 : (key === 'dnsServers' ? {} : 'x'); } const result = validateConfig(config); const unknownWarnings = result.warnings.filter((w) => w.includes('Unknown config key')); expect(unknownWarnings).toEqual([]); }); test('licenseBackup and _version (first-party writer keys) do not warn', () => { const result = validateConfig({ licenseBackup: { code: 'DC-...' }, _version: 2 }); expect(result.warnings).toEqual([]); }); test('genuine typos still warn (guard against over-allowing)', () => { const result = validateConfig({ dashboadTitle: 'typo' }); expect(result.warnings).toEqual([ 'Unknown config key "dashboadTitle" — possible typo?' ]); }); test('KNOWN_KEYS stays in sync with license-manager writer keys', () => { // license-manager writes config.licenseBackup and config.license — both // must be recognized. We assert via validateConfig (public surface) // rather than importing the private KNOWN_KEYS array. const result = validateConfig({ license: { code: 'DC-...' }, licenseBackup: { code: 'DC-...' } }); expect(result.warnings.filter((w) => w.includes('Unknown config key'))).toEqual([]); }); }); describe('config-schema sync guard: migrations writer', () => { test('_version is recognized at every migration version value', () => { // migrations.js bumps _version 0→1→2; the key itself must never warn. for (const v of [0, 1, 2, 99]) { const result = validateConfig({ _version: v }); expect(result.warnings).toEqual([]); } }); });