import test from "node:test"; import assert from "node:assert/strict"; import { ASSET_TYPES, WORKFLOW_RUN_STATUSES, WORKSPACE_TYPES, } from "../../../packages/contracts/src/domain.ts"; import { formatCustomNodeValidationIssue, validateCustomNodeDefinition, } from "../../../packages/contracts/src/custom-node.ts"; import { createMongoConnectionUri } from "../src/common/mongo/mongo.module.ts"; import { ASSET_COLLECTION_NAME, PROJECT_COLLECTION_NAME, WORKFLOW_DEFINITION_COLLECTION_NAME, WORKSPACE_COLLECTION_NAME, } from "../src/common/mongo/schemas/index.ts"; test("workspace types include personal and team", () => { assert.deepEqual(WORKSPACE_TYPES, ["personal", "team"]); }); test("asset types include raw and dataset-oriented sources", () => { assert.equal(ASSET_TYPES.includes("raw_file"), true); assert.equal(ASSET_TYPES.includes("standard_dataset"), true); assert.equal(ASSET_TYPES.includes("rosbag"), true); }); test("workflow run statuses include the documented execution states", () => { assert.equal(WORKFLOW_RUN_STATUSES.includes("pending"), true); assert.equal(WORKFLOW_RUN_STATUSES.includes("running"), true); assert.equal(WORKFLOW_RUN_STATUSES.includes("success"), true); assert.equal(WORKFLOW_RUN_STATUSES.includes("failed"), true); }); test("mongo connection uri builder uses environment-style config", () => { assert.equal( createMongoConnectionUri({ username: "emboflow", password: "emboflow", host: "localhost", port: 27017, database: "emboflow", }), "mongodb://emboflow:emboflow@localhost:27017/emboflow?authSource=admin", ); }); test("schema collection names match the core domain objects", () => { assert.equal(WORKSPACE_COLLECTION_NAME, "workspaces"); assert.equal(PROJECT_COLLECTION_NAME, "projects"); assert.equal(ASSET_COLLECTION_NAME, "assets"); assert.equal(WORKFLOW_DEFINITION_COLLECTION_NAME, "workflow_definitions"); }); test("custom node validation accepts a valid docker image utility node", () => { const issues = validateCustomNodeDefinition({ name: "Merge Assets", category: "Utility", source: { kind: "image", image: "python:3.11-alpine", command: ["python3", "-c", "print('merge')"], }, contract: { inputMode: "multi_asset_set", outputMode: "asset_set", artifactType: "json", }, }); assert.deepEqual(issues, []); }); test("custom node validation rejects invalid dockerfile and impossible source contract combinations", () => { const issues = validateCustomNodeDefinition({ name: "Bad Source", category: "Source", source: { kind: "dockerfile", dockerfileContent: "CMD [\"python3\"]", }, contract: { inputMode: "multi_asset_set", outputMode: "report", artifactType: "json", }, }); assert.deepEqual(issues, ["source_cannot_be_multi_input", "dockerfile_missing_from"]); assert.equal( formatCustomNodeValidationIssue("dockerfile_missing_from"), "custom node dockerfile must include a FROM instruction", ); });