"""Step definitions for plugin CLI commands.""" from __future__ import annotations import json from typing import Any from unittest.mock import MagicMock, patch from behave import given, then, when from cleveragents.infrastructure.plugins.types import PluginState def _make_plugin_manager( state: PluginState, description: str = "A test plugin" ) -> MagicMock: """Create a mock PluginManager with one test plugin in the given state.""" descriptor = MagicMock() descriptor.name = "test-plugin" descriptor.version = "1.0.0" descriptor.description = description descriptor.module_path = "test.module" descriptor.class_name = "TestPlugin" descriptor.state = state manager = MagicMock() manager.list_plugins.return_value = [descriptor] manager.get_plugin.return_value = descriptor return manager @given("a plugin manager with one active plugin") def step_plugin_manager_active(context: Any) -> None: """Set up a mock PluginManager with one ACTIVATED plugin.""" context.plugin_manager = _make_plugin_manager(PluginState.ACTIVATED) @given("a plugin manager with one inactive plugin") def step_plugin_manager_inactive(context: Any) -> None: """Set up a mock PluginManager with one DEACTIVATED plugin.""" context.plugin_manager = _make_plugin_manager(PluginState.DEACTIVATED) @given("a plugin manager with one plugin having a long description") def step_plugin_manager_long_desc(context: Any) -> None: """Set up a mock PluginManager with a plugin whose description exceeds 40 chars.""" context.plugin_manager = _make_plugin_manager( PluginState.ACTIVATED, description="A" * 50, ) @given('the next prompt answer is "{answer}"') def step_set_prompt_answer(context: Any, answer: str) -> None: """Store stdin input to be used by the next plugin CLI invocation.""" context.cli_input = answer + "\n" @when('I run "agents plugin {args}"') def step_run_agents_plugin(context: Any, args: str) -> None: """Invoke a plugin CLI command and store output in context.command_output.""" from typer.testing import CliRunner from cleveragents.cli.main import app plugin_manager = getattr(context, "plugin_manager", None) stdin = getattr(context, "cli_input", None) runner = CliRunner() split_args = args.split() if plugin_manager is not None: with patch( "cleveragents.cli.commands.plugin._get_plugin_manager", return_value=plugin_manager, ): result = runner.invoke( app, ["plugin", *split_args], input=stdin, catch_exceptions=True ) else: result = runner.invoke( app, ["plugin", *split_args], input=stdin, catch_exceptions=True ) context.command_output = result.output or "" @then("the plugin CLI output should be valid JSON") def step_plugin_output_is_json(context: Any) -> None: """Check if plugin CLI output is valid JSON.""" output = getattr(context, "command_output", "") try: context.json_output = json.loads(output) except json.JSONDecodeError as e: raise AssertionError(f"Output is not valid JSON: {e}") from e