feat(FN-2441): singularize one-step progress labels
- Update TaskCard step toggle label to render "step" when the unified total is 1 - Update TaskDetailModal completion label to use singular/plural based on total step count - Add regression tests in TaskCard and TaskDetailModal suites to verify singular labels and reject incorrect plural forms - Tighten existing completion-count assertions to cover singular/plural text expectations
This commit is contained in:
@@ -113,6 +113,21 @@ describe("TaskCard", () => {
|
||||
expect(screen.getByText("5 steps")).toBeDefined();
|
||||
});
|
||||
|
||||
it("uses singular step label when unified progress total is one", () => {
|
||||
render(
|
||||
<TaskCard
|
||||
task={makeTask({
|
||||
steps: [{ name: "Step 0", status: "done" }],
|
||||
})}
|
||||
onOpenDetail={noop}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("1 step")).toBeDefined();
|
||||
expect(screen.queryByText("1 steps")).toBeNull();
|
||||
});
|
||||
|
||||
it("renders workflow checks after normal steps with mapped statuses", () => {
|
||||
const { container } = render(
|
||||
<TaskCard
|
||||
|
||||
@@ -995,7 +995,7 @@ function TaskCardComponent({
|
||||
aria-expanded={showSteps}
|
||||
aria-label={showSteps ? "Hide steps" : "Show steps"}
|
||||
>
|
||||
<span>{unifiedProgress.total} steps</span>
|
||||
<span>{unifiedProgress.total} step{unifiedProgress.total === 1 ? "" : "s"}</span>
|
||||
<ChevronDown
|
||||
size={14}
|
||||
className={`card-steps-toggle-icon${showSteps ? " expanded" : ""}`}
|
||||
|
||||
@@ -1415,7 +1415,7 @@ export function TaskDetailModal({
|
||||
))}
|
||||
</div>
|
||||
<span className="step-progress-label">
|
||||
{workingTask.steps.filter(s => s.status === "done").length}/{workingTask.steps.length} steps
|
||||
{workingTask.steps.filter(s => s.status === "done").length}/{workingTask.steps.length} step{workingTask.steps.length === 1 ? "" : "s"}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -1563,6 +1563,25 @@ describe("TaskCard steps toggle", () => {
|
||||
expect(toggle.textContent).toContain("2 steps");
|
||||
});
|
||||
|
||||
it("shows singular step label for one-step tasks", () => {
|
||||
const task = makeTask({
|
||||
column: "todo",
|
||||
steps: [{ name: "Only step", status: "pending" }],
|
||||
});
|
||||
|
||||
render(
|
||||
<TaskCard
|
||||
task={task}
|
||||
onOpenDetail={vi.fn()}
|
||||
addToast={noopToast}
|
||||
/>
|
||||
);
|
||||
|
||||
const toggle = screen.getByRole("button", { name: /Show steps/i });
|
||||
expect(toggle.textContent).toContain("1 step");
|
||||
expect(toggle.textContent).not.toContain("1 steps");
|
||||
});
|
||||
|
||||
it("clicking toggle expands and shows step list", () => {
|
||||
// Use 'todo' column to test default collapsed behavior
|
||||
const task = makeTask({
|
||||
|
||||
@@ -2220,6 +2220,25 @@ describe("TaskDetailModal", () => {
|
||||
expect((segments[3] as HTMLElement).style.backgroundColor).toBe("var(--text-dim, #484f58)");
|
||||
});
|
||||
|
||||
it("displays singular completion label for one-step tasks", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({
|
||||
steps: [{ name: "Step 1", status: "done" }],
|
||||
})}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={noopDelete}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("1/1 step")).toBeTruthy();
|
||||
expect(screen.queryByText("1/1 steps")).toBeNull();
|
||||
});
|
||||
|
||||
it("displays correct completion count", () => {
|
||||
render(
|
||||
<TaskDetailModal
|
||||
@@ -2241,6 +2260,7 @@ describe("TaskDetailModal", () => {
|
||||
);
|
||||
|
||||
expect(screen.getByText("2/4 steps")).toBeTruthy();
|
||||
expect(screen.queryByText("2/4 step")).toBeNull();
|
||||
});
|
||||
|
||||
it("has data-tooltip attribute with step name and status on each segment", () => {
|
||||
|
||||
Reference in New Issue
Block a user