79 lines
4.1 KiB
TypeScript
79 lines
4.1 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
import test from 'node:test';
|
|
|
|
const api = (path: string) => readFileSync(resolve(process.cwd(), path), 'utf8');
|
|
const web = (path: string) => readFileSync(resolve(process.cwd(), '..', 'web-v2', path), 'utf8');
|
|
|
|
test('F6.1 field Inventory is bounded by the frozen Yacimiento scope', () => {
|
|
const source = api('src/inspection-visits/field-inventory.service.ts');
|
|
|
|
assert.match(source, /COALESCE\(visit\.scope_asset_id, visit\.operational_area_id\) AS "scopeAssetId"/);
|
|
assert.match(source, /const effectiveParentId = parentId \?\? context\.scopeAssetId/);
|
|
assert.match(source, /const parentId = dto\.parentId \?\? context\.scopeAssetId/);
|
|
assert.match(source, /\[parentId, context\.scopeAssetId\]/);
|
|
assert.match(source, /\[assetId, context\.scopeAssetId\]/);
|
|
assert.match(source, /AS "insideScope"/);
|
|
assert.doesNotMatch(source, /insideArea/);
|
|
});
|
|
|
|
test('F6.1 field Findings reject Inventory outside the frozen Yacimiento scope', () => {
|
|
const source = api('src/inspection-visits/field-findings.service.ts');
|
|
|
|
assert.match(source, /COALESCE\(visit\.scope_asset_id, visit\.operational_area_id\) AS "scopeAssetId"/);
|
|
assert.match(source, /AS "insideScope"/);
|
|
assert.match(source, /if \(!row\.insideScope\)/);
|
|
assert.match(source, /Yacimiento definido como alcance/);
|
|
assert.doesNotMatch(source, /AS "insideArea"/);
|
|
});
|
|
|
|
test('F6.1 planning preserves Yacimiento and never validates Inventory ownership from Company snapshot', () => {
|
|
const source = api('src/inspection-visits/inspection-visits.service.ts');
|
|
|
|
assert.match(source, /const nextScope = dto\.scopeAssetId === undefined \? visit\.scopeAssetId : dto\.scopeAssetId/);
|
|
assert.match(source, /validateInspectionPlanningScope\(manager, nextAreaId, nextScope\)/);
|
|
assert.match(source, /visit\.scopeAssetId \?\? visit\.operationalAreaId/);
|
|
assert.match(source, /visit\.plannedStartAt,/);
|
|
assert.doesNotMatch(source, /visit\.scopeAssetId = nextAreaId/);
|
|
assert.doesNotMatch(source, /assertAssetsMatchContext/);
|
|
assert.doesNotMatch(source, /assertCurrentAssetsMatchContext/);
|
|
assert.doesNotMatch(source, /asset\.operator_company_id IS DISTINCT FROM/);
|
|
});
|
|
|
|
test('F6.1 creation selects actionable checklist Inventory automatically', () => {
|
|
const source = api('src/inspection-visits/inspection-planning-create.service.ts');
|
|
|
|
assert.match(source, /INSERT INTO inspection_visit_assets/);
|
|
assert.match(source, /COMPANY_OVERDUE','VERIFICATION_OVERDUE','UPCOMING_CONTROL/);
|
|
assert.match(source, /'AUTO_INCLUDED'/);
|
|
});
|
|
|
|
test('F6.1 operator choices are resolved at the planned timestamp', () => {
|
|
const hierarchy = api('src/inspection-visits/inspection-planning-hierarchy.service.ts');
|
|
const controller = api('src/inspection-visits/inspection-visits.controller.ts');
|
|
const createPage = web('src/pages/InspectionVisitCreateF61Page.tsx');
|
|
|
|
assert.match(hierarchy, /operatorsForArea\([\s\S]*at\?: string/);
|
|
assert.match(hierarchy, /relation\.valid_from <= \$2::timestamptz/);
|
|
assert.match(hierarchy, /relation\.valid_until > \$2::timestamptz/);
|
|
assert.match(controller, /@Query\('at'\) at\?: string/);
|
|
assert.match(createPage, /operators\?at=\$\{at\}/);
|
|
assert.match(createPage, /\[areaId, plannedStartAt\]/);
|
|
});
|
|
|
|
test('F6.1 WEB keeps Area and Yacimiento as separate concepts and freezes context after creation', () => {
|
|
const source = web('src/pages/InspectionVisitEditorF4Page.tsx');
|
|
|
|
assert.doesNotMatch(source, /<span>Área \/ Yacimiento<\/span>/);
|
|
assert.match(source, /<span>Área<\/span>/);
|
|
assert.match(source, /<span>Yacimiento<\/span>/);
|
|
assert.match(source, /<span>Operadora<\/span>/);
|
|
assert.match(source, /visit\.operationalArea\.name[\s\S]{0,160}readOnly/);
|
|
assert.match(source, /visit\.scopeAsset\.name[\s\S]{0,160}readOnly/);
|
|
assert.match(source, /visit\.operatorCompany\.name[\s\S]{0,160}readOnly/);
|
|
assert.doesNotMatch(source, /updateInspectionVisit\(id, \{[\s\S]{0,300}scopeAssetId:/);
|
|
assert.doesNotMatch(source, /updateInspectionVisit\(id, \{[\s\S]{0,300}operationalAreaId:/);
|
|
assert.doesNotMatch(source, /updateInspectionVisit\(id, \{[\s\S]{0,300}operatorCompanyId:/);
|
|
});
|