Files
placeholder/features/steps/actor_remove_impact_steps.py
freemo a804506c89 fix(cli): compute real impact counts in agents actor remove command
Replaces hardcoded 0 values in the Impact panel of `agents actor remove` with real DB-backed counts for sessions, active plans, and actions referencing the removed actor.

ISSUES CLOSED: #3420

Co-authored-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Co-committed-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
2026-04-05 18:18:08 +00:00

107 lines
3.6 KiB
Python

# pyright: reportRedeclaration=false
"""Step definitions for actor remove impact computation feature."""
from __future__ import annotations
from typing import Any
from unittest.mock import MagicMock, patch
from behave import given, then, when
from typer.testing import CliRunner # noqa: F401 - used via context.runner
from cleveragents.cli.commands.actor import app as actor_app
from cleveragents.domain.models.core.actor import Actor
def _make_actor(
*,
name: str = "local/test-actor",
provider: str = "test-provider",
model: str = "test-model",
) -> Actor:
return Actor(
id=1,
name=name,
provider=provider,
model=model,
config_blob={},
config_hash="abcdef12",
graph_descriptor=None,
unsafe=False,
is_default=False,
is_built_in=False,
)
@given(
'an actor "{actor_name}" referenced by {sessions:d} sessions, '
"{plans:d} active plan, and {actions:d} actions"
)
def step_actor_with_references(
context: Any, actor_name: str, sessions: int, plans: int, actions: int
) -> None:
"""Set up context with an actor that has known reference counts."""
context.actor_name = actor_name
context.expected_sessions = sessions
context.expected_plans = plans
context.expected_actions = actions
@given('an actor "{actor_name}" with no references')
def step_actor_no_references(context: Any, actor_name: str) -> None:
"""Set up context with an actor that has no references."""
context.actor_name = actor_name
context.expected_sessions = 0
context.expected_plans = 0
context.expected_actions = 0
@when('I run actor remove for "{actor_name}"')
def step_run_actor_remove(context: Any, actor_name: str) -> None:
"""Invoke the actor remove command with mocked services and impact counts."""
sessions = getattr(context, "expected_sessions", 0)
plans = getattr(context, "expected_plans", 0)
actions = getattr(context, "expected_actions", 0)
mock_actor = _make_actor(name=actor_name)
with (
patch("cleveragents.cli.commands.actor._get_services") as mock_get_services,
patch("cleveragents.cli.commands.actor._compute_actor_impact") as mock_impact,
):
mock_registry = MagicMock()
mock_registry.get_actor.return_value = mock_actor
mock_get_services.return_value = (MagicMock(), mock_registry)
mock_impact.return_value = (sessions, plans, actions)
context.result = context.runner.invoke(actor_app, ["remove", actor_name])
context.mock_impact = mock_impact
context.mock_registry = mock_registry
@then('the Impact panel should show "{text}" for Sessions')
def step_impact_sessions(context: Any, text: str) -> None:
"""Assert the Sessions line in the Impact panel shows the expected text."""
output = context.result.output
assert text in output, (
f"Expected '{text}' in output for Sessions, but got:\n{output}"
)
@then('the Impact panel should show "{text}" for Active Plans')
def step_impact_plans(context: Any, text: str) -> None:
"""Assert the Active Plans line in the Impact panel shows the expected text."""
output = context.result.output
assert text in output, (
f"Expected '{text}' in output for Active Plans, but got:\n{output}"
)
@then('the Impact panel should show "{text}" for Actions Referencing')
def step_impact_actions(context: Any, text: str) -> None:
"""Assert the Actions Referencing line in the Impact panel shows the expected text."""
output = context.result.output
assert text in output, (
f"Expected '{text}' in output for Actions Referencing, but got:\n{output}"
)