fix(cli): store annonces inter-agent borné par projectId avec reset et réhydratation busy au changement de projet — #236
This commit is contained in:
@ -24,17 +24,19 @@ import { TargetAnnouncementsOverlay } from "./TargetAnnouncementsOverlay";
|
||||
|
||||
function setup(
|
||||
node: React.ReactNode,
|
||||
opts: { workState?: MockWorkStateGateway } = {},
|
||||
opts: { projectId?: string | null; workState?: MockWorkStateGateway } = {},
|
||||
) {
|
||||
const system = new MockSystemGateway();
|
||||
const workState = opts.workState;
|
||||
const gateways = { system, workState } as unknown as Gateways;
|
||||
render(
|
||||
const result = render(
|
||||
<DIProvider gateways={gateways}>
|
||||
<AnnouncementsProvider>{node}</AnnouncementsProvider>
|
||||
<AnnouncementsProvider projectId={opts.projectId ?? "p1"}>
|
||||
{node}
|
||||
</AnnouncementsProvider>
|
||||
</DIProvider>,
|
||||
);
|
||||
return { system };
|
||||
return { system, ...result };
|
||||
}
|
||||
|
||||
type AnnouncementEvent = Extract<DomainEvent, { type: "agentAnnouncement" }>;
|
||||
@ -84,6 +86,27 @@ describe("F3 — overlay lifecycle is the target's busy state", () => {
|
||||
expect(screen.getByText("en cours")).not.toBeNull();
|
||||
});
|
||||
|
||||
it("ignores streamed announcements from another project", async () => {
|
||||
const { system } = setup(
|
||||
<TargetAnnouncementsOverlay projectId="p1" agentId="agent-T" />,
|
||||
);
|
||||
await flush();
|
||||
|
||||
act(() => {
|
||||
system.emit(busy("agent-T", true));
|
||||
system.emit(
|
||||
announcement({
|
||||
projectId: "p2",
|
||||
target: "agent-T",
|
||||
text: "other-project",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
expect(overlay()).not.toBeNull();
|
||||
expect(screen.queryByText("other-project")).toBeNull();
|
||||
});
|
||||
|
||||
it("mounts on busy:true even before any announcement (banner only)", async () => {
|
||||
const { system } = setup(
|
||||
<TargetAnnouncementsOverlay projectId="p1" agentId="agent-T" />,
|
||||
@ -171,6 +194,64 @@ describe("F3 — overlay lifecycle is the target's busy state", () => {
|
||||
expect(overlay()).not.toBeNull();
|
||||
});
|
||||
|
||||
it("resets and rehydrates when switching project", async () => {
|
||||
const workState = new MockWorkStateGateway();
|
||||
workState._setProjectWorkState("p1", {
|
||||
agents: [
|
||||
{
|
||||
agentId: "agent-T",
|
||||
name: "Target",
|
||||
profileId: "prof",
|
||||
busy: { state: "idle" },
|
||||
tickets: [],
|
||||
},
|
||||
],
|
||||
conversations: [],
|
||||
});
|
||||
workState._setProjectWorkState("p2", {
|
||||
agents: [
|
||||
{
|
||||
agentId: "agent-T",
|
||||
name: "Target",
|
||||
profileId: "prof",
|
||||
busy: { state: "busy", ticket: "t-p2", sinceMs: 456 },
|
||||
tickets: [],
|
||||
},
|
||||
],
|
||||
conversations: [],
|
||||
});
|
||||
|
||||
const system = new MockSystemGateway();
|
||||
const gateways = { system, workState } as unknown as Gateways;
|
||||
const { rerender } = render(
|
||||
<DIProvider gateways={gateways}>
|
||||
<AnnouncementsProvider projectId="p1">
|
||||
<TargetAnnouncementsOverlay projectId="p1" agentId="agent-T" />
|
||||
</AnnouncementsProvider>
|
||||
</DIProvider>,
|
||||
);
|
||||
await flush();
|
||||
|
||||
act(() => {
|
||||
system.emit(busy("agent-T", true));
|
||||
system.emit(announcement({ projectId: "p1", text: "old-p1" }));
|
||||
});
|
||||
expect(screen.getByText("old-p1")).not.toBeNull();
|
||||
|
||||
rerender(
|
||||
<DIProvider gateways={gateways}>
|
||||
<AnnouncementsProvider projectId="p2">
|
||||
<TargetAnnouncementsOverlay projectId="p2" agentId="agent-T" />
|
||||
</AnnouncementsProvider>
|
||||
</DIProvider>,
|
||||
);
|
||||
await flush();
|
||||
|
||||
expect(overlay()).not.toBeNull();
|
||||
expect(screen.queryByText("old-p1")).toBeNull();
|
||||
expect(screen.getByText("Travaille sur une demande en cours.")).not.toBeNull();
|
||||
});
|
||||
|
||||
it("stays down when the read-model reports the agent idle", async () => {
|
||||
const workState = new MockWorkStateGateway();
|
||||
workState._setProjectWorkState("p1", {
|
||||
|
||||
Reference in New Issue
Block a user