Merge story-31: View Upcoming Stories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

# Conflicts:
#	frontend/src/api/workflow.ts
#	frontend/src/components/Chat.test.tsx
#	frontend/src/components/Chat.tsx
#	server/src/http/workflow.rs
This commit is contained in:
Dave
2026-02-19 15:54:02 +00:00
11 changed files with 521 additions and 2 deletions

View File

@@ -36,6 +36,7 @@ vi.mock("../api/workflow", () => {
recordCoverage: vi.fn(),
collectCoverage: vi.fn(),
getStoryTodos: vi.fn(),
getUpcomingStories: vi.fn(),
},
};
});
@@ -56,6 +57,7 @@ const mockedWorkflow = {
getReviewQueueAll: vi.mocked(workflowApi.getReviewQueueAll),
ensureAcceptance: vi.mocked(workflowApi.ensureAcceptance),
getStoryTodos: vi.mocked(workflowApi.getStoryTodos),
getUpcomingStories: vi.mocked(workflowApi.getUpcomingStories),
};
describe("Chat review panel", () => {
@@ -78,6 +80,7 @@ describe("Chat review panel", () => {
mockedWorkflow.getReviewQueueAll.mockResolvedValue({ stories: [] });
mockedWorkflow.ensureAcceptance.mockResolvedValue(true);
mockedWorkflow.getStoryTodos.mockResolvedValue({ stories: [] });
mockedWorkflow.getUpcomingStories.mockResolvedValue({ stories: [] });
});
it("shows an empty review queue state", async () => {
@@ -469,6 +472,23 @@ describe("Chat review panel", () => {
expect(await screen.findByText(/Coverage: 92\.0%/)).toBeInTheDocument();
});
it("fetches upcoming stories on mount and renders panel", async () => {
mockedWorkflow.getUpcomingStories.mockResolvedValueOnce({
stories: [
{ story_id: "31_view_upcoming", name: "View Upcoming Stories" },
{ story_id: "32_worktree", name: null },
],
});
render(<Chat projectPath="/tmp/project" onCloseProject={vi.fn()} />);
expect(await screen.findByText("Upcoming Stories")).toBeInTheDocument();
expect(
await screen.findByText("View Upcoming Stories"),
).toBeInTheDocument();
expect(await screen.findByText("32_worktree")).toBeInTheDocument();
});
it("collect coverage button triggers collection and refreshes gate", async () => {
const mockedCollectCoverage = vi.mocked(workflowApi.collectCoverage);
mockedCollectCoverage.mockResolvedValueOnce({