forked from jappel/leistungsbilanz-ts
tsx runs tests without type checking and tsconfig.json covers only src, so 71 type errors had accumulated unnoticed. tsconfig.tests.json now checks every test and helper, and npm run typecheck includes it. Fixtures gain the fields the DTOs have grown since they were written (manualQuantity, circuit apparent power/cos phi, downstream board loads, section totals, building, cover and board info fields). Repository lookups that return "row ?? null" now declare the null in their type, which their callers already handle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
716 lines
21 KiB
TypeScript
716 lines
21 KiB
TypeScript
import path from "node:path";
|
|
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import { eq } from "drizzle-orm";
|
|
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
|
import {
|
|
createDatabaseContext,
|
|
type DatabaseContext,
|
|
} from "../src/db/database-context.js";
|
|
import { ProjectHistoryRepository } from "../src/db/repositories/project-history.repository.js";
|
|
import { ProjectSettingsProjectCommandRepository } from "../src/db/repositories/project-settings-project-command.repository.js";
|
|
import { projectRevisions } from "../src/db/schema/project-revisions.js";
|
|
import { projects } from "../src/db/schema/projects.js";
|
|
import { distributionBoards } from "../src/db/schema/distribution-boards.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 { projectDevices } from "../src/db/schema/project-devices.js";
|
|
import { DistributionBoardFixtureRepository } from "./support/distribution-board-fixture.js";
|
|
import { ProjectRevisionConflictError } from "../src/domain/errors/project-revision-conflict.error.js";
|
|
import { createProjectSettingsUpdateProjectCommand } from "../src/domain/models/project-settings-project-command.model.js";
|
|
import { updateProjectSettings } from "../src/frontend/utils/api.js";
|
|
|
|
function createTestDatabase(): DatabaseContext {
|
|
const context = createDatabaseContext(":memory:");
|
|
migrate(context.db, {
|
|
migrationsFolder: path.resolve("src", "db", "migrations"),
|
|
});
|
|
context.db
|
|
.insert(projects)
|
|
.values({
|
|
id: "project-1",
|
|
name: "Testprojekt",
|
|
internalProjectNumber: "INT-1",
|
|
singlePhaseVoltageV: 230,
|
|
threePhaseVoltageV: 400,
|
|
})
|
|
.run();
|
|
return context;
|
|
}
|
|
|
|
function getSettings(context: DatabaseContext) {
|
|
return context.db
|
|
.select({
|
|
name: projects.name,
|
|
internalProjectNumber: projects.internalProjectNumber,
|
|
externalProjectNumber: projects.externalProjectNumber,
|
|
buildingOwner: projects.buildingOwner,
|
|
description: projects.description,
|
|
isPublicBuilding: projects.isPublicBuilding,
|
|
singlePhaseVoltageV: projects.singlePhaseVoltageV,
|
|
threePhaseVoltageV: projects.threePhaseVoltageV,
|
|
enabledDistributionBoardSupplyTypes:
|
|
projects.enabledDistributionBoardSupplyTypes,
|
|
siteAddress: projects.siteAddress,
|
|
workStage: projects.workStage,
|
|
projectLead: projects.projectLead,
|
|
projectEditor: projects.projectEditor,
|
|
currentRevision: projects.currentRevision,
|
|
})
|
|
.from(projects)
|
|
.where(eq(projects.id, "project-1"))
|
|
.get();
|
|
}
|
|
|
|
type ProjectSettingsInput = Parameters<
|
|
typeof createProjectSettingsUpdateProjectCommand
|
|
>[0];
|
|
|
|
function settings(
|
|
overrides: Partial<ProjectSettingsInput> = {}
|
|
): ProjectSettingsInput {
|
|
return {
|
|
name: "Testprojekt",
|
|
internalProjectNumber: "INT-1",
|
|
externalProjectNumber: null,
|
|
buildingOwner: null,
|
|
description: null,
|
|
isPublicBuilding: false,
|
|
singlePhaseVoltageV: 230,
|
|
threePhaseVoltageV: 400,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
siteAddress: null,
|
|
workStage: null,
|
|
projectLead: null,
|
|
projectEditor: null,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function seedDerivedVoltageRecords(context: DatabaseContext) {
|
|
context.db.insert(projectDevices).values([
|
|
{
|
|
id: "device-single",
|
|
projectId: "project-1",
|
|
name: "Leuchte",
|
|
displayName: "Leuchte",
|
|
phaseType: "single_phase",
|
|
quantity: 1,
|
|
powerPerUnit: 0.1,
|
|
simultaneityFactor: 1,
|
|
voltageV: 230,
|
|
},
|
|
{
|
|
id: "device-three",
|
|
projectId: "project-1",
|
|
name: "Pumpe",
|
|
displayName: "Pumpe",
|
|
phaseType: "three_phase",
|
|
quantity: 1,
|
|
powerPerUnit: 2,
|
|
simultaneityFactor: 1,
|
|
voltageV: 400,
|
|
},
|
|
]).run();
|
|
const board = new DistributionBoardFixtureRepository(
|
|
context.db
|
|
).createWithCircuitListAndDefaultSections("project-1", "UV-01");
|
|
const list = context.db
|
|
.select()
|
|
.from(circuitLists)
|
|
.where(eq(circuitLists.distributionBoardId, board.id))
|
|
.get();
|
|
assert.ok(list);
|
|
const sections = context.db
|
|
.select()
|
|
.from(circuitSections)
|
|
.where(eq(circuitSections.circuitListId, list.id))
|
|
.all();
|
|
const singleSection = sections.find((section) => section.key === "single_phase");
|
|
const threeSection = sections.find((section) => section.key === "three_phase");
|
|
assert.ok(singleSection);
|
|
assert.ok(threeSection);
|
|
context.db.insert(circuits).values([
|
|
{
|
|
id: "circuit-single",
|
|
circuitListId: list.id,
|
|
sectionId: singleSection.id,
|
|
equipmentIdentifier: "-2F1",
|
|
sortOrder: 10,
|
|
voltage: 230,
|
|
isReserve: 1,
|
|
},
|
|
{
|
|
id: "circuit-three",
|
|
circuitListId: list.id,
|
|
sectionId: threeSection.id,
|
|
equipmentIdentifier: "-3F1",
|
|
sortOrder: 10,
|
|
voltage: 400,
|
|
isReserve: 1,
|
|
},
|
|
]).run();
|
|
}
|
|
|
|
function getDerivedVoltages(context: DatabaseContext) {
|
|
return {
|
|
devices: context.db
|
|
.select({ id: projectDevices.id, voltageV: projectDevices.voltageV })
|
|
.from(projectDevices)
|
|
.all()
|
|
.sort((left, right) => left.id.localeCompare(right.id)),
|
|
circuits: context.db
|
|
.select({ id: circuits.id, voltage: circuits.voltage })
|
|
.from(circuits)
|
|
.all()
|
|
.sort((left, right) => left.id.localeCompare(right.id)),
|
|
};
|
|
}
|
|
|
|
describe("project settings project-command repository", () => {
|
|
it("validates settings commands and sends the expected revision from the frontend", async () => {
|
|
assert.throws(
|
|
() =>
|
|
createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
singlePhaseVoltageV: 0,
|
|
}),
|
|
/invalid values/
|
|
);
|
|
const requests: Array<{ url: string; body: unknown }> = [];
|
|
const originalFetch = globalThis.fetch;
|
|
globalThis.fetch = async (input, init) => {
|
|
requests.push({
|
|
url: String(input),
|
|
body: JSON.parse(String(init?.body)),
|
|
});
|
|
return new Response(JSON.stringify({}), {
|
|
status: 200,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
};
|
|
try {
|
|
await updateProjectSettings("project-1", 7, {
|
|
...settings(),
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
});
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
assert.deepEqual(requests, [
|
|
{
|
|
url: "/api/projects/project-1",
|
|
body: {
|
|
expectedRevision: 7,
|
|
name: "Testprojekt",
|
|
internalProjectNumber: "INT-1",
|
|
externalProjectNumber: null,
|
|
buildingOwner: null,
|
|
description: null,
|
|
isPublicBuilding: false,
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
siteAddress: null,
|
|
workStage: null,
|
|
projectLead: null,
|
|
projectEditor: null,
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("updates both voltages and supports persisted undo and redo", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
seedDerivedVoltageRecords(context);
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
const history = new ProjectHistoryRepository(context.db);
|
|
const command = createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
name: "Neuer Projektname",
|
|
buildingOwner: "Beispiel Bau GmbH",
|
|
isPublicBuilding: true,
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
});
|
|
const forward = repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command,
|
|
});
|
|
assert.deepEqual(getSettings(context), {
|
|
...settings({
|
|
name: "Neuer Projektname",
|
|
buildingOwner: "Beispiel Bau GmbH",
|
|
isPublicBuilding: true,
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
}),
|
|
currentRevision: 1,
|
|
});
|
|
assert.deepEqual(getDerivedVoltages(context), {
|
|
devices: [
|
|
{ id: "device-single", voltageV: 240 },
|
|
{ id: "device-three", voltageV: 415 },
|
|
],
|
|
circuits: [
|
|
{ id: "circuit-single", voltage: 240 },
|
|
{ id: "circuit-three", voltage: 415 },
|
|
],
|
|
});
|
|
assert.deepEqual(forward.inverse.payload, {
|
|
name: "Testprojekt",
|
|
internalProjectNumber: "INT-1",
|
|
externalProjectNumber: null,
|
|
buildingOwner: null,
|
|
description: null,
|
|
isPublicBuilding: false,
|
|
singlePhaseVoltageV: 230,
|
|
threePhaseVoltageV: 400,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
siteAddress: null,
|
|
workStage: null,
|
|
projectLead: null,
|
|
projectEditor: null,
|
|
});
|
|
|
|
const undoStep = history.getNextCommand("project-1", "undo");
|
|
assert.ok(undoStep);
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 1,
|
|
source: "undo",
|
|
historyTargetChangeSetId: undoStep.changeSetId,
|
|
command: forward.inverse,
|
|
});
|
|
assert.deepEqual(getSettings(context), {
|
|
name: "Testprojekt",
|
|
internalProjectNumber: "INT-1",
|
|
externalProjectNumber: null,
|
|
buildingOwner: null,
|
|
description: null,
|
|
isPublicBuilding: false,
|
|
singlePhaseVoltageV: 230,
|
|
threePhaseVoltageV: 400,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
siteAddress: null,
|
|
workStage: null,
|
|
projectLead: null,
|
|
projectEditor: null,
|
|
currentRevision: 2,
|
|
});
|
|
assert.deepEqual(getDerivedVoltages(context), {
|
|
devices: [
|
|
{ id: "device-single", voltageV: 230 },
|
|
{ id: "device-three", voltageV: 400 },
|
|
],
|
|
circuits: [
|
|
{ id: "circuit-single", voltage: 230 },
|
|
{ id: "circuit-three", voltage: 400 },
|
|
],
|
|
});
|
|
|
|
const redoStep = history.getNextCommand("project-1", "redo");
|
|
assert.ok(redoStep);
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 2,
|
|
source: "redo",
|
|
historyTargetChangeSetId: redoStep.changeSetId,
|
|
command,
|
|
});
|
|
assert.deepEqual(getSettings(context), {
|
|
name: "Neuer Projektname",
|
|
internalProjectNumber: "INT-1",
|
|
externalProjectNumber: null,
|
|
buildingOwner: "Beispiel Bau GmbH",
|
|
description: null,
|
|
isPublicBuilding: true,
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
siteAddress: null,
|
|
workStage: null,
|
|
projectLead: null,
|
|
projectEditor: null,
|
|
currentRevision: 3,
|
|
});
|
|
assert.deepEqual(getDerivedVoltages(context), {
|
|
devices: [
|
|
{ id: "device-single", voltageV: 240 },
|
|
{ id: "device-three", voltageV: 415 },
|
|
],
|
|
circuits: [
|
|
{ id: "circuit-single", voltage: 240 },
|
|
{ id: "circuit-three", voltage: 415 },
|
|
],
|
|
});
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
|
|
it("preserves the building classification when applying a baseline command", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
context.db
|
|
.update(projects)
|
|
.set({ isPublicBuilding: true })
|
|
.where(eq(projects.id, "project-1"))
|
|
.run();
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
|
|
const forward = repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: {
|
|
schemaVersion: 1,
|
|
type: "project.update-settings",
|
|
payload: {
|
|
name: "Stand aus Baseline-Command",
|
|
internalProjectNumber: "INT-1",
|
|
externalProjectNumber: null,
|
|
buildingOwner: null,
|
|
description: null,
|
|
singlePhaseVoltageV: 230,
|
|
threePhaseVoltageV: 400,
|
|
enabledDistributionBoardSupplyTypes: [
|
|
"AV",
|
|
"SV",
|
|
"EV",
|
|
"USV",
|
|
"MSR",
|
|
"SiBe",
|
|
],
|
|
},
|
|
},
|
|
});
|
|
|
|
assert.equal(getSettings(context)?.name, "Stand aus Baseline-Command");
|
|
assert.equal(getSettings(context)?.isPublicBuilding, true);
|
|
assert.equal(forward.inverse.schemaVersion, 1);
|
|
|
|
const history = new ProjectHistoryRepository(context.db);
|
|
const undoStep = history.getNextCommand("project-1", "undo");
|
|
assert.ok(undoStep);
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 1,
|
|
source: "undo",
|
|
historyTargetChangeSetId: undoStep.changeSetId,
|
|
command: forward.inverse,
|
|
});
|
|
assert.equal(getSettings(context)?.name, "Testprojekt");
|
|
assert.equal(getSettings(context)?.isPublicBuilding, true);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
|
|
it("persists the print cover fields with persisted undo", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
const readCover = () =>
|
|
context.db
|
|
.select({
|
|
siteAddress: projects.siteAddress,
|
|
workStage: projects.workStage,
|
|
projectLead: projects.projectLead,
|
|
projectEditor: projects.projectEditor,
|
|
})
|
|
.from(projects)
|
|
.where(eq(projects.id, "project-1"))
|
|
.get();
|
|
const forward = repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand(
|
|
settings({
|
|
siteAddress: "Musterstraße 1\n12345 Musterstadt",
|
|
workStage: "LPH 5",
|
|
projectLead: "P. Leitung",
|
|
projectEditor: "B. Arbeiter",
|
|
})
|
|
),
|
|
});
|
|
assert.deepEqual(readCover(), {
|
|
siteAddress: "Musterstraße 1\n12345 Musterstadt",
|
|
workStage: "LPH 5",
|
|
projectLead: "P. Leitung",
|
|
projectEditor: "B. Arbeiter",
|
|
});
|
|
assert.equal(forward.inverse.schemaVersion, 3);
|
|
|
|
const undoStep = new ProjectHistoryRepository(
|
|
context.db
|
|
).getNextCommand("project-1", "undo");
|
|
assert.ok(undoStep);
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 1,
|
|
source: "undo",
|
|
historyTargetChangeSetId: undoStep.changeSetId,
|
|
command: forward.inverse,
|
|
});
|
|
assert.deepEqual(readCover(), {
|
|
siteAddress: null,
|
|
workStage: null,
|
|
projectLead: null,
|
|
projectEditor: null,
|
|
});
|
|
|
|
assert.throws(
|
|
() =>
|
|
createProjectSettingsUpdateProjectCommand(
|
|
settings({ workStage: " LPH 5" })
|
|
),
|
|
/invalid values/
|
|
);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
|
|
it("keeps the cover fields when applying a version 2 command", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
context.db
|
|
.update(projects)
|
|
.set({ workStage: "LPH 3", projectLead: "P. Leitung" })
|
|
.where(eq(projects.id, "project-1"))
|
|
.run();
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
const {
|
|
siteAddress: _siteAddress,
|
|
workStage: _workStage,
|
|
projectLead: _projectLead,
|
|
projectEditor: _projectEditor,
|
|
...versionTwoPayload
|
|
} = settings({ name: "Stand aus Version 2" });
|
|
const forward = repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: {
|
|
schemaVersion: 2,
|
|
type: "project.update-settings",
|
|
payload: versionTwoPayload,
|
|
},
|
|
});
|
|
const project = context.db
|
|
.select()
|
|
.from(projects)
|
|
.where(eq(projects.id, "project-1"))
|
|
.get();
|
|
assert.equal(project?.name, "Stand aus Version 2");
|
|
assert.equal(project?.workStage, "LPH 3");
|
|
assert.equal(project?.projectLead, "P. Leitung");
|
|
assert.equal(forward.inverse.schemaVersion, 2);
|
|
assert.equal(Object.keys(forward.inverse.payload).length, 9);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
|
|
it("persists the project supply-type selection and rejects disabling an in-use type", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
enabledDistributionBoardSupplyTypes: ["AV", "MSR", "SiBe"],
|
|
}),
|
|
});
|
|
assert.deepEqual(
|
|
getSettings(context)?.enabledDistributionBoardSupplyTypes,
|
|
["AV", "MSR", "SiBe"]
|
|
);
|
|
|
|
context.db.insert(distributionBoards).values({
|
|
id: "board-1",
|
|
projectId: "project-1",
|
|
name: "UV SiBe",
|
|
supplyType: "SiBe",
|
|
}).run();
|
|
assert.throws(
|
|
() =>
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 1,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
enabledDistributionBoardSupplyTypes: ["AV", "MSR"],
|
|
}),
|
|
}),
|
|
/SiBe/
|
|
);
|
|
assert.equal(getSettings(context)?.currentRevision, 1);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
|
|
it("rejects no-op, invalid project and stale revision without partial writes", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
}),
|
|
}),
|
|
/did not change/
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
repository.executeUpdate({
|
|
projectId: "missing",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
}),
|
|
}),
|
|
/Project not found/
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 1,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
}),
|
|
}),
|
|
ProjectRevisionConflictError
|
|
);
|
|
assert.deepEqual(getSettings(context), {
|
|
...settings(),
|
|
currentRevision: 0,
|
|
});
|
|
assert.equal(
|
|
context.db.select().from(projectRevisions).all().length,
|
|
0
|
|
);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
|
|
it("rolls back both values and revision after a late history failure", () => {
|
|
const context = createTestDatabase();
|
|
try {
|
|
context.sqlite.exec(`
|
|
CREATE TRIGGER fail_project_settings_history
|
|
BEFORE INSERT ON project_history_stack_entries
|
|
BEGIN
|
|
SELECT RAISE(ABORT, 'forced project settings history failure');
|
|
END;
|
|
`);
|
|
const repository = new ProjectSettingsProjectCommandRepository(
|
|
context.db
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
repository.executeUpdate({
|
|
projectId: "project-1",
|
|
expectedRevision: 0,
|
|
source: "user",
|
|
command: createProjectSettingsUpdateProjectCommand({
|
|
...settings(),
|
|
singlePhaseVoltageV: 240,
|
|
threePhaseVoltageV: 415,
|
|
}),
|
|
}),
|
|
/forced project settings history failure/
|
|
);
|
|
assert.deepEqual(getSettings(context), {
|
|
...settings(),
|
|
currentRevision: 0,
|
|
});
|
|
assert.equal(
|
|
context.db.select().from(projectRevisions).all().length,
|
|
0
|
|
);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
});
|