import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { assertCircuitGroupSubtreeSnapshot, summarizeCircuitGroupDeletion, type CircuitGroupSubtreeSnapshot, } from "../src/domain/models/circuit-group-subtree-snapshot.model.js"; function createSnapshot(): CircuitGroupSubtreeSnapshot { return { group: { id: "group-1", circuitListId: "list-1", key: "lighting", displayName: "Beleuchtung 1", prefix: "-1F1.", sortOrder: 10, category: "lighting", groupNumber: 1, }, components: [ { component: { id: "fuse-1", circuitListId: "list-1", sectionId: "group-1", equipmentIdentifier: "-1F1.0", name: "Vorsicherung", role: "group_upstream_protection", placement: "group", sortOrder: 10, }, protectionDevice: { componentId: "fuse-1", type: "D02", ratedCurrentA: 35, fuseUtilizationCategory: "gG", tripCharacteristic: null, rcdType: null, ratedResidualCurrentMa: null, }, }, { component: { id: "rcd-1", circuitListId: "list-1", sectionId: "group-1", equipmentIdentifier: "-1Q1.0", name: "Gruppen-FI", role: "group_residual_current_protection", placement: "group", sortOrder: 20, }, protectionDevice: { componentId: "rcd-1", type: "FI", ratedCurrentA: 40, fuseUtilizationCategory: null, tripCharacteristic: null, rcdType: "A", ratedResidualCurrentMa: 30, }, }, ], circuits: [ { circuit: { id: "circuit-1", circuitListId: "list-1", sectionId: "group-1", equipmentIdentifier: "-1F1.1", displayName: "Beleuchtung", sortOrder: 10, cableType: null, cableCrossSection: null, cableLength: null, rcdAssignment: null, terminalDesignation: null, voltage: 230, controlRequirement: null, status: null, isReserve: false, remark: null, deviceRows: [ { id: "row-1", circuitId: "circuit-1", linkedProjectDeviceId: "device-1", sortOrder: 10, name: "Leuchte", displayName: "Leuchte Flur", phaseType: "single_phase", connectionKind: null, costGroup: "440", category: "Licht", level: "EG", roomId: "room-1", roomNumberSnapshot: "001", roomNameSnapshot: "Flur", quantity: 2, powerPerUnit: 0.03, simultaneityFactor: 1, cosPhi: 0.95, remark: null, overriddenFields: "[\"displayName\"]", }, ], }, protectionDevice: { circuitId: "circuit-1", type: "LS", ratedCurrentA: 10, fuseUtilizationCategory: null, tripCharacteristic: "B", rcdType: null, ratedResidualCurrentMa: null, }, }, ], }; } describe("circuit-group subtree snapshot", () => { it("validates complete relations and derives the deletion warning summary", () => { const snapshot = createSnapshot(); assert.doesNotThrow(() => assertCircuitGroupSubtreeSnapshot(snapshot) ); assert.deepEqual(summarizeCircuitGroupDeletion(snapshot), { hasUpstreamProtection: true, hasResidualCurrentProtection: true, circuitCount: 1, deviceRowCount: 1, }); }); it("rejects foreign children, duplicate BMKs and invalid protection", () => { const foreign = createSnapshot(); foreign.circuits[0].circuit.sectionId = "group-2"; assert.throws( () => assertCircuitGroupSubtreeSnapshot(foreign), /ownership/ ); const duplicate = createSnapshot(); duplicate.circuits[0].circuit.equipmentIdentifier = "-1F1.0"; assert.throws( () => assertCircuitGroupSubtreeSnapshot(duplicate), /duplicates/ ); const invalidProtection = createSnapshot(); invalidProtection.circuits[0].protectionDevice = { ...invalidProtection.circuits[0].protectionDevice!, type: "AFDD", ratedResidualCurrentMa: 30, }; assert.throws( () => assertCircuitGroupSubtreeSnapshot(invalidProtection), /configuration/ ); }); it("preserves device link and override metadata", () => { const row = createSnapshot().circuits[0].circuit.deviceRows[0]; assert.equal(row.linkedProjectDeviceId, "device-1"); assert.equal(row.overriddenFields, "[\"displayName\"]"); }); });