184 lines
5.0 KiB
JavaScript
184 lines
5.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
|
|
import defaultConfig from '../src/config/defaults.mjs';
|
|
import {
|
|
normalizeContinuityConfig,
|
|
validateContinuityConfig,
|
|
} from '../src/config/schema.mjs';
|
|
|
|
function test(name, fn) {
|
|
try {
|
|
fn();
|
|
console.log(`ok - ${name}`);
|
|
} catch (error) {
|
|
console.error(`not ok - ${name}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
test('accepts default config', () => {
|
|
const result = validateContinuityConfig(defaultConfig);
|
|
assert.equal(result.ok, true);
|
|
assert.deepEqual(result.errors, []);
|
|
assert.deepEqual(result.normalizedConfig, defaultConfig);
|
|
});
|
|
|
|
test('accepts custom receipt directory', () => {
|
|
const result = validateContinuityConfig({
|
|
receiptDir: 'tmp/continuity-receipts',
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
assert.equal(result.normalizedConfig.receiptDir, 'tmp/continuity-receipts');
|
|
assert.deepEqual(result.errors, []);
|
|
});
|
|
|
|
test('accepts custom legal terminal states list', () => {
|
|
const result = validateContinuityConfig({
|
|
legalTerminalStates: ['waiting_user', 'blocked', 'done_elsewhere'],
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
assert.deepEqual(result.normalizedConfig.legalTerminalStates, ['waiting_user', 'blocked', 'done_elsewhere']);
|
|
});
|
|
|
|
test('normalizes missing fields from defaults', () => {
|
|
const normalized = normalizeContinuityConfig({
|
|
debug: true,
|
|
});
|
|
|
|
assert.equal(normalized.debug, true);
|
|
assert.equal(normalized.enabled, defaultConfig.enabled);
|
|
assert.equal(normalized.receiptDir, defaultConfig.receiptDir);
|
|
assert.deepEqual(normalized.legalTerminalStates, defaultConfig.legalTerminalStates);
|
|
assert.notEqual(normalized.legalTerminalStates, defaultConfig.legalTerminalStates);
|
|
assert.equal(normalized.adapter.genericPreflight.enabled, true);
|
|
});
|
|
|
|
test('normalizes generic preflight adapter block label', () => {
|
|
const normalized = normalizeContinuityConfig({
|
|
adapter: {
|
|
genericPreflight: {
|
|
injectBlockLabel: ' CUSTOM_GENERIC_GATE ',
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(normalized.adapter.genericPreflight.injectBlockLabel, 'CUSTOM_GENERIC_GATE');
|
|
});
|
|
|
|
test('rejects non-array legalTerminalStates', () => {
|
|
const result = validateContinuityConfig({
|
|
legalTerminalStates: 'waiting_user',
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /legalTerminalStates/);
|
|
assert.match(result.errors.join('\n'), /array/i);
|
|
});
|
|
|
|
test('rejects invalid legalTerminalStates entry types', () => {
|
|
const result = validateContinuityConfig({
|
|
legalTerminalStates: ['waiting_user', 123],
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /legalTerminalStates\[1\]/);
|
|
assert.match(result.errors.join('\n'), /string/i);
|
|
});
|
|
|
|
test('rejects empty receiptDir', () => {
|
|
const result = validateContinuityConfig({
|
|
receiptDir: ' ',
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /receiptDir/);
|
|
});
|
|
|
|
test('rejects malformed adapter.forceRecall shape', () => {
|
|
const result = validateContinuityConfig({
|
|
adapter: {
|
|
forceRecall: false,
|
|
},
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /adapter\.forceRecall/);
|
|
});
|
|
|
|
test('rejects malformed adapter.genericPreflight shape', () => {
|
|
const result = validateContinuityConfig({
|
|
adapter: {
|
|
genericPreflight: false,
|
|
},
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /adapter\.genericPreflight/);
|
|
});
|
|
|
|
test('rejects malformed adapter.forceRecall.enabled type', () => {
|
|
const result = validateContinuityConfig({
|
|
adapter: {
|
|
forceRecall: {
|
|
enabled: 'yes',
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /adapter\.forceRecall\.enabled/);
|
|
});
|
|
|
|
test('rejects malformed adapter.forceRecall.injectBlockLabel type', () => {
|
|
const result = validateContinuityConfig({
|
|
adapter: {
|
|
forceRecall: {
|
|
injectBlockLabel: 42,
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /injectBlockLabel/);
|
|
});
|
|
|
|
test('rejects malformed adapter.genericPreflight.enabled type', () => {
|
|
const result = validateContinuityConfig({
|
|
adapter: {
|
|
genericPreflight: {
|
|
enabled: 'yes',
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /adapter\.genericPreflight\.enabled/);
|
|
});
|
|
|
|
test('rejects malformed adapter.genericPreflight.injectBlockLabel type', () => {
|
|
const result = validateContinuityConfig({
|
|
adapter: {
|
|
genericPreflight: {
|
|
injectBlockLabel: 42,
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /adapter\.genericPreflight\.injectBlockLabel/);
|
|
});
|
|
|
|
test('rejects unknown top-level key', () => {
|
|
const result = validateContinuityConfig({
|
|
unexpected: true,
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.errors.join('\n'), /unknown/i);
|
|
assert.match(result.errors.join('\n'), /unexpected/);
|
|
});
|
|
|
|
console.log('continuity.config.test.mjs PASS');
|