feat(workbench): expand SCADA monitoring and investigation presentation
This commit is contained in:
@@ -153,7 +153,7 @@ describe("live investigation presentation following", () => {
|
||||
test.channel.publish({ type: "events", events: [event(12, openChart), event(20, openChart), event(21, closeChart)] });
|
||||
oldDisplay.resolve();
|
||||
await vi.waitFor(() => expect(execute.mock.calls.map(([command]) => command.action)).toEqual(["highlight_features", "close_chart"]));
|
||||
expect(test.clear.mock.calls.length).toBeGreaterThan(clearCount);
|
||||
expect(test.clear.mock.calls.length).toBe(clearCount);
|
||||
expect(execute.mock.calls[1]?.[1].aborted).toBe(false);
|
||||
} finally { oldDisplay.resolve(); test.follower.stop(); }
|
||||
});
|
||||
@@ -199,3 +199,51 @@ it("reads saved history even before the live event stream opens", async () => {
|
||||
expect(test.execute).not.toHaveBeenCalled();
|
||||
} finally { test.follower.stop(); }
|
||||
});
|
||||
|
||||
|
||||
it("keeps successful results across disconnect and failed reconnect, clearing only for a new identity", async () => {
|
||||
let visible = "saved chart";
|
||||
const clear = vi.fn(() => { visible = ""; });
|
||||
const fetchCursor = vi.fn(async () => cursor(10));
|
||||
const test = setup({ clear, fetchCursor });
|
||||
test.follower.start(); test.channel.publish({ type: "open" });
|
||||
try {
|
||||
await vi.waitFor(() => expect(test.onStatus).toHaveBeenCalledWith("live"));
|
||||
visible = "saved chart";
|
||||
clear.mockClear();
|
||||
test.channel.publish({ type: "disconnect" });
|
||||
expect(visible).toBe("saved chart");
|
||||
expect(clear).not.toHaveBeenCalled();
|
||||
fetchCursor.mockRejectedValueOnce(new Error("offline"));
|
||||
test.channel.publish({ type: "open" });
|
||||
await vi.waitFor(() => expect(test.onStatus).toHaveBeenCalledWith("error", "offline"));
|
||||
expect(visible).toBe("saved chart");
|
||||
fetchCursor.mockResolvedValueOnce(cursor(20, 2));
|
||||
test.channel.publish({ type: "open" });
|
||||
await vi.waitFor(() => expect(clear).toHaveBeenCalledTimes(1));
|
||||
expect(visible).toBe("");
|
||||
} finally { test.follower.stop(); }
|
||||
});
|
||||
|
||||
it("clears a changed generation before hydrating its saved results and ignores a stale connection", async () => {
|
||||
const stale = deferred<InvestigationPresentationCursor>();
|
||||
const order: string[] = [];
|
||||
const fetchCursor = vi.fn(async () => cursor(10))
|
||||
.mockResolvedValueOnce(cursor(10))
|
||||
.mockImplementationOnce(() => stale.promise)
|
||||
.mockResolvedValueOnce(cursor(30, 2));
|
||||
const test = setup({ fetchCursor, clear: () => order.push("clear"), loadHistory: async (next) => { order.push(`history:${next.execution_generation}`); } });
|
||||
test.follower.start();
|
||||
try {
|
||||
await vi.waitFor(() => expect(order).toContain("history:1"));
|
||||
order.length = 0;
|
||||
test.channel.publish({ type: "open" });
|
||||
test.channel.publish({ type: "disconnect" });
|
||||
test.channel.publish({ type: "open" });
|
||||
await vi.waitFor(() => expect(order).toContain("history:2"));
|
||||
expect(order).toEqual(["clear", "history:2"]);
|
||||
stale.resolve(cursor(20));
|
||||
await Promise.resolve();
|
||||
expect(order).toEqual(["clear", "history:2"]);
|
||||
} finally { stale.resolve(cursor(20)); test.follower.stop(); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user