forked from jappel/leistungsbilanz-ts
87 lines
3.5 KiB
TypeScript
87 lines
3.5 KiB
TypeScript
import path from "node:path";
|
|
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
|
|
import { createDatabaseContext } from "../src/db/database-context.js";
|
|
import { parseExternalModelStateSnapshot } from "../src/domain/models/project-state-snapshot.model.js";
|
|
import { createDefaultExternalModelConfiguration } from "../src/external-model/configuration/external-model-configuration.js";
|
|
|
|
const lowerId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee-ffffffff";
|
|
const upperId = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE-FFFFFFFF";
|
|
|
|
function fullBatch(id: string, importedAtIso: string) {
|
|
return {
|
|
id,
|
|
projectId: "p",
|
|
sourceId: "s",
|
|
importKind: "follow_up" as const,
|
|
importedAtIso,
|
|
fileName: `${id}.xlsx`,
|
|
sha256: "a".repeat(64),
|
|
objectCount: 1,
|
|
appliedProjectRevision: 3,
|
|
configurationSnapshot: createDefaultExternalModelConfiguration(),
|
|
originalContentBase64: "AA==",
|
|
document: {
|
|
sheetName: "Bauteilliste",
|
|
headerRowNumber: 1,
|
|
firstDataRowNumber: 3,
|
|
firstDataColumnNumber: 1,
|
|
columns: [],
|
|
rows: [],
|
|
issues: [],
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("Linear XLSX external model foundation", () => {
|
|
it("keeps only the newest batch complete", () => {
|
|
const newest = fullBatch("new", "2026-02-01T00:00:00.000Z");
|
|
const older = {
|
|
...fullBatch("old", "2026-01-01T00:00:00.000Z"),
|
|
appliedProjectRevision: null,
|
|
configurationSnapshot: null,
|
|
originalContentBase64: null,
|
|
document: null,
|
|
};
|
|
assert.doesNotThrow(() => parseExternalModelStateSnapshot({
|
|
source: { id: "s", projectId: "p", name: "Revit", sourceType: "revit_xlsx" },
|
|
importBatches: [older, newest],
|
|
roomMappings: [],
|
|
objects: [],
|
|
}));
|
|
assert.throws(() => parseExternalModelStateSnapshot({
|
|
source: { id: "s", projectId: "p", name: "Revit", sourceType: "revit_xlsx" },
|
|
importBatches: [newest, fullBatch("newer", "2026-03-01T00:00:00.000Z")],
|
|
roomMappings: [],
|
|
objects: [],
|
|
}), /Nur der letzte Importbatch/);
|
|
});
|
|
|
|
it("compares Worksharing-IDs exactly and allows duplicate IfcGUID values", () => {
|
|
const context = createDatabaseContext(":memory:");
|
|
try {
|
|
migrate(context.db, { migrationsFolder: path.resolve("src", "db", "migrations") });
|
|
context.sqlite.exec(`
|
|
INSERT INTO projects (id, name) VALUES ('p', 'Projekt');
|
|
INSERT INTO external_model_sources (id, project_id, name) VALUES ('s', 'p', 'Revit');
|
|
INSERT INTO external_import_batches
|
|
(id, project_id, source_id, import_kind, imported_at_iso, file_name, sha256, object_count)
|
|
VALUES ('b', 'p', 's', 'initial', '2026-01-01T00:00:00.000Z', 'model.xlsx', '${"a".repeat(64)}', 2);
|
|
`);
|
|
const insert = context.sqlite.prepare(`
|
|
INSERT INTO external_model_objects
|
|
(id, project_id, source_id, worksharing_id, ifc_guid, device_type_id,
|
|
last_seen_import_batch_id, last_accepted_import_batch_id,
|
|
accepted_source_values, planning_values, overridden_fields)
|
|
VALUES (?, 'p', 's', ?, 'same-IfcGUID', 'type', 'b', 'b', '{}', '{}', '[]')
|
|
`);
|
|
insert.run("o1", lowerId);
|
|
insert.run("o2", upperId);
|
|
assert.equal(context.sqlite.prepare("SELECT count(*) AS count FROM external_model_objects").get()!.count, 2);
|
|
assert.throws(() => insert.run("o3", lowerId), /UNIQUE constraint failed/);
|
|
} finally {
|
|
context.close();
|
|
}
|
|
});
|
|
});
|