Files
dh-inspeccion-v2/api-v3/test/unit/dashboard-service.test.ts
T
admin 35d4630581 F5 · Inventario operativo, territorio y catálogo autorizado (#25)
* fix(web): simplify inventory administration menu

* fix(web): remove legacy imports and function catalog routes

* fix(web): remove redundant inspections lifecycle legend

* feat(inventory): distinguish physical instances from structural records

* fix(dashboard): align inventory and act follow-up metrics

* fix(web): align dashboard summary contract

* fix(web): clarify dashboard act and report concepts

* feat(inventory): mark field-created records as real instances

* feat(inventory): map physical instance flag on asset entity

* fix(inventory): keep field yacimientos structural

* feat(inventory): classify future concrete instances at database level

* fix(inventory): count only installation and subinstallation instances

* feat(inventory): add authoritative F5 source snapshot

* feat(inventory): preload authoritative territory model

* feat(inventory): preload authoritative technical catalog

* fix(findings): use only authoritative F5 family catalog

* fix(inventory): preserve non-hierarchical operator snapshot compatibility

* feat(inventory): add inventory-only asset filter

* feat(inventory): add inventory-only tree filter

* feat(inventory): add inventory browser query contract

* feat(inventory): add area-owned inventory browser

* feat(inventory): expose area-owned inventory browser

* refactor(inventory): remove function catalog and add inventory browser

* fix(inventory): make operator relation temporal and non-owning

* feat(web): add inventory browser API client

* feat(inventory): extend inventory browser filters

* feat(inventory): add real inventory list endpoint logic

* feat(inventory): expose real inventory list

* feat(web): add real inventory list client

* refactor(web): make inventory hierarchy area-owned

* fix(web): show only real inventory instances

* fix(web): style act follow-up tabs and F5 inventory context

* fix(web): load F5 flow styles

* fix(inventory): apply area-owned operational guard on F5 up

* fix(inventory): treat company on asset as non-owning creation snapshot

* fix(inventory): resolve field inventory by area hierarchy, not company ownership

* fix(inventory): preserve custom catalog and apply authoritative universal findings

* fix(inventory): harden authoritative catalog migration checks

* fix(inventory): make authoritative territory preload safely reversible

* feat(inventory): allow independent company master creation

* fix(inventory): make guided creation area-owned and support companies

* feat(web): expose independent company master in inventory setup

* feat(web): create companies independently from physical inventory hierarchy

* fix(inventory): merge by physical area and preserve sealed documents

* test(inventory): lock F5 authoritative model and merge invariants

* feat(inventory): add family administration DTOs

* feat(inventory): administer installation and subinstallation classifications

* feat(inventory): expose family classification administration

* feat(web): add inventory classification administration API

* fix(web): configure finding applicability by inventory classification

* fix(web): redefine inventory configuration around hierarchy classifications and columns

* chore(release): identify F5 inventory model

* chore(release): bump API for F5 inventory model

* test(release): expect F5 health metadata

* chore(release): align WEB package with F5 inventory cut

* chore(release): expose F5 WEB phase

* test(dashboard): expect inspector activity and act follow-up metrics

* test(dashboard): route F5 summary query mocks explicitly

* ci: rehearse all migrations on clean PostGIS before merge

* ci: prove F5 migrations revert and reapply cleanly

* test(f5): align operational navigation contract

* test(f5): align operator lifecycle with area-owned inventory

* test(f5): make merge compatibility area-based

* test(f5): distinguish literal and normalized yacimiento counts

* test(f5): model normalized yacimiento collision explicitly

* ci(f5): bootstrap historical admin prerequisite in clean migration rehearsal

* ci(f5): bypass irreversible historical reset in clean rehearsal

* fix(f5): make territory SQL parameter types explicit

* fix(f5): guarantee canonical inventory hierarchy before territory preload

* ci(f5): include canonical hierarchy migration in rollback gate

* fix(f5): type relation backup markers explicitly

* fix(f5): make catalog SQL text parameter types explicit
2026-09-08 23:18:15 -03:00

56 lines
2.1 KiB
TypeScript

import { strict as assert } from 'node:assert';
import test from 'node:test';
import { DashboardService } from '../../src/dashboard/dashboard.service';
test('DashboardService returns F5 operational counts and inspector activity consistently', async () => {
const recent = [{
id: 'event-id',
occurredAt: new Date('2026-09-08T12:00:00.000Z'),
actorUsername: 'inspector1',
action: 'INSPECTION_STARTED',
entityType: 'inspection_visit',
entityId: 'visit-id',
}];
const manager = {
query: async (sql: string) => {
if (sql.includes('COUNT(*) FROM users')) {
return [{
activeUsers: '4', inactiveUsers: '2', activeSessions: '3',
totalAssets: '0', assetsNeedValidation: '0', assetsWithoutGeometry: '0', plannedInspections: '2',
openFindings: '8', actsInFollowUp: '6', findingsWithoutControlDate: '5', overdueControls: '2', controlsNext30Days: '3',
reportsWorking: '1', reportsOfficialized: '2', sealedActsWithoutReport: '4',
}];
}
if (sql.includes('FROM audit_events event')) return recent;
if (sql.includes('next_control_on AS "nextControlOn"')) return [];
throw new Error(`Unexpected DashboardService query in test: ${sql}`);
},
};
const dataSource = {
transaction: async (_isolation: string, operation: (value: typeof manager) => unknown) => operation(manager),
};
const result = await new DashboardService(dataSource as never).summary();
assert.deepEqual(result.counts, {
totalAssets: 0,
assetsNeedValidation: 0,
assetsWithoutGeometry: 0,
plannedInspections: 2,
activeUsers: 4,
inactiveUsers: 2,
activeSessions: 3,
openFindings: 8,
actsInFollowUp: 6,
findingsWithoutControlDate: 5,
overdueControls: 2,
controlsNext30Days: 3,
reportsWorking: 1,
reportsOfficialized: 2,
sealedActsWithoutReport: 4,
});
assert.deepEqual(result.recentInspectorActivity, recent);
assert.equal('recentAudit' in result, false);
assert.deepEqual(result.upcomingControls, []);
assert.equal(typeof result.generatedAt, 'string');
});