| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "testing" |
| 6 | ) |
| 7 | |
| 8 | func TestClearRemotePendingPromptExactPreservesReplacement(t *testing.T) { |
| 9 | tab := &remoteTab{ |
| 10 | id: "remote-1", ref: RemoteTabRef{HostID: "host-a"}, gen: 7, |
| 11 | session: remoteTabSessionState{sessionID: "session-a"}, |
| 12 | pendingEvents: map[string]json.RawMessage{ |
| 13 | "ask_request:1": json.RawMessage(`{"kind":"ask_request","runtimeEpoch":"runtime-new","ask":{"id":"1","turnId":"turn-new","questions":[]}}`), |
| 14 | }, |
| 15 | runtime: remoteTabRuntimeState{pendingPrompt: true}, |
| 16 | } |
| 17 | a := &App{remoteTabs: map[string]*remoteTab{tab.id: tab}, remoteEventHook: func(string, any) {}} |
| 18 | old := RemotePromptTarget{TabID: tab.id, HostID: "host-a", SessionID: "session-a", SessionGeneration: 7, |
| 19 | PromptID: "1", TurnID: "turn-old", RuntimeEpoch: "runtime-old", Kind: "ask"} |
| 20 | a.clearRemotePendingPromptExact(old) |
| 21 | if len(tab.pendingEvents) != 1 || !tab.runtime.pendingPrompt { |
| 22 | t.Fatalf("old completion removed replacement: pending=%d runtime=%+v", len(tab.pendingEvents), tab.runtime) |
| 23 | } |
| 24 | current := old |
| 25 | current.TurnID, current.RuntimeEpoch = "turn-new", "runtime-new" |
| 26 | a.clearRemotePendingPromptExact(current) |
| 27 | if len(tab.pendingEvents) != 0 || tab.runtime.pendingPrompt { |
| 28 | t.Fatalf("current completion did not clear its request: pending=%d runtime=%+v", len(tab.pendingEvents), tab.runtime) |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | func TestRemotePendingEventKeyIncludesMCPIdentity(t *testing.T) { |
| 33 | frame := json.RawMessage(`{"kind":"mcp_interaction","mcpInteraction":{"id":"elicitation-1","turnId":"turn-1"}}`) |
| 34 | if got := remotePendingEventKey("mcp_interaction", frame); got != "mcp_interaction:elicitation-1" { |
| 35 | t.Fatalf("pending MCP key = %q", got) |
| 36 | } |
| 37 | } |
| 38 |