feat(FN-1484): fix agent picker stale cache on project switch
- Clear agent cache when projectId changes in QuickEntryBox and InlineCreateCard - Add regression tests for agent picker cache invalidation behavior - Add changeset for @gsxdsm/fusion patch release
This commit is contained in:
@@ -1082,6 +1082,106 @@ describe("InlineCreateCard button visibility when collapsed", () => {
|
||||
expect(payload.assignedAgentId).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("fetches fresh agents when projectId changes to prevent stale cache leakage", async () => {
|
||||
const project1Agents = [
|
||||
{
|
||||
id: "agent-001",
|
||||
name: "Project One Agent",
|
||||
role: "executor",
|
||||
state: "active",
|
||||
metadata: {},
|
||||
createdAt: "2026-01-01T00:00:00.000Z",
|
||||
updatedAt: "2026-01-01T00:00:00.000Z",
|
||||
},
|
||||
] as any;
|
||||
|
||||
const project2Agents = [
|
||||
{
|
||||
id: "agent-002",
|
||||
name: "Project Two Agent",
|
||||
role: "executor",
|
||||
state: "active",
|
||||
metadata: {},
|
||||
createdAt: "2026-01-01T00:00:00.000Z",
|
||||
updatedAt: "2026-01-01T00:00:00.000Z",
|
||||
},
|
||||
] as any;
|
||||
|
||||
// First render with project 1
|
||||
vi.mocked(fetchAgents).mockResolvedValueOnce(project1Agents);
|
||||
const { rerender } = renderCard([], { projectId: "proj-1" });
|
||||
expandCard();
|
||||
|
||||
// Open agent picker - should show project 1 agent
|
||||
fireEvent.click(screen.getByTestId("inline-create-agent-button"));
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Project One Agent")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Close picker and switch to project 2
|
||||
fireEvent.click(screen.getByTestId("inline-create-agent-button"));
|
||||
|
||||
// Rerender with different projectId - agents should be cleared and re-fetched
|
||||
vi.mocked(fetchAgents).mockResolvedValueOnce(project2Agents);
|
||||
rerender(<InlineCreateCard
|
||||
tasks={[]}
|
||||
onSubmit={vi.fn()}
|
||||
onCancel={vi.fn()}
|
||||
addToast={vi.fn()}
|
||||
availableModels={MOCK_MODELS}
|
||||
projectId="proj-2"
|
||||
/>);
|
||||
|
||||
// Open picker again for project 2
|
||||
expandCard();
|
||||
fireEvent.click(screen.getByTestId("inline-create-agent-button"));
|
||||
|
||||
await waitFor(() => {
|
||||
// Should show project 2's agent, not the stale project 1 agent
|
||||
expect(screen.getByText("Project Two Agent")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Verify project 1's agent is NOT shown
|
||||
expect(screen.queryByText("Project One Agent")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("clears selected agent when projectId changes", async () => {
|
||||
const agents = [
|
||||
{
|
||||
id: "agent-001",
|
||||
name: "Test Agent",
|
||||
role: "executor",
|
||||
state: "active",
|
||||
metadata: {},
|
||||
createdAt: "2026-01-01T00:00:00.000Z",
|
||||
updatedAt: "2026-01-01T00:00:00.000Z",
|
||||
},
|
||||
] as any;
|
||||
|
||||
vi.mocked(fetchAgents).mockResolvedValue(agents);
|
||||
const { rerender } = renderCard([], { projectId: "proj-1" });
|
||||
expandCard();
|
||||
|
||||
// Select an agent
|
||||
fireEvent.click(screen.getByTestId("inline-create-agent-button"));
|
||||
await waitFor(() => expect(screen.getByText("Test Agent")).toBeInTheDocument());
|
||||
fireEvent.click(screen.getByText("Test Agent"));
|
||||
|
||||
// Switch to different project
|
||||
rerender(<InlineCreateCard
|
||||
tasks={[]}
|
||||
onSubmit={vi.fn()}
|
||||
onCancel={vi.fn()}
|
||||
addToast={vi.fn()}
|
||||
availableModels={MOCK_MODELS}
|
||||
projectId="proj-2"
|
||||
/>);
|
||||
|
||||
// Selected agent should be cleared, picker should show "Agent" without name
|
||||
const agentButton = screen.getByTestId("inline-create-agent-button");
|
||||
expect(agentButton.textContent).toBe(" Agent");
|
||||
});
|
||||
});
|
||||
|
||||
describe("description fullscreen expansion", () => {
|
||||
|
||||
Reference in New Issue
Block a user