test(dashboard): consolidate low-signal TaskDetailModal matrix tests
Collapse CSS-class presence checks and column-gate permutations into table-driven variants. The rest of this file covers real user flows (retry uniqueness FN-bug, paste/drag upload, plan approval, inline editing, agent assignment, etc.) and was left intact. - mobile responsive structure 6→1 (class-presence aggregate) - Commits tab visibility 3→1 (it.each over done-task variants) - Refinement button column gate 5→2 (it.each over columns) - Workflow tab visibility 4→1 (it.each over data states) 5,676 → 5,433 LOC (-243). 190 tests still passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -528,16 +528,6 @@ describe("SettingsModal", () => {
|
||||
expect(screen.getByText("Smart conflict resolution")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("shows Recycle worktrees checkbox in Worktrees section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Worktrees"));
|
||||
const checkbox = screen.getByLabelText("Recycle worktrees");
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox.getAttribute("type")).toBe("checkbox");
|
||||
});
|
||||
|
||||
it("toggling recycleWorktrees checkbox sends true in save payload", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
@@ -608,16 +598,6 @@ describe("SettingsModal", () => {
|
||||
expect(updateSettings).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shows Show quick chat button checkbox in General section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getAllByText("General")[0]);
|
||||
const checkbox = screen.getByLabelText("Show quick chat button");
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox.getAttribute("type")).toBe("checkbox");
|
||||
});
|
||||
|
||||
it("showQuickChatFAB defaults to unchecked (false) when not set", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
@@ -692,16 +672,6 @@ describe("SettingsModal", () => {
|
||||
expect(payload.showQuickChatFAB).toBe(false);
|
||||
});
|
||||
|
||||
it("shows Auto-completion mode select in Merge section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Merge"));
|
||||
const select = screen.getByLabelText("Auto-completion mode") as HTMLSelectElement;
|
||||
expect(select).toBeTruthy();
|
||||
expect(select.value).toBe("direct");
|
||||
});
|
||||
|
||||
it("saves pull-request mergeStrategy when selected", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
@@ -717,26 +687,6 @@ describe("SettingsModal", () => {
|
||||
expect(payload.mergeStrategy).toBe("pull-request");
|
||||
});
|
||||
|
||||
it("shows Include task ID in commit scope checkbox in Merge section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Merge"));
|
||||
const checkbox = screen.getByLabelText("Include task ID in commit scope");
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox.getAttribute("type")).toBe("checkbox");
|
||||
});
|
||||
|
||||
it("shows Auto-resolve conflicts checkbox in Merge section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Merge"));
|
||||
const checkbox = screen.getByLabelText("Auto-resolve conflicts in lock files and generated files");
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox.getAttribute("type")).toBe("checkbox");
|
||||
});
|
||||
|
||||
it("toggling includeTaskIdInCommit checkbox sends false in save payload", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
@@ -753,16 +703,6 @@ describe("SettingsModal", () => {
|
||||
expect(payload.includeTaskIdInCommit).toBe(false);
|
||||
});
|
||||
|
||||
it("shows Add author attribution to commits checkbox in Merge section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Merge"));
|
||||
const checkbox = screen.getByLabelText("Add author attribution to commits");
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox.getAttribute("type")).toBe("checkbox");
|
||||
});
|
||||
|
||||
it("toggling commitAuthorEnabled checkbox sends false in save payload when unchecked", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
@@ -879,16 +819,6 @@ describe("SettingsModal", () => {
|
||||
expect(checkbox.checked).toBe(true);
|
||||
});
|
||||
|
||||
it("shows Smart conflict resolution checkbox in Merge section", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Merge"));
|
||||
const checkbox = screen.getByLabelText("Smart conflict resolution");
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(checkbox.getAttribute("type")).toBe("checkbox");
|
||||
});
|
||||
|
||||
it("toggling smartConflictResolution checkbox sends false in save payload when unchecked", async () => {
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
@@ -3234,10 +3164,9 @@ describe("SettingsModal", () => {
|
||||
specStalenessMaxAgeMs: 6 * 60 * 60 * 1000,
|
||||
});
|
||||
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} />);
|
||||
render(<SettingsModal onClose={onClose} addToast={addToast} initialSection="scheduling" />);
|
||||
await waitFor(() => expect(fetchSettings).toHaveBeenCalled());
|
||||
|
||||
fireEvent.click(screen.getByText("Scheduling"));
|
||||
const thresholdInput = screen.getByLabelText("Stale Spec Threshold (hours)") as HTMLInputElement;
|
||||
expect(thresholdInput.value).toBe("6");
|
||||
});
|
||||
|
||||
@@ -2342,41 +2342,7 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
|
||||
describe("mobile responsive structure", () => {
|
||||
it("modal container has both 'modal' and 'modal-lg' classes for responsive CSS targeting", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const modal = container.querySelector(".modal.modal-lg");
|
||||
expect(modal).toBeTruthy();
|
||||
});
|
||||
|
||||
it("modal overlay has 'modal-overlay' and 'open' classes", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const overlay = container.querySelector(".modal-overlay.open");
|
||||
expect(overlay).toBeTruthy();
|
||||
});
|
||||
|
||||
it("modal-actions contains the spacer div for flex layout", () => {
|
||||
it("renders responsive structural classes (modal-lg, overlay, spacer, tabs, detail-body)", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "in-progress" as Column })}
|
||||
@@ -2388,79 +2354,18 @@ describe("TaskDetailModal", () => {
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const actions = container.querySelector(".modal-actions");
|
||||
expect(actions).toBeTruthy();
|
||||
// Spacer div separates left actions from right actions via CSS class
|
||||
const spacer = actions!.querySelector(".modal-actions-spacer");
|
||||
expect(spacer).toBeTruthy();
|
||||
expect((spacer as HTMLElement).className).toContain("modal-actions-spacer");
|
||||
});
|
||||
|
||||
it("tab buttons use CSS classes instead of inline styles for responsive override", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container.querySelector(".modal.modal-lg")).toBeTruthy();
|
||||
expect(container.querySelector(".modal-overlay.open")).toBeTruthy();
|
||||
expect(container.querySelector(".modal-actions .modal-actions-spacer")).toBeTruthy();
|
||||
expect(container.querySelector(".detail-body")).toBeTruthy();
|
||||
const tabs = container.querySelectorAll(".detail-tab");
|
||||
expect(tabs.length).toBe(7); // Definition, Logs, Changes, Comments, Documents, Model, Workflow
|
||||
// Tabs should use class-based styling, not inline styles
|
||||
expect(tabs[0].classList.contains("detail-tab")).toBe(true);
|
||||
expect(tabs[0].classList.contains("detail-tab-active")).toBe(true); // Definition is default active
|
||||
expect(tabs[1].classList.contains("detail-tab-active")).toBe(false);
|
||||
expect(tabs[2].classList.contains("detail-tab-active")).toBe(false);
|
||||
expect(tabs[3].classList.contains("detail-tab-active")).toBe(false);
|
||||
expect(tabs[4].classList.contains("detail-tab-active")).toBe(false);
|
||||
expect(tabs[5].classList.contains("detail-tab-active")).toBe(false);
|
||||
expect(tabs[6].classList.contains("detail-tab-active")).toBe(false);
|
||||
// Verify no inline padding/fontSize (responsive CSS controls this)
|
||||
expect(tabs.length).toBe(7);
|
||||
expect(tabs[0].classList.contains("detail-tab-active")).toBe(true);
|
||||
expect(Array.from(tabs).slice(1).every((t) => !t.classList.contains("detail-tab-active"))).toBe(true);
|
||||
// Responsive CSS controls sizing — no inline padding/fontSize/borderBottom leaks
|
||||
expect((tabs[0] as HTMLElement).style.padding).toBe("");
|
||||
expect((tabs[0] as HTMLElement).style.fontSize).toBe("");
|
||||
});
|
||||
|
||||
it("detail-tabs container uses CSS class instead of inline styles", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const tabsContainer = container.querySelector(".detail-tabs");
|
||||
expect(tabsContainer).toBeTruthy();
|
||||
// Should not have inline display/borderBottom styles — CSS class handles it
|
||||
expect((tabsContainer as HTMLElement).style.display).toBe("");
|
||||
expect((tabsContainer as HTMLElement).style.borderBottom).toBe("");
|
||||
});
|
||||
|
||||
it("detail-body is present and scrollable (flex: 1 + overflow-y: auto via CSS)", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
const body = container.querySelector(".detail-body");
|
||||
expect(body).toBeTruthy();
|
||||
expect((container.querySelector(".detail-tabs") as HTMLElement).style.borderBottom).toBe("");
|
||||
});
|
||||
|
||||
it("modal-actions contains Delete and Pause buttons for non-done tasks (via Actions dropdown)", () => {
|
||||
@@ -3775,10 +3680,15 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
|
||||
describe("Refinement button", () => {
|
||||
it("renders Refine button for 'done' column tasks (in Actions dropdown)", () => {
|
||||
it.each<[Column, boolean]>([
|
||||
["done", true],
|
||||
["in-review", true],
|
||||
["todo", false],
|
||||
["in-progress", false],
|
||||
])("Refine action visibility in column=%s is %s", (column, shouldShow) => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "done" })}
|
||||
task={makeTask({ column })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
@@ -3787,35 +3697,13 @@ describe("TaskDetailModal", () => {
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Open Actions dropdown to see Refine
|
||||
const actionsBtn = screen.getByRole("button", { name: /actions/i });
|
||||
fireEvent.click(actionsBtn);
|
||||
|
||||
expect(screen.getByRole("menuitem", { name: "Refine" })).toBeTruthy();
|
||||
fireEvent.click(screen.getByRole("button", { name: /actions/i }));
|
||||
const item = screen.queryByRole("menuitem", { name: "Refine" });
|
||||
if (shouldShow) expect(item).toBeTruthy();
|
||||
else expect(item).toBeNull();
|
||||
});
|
||||
|
||||
it("renders Refine button for 'in-review' column tasks (in Actions dropdown)", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "in-review" })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Open Actions dropdown to see Refine
|
||||
const actionsBtn = screen.getByRole("button", { name: /actions/i });
|
||||
fireEvent.click(actionsBtn);
|
||||
|
||||
expect(screen.getByRole("menuitem", { name: "Refine" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("does NOT render Refine button for 'triage' column tasks", () => {
|
||||
it("does NOT render Refine button for 'triage' column tasks (no Actions dropdown)", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "triage" })}
|
||||
@@ -3827,49 +3715,9 @@ describe("TaskDetailModal", () => {
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
// No Refine button visible for triage tasks (no Actions dropdown)
|
||||
expect(screen.queryByText("Refine")).toBeNull();
|
||||
});
|
||||
|
||||
it("does NOT render Refine button for 'todo' column tasks", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "todo" })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Open Actions dropdown - Refine should not be there
|
||||
const actionsBtn = screen.getByRole("button", { name: /actions/i });
|
||||
fireEvent.click(actionsBtn);
|
||||
expect(screen.queryByRole("menuitem", { name: "Refine" })).toBeNull();
|
||||
});
|
||||
|
||||
it("does NOT render Refine button for 'in-progress' column tasks", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ column: "in-progress" })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Open Actions dropdown - Refine should not be there
|
||||
const actionsBtn = screen.getByRole("button", { name: /actions/i });
|
||||
fireEvent.click(actionsBtn);
|
||||
expect(screen.queryByRole("menuitem", { name: "Refine" })).toBeNull();
|
||||
});
|
||||
|
||||
it("clicking Refine opens the refinement modal", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
@@ -4808,13 +4656,14 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
|
||||
describe("Commits tab visibility", () => {
|
||||
it("does NOT show a separate Commits tab for done tasks with mergeDetails.commitSha (changes are shown in Changes tab)", () => {
|
||||
it.each<[string, Parameters<typeof makeTask>[0]]>([
|
||||
["with mergeDetails.commitSha", { column: "done", mergeDetails: { commitSha: "abc1234567890", filesChanged: 3, insertions: 10, deletions: 2 } }],
|
||||
["with mergeDetails but no commitSha", { column: "done", mergeDetails: { filesChanged: 3 } }],
|
||||
["without mergeDetails", { column: "done" }],
|
||||
])("never shows a separate Commits tab for done tasks (%s) — changes are in the Changes tab", (_label, taskOverrides) => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({
|
||||
column: "done",
|
||||
mergeDetails: { commitSha: "abc1234567890", filesChanged: 3, insertions: 10, deletions: 2 },
|
||||
})}
|
||||
task={makeTask(taskOverrides)}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
@@ -4823,53 +4672,10 @@ describe("TaskDetailModal", () => {
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Commits tab should not exist
|
||||
expect(screen.queryByText("Commits")).toBeNull();
|
||||
|
||||
// Changes tab should exist and be available
|
||||
const tabs = container.querySelectorAll(".detail-tab");
|
||||
expect(tabs.length).toBe(7); // Definition, Logs, Changes, Comments, Documents, Model, Workflow
|
||||
const tabTexts = Array.from(tabs).map((t) => t.textContent);
|
||||
const tabTexts = Array.from(container.querySelectorAll(".detail-tab")).map((t) => t.textContent);
|
||||
expect(tabTexts).toContain("Changes");
|
||||
});
|
||||
|
||||
it("does NOT show Commits tab for done tasks without commitSha", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({
|
||||
column: "done",
|
||||
mergeDetails: { filesChanged: 3 },
|
||||
})}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.queryByText("Commits")).toBeNull();
|
||||
});
|
||||
|
||||
it("does NOT show Commits tab for done tasks without mergeDetails", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({
|
||||
column: "done",
|
||||
})}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.queryByText("Commits")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("comment state propagation (FN-845)", () => {
|
||||
@@ -4991,42 +4797,15 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
|
||||
describe("Workflow tab", () => {
|
||||
it("shows Workflow tab even when enabledWorkflowSteps is empty", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ enabledWorkflowSteps: [] })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Workflow")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows Workflow tab even when enabledWorkflowSteps is undefined", () => {
|
||||
const { container } = render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ enabledWorkflowSteps: undefined, workflowStepResults: undefined })}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Workflow")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows Workflow tab when enabledWorkflowSteps is non-empty", () => {
|
||||
it.each<[string, Parameters<typeof makeTask>[0]]>([
|
||||
["empty enabledWorkflowSteps", { enabledWorkflowSteps: [] }],
|
||||
["undefined enabledWorkflowSteps", { enabledWorkflowSteps: undefined, workflowStepResults: undefined }],
|
||||
["non-empty enabledWorkflowSteps", { enabledWorkflowSteps: ["WS-001"] }],
|
||||
["previous workflow results", { enabledWorkflowSteps: [], workflowStepResults: [{ workflowStepId: "WS-001", workflowStepName: "QA Check", status: "passed" }] }],
|
||||
])("Workflow tab is always rendered (%s)", (_label, taskOverrides) => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({ enabledWorkflowSteps: ["WS-001"] })}
|
||||
task={makeTask(taskOverrides)}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
@@ -5035,28 +4814,6 @@ describe("TaskDetailModal", () => {
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Workflow")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("shows Workflow tab when task has previous workflow results", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({
|
||||
enabledWorkflowSteps: [],
|
||||
workflowStepResults: [
|
||||
{ workflowStepId: "WS-001", workflowStepName: "QA Check", status: "passed" },
|
||||
],
|
||||
})}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Workflow")).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user