Add external object new circuit command
This commit is contained in:
@@ -6,11 +6,13 @@ import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
||||
import { createDatabaseContext, type AppDatabase } from "../src/db/database-context.js";
|
||||
import { ExternalObjectRowAssignmentProjectCommandRepository } from "../src/db/repositories/external-object-row-assignment-project-command.repository.js";
|
||||
import { ExternalObjectNewRowProjectCommandRepository } from "../src/db/repositories/external-object-new-row-project-command.repository.js";
|
||||
import { ExternalObjectNewCircuitProjectCommandRepository } from "../src/db/repositories/external-object-new-circuit-project-command.repository.js";
|
||||
import { toCircuitDeviceRowSnapshot } from "../src/db/repositories/circuit-device-row-structure.persistence.js";
|
||||
import { circuitDeviceRows } from "../src/db/schema/circuit-device-rows.js";
|
||||
import { circuitLists } from "../src/db/schema/circuit-lists.js";
|
||||
import { circuitSections } from "../src/db/schema/circuit-sections.js";
|
||||
import { circuits } from "../src/db/schema/circuits.js";
|
||||
import { circuitProtectionDevices } from "../src/db/schema/circuit-protection-devices.js";
|
||||
import { distributionBoards } from "../src/db/schema/distribution-boards.js";
|
||||
import { externalImportBatches } from "../src/db/schema/external-import-batches.js";
|
||||
import { externalModelObjects } from "../src/db/schema/external-model-objects.js";
|
||||
@@ -24,6 +26,10 @@ import {
|
||||
createExternalObjectNewRowProjectCommand,
|
||||
externalObjectAssignToNewRowCommandType,
|
||||
} from "../src/domain/models/external-object-new-row-project-command.model.js";
|
||||
import {
|
||||
createExternalObjectNewCircuitProjectCommand,
|
||||
externalObjectAssignToNewCircuitCommandType,
|
||||
} from "../src/domain/models/external-object-new-circuit-project-command.model.js";
|
||||
import type { ExternalModelObjectSnapshot } from "../src/external-model/domain/external-model-contracts.js";
|
||||
import { externalCsvTestConfiguration } from "./fixtures/revit-csv-fixtures.js";
|
||||
|
||||
@@ -376,3 +382,192 @@ describe("external object new-row project command", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function newExternalCircuit(database: AppDatabase) {
|
||||
const sourceRow = row(database, "row-2");
|
||||
return {
|
||||
id: "circuit-new",
|
||||
circuitListId: "list-1",
|
||||
sectionId: "section-1",
|
||||
equipmentIdentifier: "-2F1.3",
|
||||
displayName: "Steckdose",
|
||||
sortOrder: 30,
|
||||
cableType: null,
|
||||
cableCrossSection: null,
|
||||
cableLength: null,
|
||||
rcdAssignment: null,
|
||||
terminalDesignation: null,
|
||||
voltage: 230,
|
||||
controlRequirement: null,
|
||||
status: null,
|
||||
isReserve: false,
|
||||
remark: null,
|
||||
deviceRows: [{
|
||||
...sourceRow,
|
||||
id: "row-new",
|
||||
circuitId: "circuit-new",
|
||||
quantity: 2,
|
||||
manualQuantity: 0,
|
||||
}],
|
||||
protectionDevice: {
|
||||
circuitId: "circuit-new",
|
||||
type: "FI_LS" as const,
|
||||
ratedCurrentA: 16,
|
||||
fuseUtilizationCategory: null,
|
||||
tripCharacteristic: "B" as const,
|
||||
rcdType: "A" as const,
|
||||
ratedResidualCurrentMa: 30,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("external object new-circuit project command", () => {
|
||||
it("creates circuit, protection, row and links as one undoable revision", () => {
|
||||
const context = createFixture(null);
|
||||
try {
|
||||
const object = objectSnapshot(null);
|
||||
const circuit = newExternalCircuit(context.db);
|
||||
const command = createExternalObjectNewCircuitProjectCommand(
|
||||
externalObjectAssignToNewCircuitCommandType,
|
||||
{
|
||||
circuit,
|
||||
objects: [{
|
||||
expected: object,
|
||||
target: { ...object, circuitDeviceRowId: "row-new" },
|
||||
}],
|
||||
confirmedConflictObjectIds: [],
|
||||
}
|
||||
);
|
||||
const repository = new ExternalObjectNewCircuitProjectCommandRepository(context.db);
|
||||
const inserted = repository.execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 0,
|
||||
source: "user",
|
||||
command,
|
||||
});
|
||||
assert.equal(
|
||||
context.db.select().from(circuits).where(eq(circuits.id, "circuit-new")).get()!
|
||||
.equipmentIdentifier,
|
||||
"-2F1.3"
|
||||
);
|
||||
assert.equal(row(context.db, "row-new").manualQuantity, 0);
|
||||
assert.equal(
|
||||
context.db.select().from(circuitProtectionDevices)
|
||||
.where(eq(circuitProtectionDevices.circuitId, "circuit-new")).get()!.type,
|
||||
"FI_LS"
|
||||
);
|
||||
assert.equal(
|
||||
context.db.select().from(externalModelObjects).get()!.circuitDeviceRowId,
|
||||
"row-new"
|
||||
);
|
||||
assert.throws(
|
||||
() => repository.execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 1,
|
||||
source: "user",
|
||||
command: inserted.inverse,
|
||||
}),
|
||||
/only be removed through project history/
|
||||
);
|
||||
|
||||
const undone = repository.execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 1,
|
||||
source: "undo",
|
||||
historyTargetChangeSetId: inserted.revision.changeSetId,
|
||||
command: inserted.inverse,
|
||||
});
|
||||
assert.equal(
|
||||
context.db.select().from(circuits).where(eq(circuits.id, "circuit-new")).get(),
|
||||
undefined
|
||||
);
|
||||
assert.equal(context.db.select().from(externalModelObjects).get()!.circuitDeviceRowId, null);
|
||||
|
||||
repository.execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 2,
|
||||
source: "redo",
|
||||
historyTargetChangeSetId: inserted.revision.changeSetId,
|
||||
command: undone.inverse,
|
||||
});
|
||||
assert.equal(
|
||||
context.db.select().from(circuits).where(eq(circuits.id, "circuit-new")).get()!
|
||||
.equipmentIdentifier,
|
||||
"-2F1.3"
|
||||
);
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects a preplanned BMK that does not belong to the target group", () => {
|
||||
const context = createFixture(null);
|
||||
try {
|
||||
const object = objectSnapshot(null);
|
||||
const circuit = {
|
||||
...newExternalCircuit(context.db),
|
||||
equipmentIdentifier: "-1F1.3",
|
||||
};
|
||||
assert.throws(
|
||||
() => new ExternalObjectNewCircuitProjectCommandRepository(context.db).execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 0,
|
||||
source: "user",
|
||||
command: createExternalObjectNewCircuitProjectCommand(
|
||||
externalObjectAssignToNewCircuitCommandType,
|
||||
{
|
||||
circuit,
|
||||
objects: [{
|
||||
expected: object,
|
||||
target: { ...object, circuitDeviceRowId: "row-new" },
|
||||
}],
|
||||
confirmedConflictObjectIds: [],
|
||||
}
|
||||
),
|
||||
}),
|
||||
/equipment identifier does not match target group/
|
||||
);
|
||||
assert.equal(context.db.select().from(externalModelObjects).get()!.circuitDeviceRowId, null);
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("rolls back the complete circuit subtree when history persistence fails", () => {
|
||||
const context = createFixture(null);
|
||||
try {
|
||||
context.sqlite.exec(`
|
||||
CREATE TRIGGER fail_new_circuit_history
|
||||
BEFORE INSERT ON project_change_sets
|
||||
BEGIN SELECT RAISE(ABORT, 'late history failure'); END;
|
||||
`);
|
||||
const object = objectSnapshot(null);
|
||||
assert.throws(
|
||||
() => new ExternalObjectNewCircuitProjectCommandRepository(context.db).execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 0,
|
||||
source: "user",
|
||||
command: createExternalObjectNewCircuitProjectCommand(
|
||||
externalObjectAssignToNewCircuitCommandType,
|
||||
{
|
||||
circuit: newExternalCircuit(context.db),
|
||||
objects: [{
|
||||
expected: object,
|
||||
target: { ...object, circuitDeviceRowId: "row-new" },
|
||||
}],
|
||||
confirmedConflictObjectIds: [],
|
||||
}
|
||||
),
|
||||
}),
|
||||
/late history failure/
|
||||
);
|
||||
assert.equal(
|
||||
context.db.select().from(circuits).where(eq(circuits.id, "circuit-new")).get(),
|
||||
undefined
|
||||
);
|
||||
assert.equal(context.db.select().from(externalModelObjects).get()!.circuitDeviceRowId, null);
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user