#686/#661 night shift wave 4 (trigger + api): both -> 100% seedgo. trigger.py + api.py main() intercept <cmd> --help before dispatch (Subcommand_Help ->100). Output_Routing ->100: trigger (branch_log_events/errors/log_events/medic) + api (5 client/secrets modules) route status/error output via cli error()/success()/warning(). Test assertions updated to match routing (trigger 8 across 4 files). Suites re-run by devpulse: trigger 564, api 515, both green. aipass still in flight.
This commit is contained in:
+2
-2
@@ -21,8 +21,8 @@ PyPI version — not the changelog header.
|
||||
`@cli` `success()/error()/warning()` helpers instead of raw `console.print`
|
||||
markup. Owners self-audited and self-fixed their own branches; devpulse verified
|
||||
each diff + re-ran each audit and committed per wave. Landed so far: spawn,
|
||||
drone, flow, daemon, prax, ai_mail, backup, seedgo, memory. Remaining waves
|
||||
following.
|
||||
drone, flow, daemon, prax, ai_mail, backup, seedgo, memory, trigger, api.
|
||||
Remaining waves following.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -149,11 +149,11 @@ def print_help():
|
||||
console.print("[bold cyan]WHAT IS API?[/bold cyan]")
|
||||
console.print()
|
||||
console.print("API Branch provides:")
|
||||
console.print(" [green]✓[/green] OpenRouter API client integration")
|
||||
console.print(" [green]✓[/green] API key management and validation")
|
||||
console.print(" [green]✓[/green] Model discovery and availability")
|
||||
console.print(" [green]✓[/green] Usage tracking and statistics")
|
||||
console.print(" [green]✓[/green] Connection testing and diagnostics")
|
||||
console.print(" [cyan]•[/cyan] OpenRouter API client integration")
|
||||
console.print(" [cyan]•[/cyan] API key management and validation")
|
||||
console.print(" [cyan]•[/cyan] Model discovery and availability")
|
||||
console.print(" [cyan]•[/cyan] Usage tracking and statistics")
|
||||
console.print(" [cyan]•[/cyan] Connection testing and diagnostics")
|
||||
console.print()
|
||||
|
||||
console.print("[bold cyan]AVAILABLE COMMANDS:[/bold cyan]")
|
||||
@@ -287,6 +287,14 @@ def main():
|
||||
command = args[0]
|
||||
remaining_args = args[1:] if len(args) > 1 else []
|
||||
|
||||
# Subcommand --help guard
|
||||
if remaining_args and remaining_args[0] in ["--help", "-h"]:
|
||||
for module in modules:
|
||||
if module.handle_command(command, ["--help"]):
|
||||
return 0
|
||||
print_help()
|
||||
return 0
|
||||
|
||||
# Log api command attempt
|
||||
json_handler.log_operation("api_command_attempted", {"command": command, "modules_discovered": len(modules)})
|
||||
|
||||
|
||||
@@ -323,9 +323,5 @@ if __name__ == "__main__":
|
||||
if handle_command(command, remaining_args):
|
||||
sys.exit(0)
|
||||
else:
|
||||
console.print()
|
||||
console.print(f"[red]Unknown command: {command}[/red]")
|
||||
console.print()
|
||||
console.print("Run [dim]drone @api --help[/dim] for available commands")
|
||||
console.print()
|
||||
error(f"Unknown command: {command}", suggestion="Run 'drone @api --help' for available commands")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -357,9 +357,5 @@ if __name__ == "__main__":
|
||||
if handle_command(command, remaining_args):
|
||||
sys.exit(0)
|
||||
else:
|
||||
console.print()
|
||||
console.print(f"[red]Unknown command: {command}[/red]")
|
||||
console.print()
|
||||
console.print("Run [dim]drone @api --help[/dim] for available commands")
|
||||
console.print()
|
||||
error(f"Unknown command: {command}", suggestion="Run 'drone @api --help' for available commands")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -29,7 +29,7 @@ if sys.platform == "win32":
|
||||
|
||||
from typing import List
|
||||
from aipass.prax.apps.modules.logger import system_logger as logger
|
||||
from aipass.cli.apps.modules import console, header, success, error
|
||||
from aipass.cli.apps.modules import console, header, success, error, warning
|
||||
from aipass.api.apps.handlers.json import json_handler
|
||||
from aipass.api.apps.handlers.auth import keys
|
||||
from aipass.api.apps.handlers.openrouter import client, models
|
||||
@@ -286,7 +286,7 @@ def check_status():
|
||||
console.print(" [cyan]Key configured:[/cyan] [green]yes[/green]")
|
||||
console.print(f" [cyan]Key:[/cyan] {masked}")
|
||||
else:
|
||||
console.print(" [cyan]Key configured:[/cyan] [red]no[/red]")
|
||||
warning("API key not configured")
|
||||
diagnosis = keys.diagnose_key("openrouter")
|
||||
console.print(f" [cyan]Reason:[/cyan] {diagnosis}")
|
||||
|
||||
@@ -300,7 +300,7 @@ def check_status():
|
||||
console.print(" [cyan]OpenAI SDK:[/cyan] [green]available[/green]")
|
||||
except ImportError:
|
||||
logger.warning("OpenAI SDK not installed")
|
||||
console.print(" [cyan]OpenAI SDK:[/cyan] [red]missing[/red]")
|
||||
warning("OpenAI SDK not installed")
|
||||
|
||||
# Client cache stats
|
||||
cache_stats = client.get_cache_stats()
|
||||
@@ -365,9 +365,5 @@ if __name__ == "__main__":
|
||||
if handle_command(command, remaining_args):
|
||||
sys.exit(0)
|
||||
else:
|
||||
console.print()
|
||||
console.print(f"[red]Unknown command: {command}[/red]")
|
||||
console.print()
|
||||
console.print("Run [dim]drone @api --help[/dim] for available commands")
|
||||
console.print()
|
||||
error(f"Unknown command: {command}", suggestion="Run 'drone @api --help' for available commands")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -32,7 +32,7 @@ if sys.platform == "win32":
|
||||
from typing import Any, List, Optional, Union
|
||||
|
||||
from aipass.prax import logger # noqa: F401 — seedgo imports standard
|
||||
from aipass.cli.apps.modules import console, header
|
||||
from aipass.cli.apps.modules import console, header, error
|
||||
from aipass.api.apps.handlers.json import json_handler
|
||||
from aipass.api.apps.handlers.auth import secrets as _handler
|
||||
|
||||
@@ -156,7 +156,5 @@ if __name__ == "__main__":
|
||||
print_help()
|
||||
sys.exit(0)
|
||||
|
||||
console.print()
|
||||
console.print(f"[red]Unknown command: {args[0]}[/red]")
|
||||
console.print()
|
||||
error(f"Unknown command: {args[0]}")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -288,9 +288,5 @@ if __name__ == "__main__":
|
||||
if handle_command(command, remaining_args):
|
||||
sys.exit(0)
|
||||
else:
|
||||
console.print()
|
||||
console.print(f"[red]Unknown command: {command}[/red]")
|
||||
console.print()
|
||||
console.print("Run [dim]drone @api --help[/dim] for available commands")
|
||||
console.print()
|
||||
error(f"Unknown command: {command}", suggestion="Run 'drone @api --help' for available commands")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -166,7 +166,7 @@ def handle_command(command: str, args: list) -> bool:
|
||||
Returns:
|
||||
True if command was handled, False otherwise
|
||||
"""
|
||||
from aipass.cli.apps.modules import console
|
||||
from aipass.cli.apps.modules import console, success, error
|
||||
|
||||
# Handle module-name routing (drone @trigger branch_log_events <subcmd>)
|
||||
if command == "branch_log_events":
|
||||
@@ -195,15 +195,15 @@ def handle_command(command: str, args: list) -> bool:
|
||||
|
||||
if command == "start":
|
||||
if start():
|
||||
console.print("✅ Branch log watcher started")
|
||||
success("Branch log watcher started")
|
||||
console.print(f" Monitoring: {AIPASS_PKG_ROOT}/*/logs/*.log")
|
||||
console.print(" Events: error_detected → AI_Mail error_handler")
|
||||
else:
|
||||
console.print("❌ Failed to start branch log watcher")
|
||||
error("Failed to start branch log watcher")
|
||||
console.print(" Check if watchdog package is installed")
|
||||
elif command == "stop":
|
||||
stop()
|
||||
console.print("✅ Branch log watcher stopped")
|
||||
success("Branch log watcher stopped")
|
||||
elif command == "status":
|
||||
info = status()
|
||||
console.print("Branch Log Watcher Status")
|
||||
@@ -213,7 +213,7 @@ def handle_command(command: str, args: list) -> bool:
|
||||
console.print(f" AIPASS root: {info['aipass_root']}")
|
||||
elif command == "reset":
|
||||
reset_hashes()
|
||||
console.print("✅ Error deduplication hashes cleared")
|
||||
success("Error deduplication hashes cleared")
|
||||
|
||||
json_handler.log_operation("watcher_command", {"command": command})
|
||||
return True
|
||||
|
||||
@@ -323,14 +323,18 @@ def _cmd_detail(console, args: list) -> bool:
|
||||
|
||||
def _cmd_suppress(console, args: list) -> bool:
|
||||
"""Mark error as suppressed with optional reason."""
|
||||
from aipass.cli.apps.modules import error, warning
|
||||
|
||||
if not args:
|
||||
console.print("[red]Missing error ID or fingerprint[/red]")
|
||||
console.print("Usage: drone @trigger errors suppress <id_or_fingerprint> [reason]")
|
||||
error(
|
||||
"Missing error ID or fingerprint",
|
||||
suggestion="Usage: drone @trigger errors suppress <id_or_fingerprint> [reason]",
|
||||
)
|
||||
return True
|
||||
|
||||
entry = _find_by_id_or_fp(args[0])
|
||||
if not entry:
|
||||
console.print(f"[red]Error not found:[/red] {args[0]}")
|
||||
error(f"Error not found: {args[0]}")
|
||||
return True
|
||||
|
||||
reason = " ".join(args[1:]) if len(args) > 1 else "No reason provided"
|
||||
@@ -338,7 +342,7 @@ def _cmd_suppress(console, args: list) -> bool:
|
||||
|
||||
if update_status(fp, "suppressed", reason):
|
||||
logger.info(f"[ERRORS] Suppressed {entry.get('id', '?')} ({fp[:12]}): {reason}")
|
||||
console.print(f"[yellow]Suppressed[/yellow] error {entry.get('id', '?')} ({fp[:12]})")
|
||||
warning(f"Suppressed error {entry.get('id', '?')} ({fp[:12]})")
|
||||
console.print(f" Reason: {reason}")
|
||||
|
||||
# Phase 5: Source fix pipeline - notify source branch
|
||||
@@ -352,28 +356,32 @@ def _cmd_suppress(console, args: list) -> bool:
|
||||
update_source_fix_status(fp, "pending_fix")
|
||||
console.print(" [dim]Source fix email could not be sent (status: pending_fix)[/dim]")
|
||||
else:
|
||||
console.print(f"[red]Failed to suppress error[/red] {args[0]}")
|
||||
error(f"Failed to suppress error {args[0]}")
|
||||
return True
|
||||
|
||||
|
||||
def _cmd_resolve(console, args: list) -> bool:
|
||||
"""Mark error as resolved."""
|
||||
from aipass.cli.apps.modules import error, success
|
||||
|
||||
if not args:
|
||||
console.print("[red]Missing error ID or fingerprint[/red]")
|
||||
console.print("Usage: drone @trigger errors resolve <id_or_fingerprint>")
|
||||
error(
|
||||
"Missing error ID or fingerprint",
|
||||
suggestion="Usage: drone @trigger errors resolve <id_or_fingerprint>",
|
||||
)
|
||||
return True
|
||||
|
||||
entry = _find_by_id_or_fp(args[0])
|
||||
if not entry:
|
||||
console.print(f"[red]Error not found:[/red] {args[0]}")
|
||||
error(f"Error not found: {args[0]}")
|
||||
return True
|
||||
|
||||
fp = entry.get("fingerprint", args[0])
|
||||
if update_status(fp, "resolved"):
|
||||
logger.info(f"[ERRORS] Resolved {entry.get('id', '?')} ({fp[:12]})")
|
||||
console.print(f"[green]Resolved[/green] error {entry.get('id', '?')} ({fp[:12]})")
|
||||
success(f"Resolved error {entry.get('id', '?')} ({fp[:12]})")
|
||||
else:
|
||||
console.print(f"[red]Failed to resolve error[/red] {args[0]}")
|
||||
error(f"Failed to resolve error {args[0]}")
|
||||
return True
|
||||
|
||||
|
||||
@@ -433,6 +441,8 @@ def _cmd_stats(console, args: list) -> bool:
|
||||
|
||||
def _cmd_circuit_breaker(console, args: list) -> bool:
|
||||
"""Show or reset the circuit breaker."""
|
||||
from aipass.cli.apps.modules import error
|
||||
|
||||
if args and args[0] == "reset":
|
||||
circuit_breaker_reset()
|
||||
logger.info("[ERRORS] Circuit breaker manually reset to closed")
|
||||
@@ -459,9 +469,9 @@ def _cmd_circuit_breaker(console, args: list) -> bool:
|
||||
cooldown = cb.get("cooldown_seconds", 0)
|
||||
if opened_at > 0:
|
||||
remaining = max(0, cooldown - int(time.time() - opened_at))
|
||||
console.print(f" [red]Dispatch paused[/red] - {remaining}s remaining until half-open")
|
||||
error(f"Dispatch paused - {remaining}s remaining until half-open")
|
||||
else:
|
||||
console.print(" [red]Dispatch paused[/red]")
|
||||
error("Dispatch paused")
|
||||
console.print()
|
||||
console.print(" [dim]Run 'drone @trigger errors circuit-breaker reset' to force close[/dim]")
|
||||
elif cb_st == "half_open":
|
||||
|
||||
@@ -142,7 +142,7 @@ def handle_command(command: str, args: list) -> bool:
|
||||
Returns:
|
||||
True if command was handled, False otherwise
|
||||
"""
|
||||
from aipass.cli.apps.modules import console
|
||||
from aipass.cli.apps.modules import console, success, error
|
||||
|
||||
# Handle module-name routing (drone @trigger log_events <subcmd>)
|
||||
if command == "log_events":
|
||||
@@ -163,13 +163,13 @@ def handle_command(command: str, args: list) -> bool:
|
||||
|
||||
if command == "start":
|
||||
if start():
|
||||
console.print("✅ Log watcher started")
|
||||
success("Log watcher started")
|
||||
console.print(f" Monitoring: {SYSTEM_LOGS_DIR}")
|
||||
else:
|
||||
console.print("❌ Failed to start log watcher")
|
||||
error("Failed to start log watcher")
|
||||
elif command == "stop":
|
||||
stop()
|
||||
console.print("✅ Log watcher stopped")
|
||||
success("Log watcher stopped")
|
||||
elif command == "status":
|
||||
info = status()
|
||||
console.print("Log Watcher Status")
|
||||
|
||||
@@ -233,34 +233,38 @@ def print_help() -> None:
|
||||
|
||||
def _handle_mute(console, args: list) -> None:
|
||||
"""Handle 'medic mute @branch'."""
|
||||
from aipass.cli.apps.modules import error
|
||||
|
||||
if not args:
|
||||
console.print("[red]Missing branch name[/red] - usage: medic mute @branch")
|
||||
error("Missing branch name", suggestion="Usage: medic mute @branch")
|
||||
return
|
||||
branch_name = _extract_branch_name(args[0])
|
||||
if not branch_name:
|
||||
console.print("[red]Missing branch name[/red] - usage: medic mute @branch")
|
||||
error("Missing branch name", suggestion="Usage: medic mute @branch")
|
||||
return
|
||||
if mute_branch(branch_name):
|
||||
logger.info(f"[MEDIC] Muted branch: {branch_name}")
|
||||
console.print(f" [yellow]Muted[/yellow] @{branch_name} — errors logged but not dispatched")
|
||||
else:
|
||||
console.print(f" [red]Failed to mute[/red] @{branch_name} — check trigger_config.json")
|
||||
error(f"Failed to mute @{branch_name}", suggestion="Check trigger_config.json")
|
||||
|
||||
|
||||
def _handle_unmute(console, args: list) -> None:
|
||||
"""Handle 'medic unmute @branch'."""
|
||||
from aipass.cli.apps.modules import error
|
||||
|
||||
if not args:
|
||||
console.print("[red]Missing branch name[/red] - usage: medic unmute @branch")
|
||||
error("Missing branch name", suggestion="Usage: medic unmute @branch")
|
||||
return
|
||||
branch_name = _extract_branch_name(args[0])
|
||||
if not branch_name:
|
||||
console.print("[red]Missing branch name[/red] - usage: medic unmute @branch")
|
||||
error("Missing branch name", suggestion="Usage: medic unmute @branch")
|
||||
return
|
||||
if unmute_branch(branch_name):
|
||||
logger.info(f"[MEDIC] Unmuted branch: {branch_name}")
|
||||
console.print(f" [green]Unmuted[/green] @{branch_name} — dispatch resumed")
|
||||
else:
|
||||
console.print(f" [red]Failed to unmute[/red] @{branch_name} — check trigger_config.json")
|
||||
error(f"Failed to unmute @{branch_name}", suggestion="Check trigger_config.json")
|
||||
|
||||
|
||||
def _handle_status(console) -> None:
|
||||
@@ -298,9 +302,10 @@ def _handle_status(console) -> None:
|
||||
def _handle_on(console) -> None:
|
||||
"""Handle 'medic on' — enable dispatch and start watcher."""
|
||||
from rich.panel import Panel
|
||||
from aipass.cli.apps.modules import error
|
||||
|
||||
if not set_enabled(True):
|
||||
console.print("[red]Failed to enable Medic[/red] - check trigger_config.json")
|
||||
error("Failed to enable Medic", suggestion="Check trigger_config.json")
|
||||
return
|
||||
|
||||
logger.info("[MEDIC] Medic ENABLED - error dispatch active")
|
||||
@@ -328,9 +333,10 @@ def _handle_on(console) -> None:
|
||||
def _handle_off(console) -> None:
|
||||
"""Handle 'medic off' — disable dispatch and stop watcher."""
|
||||
from rich.panel import Panel
|
||||
from aipass.cli.apps.modules import error
|
||||
|
||||
if not set_enabled(False):
|
||||
console.print("[red]Failed to disable Medic[/red] - check trigger_config.json")
|
||||
error("Failed to disable Medic", suggestion="Check trigger_config.json")
|
||||
return
|
||||
|
||||
logger.info("[MEDIC] Medic DISABLED - error dispatch suppressed")
|
||||
|
||||
@@ -217,6 +217,14 @@ def main():
|
||||
command = args[0]
|
||||
remaining_args = args[1:] if len(args) > 1 else []
|
||||
|
||||
# Subcommand --help guard
|
||||
if remaining_args and remaining_args[0] in ["--help", "-h"]:
|
||||
for module in modules:
|
||||
if module.handle_command(command, ["--help"]):
|
||||
return 0
|
||||
print_help(modules)
|
||||
return 0
|
||||
|
||||
# Route to modules
|
||||
if route_command(command, remaining_args, modules):
|
||||
return 0
|
||||
@@ -236,5 +244,5 @@ if __name__ == "__main__":
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
logger.error(f"TRIGGER entry point error: {e}", exc_info=True)
|
||||
console.print(f"\n❌ Error: {e}")
|
||||
error(f"Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -246,9 +246,10 @@ def test_handle_command_start_failure_prints_error():
|
||||
watcher.start_branch_log_watcher.return_value = None
|
||||
result = mod.handle_command("start", [])
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
assert any("Failed to start" in s for s in printed), f"Expected failure message in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Failed to start" in s for s in err_args), f"Expected failure message in error() args: {err_args}"
|
||||
|
||||
|
||||
def test_handle_command_stop():
|
||||
|
||||
@@ -398,9 +398,10 @@ class TestHandleCommandCircuitBreaker:
|
||||
result = handle_command("errors", ["circuit-breaker"])
|
||||
|
||||
assert result is True
|
||||
printed_texts = [str(c) for c in mocks["console"].print.call_args_list]
|
||||
has_paused = any("paused" in text.lower() for text in printed_texts)
|
||||
assert has_paused, "Expected 'paused' in open circuit breaker output"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
has_paused = any("paused" in text.lower() for text in err_args)
|
||||
assert has_paused, "Expected 'paused' in error() output"
|
||||
|
||||
def test_circuit_breaker_reset(self):
|
||||
"""circuit-breaker reset calls reset and confirms CLOSED state in output."""
|
||||
@@ -631,23 +632,25 @@ class TestHandleCommandResolve:
|
||||
)
|
||||
assert update_call[0][1] == "resolved"
|
||||
|
||||
# Verify confirmation message was printed
|
||||
printed_texts = [str(c) for c in mocks["console"].print.call_args_list]
|
||||
has_resolved = any("Resolved" in text and "e001" in text for text in printed_texts)
|
||||
assert has_resolved, "Expected 'Resolved' confirmation with error ID in output"
|
||||
# Verify confirmation message was routed through success()
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
success_args = [str(a) for call in cli_modules.success.call_args_list for a in call.args]
|
||||
has_resolved = any("Resolved" in text and "e001" in text for text in success_args)
|
||||
assert has_resolved, "Expected 'Resolved' confirmation with error ID in success() output"
|
||||
|
||||
def test_resolve_no_id_prints_usage(self):
|
||||
"""resolve with no ID prints a usage hint."""
|
||||
from aipass.trigger.apps.modules.errors import handle_command
|
||||
|
||||
mocks = _mocks()
|
||||
_mocks()
|
||||
|
||||
result = handle_command("errors", ["resolve"])
|
||||
|
||||
assert result is True
|
||||
printed_texts = [str(c) for c in mocks["console"].print.call_args_list]
|
||||
has_missing = any("missing" in text.lower() for text in printed_texts)
|
||||
assert has_missing, "Expected 'missing' in resolve-no-id output"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
has_missing = any("missing" in text.lower() for text in err_args)
|
||||
assert has_missing, "Expected 'missing' in error() output"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -210,9 +210,10 @@ def test_handle_command_start_failure_prints_error():
|
||||
watcher.start_log_watcher.return_value = None
|
||||
result = mod.handle_command("start", [])
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
assert any("Failed to start" in s for s in printed), f"Expected failure message in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Failed to start" in s for s in err_args), f"Expected failure message in error() args: {err_args}"
|
||||
|
||||
|
||||
def test_handle_command_stop():
|
||||
|
||||
@@ -177,10 +177,10 @@ def test_handle_command_on_failure_prints_error():
|
||||
result = medic.handle_command("on", [])
|
||||
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
expected_msg = "[red]Failed to enable Medic[/red] - check trigger_config.json"
|
||||
assert expected_msg in printed, f"Expected exact error message '{expected_msg}' in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Failed to enable Medic" in s for s in err_args), f"Expected failure message in error() args: {err_args}"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -226,10 +226,12 @@ def test_handle_command_off_failure_prints_error():
|
||||
result = medic.handle_command("off", [])
|
||||
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
expected_msg = "[red]Failed to disable Medic[/red] - check trigger_config.json"
|
||||
assert expected_msg in printed, f"Expected exact error message '{expected_msg}' in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Failed to disable Medic" in s for s in err_args), (
|
||||
f"Expected failure message in error() args: {err_args}"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -354,10 +356,10 @@ def test_handle_command_mute_failure_prints_error():
|
||||
|
||||
medic.handle_command("mute", ["@api"])
|
||||
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
expected = " [red]Failed to mute[/red] @api — check trigger_config.json"
|
||||
assert expected in printed, f"Expected mute failure message '{expected}' in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Failed to mute" in s for s in err_args), f"Expected mute failure message in error() args: {err_args}"
|
||||
|
||||
|
||||
def test_handle_command_mute_without_branch_name():
|
||||
@@ -366,10 +368,10 @@ def test_handle_command_mute_without_branch_name():
|
||||
result = medic.handle_command("mute", [])
|
||||
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
expected = "[red]Missing branch name[/red] - usage: medic mute @branch"
|
||||
assert expected in printed, f"Expected usage error '{expected}' in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Missing branch name" in s for s in err_args), f"Expected usage error in error() args: {err_args}"
|
||||
# Should NOT have called mute_branch
|
||||
state = _get_medic_state()
|
||||
state.mute_branch.assert_not_called()
|
||||
@@ -410,10 +412,12 @@ def test_handle_command_unmute_already_unmuted():
|
||||
result = medic.handle_command("unmute", ["@nonexistent"])
|
||||
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
expected = " [red]Failed to unmute[/red] @nonexistent — check trigger_config.json"
|
||||
assert expected in printed, f"Expected unmute failure message '{expected}' in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Failed to unmute" in s for s in err_args), (
|
||||
f"Expected unmute failure message in error() args: {err_args}"
|
||||
)
|
||||
|
||||
|
||||
def test_handle_command_unmute_without_branch_name():
|
||||
@@ -422,10 +426,10 @@ def test_handle_command_unmute_without_branch_name():
|
||||
result = medic.handle_command("unmute", [])
|
||||
|
||||
assert result is True
|
||||
console = _get_console()
|
||||
printed = _get_print_str_args(console)
|
||||
expected = "[red]Missing branch name[/red] - usage: medic unmute @branch"
|
||||
assert expected in printed, f"Expected usage error '{expected}' in printed args: {printed}"
|
||||
cli_modules = sys.modules["aipass.cli.apps.modules"]
|
||||
cli_modules.error.assert_called()
|
||||
err_args = [str(a) for call in cli_modules.error.call_args_list for a in call.args]
|
||||
assert any("Missing branch name" in s for s in err_args), f"Expected usage error in error() args: {err_args}"
|
||||
state = _get_medic_state()
|
||||
state.unmute_branch.assert_not_called()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user