Model complete distribution board subtrees
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
updateDistributionBoardComponentSnapshot,
|
||||
} from "../src/frontend/utils/distribution-board-component-editing.js";
|
||||
import "./distribution-board-component-structure-project-command.repository.test.js";
|
||||
import "./distribution-board-subtree.test.js";
|
||||
|
||||
describe("distribution board component catalog", () => {
|
||||
it("defines the agreed component roles and placement zones", () => {
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
import {
|
||||
assertDistributionBoardSubtreeSnapshot,
|
||||
cloneDistributionBoardSubtree,
|
||||
type DistributionBoardSubtreeSnapshot,
|
||||
} from "../src/domain/models/distribution-board-subtree-snapshot.model.js";
|
||||
import {
|
||||
createDistributionBoardDeleteSubtreeProjectCommand,
|
||||
createDistributionBoardInsertSubtreeProjectCommand,
|
||||
} from "../src/domain/models/distribution-board-subtree-project-command.model.js";
|
||||
|
||||
function createSnapshot(): DistributionBoardSubtreeSnapshot {
|
||||
return {
|
||||
distributionBoard: {
|
||||
id: "board-1",
|
||||
projectId: "project-1",
|
||||
name: "UV 1",
|
||||
floorId: "floor-1",
|
||||
supplyType: "AV",
|
||||
simultaneityFactor: 0.8,
|
||||
},
|
||||
circuitList: {
|
||||
id: "list-1",
|
||||
projectId: "project-1",
|
||||
distributionBoardId: "board-1",
|
||||
name: "UV 1 Stromkreisliste",
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
id: "section-1",
|
||||
circuitListId: "list-1",
|
||||
key: "lighting",
|
||||
displayName: "Beleuchtung 1",
|
||||
prefix: "-1F1.",
|
||||
sortOrder: 10,
|
||||
category: "lighting",
|
||||
groupNumber: 1,
|
||||
},
|
||||
],
|
||||
components: [
|
||||
{
|
||||
component: {
|
||||
id: "main-1",
|
||||
circuitListId: "list-1",
|
||||
sectionId: null,
|
||||
equipmentIdentifier: "-Q0",
|
||||
name: "Hauptschalter",
|
||||
role: "main_switch",
|
||||
placement: "header",
|
||||
sortOrder: 10,
|
||||
},
|
||||
protectionDevice: null,
|
||||
},
|
||||
{
|
||||
component: {
|
||||
id: "rcd-1",
|
||||
circuitListId: "list-1",
|
||||
sectionId: "section-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: [
|
||||
{
|
||||
id: "circuit-1",
|
||||
circuitListId: "list-1",
|
||||
sectionId: "section-1",
|
||||
equipmentIdentifier: "-1F1.1",
|
||||
displayName: "Licht",
|
||||
sortOrder: 10,
|
||||
protectionType: null,
|
||||
protectionRatedCurrent: null,
|
||||
protectionCharacteristic: null,
|
||||
cableType: "NYM-J",
|
||||
cableCrossSection: "3x1,5 mm²",
|
||||
cableLength: 10,
|
||||
rcdAssignment: null,
|
||||
terminalDesignation: null,
|
||||
voltage: 230,
|
||||
controlRequirement: null,
|
||||
status: null,
|
||||
isReserve: false,
|
||||
remark: null,
|
||||
deviceRows: [
|
||||
{
|
||||
id: "row-1",
|
||||
circuitId: "circuit-1",
|
||||
linkedProjectDeviceId: "device-1",
|
||||
legacyConsumerId: "legacy-1",
|
||||
sortOrder: 10,
|
||||
name: "Leuchte",
|
||||
displayName: "Leuchte",
|
||||
phaseType: "single_phase",
|
||||
connectionKind: null,
|
||||
costGroup: null,
|
||||
category: null,
|
||||
level: null,
|
||||
roomId: "room-1",
|
||||
roomNumberSnapshot: "1.01",
|
||||
roomNameSnapshot: "Büro",
|
||||
quantity: 1,
|
||||
powerPerUnit: 0.1,
|
||||
simultaneityFactor: 1,
|
||||
cosPhi: 0.9,
|
||||
remark: null,
|
||||
overriddenFields: null,
|
||||
},
|
||||
],
|
||||
protectionDevice: {
|
||||
circuitId: "circuit-1",
|
||||
type: "LS",
|
||||
ratedCurrentA: 10,
|
||||
fuseUtilizationCategory: null,
|
||||
tripCharacteristic: "B",
|
||||
rcdType: null,
|
||||
ratedResidualCurrentMa: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
describe("distribution-board subtree snapshot", () => {
|
||||
it("validates complete populated board structures and commands", () => {
|
||||
const snapshot = createSnapshot();
|
||||
assert.doesNotThrow(() =>
|
||||
assertDistributionBoardSubtreeSnapshot(snapshot)
|
||||
);
|
||||
assert.equal(
|
||||
createDistributionBoardInsertSubtreeProjectCommand(snapshot).type,
|
||||
"distribution-board.insert-subtree"
|
||||
);
|
||||
assert.equal(
|
||||
createDistributionBoardDeleteSubtreeProjectCommand(snapshot).type,
|
||||
"distribution-board.delete-subtree"
|
||||
);
|
||||
});
|
||||
|
||||
it("clones every owned id while preserving project links and values", () => {
|
||||
const ids = Array.from({ length: 6 }, (_, index) => `new-${index + 1}`);
|
||||
const clone = cloneDistributionBoardSubtree(
|
||||
createSnapshot(),
|
||||
"UV 1 Kopie",
|
||||
() => ids.shift()!
|
||||
);
|
||||
|
||||
assert.equal(clone.distributionBoard.id, "new-1");
|
||||
assert.equal(clone.circuitList.id, "new-1");
|
||||
assert.equal(clone.distributionBoard.name, "UV 1 Kopie");
|
||||
assert.equal(clone.circuitList.name, "UV 1 Kopie Stromkreisliste");
|
||||
assert.equal(clone.sections[0].id, "new-2");
|
||||
assert.equal(clone.circuits[0].id, "new-3");
|
||||
assert.equal(clone.components[0].component.id, "new-4");
|
||||
assert.equal(clone.components[1].component.id, "new-5");
|
||||
assert.equal(clone.components[1].component.sectionId, "new-2");
|
||||
assert.equal(clone.components[1].protectionDevice?.componentId, "new-5");
|
||||
assert.equal(clone.circuits[0].sectionId, "new-2");
|
||||
assert.equal(clone.circuits[0].deviceRows[0].id, "new-6");
|
||||
assert.equal(clone.circuits[0].deviceRows[0].circuitId, "new-3");
|
||||
assert.equal(
|
||||
clone.circuits[0].deviceRows[0].linkedProjectDeviceId,
|
||||
"device-1"
|
||||
);
|
||||
assert.equal(clone.circuits[0].deviceRows[0].roomId, "room-1");
|
||||
assert.equal(clone.circuits[0].deviceRows[0].legacyConsumerId, null);
|
||||
assert.equal(clone.circuits[0].protectionDevice?.circuitId, "new-3");
|
||||
assert.doesNotThrow(() => assertDistributionBoardSubtreeSnapshot(clone));
|
||||
});
|
||||
|
||||
it("rejects broken ownership and duplicate equipment identifiers", () => {
|
||||
const brokenOwnership = createSnapshot();
|
||||
brokenOwnership.circuits[0].sectionId = "missing";
|
||||
assert.throws(
|
||||
() => assertDistributionBoardSubtreeSnapshot(brokenOwnership),
|
||||
/ownership/
|
||||
);
|
||||
|
||||
const duplicateIdentifier = createSnapshot();
|
||||
duplicateIdentifier.components[0].component.equipmentIdentifier =
|
||||
" -1f1.1 ";
|
||||
assert.throws(
|
||||
() => assertDistributionBoardSubtreeSnapshot(duplicateIdentifier),
|
||||
/duplicate equipment identifier/
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user