123 lines
4.3 KiB
TypeScript
123 lines
4.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
POLICY_EVALUATION_RULE_CATALOG,
|
|
policyEvaluationRuleCatalogValidationErrors,
|
|
type PolicyEvaluationRule,
|
|
type PolicyEvaluationRuleCatalog
|
|
} from '../../src/domain/policy-evaluation-rules';
|
|
|
|
function rule(overrides: Partial<PolicyEvaluationRule> = {}): PolicyEvaluationRule {
|
|
return {
|
|
version: 1,
|
|
id: 'synthetic-rule',
|
|
identityId: 'synthetic-identity',
|
|
deliveryMechanism: 'registry-policy',
|
|
contexts: [{
|
|
version: 1,
|
|
productFamily: 'Windows Server',
|
|
productVersion: '2022',
|
|
roles: ['Member Server'],
|
|
scopes: ['computer']
|
|
}],
|
|
baselineDisposition: 'explicit-recommendation',
|
|
comparator: { kind: 'equality' },
|
|
riskRule: { version: 1, id: 'synthetic-risk', severity: 'medium' },
|
|
dependencies: [],
|
|
...overrides
|
|
};
|
|
}
|
|
|
|
function catalog(rules: PolicyEvaluationRule[]): PolicyEvaluationRuleCatalog {
|
|
return {
|
|
version: 1,
|
|
id: 'synthetic-released-catalog',
|
|
catalog: POLICY_EVALUATION_RULE_CATALOG,
|
|
status: 'released',
|
|
rules
|
|
};
|
|
}
|
|
|
|
describe('policy evaluation rule catalog release validation', () => {
|
|
it('accepts distinct, fully typed released rules', () => {
|
|
expect(policyEvaluationRuleCatalogValidationErrors(catalog([
|
|
rule(),
|
|
rule({
|
|
id: 'domain-controller-rule',
|
|
contexts: [{
|
|
version: 1,
|
|
productFamily: 'Windows Server',
|
|
productVersion: '2022',
|
|
roles: ['Domain Controller'],
|
|
scopes: ['computer']
|
|
}]
|
|
})
|
|
]))).toEqual([]);
|
|
});
|
|
|
|
it.each([
|
|
[{ kind: 'enum', orderedValues: ['on'], direction: 'sideways' }],
|
|
[{ kind: 'bitmask', mode: 'contains-any' }],
|
|
[{ kind: 'set', mode: 'overlap' }],
|
|
[{ kind: 'audit-flags', mode: 'subset' }],
|
|
[{ kind: 'invented' }]
|
|
])('rejects an unsupported comparator contract', (comparator) => {
|
|
const errors = policyEvaluationRuleCatalogValidationErrors(catalog([
|
|
rule({ comparator: comparator as PolicyEvaluationRule['comparator'] })
|
|
]));
|
|
expect(errors).toContain('Eine ausdrueckliche Baselineempfehlung benoetigt Comparator und Risikoregel.');
|
|
});
|
|
|
|
it('rejects unsupported runtime enum values at the release boundary', () => {
|
|
const invalid = rule({
|
|
deliveryMechanism: 'invented' as PolicyEvaluationRule['deliveryMechanism'],
|
|
riskRule: { version: 1, id: 'synthetic-risk', severity: 'urgent' as 'medium' }
|
|
});
|
|
const errors = policyEvaluationRuleCatalogValidationErrors(catalog([invalid]));
|
|
expect(errors).toEqual(expect.arrayContaining([
|
|
'Der Policy-Evaluation-Regelkatalog enthaelt eine ungueltige oder doppelte Regel.',
|
|
'Eine ausdrueckliche Baselineempfehlung benoetigt Comparator und Risikoregel.'
|
|
]));
|
|
});
|
|
|
|
it('rejects selectors and separate rules that can match the same context', () => {
|
|
const overlappingContext = {
|
|
version: 1 as const,
|
|
productFamily: 'windows-server',
|
|
productVersion: '2022',
|
|
roles: ['any'],
|
|
scopes: ['computer'] as Array<'computer' | 'user'>
|
|
};
|
|
const errors = policyEvaluationRuleCatalogValidationErrors(catalog([
|
|
rule({ contexts: [rule().contexts[0], overlappingContext] }),
|
|
rule({ id: 'ambiguous-rule', contexts: [overlappingContext] })
|
|
]));
|
|
expect(errors).toEqual(expect.arrayContaining([
|
|
'Eine Policy-Evaluation-Regel besitzt ueberlappende Kontextselektoren.',
|
|
'Der freigegebene Policy-Evaluation-Regelkatalog enthaelt mehrdeutige Kontextregeln.'
|
|
]));
|
|
});
|
|
|
|
it('rejects conflicting reusable risk and dependency definitions', () => {
|
|
const dependency = {
|
|
version: 1 as const,
|
|
id: 'shared-dependency',
|
|
identityId: 'dependency-target',
|
|
deliveryMechanism: 'registry-policy' as const,
|
|
kind: 'prerequisite' as const
|
|
};
|
|
const errors = policyEvaluationRuleCatalogValidationErrors(catalog([
|
|
rule({ dependencies: [dependency] }),
|
|
rule({
|
|
id: 'separate-context-rule',
|
|
contexts: [{ ...rule().contexts[0], roles: ['Domain Controller'] }],
|
|
riskRule: { version: 1, id: 'synthetic-risk', severity: 'high' },
|
|
dependencies: [{ ...dependency, kind: 'override' }]
|
|
})
|
|
]));
|
|
expect(errors).toEqual(expect.arrayContaining([
|
|
'Eine Risikoregel besitzt widerspruechliche Definitionen.',
|
|
'Eine Abhaengigkeitsregel besitzt widerspruechliche Definitionen.'
|
|
]));
|
|
});
|
|
});
|