Files
cleveragents-core/features/steps/tui_shell_safety_steps.py
T
2026-06-17 00:21:34 -04:00

131 lines
4.4 KiB
Python

"""Shell safety-related step definitions for the TUI app coverage suite."""
from __future__ import annotations
import os
from types import SimpleNamespace
from unittest.mock import patch
from behave import given, then, when
from cleveragents.tui.input.modes import InputMode, ModeResult
from cleveragents.tui.shell_safety import (
DangerousCommandWarning,
DangerousPattern,
ShellDangerLevel,
)
from features.steps._tui_helpers import _submit_text, _submit_text_with_mocked_shell
@when('I submit "{text}" to the app')
def step_submit_text(context, text):
os.environ["CLEVERAGENTS_ALLOW_DANGEROUS_SHELL"] = "1"
def restore_env() -> None:
os.environ.pop("CLEVERAGENTS_ALLOW_DANGEROUS_SHELL", None)
context.add_cleanup(restore_env)
_submit_text(context, text)
@when('I submit "{text}" to the app with shell execution mocked')
def step_submit_text_mocked_shell(context, text):
os.environ["CLEVERAGENTS_ALLOW_DANGEROUS_SHELL"] = "1"
def restore_env() -> None:
os.environ.pop("CLEVERAGENTS_ALLOW_DANGEROUS_SHELL", None)
context.add_cleanup(restore_env)
_submit_text_with_mocked_shell(context, text)
@when("I submit shell text that produces a None shell result")
def step_submit_shell_none(context):
# Patch the mode router to emulate a shell submission returning None.
with patch(
"cleveragents.tui.app.InputModeRouter.process",
return_value=ModeResult(
mode=InputMode.SHELL,
expanded_text="!nothing",
references=[],
shell_result=None,
command_result=None,
shell_warning=None,
),
):
_submit_text(context, "!nothing")
@then("the shell warning indicator should be visible")
def step_shell_warning_visible(context):
MockStatic = context._tui_mock_static
banner = context._tui_app.query_one("#shell-warning", MockStatic)
assert banner.display is True, "Expected shell warning indicator to be visible"
assert banner._text, "Expected warning indicator text to be populated"
@then("the shell warning indicator should not be visible")
def step_shell_warning_hidden(context):
MockStatic = context._tui_mock_static
banner = context._tui_app.query_one("#shell-warning", MockStatic)
assert banner.display is False, "Expected shell warning indicator to be hidden"
assert banner._text == "", "Expected warning indicator text to be cleared"
@then("the prompt should be marked as dangerous")
def step_prompt_marked_dangerous(context):
from cleveragents.tui.widgets.prompt import PromptInput
prompt = context._tui_app.query_one("#prompt", PromptInput)
assert prompt.has_class("dangerous"), "Expected prompt to have dangerous class"
@then("the prompt should not be marked as dangerous")
def step_prompt_not_dangerous(context):
from cleveragents.tui.widgets.prompt import PromptInput
prompt = context._tui_app.query_one("#prompt", PromptInput)
assert not prompt.has_class("dangerous"), "Expected prompt to be safe"
@given("shell danger warnings are disabled in settings")
@when("shell danger warnings are disabled in settings")
def step_disable_shell_warnings(context):
stub = SimpleNamespace(shell_warn_dangerous=False)
app_patcher = patch("cleveragents.tui.app.get_settings", return_value=stub)
app_patcher.start()
context.add_cleanup(app_patcher.stop)
@when('I ask the app to confirm shell command "{command}"')
def step_confirm_shell_command(context, command):
context._tui_shell_confirmation = context._tui_app._confirm_dangerous_shell(command)
@then("the shell confirmation result should be allowed")
def step_shell_confirmation_allowed(context):
assert context._tui_shell_confirmation is True
@then("the shell confirmation result should be blocked")
def step_shell_confirmation_blocked(context):
assert context._tui_shell_confirmation is False
@when("I ask the app to handle a shell warning")
def step_handle_shell_warning(context):
pattern = DangerousPattern(
name="test_warning",
pattern=r"rm -rf",
level=ShellDangerLevel.CRITICAL,
description="test warning",
)
warning = DangerousCommandWarning.from_pattern("rm -rf /tmp", pattern)
context._tui_shell_warning_result = context._tui_app._handle_shell_warning(warning)
@then("the shell warning callback result should be allowed")
def step_shell_warning_callback_allowed(context):
assert context._tui_shell_warning_result is True