Files

109 lines
4.1 KiB
Python

"""Tests for the /new command."""
from unittest.mock import AsyncMock, MagicMock
class TestNewCommand:
async def test_execute_calls_start_new_session(self):
from EvoScientist.commands.base import CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
ctx = CommandContext(
agent=None,
thread_id="old-tid",
ui=ui,
workspace_dir="/old/ws",
)
await NewCommand().execute(ctx, [])
ui.start_new_session.assert_awaited_once()
def test_requires_agent_false(self):
from EvoScientist.commands.implementation.session import NewCommand
assert NewCommand().requires_agent is False
async def test_no_agent_access(self):
"""Command body must not touch ctx.agent (it's still loading)."""
from EvoScientist.commands.base import CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
ctx = CommandContext(agent=None, thread_id="tid", ui=ui)
# No AttributeError even though ctx.agent is None
await NewCommand().execute(ctx, [])
async def test_clears_invited_experts_and_announces(self):
"""/new dismisses invited experts uniformly with channel-shutdown clear."""
from EvoScientist.commands.base import ChannelRuntime, CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
runtime = ChannelRuntime()
runtime.active_teams = ["idea-brainstorm"]
ctx = CommandContext(
agent=None,
thread_id="tid",
ui=ui,
channel_runtime=runtime,
)
await NewCommand().execute(ctx, [])
assert runtime.active_teams == []
messages = [call.args[0] for call in ui.append_system.call_args_list]
assert any(
"Dismissed experts on new session: idea-brainstorm" in msg
for msg in messages
)
async def test_no_announcement_when_no_experts_invited(self):
"""No noise on ``/new`` when the invite list is already empty."""
from EvoScientist.commands.base import ChannelRuntime, CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
runtime = ChannelRuntime()
ctx = CommandContext(
agent=None,
thread_id="tid",
ui=ui,
channel_runtime=runtime,
)
await NewCommand().execute(ctx, [])
ui.append_system.assert_not_called()
async def test_no_announcement_without_channel_runtime(self):
"""Runs cleanly when no ChannelRuntime is attached."""
from EvoScientist.commands.base import CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
ctx = CommandContext(agent=None, thread_id="tid", ui=ui, channel_runtime=None)
await NewCommand().execute(ctx, [])
ui.append_system.assert_not_called()
async def test_failed_session_start_keeps_invitations(self):
"""A raising start_new_session leaves the current session's invites."""
import pytest
from EvoScientist.commands.base import ChannelRuntime, CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock(side_effect=RuntimeError("gateway down"))
runtime = ChannelRuntime()
runtime.active_teams = ["idea-brainstorm"]
ctx = CommandContext(
agent=None,
thread_id="tid",
ui=ui,
channel_runtime=runtime,
)
with pytest.raises(RuntimeError):
await NewCommand().execute(ctx, [])
assert runtime.active_teams == ["idea-brainstorm"]