65 lines
3.7 KiB
TypeScript
65 lines
3.7 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { readFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
|
|
const read = (path: string) => readFileSync(resolve(process.cwd(), path), 'utf8');
|
|
const migration = read('src/database/migrations/1788976800000-phase-d5-4-contextual-finding-catalog.ts');
|
|
const catalogService = read('src/inspection-findings/finding-catalog.service.ts');
|
|
const catalogController = read('src/inspection-findings/finding-catalog.controller.ts');
|
|
const findingsService = read('src/inspection-findings/inspection-findings.service.ts');
|
|
const createFindingDto = read('src/inspection-findings/dto/create-inspection-finding.dto.ts');
|
|
const catalogItemDto = read('src/inspection-findings/dto/create-finding-catalog-item.dto.ts');
|
|
const closingService = read('src/inspection-closing/inspection-closing.service.ts');
|
|
const wordBuilder = read('src/inspection-reports/inspection-report-word-builder.ts');
|
|
|
|
test('D5.4 models type applicability and concrete Inventory exceptions separately', () => {
|
|
assert.match(migration, /CREATE TABLE finding_catalog_asset_type_profiles/);
|
|
assert.match(migration, /CREATE TABLE finding_catalog_item_asset_types/);
|
|
assert.match(migration, /CREATE TABLE finding_catalog_asset_overrides/);
|
|
assert.match(catalogService, /replaceAssetTypeSelection/);
|
|
assert.match(catalogService, /replaceAssetSelection/);
|
|
assert.match(catalogService, /typeDefaultEnabled/);
|
|
});
|
|
|
|
test('D5.4 exposes only applicable catalog items and enforces the same rule on field creation', () => {
|
|
assert.match(catalogController, /@Get\('applicable\/:assetId'\)/);
|
|
assert.match(catalogService, /listApplicableForAsset/);
|
|
assert.match(findingsService, /FINDING_CATALOG_ITEM_NOT_APPLICABLE/);
|
|
assert.match(findingsService, /finding_catalog_asset_type_profiles profile/);
|
|
assert.match(findingsService, /finding_catalog_asset_overrides override/);
|
|
assert.match(findingsService, /await this\.requireCatalogItem\(manager, finding\.catalogItemId, dto\.assetId\)/);
|
|
});
|
|
|
|
test('D5.4 stores suggested and actual severity independently on the 1 to 10 scale', () => {
|
|
assert.match(migration, /suggested_severity smallint/);
|
|
assert.match(migration, /severity smallint/);
|
|
assert.match(migration, /BETWEEN 1 AND 10/);
|
|
assert.match(catalogItemDto, /@Min\(1\)/);
|
|
assert.match(catalogItemDto, /@Max\(10\)/);
|
|
assert.match(createFindingDto, /severity\?: number/);
|
|
assert.match(findingsService, /suggestedSeverity: catalog\?\.suggestedSeverity/);
|
|
assert.match(findingsService, /severity: dto\.severity \?\? catalog\?\.suggestedSeverity/);
|
|
assert.match(closingService, /finding\.severity/);
|
|
assert.match(wordBuilder, /'Gravedad'/);
|
|
});
|
|
|
|
test('D5.4 turns OTHER into an office proposal without rewriting the original finding', () => {
|
|
assert.match(migration, /CREATE TABLE finding_catalog_proposals/);
|
|
assert.match(findingsService, /INSERT INTO finding_catalog_proposals/);
|
|
assert.match(catalogService, /FINDING_CATALOG_PROPOSAL_ALREADY_REVIEWED/);
|
|
assert.match(catalogService, /status = 'MATCHED'/);
|
|
assert.match(catalogService, /status = 'REJECTED'/);
|
|
assert.doesNotMatch(catalogService, /UPDATE inspection_findings SET catalog_item_id/);
|
|
});
|
|
|
|
test('D5.4 keeps contextual catalog administration in office permissions and audited routes', () => {
|
|
assert.match(catalogController, /@Put\('asset-types\/:assetTypeId\/selection'\)/);
|
|
assert.match(catalogController, /@Put\('assets\/:assetId\/selection'\)/);
|
|
assert.match(catalogController, /@Get\('proposals'\)/);
|
|
assert.match(catalogController, /finding_catalog\.manage/);
|
|
assert.match(catalogService, /FINDING_CATALOG_TYPE_APPLICABILITY_UPDATED/);
|
|
assert.match(catalogService, /FINDING_CATALOG_ASSET_SELECTION_UPDATED/);
|
|
assert.match(catalogService, /FINDING_CATALOG_PROPOSAL_MATCHED/);
|
|
});
|