|
8 | 8 | # Add hooks/lib to path |
9 | 9 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "hooks", "lib")) |
10 | 10 |
|
11 | | -from agent_status import build_status_message, clear_cache, _COLOR_EMOJI_MAP |
| 11 | +from agent_status import build_status_message, clear_cache, get_handoff_message, _COLOR_EMOJI_MAP |
12 | 12 |
|
13 | 13 |
|
14 | 14 | @pytest.fixture(autouse=True) |
@@ -178,3 +178,96 @@ def test_clear_cache_resets(self, monkeypatch, project_with_agents): |
178 | 178 | clear_cache() |
179 | 179 | r2 = build_status_message(project_root=project_with_agents) |
180 | 180 | assert r1 == r2 # Same result, but freshly loaded |
| 181 | + |
| 182 | + |
| 183 | +class TestHandoffMessage: |
| 184 | + """Tests for agent handoff detection and message generation.""" |
| 185 | + |
| 186 | + def test_no_handoff_on_first_call(self, monkeypatch, project_with_agents): |
| 187 | + """First call should not produce a handoff message.""" |
| 188 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 189 | + build_status_message(project_root=project_with_agents) |
| 190 | + assert get_handoff_message() is None |
| 191 | + |
| 192 | + def test_no_handoff_when_same_agent(self, monkeypatch, project_with_agents): |
| 193 | + """Repeated calls with the same agent should not produce a handoff.""" |
| 194 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 195 | + build_status_message(project_root=project_with_agents) |
| 196 | + build_status_message(project_root=project_with_agents) |
| 197 | + assert get_handoff_message() is None |
| 198 | + |
| 199 | + def test_handoff_when_agent_changes(self, monkeypatch, project_with_agents): |
| 200 | + """Switching agents should produce a handoff message with both faces.""" |
| 201 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 202 | + build_status_message(project_root=project_with_agents) |
| 203 | + |
| 204 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "Backend Developer") |
| 205 | + build_status_message(project_root=project_with_agents) |
| 206 | + |
| 207 | + handoff = get_handoff_message() |
| 208 | + assert handoff is not None |
| 209 | + # Previous agent face: ★‿★ (frontend-developer) |
| 210 | + assert "\u2605\u203f\u2605" in handoff |
| 211 | + # New agent face: ●‿● (Backend Developer) |
| 212 | + assert "\u25cf\u203f\u25cf" in handoff |
| 213 | + # Arrow separator |
| 214 | + assert "\u2192" in handoff # → |
| 215 | + # 교대 suffix |
| 216 | + assert "\uad50\ub300!" in handoff # 교대! |
| 217 | + |
| 218 | + def test_handoff_includes_agent_names(self, monkeypatch, project_with_agents): |
| 219 | + """Handoff message should include both agent names.""" |
| 220 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 221 | + build_status_message(project_root=project_with_agents) |
| 222 | + |
| 223 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "Backend Developer") |
| 224 | + build_status_message(project_root=project_with_agents) |
| 225 | + |
| 226 | + handoff = get_handoff_message() |
| 227 | + assert "frontend-developer" in handoff |
| 228 | + assert "Backend Developer" in handoff |
| 229 | + |
| 230 | + def test_handoff_with_fallback_face(self, monkeypatch, project_with_agents): |
| 231 | + """Agent without visual data should use robot emoji in handoff.""" |
| 232 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 233 | + build_status_message(project_root=project_with_agents) |
| 234 | + |
| 235 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "plain-agent") |
| 236 | + build_status_message(project_root=project_with_agents) |
| 237 | + |
| 238 | + handoff = get_handoff_message() |
| 239 | + assert handoff is not None |
| 240 | + assert "\U0001f916" in handoff # 🤖 fallback for plain-agent |
| 241 | + |
| 242 | + def test_handoff_resets_after_read(self, monkeypatch, project_with_agents): |
| 243 | + """Handoff message should reset on next build_status_message call.""" |
| 244 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 245 | + build_status_message(project_root=project_with_agents) |
| 246 | + |
| 247 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "Backend Developer") |
| 248 | + build_status_message(project_root=project_with_agents) |
| 249 | + assert get_handoff_message() is not None |
| 250 | + |
| 251 | + # Same agent again — no new handoff |
| 252 | + build_status_message(project_root=project_with_agents) |
| 253 | + assert get_handoff_message() is None |
| 254 | + |
| 255 | + def test_handoff_cleared_by_clear_cache(self, monkeypatch, project_with_agents): |
| 256 | + """clear_cache should reset handoff state.""" |
| 257 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 258 | + build_status_message(project_root=project_with_agents) |
| 259 | + |
| 260 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "Backend Developer") |
| 261 | + build_status_message(project_root=project_with_agents) |
| 262 | + |
| 263 | + clear_cache() |
| 264 | + assert get_handoff_message() is None |
| 265 | + |
| 266 | + def test_no_handoff_when_agent_unset(self, monkeypatch, project_with_agents): |
| 267 | + """Setting agent then unsetting should not produce handoff.""" |
| 268 | + monkeypatch.setenv("CODINGBUDDY_ACTIVE_AGENT", "frontend-developer") |
| 269 | + build_status_message(project_root=project_with_agents) |
| 270 | + |
| 271 | + monkeypatch.delenv("CODINGBUDDY_ACTIVE_AGENT", raising=False) |
| 272 | + build_status_message(project_root=project_with_agents) |
| 273 | + assert get_handoff_message() is None |
0 commit comments