Include components in project snapshots
This commit is contained in:
@@ -32,6 +32,9 @@ function minimalSnapshot() {
|
||||
distributionBoards: [],
|
||||
circuitLists: [],
|
||||
circuitSections: [],
|
||||
distributionBoardComponents: [],
|
||||
circuitProtectionDevices: [],
|
||||
distributionBoardComponentProtectionDevices: [],
|
||||
circuits: [],
|
||||
projectDevices: [],
|
||||
floors: [],
|
||||
@@ -39,6 +42,111 @@ function minimalSnapshot() {
|
||||
};
|
||||
}
|
||||
|
||||
function legacyMinimalSnapshot() {
|
||||
const {
|
||||
distributionBoardComponents: _distributionBoardComponents,
|
||||
circuitProtectionDevices: _circuitProtectionDevices,
|
||||
distributionBoardComponentProtectionDevices:
|
||||
_distributionBoardComponentProtectionDevices,
|
||||
...snapshot
|
||||
} = minimalSnapshot();
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function protectedSnapshot() {
|
||||
return {
|
||||
...minimalSnapshot(),
|
||||
distributionBoards: [
|
||||
{
|
||||
id: "board-1",
|
||||
projectId: "project-1",
|
||||
name: "UV 1",
|
||||
floorId: null,
|
||||
supplyType: null,
|
||||
simultaneityFactor: 1,
|
||||
},
|
||||
],
|
||||
circuitLists: [
|
||||
{
|
||||
id: "list-1",
|
||||
projectId: "project-1",
|
||||
distributionBoardId: "board-1",
|
||||
name: "UV 1 Stromkreisliste",
|
||||
},
|
||||
],
|
||||
circuitSections: [
|
||||
{
|
||||
id: "section-1",
|
||||
circuitListId: "list-1",
|
||||
key: "lighting",
|
||||
displayName: "Beleuchtung 1",
|
||||
prefix: "-1F1.",
|
||||
sortOrder: 10,
|
||||
category: "lighting" as const,
|
||||
groupNumber: 1,
|
||||
},
|
||||
],
|
||||
circuits: [
|
||||
{
|
||||
id: "circuit-1",
|
||||
circuitListId: "list-1",
|
||||
sectionId: "section-1",
|
||||
equipmentIdentifier: "-1F1.1",
|
||||
displayName: "Reserve",
|
||||
sortOrder: 10,
|
||||
protectionType: null,
|
||||
protectionRatedCurrent: null,
|
||||
protectionCharacteristic: null,
|
||||
cableType: null,
|
||||
cableCrossSection: null,
|
||||
cableLength: null,
|
||||
rcdAssignment: null,
|
||||
terminalDesignation: null,
|
||||
voltage: 230,
|
||||
controlRequirement: null,
|
||||
status: null,
|
||||
isReserve: true,
|
||||
remark: null,
|
||||
deviceRows: [],
|
||||
},
|
||||
],
|
||||
distributionBoardComponents: [
|
||||
{
|
||||
id: "component-1",
|
||||
circuitListId: "list-1",
|
||||
sectionId: "section-1",
|
||||
equipmentIdentifier: "-1Q1.0",
|
||||
name: "Gruppen-FI",
|
||||
role: "group_residual_current_protection" as const,
|
||||
placement: "group" as const,
|
||||
sortOrder: 10,
|
||||
},
|
||||
],
|
||||
circuitProtectionDevices: [
|
||||
{
|
||||
circuitId: "circuit-1",
|
||||
type: "LS" as const,
|
||||
ratedCurrentA: 10,
|
||||
fuseUtilizationCategory: null,
|
||||
tripCharacteristic: "B" as const,
|
||||
rcdType: null,
|
||||
ratedResidualCurrentMa: null,
|
||||
},
|
||||
],
|
||||
distributionBoardComponentProtectionDevices: [
|
||||
{
|
||||
componentId: "component-1",
|
||||
type: "FI" as const,
|
||||
ratedCurrentA: 40,
|
||||
fuseUtilizationCategory: null,
|
||||
tripCharacteristic: null,
|
||||
rcdType: "A" as const,
|
||||
ratedResidualCurrentMa: 30,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
describe("project state snapshot model", () => {
|
||||
it("round-trips a versioned logical project state", () => {
|
||||
const snapshot = parseProjectStateSnapshot(minimalSnapshot());
|
||||
@@ -52,7 +160,7 @@ describe("project state snapshot model", () => {
|
||||
|
||||
it("upgrades version-one snapshots with empty project metadata", () => {
|
||||
const legacy = {
|
||||
...minimalSnapshot(),
|
||||
...legacyMinimalSnapshot(),
|
||||
schemaVersion: 1 as const,
|
||||
project: {
|
||||
id: "project-1",
|
||||
@@ -82,7 +190,7 @@ describe("project state snapshot model", () => {
|
||||
|
||||
it("upgrades version-two distribution boards without inferred assignments", () => {
|
||||
const previous = {
|
||||
...minimalSnapshot(),
|
||||
...legacyMinimalSnapshot(),
|
||||
schemaVersion: 2 as const,
|
||||
project: {
|
||||
...minimalSnapshot().project,
|
||||
@@ -110,7 +218,7 @@ describe("project state snapshot model", () => {
|
||||
|
||||
it("upgrades version-three snapshots with all project supply types", () => {
|
||||
const previous = {
|
||||
...minimalSnapshot(),
|
||||
...legacyMinimalSnapshot(),
|
||||
schemaVersion: 3 as const,
|
||||
project: {
|
||||
...minimalSnapshot().project,
|
||||
@@ -131,7 +239,7 @@ describe("project state snapshot model", () => {
|
||||
|
||||
it("normalizes version-four device voltages to project settings", () => {
|
||||
const previous = {
|
||||
...minimalSnapshot(),
|
||||
...legacyMinimalSnapshot(),
|
||||
schemaVersion: 4 as const,
|
||||
projectDevices: [
|
||||
{
|
||||
@@ -161,7 +269,7 @@ describe("project state snapshot model", () => {
|
||||
|
||||
it("upgrades version-five distribution boards with a neutral factor", () => {
|
||||
const previous = {
|
||||
...minimalSnapshot(),
|
||||
...legacyMinimalSnapshot(),
|
||||
schemaVersion: 5 as const,
|
||||
distributionBoards: [
|
||||
{
|
||||
@@ -183,6 +291,116 @@ describe("project state snapshot model", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("upgrades version-six sections without inventing component data", () => {
|
||||
const previous = {
|
||||
...legacyMinimalSnapshot(),
|
||||
schemaVersion: 6 as const,
|
||||
circuitSections: [
|
||||
{
|
||||
id: "section-lighting",
|
||||
circuitListId: "list-1",
|
||||
key: "lighting",
|
||||
displayName: "Beleuchtung",
|
||||
prefix: "-1F",
|
||||
sortOrder: 10,
|
||||
},
|
||||
{
|
||||
id: "section-unassigned",
|
||||
circuitListId: "list-1",
|
||||
key: "unassigned",
|
||||
displayName: "Nicht zugeordnet",
|
||||
prefix: "-UF",
|
||||
sortOrder: 90,
|
||||
},
|
||||
],
|
||||
distributionBoards: [
|
||||
{
|
||||
id: "board-1",
|
||||
projectId: "project-1",
|
||||
name: "UV 1",
|
||||
floorId: null,
|
||||
supplyType: null,
|
||||
simultaneityFactor: 1,
|
||||
},
|
||||
],
|
||||
circuitLists: [
|
||||
{
|
||||
id: "list-1",
|
||||
projectId: "project-1",
|
||||
distributionBoardId: "board-1",
|
||||
name: "UV 1 Stromkreisliste",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const snapshot = parseProjectStateSnapshot(previous);
|
||||
|
||||
assert.deepEqual(
|
||||
snapshot.circuitSections.map(
|
||||
({ key, category, groupNumber }) => ({
|
||||
key,
|
||||
category,
|
||||
groupNumber,
|
||||
})
|
||||
),
|
||||
[
|
||||
{
|
||||
key: "lighting",
|
||||
category: "lighting",
|
||||
groupNumber: 1,
|
||||
},
|
||||
{
|
||||
key: "unassigned",
|
||||
category: null,
|
||||
groupNumber: null,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert.deepEqual(snapshot.distributionBoardComponents, []);
|
||||
assert.deepEqual(snapshot.circuitProtectionDevices, []);
|
||||
assert.deepEqual(
|
||||
snapshot.distributionBoardComponentProtectionDevices,
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
it("validates the complete group, component and protection graph", () => {
|
||||
const snapshot = parseProjectStateSnapshot(protectedSnapshot());
|
||||
|
||||
assert.equal(snapshot.circuitSections[0]?.groupNumber, 1);
|
||||
assert.equal(
|
||||
snapshot.distributionBoardComponents[0]?.sectionId,
|
||||
"section-1"
|
||||
);
|
||||
assert.equal(
|
||||
snapshot.circuitProtectionDevices[0]?.tripCharacteristic,
|
||||
"B"
|
||||
);
|
||||
assert.equal(
|
||||
snapshot.distributionBoardComponentProtectionDevices[0]
|
||||
?.ratedResidualCurrentMa,
|
||||
30
|
||||
);
|
||||
|
||||
const duplicateBmk = protectedSnapshot();
|
||||
duplicateBmk.distributionBoardComponents[0]!.equipmentIdentifier =
|
||||
" -1f1.1 ";
|
||||
assert.throws(
|
||||
() => parseProjectStateSnapshot(duplicateBmk),
|
||||
/duplicate equipment identifiers/
|
||||
);
|
||||
|
||||
const invalidProtection = protectedSnapshot();
|
||||
invalidProtection.circuitProtectionDevices[0] = {
|
||||
...invalidProtection.circuitProtectionDevices[0]!,
|
||||
ratedCurrentA: 35,
|
||||
};
|
||||
assert.throws(
|
||||
() => parseProjectStateSnapshot(invalidProtection),
|
||||
/protection-device configuration is invalid/
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects duplicate ids and cross-project ownership", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
|
||||
Reference in New Issue
Block a user