fix(tui): repair shell-safety test scaffolding
CI / lint (pull_request) Successful in 49s
CI / quality (pull_request) Successful in 48s
CI / typecheck (pull_request) Successful in 1m17s
CI / security (pull_request) Successful in 1m30s
CI / build (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 29s
CI / push-validation (pull_request) Successful in 22s
CI / unit_tests (pull_request) Successful in 6m26s
CI / docker (pull_request) Successful in 1m48s
CI / coverage (pull_request) Failing after 13m18s
CI / integration_tests (pull_request) Successful in 21m6s
CI / status-check (pull_request) Failing after 3s
CI / lint (pull_request) Successful in 49s
CI / quality (pull_request) Successful in 48s
CI / typecheck (pull_request) Successful in 1m17s
CI / security (pull_request) Successful in 1m30s
CI / build (pull_request) Successful in 33s
CI / helm (pull_request) Successful in 29s
CI / push-validation (pull_request) Successful in 22s
CI / unit_tests (pull_request) Successful in 6m26s
CI / docker (pull_request) Successful in 1m48s
CI / coverage (pull_request) Failing after 13m18s
CI / integration_tests (pull_request) Successful in 21m6s
CI / status-check (pull_request) Failing after 3s
Three independent test-scaffold defects blocked the unit_tests and integration_tests gates on PR #6361's shell-safety wiring: - features/steps/_tui_helpers.py: the mocked-shell helper patched cleveragents.tui.input.shell_exec.run_shell_command, but modes.py binds the symbol into its own namespace via `from ... import`. The patch was inert, and only the CLEVERAGENTS_ALLOW_DANGEROUS_SHELL=1 gate kept the real `rm -rf /tmp` from running in the behave runner. Patch the use site (modes.run_shell_command) instead. - src/cleveragents/tui/widgets/prompt.py: _FallbackPromptInput (used whenever Textual is mocked or unavailable) had no add_class / remove_class / has_class, so the new "prompt should be marked as dangerous" assertions raised AttributeError and the three new scenarios errored. The production path (_TextualPromptInput) already inherits these from textual.containers.Horizontal; the fallback now mirrors that contract via a small self._classes set. - robot/tui_shell_safety.robot: Catenate's space-based argument separator collapses multi-space indentation, so the Python function bodies (warn_callback, deny) landed at column 0 and the helper scripts died with IndentationError before either assertion ran. Preserve the 4-space indent with ${SPACE * 4} markers. ISSUES CLOSED: #6361
This commit is contained in:
@@ -19,13 +19,21 @@ def _submit_text(context, text: str) -> None:
|
||||
|
||||
|
||||
def _submit_text_with_mocked_shell(context, text: str, stdout: str = "mocked") -> None:
|
||||
"""Submit *text* while faking shell execution."""
|
||||
"""Submit *text* while faking shell execution.
|
||||
|
||||
The patch target is the use site in ``modes`` rather than the
|
||||
definition site in ``shell_exec``: ``modes`` did
|
||||
``from cleveragents.tui.input.shell_exec import run_shell_command``,
|
||||
binding the symbol into its own namespace; patching the source
|
||||
module would leave that binding (and therefore the real
|
||||
``subprocess.run`` call) untouched.
|
||||
"""
|
||||
|
||||
def fake_run(command: str, **_: Any) -> ShellResult:
|
||||
return ShellResult(command=command, exit_code=0, stdout=stdout, stderr="")
|
||||
|
||||
with patch(
|
||||
"cleveragents.tui.input.shell_exec.run_shell_command",
|
||||
"cleveragents.tui.input.modes.run_shell_command",
|
||||
side_effect=fake_run,
|
||||
):
|
||||
_submit_text(context, text)
|
||||
|
||||
@@ -20,8 +20,8 @@ Shell Safety Service Blocks Denied Command
|
||||
... warnings: list[DangerousCommandWarning] = []
|
||||
...
|
||||
... def warn_callback(warning: DangerousCommandWarning) -> bool:
|
||||
... warnings.append(warning)
|
||||
... return False
|
||||
... ${SPACE * 4}warnings.append(warning)
|
||||
... ${SPACE * 4}return False
|
||||
...
|
||||
... router = InputModeRouter(lambda cmd: "handled", shell_safety=ShellSafetyService(warn_callback=warn_callback))
|
||||
... os.environ.pop("CLEVERAGENTS_ALLOW_DANGEROUS_SHELL", None)
|
||||
@@ -47,8 +47,8 @@ Shell Confirm Callback Gates All Commands
|
||||
... counter = {"count": 0}
|
||||
...
|
||||
... def deny(command: str) -> bool:
|
||||
... counter["count"] += 1
|
||||
... return False
|
||||
... ${SPACE * 4}counter["count"] += 1
|
||||
... ${SPACE * 4}return False
|
||||
...
|
||||
... result = run_shell_command("chmod -R 777 /tmp/test-shell-safety", confirm_dangerous=deny)
|
||||
... assert counter["count"] == 1, f"Expected confirm to be invoked once, got {counter['count']}"
|
||||
|
||||
@@ -248,12 +248,20 @@ class _TextualPromptInput(_PromptSymbolMixin, _HorizontalBase):
|
||||
|
||||
|
||||
class _FallbackPromptInput(_PromptSymbolMixin):
|
||||
"""Fallback prompt input used when Textual is unavailable."""
|
||||
"""Fallback prompt input used when Textual is unavailable.
|
||||
|
||||
Mirrors the Textual Widget CSS-class API (``add_class`` /
|
||||
``remove_class`` / ``has_class``) so callers that toggle styling
|
||||
classes on the outer prompt (e.g. ``add_class("dangerous")`` from
|
||||
the shell-safety surfacing path) work uniformly across production
|
||||
and fallback/mock paths.
|
||||
"""
|
||||
|
||||
def __init__(self, placeholder: str = "", **_: object) -> None:
|
||||
self.placeholder = placeholder
|
||||
self._input = cast(_MutableValueInput, _InputBase())
|
||||
self._current_symbol = _PROMPT_SYMBOLS[InputMode.NORMAL]
|
||||
self._classes: set[str] = set()
|
||||
self._update_symbol(self._input.value)
|
||||
|
||||
@property
|
||||
@@ -270,6 +278,15 @@ class _FallbackPromptInput(_PromptSymbolMixin):
|
||||
if callable(focus):
|
||||
focus()
|
||||
|
||||
def add_class(self, name: str) -> None:
|
||||
self._classes.add(name)
|
||||
|
||||
def remove_class(self, name: str) -> None:
|
||||
self._classes.discard(name)
|
||||
|
||||
def has_class(self, name: str) -> bool:
|
||||
return name in self._classes
|
||||
|
||||
def _apply_symbol(self, symbol: str) -> None:
|
||||
self._current_symbol = symbol
|
||||
|
||||
|
||||
Reference in New Issue
Block a user