All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 6m12s
CI / Build container images (pull_request) Successful in 4m2s
CI / Auth e2e pack (pull_request) Successful in 8m29s
CI / Import/export fidelity gate (pull_request) Successful in 54s
CD / Build and push images (push) Successful in 31s
CD / Deploy to Test (push) Successful in 14s
CD / Smoke tests against Test (push) Successful in 1m29s
CD / Promote to Int (push) Successful in 14s
CI / Build container images (push) Has been skipped
CI / Lint, typecheck, test (push) Successful in 6m30s
CI / Auth e2e pack (push) Successful in 8m6s
CI / Import/export fidelity gate (push) Successful in 57s
The deployment declares through VS_NFD_MODE (off | marked | hidden | enforced, default off) how the application treats configuration that violates the VS-NfD reference profile — deploy-level like BACKUP_ALLOWED_TARGETS, so a compromised Site Admin cannot widen it. The catalog in shared (vs-nfd-profile.ts) is the single source of truth: every profile-relevant setting with a decidable compliant value, judgement calls in an explicit advisory list, and a fence test parsing the hardening guide's reference tables so neither can drift (pattern #201). The api evaluates the catalog against the typed settings registry and validated env and exposes mode + verdict on GET /admin/system/vs-nfd-profile; the admin settings view shows the card whenever the mode is not off. Display only — the treatments land with #244–#246 (ADR 0027, proposed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
60 lines
2.4 KiB
TypeScript
60 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
VS_NFD_PROFILE,
|
|
VS_NFD_PROFILE_ADVISORY,
|
|
describeCompliance,
|
|
isVsNfdCompliant,
|
|
vsNfdModeSchema,
|
|
} from './vs-nfd-profile';
|
|
|
|
describe('vsNfdModeSchema (issue #243)', () => {
|
|
it('accepts the four modes and rejects anything else', () => {
|
|
for (const mode of ['off', 'marked', 'hidden', 'enforced']) {
|
|
expect(vsNfdModeSchema.parse(mode)).toBe(mode);
|
|
}
|
|
expect(() => vsNfdModeSchema.parse('strict')).toThrow();
|
|
});
|
|
});
|
|
|
|
describe('isVsNfdCompliant', () => {
|
|
const entry = (compliance: (typeof VS_NFD_PROFILE)[number]['compliance']) =>
|
|
({ scope: 'instance', key: 'x', compliance, hardeningRef: '1.1' }) as const;
|
|
|
|
it('equals compares strictly — no truthiness shortcuts', () => {
|
|
expect(isVsNfdCompliant(entry({ kind: 'equals', value: false }), false)).toBe(true);
|
|
expect(isVsNfdCompliant(entry({ kind: 'equals', value: false }), 'false')).toBe(false);
|
|
expect(isVsNfdCompliant(entry({ kind: 'equals', value: 'closed' }), 'closed')).toBe(true);
|
|
expect(isVsNfdCompliant(entry({ kind: 'equals', value: 'closed' }), 'open')).toBe(false);
|
|
});
|
|
|
|
it('maxNumber bounds numeric values and rejects non-numbers', () => {
|
|
expect(isVsNfdCompliant(entry({ kind: 'maxNumber', value: 12 }), 12)).toBe(true);
|
|
expect(isVsNfdCompliant(entry({ kind: 'maxNumber', value: 12 }), 13)).toBe(false);
|
|
expect(isVsNfdCompliant(entry({ kind: 'maxNumber', value: 12 }), '2')).toBe(false);
|
|
});
|
|
|
|
it('nonEmpty requires actual text', () => {
|
|
expect(isVsNfdCompliant(entry({ kind: 'nonEmpty' }), 'Impressum')).toBe(true);
|
|
expect(isVsNfdCompliant(entry({ kind: 'nonEmpty' }), ' ')).toBe(false);
|
|
expect(isVsNfdCompliant(entry({ kind: 'nonEmpty' }), undefined)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('catalog shape', () => {
|
|
it('lists every key at most once per scope, disjoint from the advisory list', () => {
|
|
const keyOf = (e: { scope: string; key: string }) => `${e.scope}:${e.key}`;
|
|
const catalog = VS_NFD_PROFILE.map(keyOf);
|
|
const advisory = VS_NFD_PROFILE_ADVISORY.map(keyOf);
|
|
expect(new Set(catalog).size).toBe(catalog.length);
|
|
expect(new Set(advisory).size).toBe(advisory.length);
|
|
expect(catalog.filter((key) => advisory.includes(key))).toEqual([]);
|
|
});
|
|
|
|
it('describes every predicate for display', () => {
|
|
for (const entry of VS_NFD_PROFILE) {
|
|
expect(describeCompliance(entry.compliance)).not.toBe('');
|
|
}
|
|
});
|
|
});
|