TestCmdDoLiveSessionGuard checks that a task whose session_id is in the live-claude-process set refuses to spawn (when focus can't find the tab) unless --force is passed. This is feature 3 of the bundled fields/sessions task. The focus path is short-circuited by stubbing iterm.PSRunner with empty ou
(t *testing.T)
| 128 | return &os.PathError{Op: "stat", Path: p, Err: os.ErrNotExist} |
| 129 | } |
| 130 | t.Cleanup(func() { claude.StatFn = old }) |
| 131 | } |
| 132 | |
| 133 | // TestCmdDoLiveSessionGuard checks that a task whose session_id is in |
| 134 | // the live-claude-process set refuses to spawn (when focus can't find |
| 135 | // the tab) unless --force is passed. This is feature 3 of the |
| 136 | // bundled fields/sessions task. The focus path is short-circuited by |
| 137 | // stubbing iterm.PSRunner with empty output so ttyForClaudeSession |
| 138 | // returns "" → FocusSession returns (false, nil) → fall through to |
| 139 | // the original error message. |
| 140 | func TestCmdDoLiveSessionGuard(t *testing.T) { |
| 141 | setupFlowRoot(t) |
| 142 | seedTask(t, "live-task") |
| 143 | |
| 144 | // This exercises the Claude-specific live-process guard. Clear the |
| 145 | // ambient harness inherited from the test process (which may be Codex) |
| 146 | // so harnessForSpawn selects Claude as intended. |
| 147 | for _, h := range allHarnesses() { |
| 148 | t.Setenv(h.SessionIDEnvVar(), "") |
| 149 | } |
| 150 | |
| 151 | const pinnedSID = "abcdef12-3456-4789-8abc-def012345678" |
| 152 | // Pre-bind the task to the pinned session so the live check has |
| 153 | // something to match against. (Without bootstrapping via cmdDo — |
| 154 | // that would also try to spawn an iTerm tab.) |
| 155 | db := openFlowDB(t) |
| 156 | if _, err := db.Exec( |
| 157 | `UPDATE tasks SET session_id=?, session_started=? WHERE slug='live-task'`, |
| 158 | pinnedSID, flowdb.NowISO(), |
| 159 | ); err != nil { |
| 160 | t.Fatal(err) |
| 161 | } |
| 162 | |
| 163 | // Make ps (the app-level psRunner) say this UUID is alive so the |
| 164 | // live guard fires. |
| 165 | stubPS(t, " PID COMMAND\n12345 /bin/claude --session-id "+pinnedSID+"\n") |
| 166 | |
| 167 | // Make iterm.PSRunner (the focus-path probe) return no rows so the |
| 168 | // focus attempt deterministically returns (false, nil) and we fall |
| 169 | // through to the original "running elsewhere" error. |
| 170 | oldFocusPS := iterm.PSRunner |
| 171 | iterm.PSRunner = func() ([]byte, error) { return []byte(""), nil } |
| 172 | t.Cleanup(func() { iterm.PSRunner = oldFocusPS }) |
| 173 | |
| 174 | count, _ := stubITerm(t) |
| 175 | if rc := cmdDo([]string{"live-task"}); rc != 1 { |
| 176 | t.Errorf("cmdDo: rc=%d, want 1 when live session blocks spawn (focus miss)", rc) |
nothing calls this directly
no test coverage detected