F2.3: probar contrato de Hallazgos desde Inventario
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import 'reflect-metadata';
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { validate } from 'class-validator';
|
||||
import { REQUIRED_PERMISSIONS_KEY } from '../../src/authorization/decorators/require-permissions.decorator';
|
||||
import { CreateFieldFindingDto } from '../../src/inspection-visits/dto/create-field-finding.dto';
|
||||
import { FieldFindingsController } from '../../src/inspection-visits/field-findings.controller';
|
||||
|
||||
function permissions(method: string): string[] {
|
||||
const controller = FieldFindingsController.prototype;
|
||||
const handler = controller[method as keyof typeof controller];
|
||||
return Reflect.getMetadata(REQUIRED_PERMISSIONS_KEY, handler) as string[];
|
||||
}
|
||||
|
||||
test('F2.3 mantiene los Hallazgos de campo bajo ejecución móvil y permisos explícitos', () => {
|
||||
assert.deepEqual(permissions('options'), ['inspection_findings.create', 'inspections.execute']);
|
||||
assert.deepEqual(permissions('list'), ['inspection_findings.read', 'inspections.execute']);
|
||||
assert.deepEqual(permissions('create'), ['inspection_findings.create', 'inspections.execute']);
|
||||
});
|
||||
|
||||
test('F2.3 exige descripción y título cuando el inspector usa OTROS', async () => {
|
||||
const dto = plainToInstance(CreateFieldFindingDto, {
|
||||
description: '',
|
||||
catalogItemId: null,
|
||||
customTitle: '',
|
||||
});
|
||||
const errors = await validate(dto);
|
||||
const properties = new Set(errors.map((error) => error.property));
|
||||
assert.equal(properties.has('description'), true);
|
||||
assert.equal(properties.has('customTitle'), true);
|
||||
});
|
||||
|
||||
test('F2.3 vuelve a validar contexto, selección y GPS+foto en servidor antes del Hallazgo', () => {
|
||||
const source = readFileSync('src/inspection-visits/field-findings.service.ts', 'utf8');
|
||||
assert.match(source, /assertMobileInspector\(principal\)/);
|
||||
assert.match(source, /row\.visitStatus !== 'IN_PROGRESS'/);
|
||||
assert.match(source, /FIELD_FINDING_INSPECTOR_NOT_ASSIGNED/);
|
||||
assert.match(source, /FIELD_FINDING_INVENTORY_OUTSIDE_CONTEXT/);
|
||||
assert.match(source, /FIELD_FINDING_INVENTORY_NOT_SELECTED/);
|
||||
assert.match(source, /hasGeometry && creationGpsCaptured && fieldPhotoCount > 0/);
|
||||
assert.match(source, /FIELD_FINDING_CAPTURE_REQUIRED/);
|
||||
});
|
||||
|
||||
test('F2.3 resuelve exactamente el Acta DRAFT actual y no vuelve a la regla de un Acta por inspección', () => {
|
||||
const source = readFileSync('src/inspection-visits/field-findings.service.ts', 'utf8');
|
||||
assert.match(source, /FROM inspection_acts/);
|
||||
assert.match(source, /status = 'DRAFT'/);
|
||||
assert.match(source, /LIMIT 2/);
|
||||
assert.match(source, /FIELD_FINDING_DRAFT_ACT_REQUIRED/);
|
||||
assert.match(source, /FIELD_FINDING_MULTIPLE_DRAFT_ACTS/);
|
||||
});
|
||||
|
||||
test('F2.3 reutiliza catálogo contextual y creación canónica, conserva OTROS y permite varios Hallazgos', () => {
|
||||
const fieldSource = readFileSync('src/inspection-visits/field-findings.service.ts', 'utf8');
|
||||
const catalogSource = readFileSync('src/inspection-findings/finding-catalog.service.ts', 'utf8');
|
||||
const findingSource = readFileSync('src/inspection-findings/inspection-findings.service.ts', 'utf8');
|
||||
|
||||
assert.match(fieldSource, /this\.catalog\.listApplicableForAsset\(assetId, \{\}\)/);
|
||||
assert.match(fieldSource, /this\.findings\.create\(act\.id, payload, principal, request\)/);
|
||||
assert.match(fieldSource, /canAddAnother: true/);
|
||||
assert.match(catalogSource, /code: 'OTHER'/);
|
||||
assert.match(catalogSource, /label: 'OTROS'/);
|
||||
assert.match(findingSource, /finding_catalog_proposals/);
|
||||
assert.match(findingSource, /PENDING/);
|
||||
});
|
||||
Reference in New Issue
Block a user