feat(FN-1906): merge fusion/fn-1906
This commit is contained in:
@@ -783,6 +783,24 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr
|
||||
|
||||
const handleMissionUpdated = (rawEvent: Event) => {
|
||||
refreshHealth();
|
||||
|
||||
// Update mission status in the list to keep badges in sync
|
||||
const messageEvent = rawEvent as MessageEvent<string>;
|
||||
if (messageEvent.data) {
|
||||
try {
|
||||
const updatedMission = JSON.parse(messageEvent.data);
|
||||
if (updatedMission?.id) {
|
||||
setMissions((prev) =>
|
||||
prev.map((m) =>
|
||||
m.id === updatedMission.id ? { ...m, ...updatedMission } : m
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
// ignore invalid payloads
|
||||
}
|
||||
}
|
||||
|
||||
// Reload the selected mission detail to reflect updated mission state (autopilot, status, etc.)
|
||||
if (selectedMission) {
|
||||
void loadMissionDetail(selectedMission.id);
|
||||
|
||||
@@ -911,6 +911,42 @@ describe("MissionManager", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("updates mission status badge when mission:updated SSE event arrives", async () => {
|
||||
globalThis.fetch = createFetchMock();
|
||||
globalThis.EventSource = MockEventSource as unknown as typeof globalThis.EventSource;
|
||||
|
||||
render(<MissionManager isOpen={true} onClose={vi.fn()} addToast={vi.fn()} />);
|
||||
|
||||
// Wait for initial render — M-001 has status "planning"
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Build Auth System")).toBeDefined();
|
||||
});
|
||||
|
||||
// Verify initial status badge shows "planning"
|
||||
const missionItem = screen.getByText("Build Auth System").closest(".mission-list__item");
|
||||
expect(missionItem).toBeDefined();
|
||||
const planningBadges = missionItem!.querySelectorAll(".mission-status-badge");
|
||||
expect([...planningBadges].some((b) => b.textContent === "planning")).toBe(true);
|
||||
|
||||
// Emit mission:updated SSE event changing M-001 to "active"
|
||||
await act(async () => {
|
||||
for (const source of MockEventSource.instances) {
|
||||
source.emit("mission:updated", {
|
||||
id: "M-001",
|
||||
title: "Build Auth System",
|
||||
status: "active",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Verify the badge now shows "active" instead of "planning"
|
||||
await waitFor(() => {
|
||||
const updatedBadges = missionItem!.querySelectorAll(".mission-status-badge");
|
||||
expect([...updatedBadges].some((b) => b.textContent === "active")).toBe(true);
|
||||
expect([...updatedBadges].some((b) => b.textContent === "planning")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("reloads selected mission detail when slice:updated SSE event arrives", async () => {
|
||||
const fetchMock = createDetailFetchMock(mockMissionEvents);
|
||||
globalThis.fetch = fetchMock;
|
||||
|
||||
Reference in New Issue
Block a user