Layout and search fix
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 2m4s
🏗️ Build and Test JellyTau / Android Compile Check (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Successful in 23s
Build & Release / Run Tests (push) Failing after 2m45s
Build & Release / Build Linux (push) Has been skipped
Build & Release / Build Android (push) Has been skipped
Build & Release / Create Release (push) Has been skipped

This commit is contained in:
2026-07-11 19:55:55 +02:00
parent a2cd9978f0
commit 2a1f1689b4
20 changed files with 991 additions and 995 deletions
+62
View File
@@ -295,6 +295,68 @@ describe("playbackMode store", () => {
});
});
describe("refresh (reconcile to Rust authoritative mode)", () => {
it("adopts the Rust mode and aligns the selected session", async () => {
const { playbackMode } = await import("./playbackMode");
// Start disagreeing with Rust: store thinks local, Rust says remote.
playbackMode.setMode("local");
mockInvoke.mockResolvedValueOnce({ type: "remote", session_id: "sess-xyz" });
await playbackMode.refresh();
const state = get(playbackMode);
expect(state.mode).toBe("remote");
expect(state.remoteSessionId).toBe("sess-xyz");
// The merged UI stores follow selectedSession, so it must be aligned too.
expect(mockSelectSession).toHaveBeenCalledWith("sess-xyz");
});
it("clears the selected session when Rust reports non-remote", async () => {
const { playbackMode } = await import("./playbackMode");
playbackMode.setMode("remote", "sess-old");
mockInvoke.mockResolvedValueOnce({ type: "idle" });
await playbackMode.refresh();
const state = get(playbackMode);
expect(state.mode).toBe("idle");
expect(state.remoteSessionId).toBeNull();
expect(mockSelectSession).toHaveBeenCalledWith(null);
});
});
describe("transfer reconciles to Rust on completion", () => {
it("refreshes from Rust after a successful transferToRemote", async () => {
const { playbackMode } = await import("./playbackMode");
// First call: the transfer command; second call: the finally refresh.
mockInvoke.mockResolvedValueOnce(undefined);
mockInvoke.mockResolvedValueOnce({ type: "remote", session_id: "session-456" });
await playbackMode.transferToRemote("session-456");
expect(mockInvoke).toHaveBeenCalledWith("playback_mode_get_current");
});
it("still reconciles to Rust when transferToRemote throws mid-transfer", async () => {
const { playbackMode } = await import("./playbackMode");
// Transfer command fails, leaving the optimistic state possibly wrong.
mockInvoke.mockRejectedValueOnce(new Error("boom"));
// The finally refresh reads the true mode (Rust never left local).
mockInvoke.mockResolvedValueOnce({ type: "local" });
await expect(playbackMode.transferToRemote("session-456")).rejects.toThrow("boom");
// The reconciling read must have happened despite the throw.
expect(mockInvoke).toHaveBeenCalledWith("playback_mode_get_current");
const state = get(playbackMode);
expect(state.mode).toBe("local");
});
});
describe("clearError", () => {
it("should clear transfer error", async () => {
const { playbackMode } = await import("./playbackMode");