Files
kandev/apps/web/components/task-create-dialog-prop-builders.test.ts

158 lines
4.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { DialogFormBodyProps, DialogFormState, StepType } from "./task-create-dialog-types";
import {
computeHasAllBranches,
localRepositoryCreationEnabled,
resolveDialogLaunchPreview,
resolveWorkflowName,
} from "./task-create-dialog-prop-builders";
const WORKFLOW_ID = "workflow-1";
const IN_PROGRESS = "In Progress";
function formState(overrides: Partial<DialogFormState>): DialogFormState {
return {
noRepository: false,
useRemote: false,
repositories: [],
remoteRepos: [],
...overrides,
} as DialogFormState;
}
describe("computeHasAllBranches", () => {
it("accepts no-repository tasks", () => {
expect(computeHasAllBranches(formState({ noRepository: true }))).toBe(true);
});
it("requires a branch on every populated remote row", () => {
expect(
computeHasAllBranches(
formState({
useRemote: true,
remoteRepos: [
{ key: "one", url: "https://example.com/one.git", branch: "main", source: "paste" },
{ key: "two", url: "https://example.com/two.git", branch: "", source: "paste" },
],
}),
),
).toBe(false);
});
it("rejects remote mode without a populated row", () => {
expect(computeHasAllBranches(formState({ useRemote: true }))).toBe(false);
});
it("accepts a branched remote row and ignores an empty trailing row", () => {
expect(
computeHasAllBranches(
formState({
useRemote: true,
remoteRepos: [
{ key: "one", url: "https://example.com/one.git", branch: "main", source: "paste" },
{ key: "two", url: "", branch: "", source: "paste" },
],
}),
),
).toBe(true);
});
it("rejects local mode without a repository row", () => {
expect(computeHasAllBranches(formState({}))).toBe(false);
});
it("rejects a local repository row without a branch", () => {
expect(
computeHasAllBranches(
formState({ repositories: [{ key: "one", repositoryId: "repo-one", branch: "" }] }),
),
).toBe(false);
});
it("requires a branch on every local repository row", () => {
expect(
computeHasAllBranches(
formState({
repositories: [
{ key: "one", repositoryId: "repo-one", branch: "main" },
{ key: "two", repositoryId: "repo-two", branch: "develop" },
],
}),
),
).toBe(true);
});
});
describe("localRepositoryCreationEnabled", () => {
it("allows repository creation only for an unlocked new-task form", () => {
expect(localRepositoryCreationEnabled(true, false)).toBe(true);
expect(localRepositoryCreationEnabled(false, false)).toBe(false);
expect(localRepositoryCreationEnabled(true, true)).toBe(false);
});
});
describe("resolveWorkflowName", () => {
const workflows = [
{ id: "wf-dev", name: "Development" },
{ id: "wf-ops", name: "Operations" },
];
it("returns the name of the effective workflow", () => {
expect(resolveWorkflowName(workflows, "wf-dev")).toBe("Development");
});
it("returns null when no workflow is effective or the id is unknown", () => {
expect(resolveWorkflowName(workflows, null)).toBeNull();
expect(resolveWorkflowName(workflows, "wf-missing")).toBeNull();
});
});
describe("resolveDialogLaunchPreview", () => {
it("projects the selected workflow snapshot only for create mode", () => {
const steps: StepType[] = [
{
id: "step-1",
title: IN_PROGRESS,
position: 0,
is_start_step: true,
prompt: "Run {{task_prompt}}",
},
];
const snapshots = {
[WORKFLOW_ID]: { steps },
} as unknown as DialogFormBodyProps["snapshots"];
expect(resolveDialogLaunchPreview(true, WORKFLOW_ID, null, snapshots, true)).toEqual({
stepId: "step-1",
stepName: IN_PROGRESS,
stepPrompt: "Run {{task_prompt}}",
});
expect(resolveDialogLaunchPreview(false, WORKFLOW_ID, null, snapshots, true)).toBeNull();
});
it("projects the first positional step for the empty-description plan-mode action", () => {
const steps: StepType[] = [
{ id: "backlog", title: "Backlog", position: 0, prompt: "Queue it" },
{
id: "auto-start",
title: IN_PROGRESS,
position: 1,
events: { on_enter: [{ type: "auto_start_agent" }] },
prompt: "Run {{task_prompt}}",
},
];
const snapshots = {
[WORKFLOW_ID]: { steps },
} as unknown as DialogFormBodyProps["snapshots"];
expect(resolveDialogLaunchPreview(true, WORKFLOW_ID, null, snapshots, false)).toMatchObject({
stepId: "backlog",
stepName: "Backlog",
});
expect(resolveDialogLaunchPreview(true, WORKFLOW_ID, null, snapshots, true)).toMatchObject({
stepId: "auto-start",
stepName: IN_PROGRESS,
});
});
});