// Starter packs SP7 (#1873, design section 8): resolveInstance carries the organization's // workflows, plus the given project's, the project's winning by name. An organization with no // workflows resolves, and digests, exactly as before. import { test } from "node:test"; import assert from "node:assert/strict"; import { join } from "node:path"; import { projectFilePath, resolveInstance, validateBusinessDocument, validateProjectDocument } from "../src/index.mjs"; import { businessDoc, REPO_ROLES, systemFor, tmp } from "./helpers.mjs"; const CHANGE = { title: "Change", description: "One change from task to merge.", steps: [ { title: "Write the task", state: "todo", roles: ["pm"] }, { title: "Implement", state: "in-progress", roles: ["coder"] }, { title: "Approve the merge", state: "done", roles: ["human"] }, ] }; const HOTFIX = { steps: [{ title: "Patch", state: "in-progress", roles: ["coder"] }] }; const PROJECT_CHANGE = { title: "Project change", steps: [{ title: "Ship it", state: "done", roles: ["reviewer"] }] }; function load(root, mutate) { const doc = businessDoc(root); mutate?.(doc); return { doc, business: validateBusinessDocument(doc, join(root, "businesses", "acme.json"), { rolesDir: REPO_ROLES }) }; } const projectOf = (doc) => validateProjectDocument({ projectVersion: 1, id: "stack" }, projectFilePath(doc.projects.stack.root)); test("SP7 resolveInstance puts the organization's workflows on the resolved record", () => { const root = tmp(); const { business } = load(root, (doc) => { doc.workflows = { change: CHANGE, hotfix: HOTFIX }; }); for (const instance of ["chief", "pm", "coder", "cto"]) { const r = resolveInstance({ system: systemFor(root), business, instance }); assert.deepEqual(r.workflows, { change: CHANGE, hotfix: HOTFIX }, instance); assert.ok(Object.isFrozen(r.workflows.change.steps[0].roles), "the record is frozen"); } // The record holds its own copy, not the loaded business's objects. const r = resolveInstance({ system: systemFor(root), business, instance: "chief" }); assert.notEqual(r.workflows.change, business.workflows.change); }); test("SP7 with a project, the project's workflows join the organization's and win by name", () => { const root = tmp(); const { doc, business } = load(root, (d) => { d.workflows = { change: CHANGE, hotfix: HOTFIX }; d.projects.stack.workflows = { change: PROJECT_CHANGE, review: HOTFIX }; }); const system = systemFor(root); const withProject = resolveInstance({ system, business, project: projectOf(doc), instance: "coder" }); assert.equal(withProject.project, "stack"); assert.deepEqual(withProject.workflows, { change: PROJECT_CHANGE, hotfix: HOTFIX, review: HOTFIX }); // The launcher names no project today (cli/src/launcher.mjs), so a launch sees the org's only. const noProject = resolveInstance({ system, business, instance: "coder" }); assert.deepEqual(noProject.workflows, { change: CHANGE, hotfix: HOTFIX }); }); test("SP7 an organization with no workflows resolves and digests as before", () => { const root = tmp(); const system = systemFor(root); const plain = load(root).business; // Project workflows only: a launch with no project sees none, so the record is the plain one. const projectOnly = load(root, (d) => { d.projects.stack.workflows = { review: HOTFIX }; }); for (const instance of ["chief", "pm", "coder"]) { const a = resolveInstance({ system, business: plain, instance }); const b = resolveInstance({ system, business: projectOnly.business, instance }); assert.ok(!Object.hasOwn(a, "workflows"), instance); assert.ok(!Object.hasOwn(b, "workflows"), instance); assert.equal(b.digest, a.digest, instance); } // With the project named, the project's workflows reach the record and change the digest. const named = resolveInstance({ system, business: projectOnly.business, project: projectOf(projectOnly.doc), instance: "coder" }); assert.deepEqual(named.workflows, { review: HOTFIX }); }); test("SP7 a step role naming no definition stays on the record as written", () => { const root = tmp(); const ghost = { steps: [{ title: "Survey", state: "todo", roles: ["scout", "human"] }] }; const { business } = load(root, (d) => { d.workflows = { ghost }; }); const r = resolveInstance({ system: systemFor(root), business, instance: "chief" }); assert.deepEqual(r.workflows, { ghost }); });