Files
leistungsbilanz-ts/tests/circuit-group-subtree-snapshot.test.ts
T

170 lines
4.8 KiB
TypeScript

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\"]");
});
});