Files
dh-inspeccion-v2/api-v3/test/unit/mobile-inspector-integration.test.ts

44 lines
1.8 KiB
TypeScript

import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import test from 'node:test';
async function source(relativePath: string): Promise<string> {
return readFile(resolve(process.cwd(), 'src', relativePath), 'utf8');
}
function policyCalls(value: string): number {
return value.match(/assertMobileInspector\(principal\);/g)?.length ?? 0;
}
test('D5.1 applies the mobile-inspector policy to every field operation', async () => {
const [visits, acts, findings, evidence, closing] = await Promise.all([
source('inspection-visits/inspection-visits.service.ts'),
source('inspection-acts/inspection-acts.service.ts'),
source('inspection-findings/inspection-findings.service.ts'),
source('inspection-findings/inspection-evidence.service.ts'),
source('inspection-closing/inspection-closing.service.ts'),
]);
assert.equal(policyCalls(visits), 1);
assert.equal(policyCalls(acts), 3);
assert.equal(policyCalls(findings), 2);
assert.equal(policyCalls(evidence), 1);
assert.equal(policyCalls(closing), 7);
assert.match(evidence, /purpose === InspectionEvidencePurpose\.OBSERVATION/);
});
test('D5.1 leaves company follow-up outside the field-operation gate', async () => {
const findings = await source('inspection-findings/inspection-findings.service.ts');
const followUp = findings.slice(findings.indexOf('async updateFollowUp('));
assert.doesNotMatch(followUp, /assertMobileInspector/);
});
test('D5.1 migration grants operational permissions only to inspector', async () => {
const migration = await source(
'database/migrations/1787331600000-phase-d5-1-mobile-inspection-policy.ts',
);
assert.match(migration, /role\.code <> 'inspector'/);
assert.match(migration, /role\.code = 'inspector'/);
assert.doesNotMatch(migration, /inspection_findings\.follow_up/);
});