0799369407
Enabled inline diff rendering by default in PermissionQuestionWidget when diffs are available. Added a public show_diff property with getter and setter to control diff visibility, and updated refresh to honor this property. Extended Behave feature scenarios to cover default diff rendering, visibility toggling, and no-diff behavior. Introduced supporting step definitions for toggling show_diff and asserting absence of diff text. ISSUES CLOSED: #8303
181 lines
9.9 KiB
Gherkin
181 lines
9.9 KiB
Gherkin
Feature: Permission Question Widget
|
|
As a TUI user
|
|
I want an inline permission question widget
|
|
So that I can allow or reject single-file operations without leaving the conversation stream
|
|
|
|
Background:
|
|
Given the permission question widget module is imported
|
|
|
|
# ── Domain model ──────────────────────────────────────────────────────────
|
|
|
|
Scenario: Create InlinePermissionQuestion with file path and type
|
|
When I create an InlinePermissionQuestion for "src/auth/handler.py" with type "file_write"
|
|
Then the question file path should be "src/auth/handler.py"
|
|
And the question request type should be "file_write"
|
|
And the question has_diff should be False
|
|
|
|
Scenario: InlinePermissionQuestion with diff content
|
|
Given an InlinePermissionQuestion for "src/main.py" with type "file_write" and diff "@@ -1,3 +1,4 @@\n+import os"
|
|
Then the question has_diff should be True
|
|
|
|
Scenario: InlinePermissionQuestion description_line for file_write
|
|
When I create an InlinePermissionQuestion for "src/auth/handler.py" with type "file_write"
|
|
Then the description line should contain "write to"
|
|
|
|
Scenario: InlinePermissionQuestion description_line for file_delete
|
|
When I create an InlinePermissionQuestion for "src/old.py" with type "file_delete"
|
|
Then the description line should contain "delete"
|
|
|
|
Scenario: InlinePermissionQuestion description_line for shell_exec
|
|
When I create an InlinePermissionQuestion for "make test" with type "shell_exec"
|
|
Then the description line should contain "execute"
|
|
|
|
# ── Widget creation ───────────────────────────────────────────────────────
|
|
|
|
Scenario: Widget creation renders permission request
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
Then the widget text should contain "Permission Required"
|
|
And the widget text should contain "src/auth/handler.py"
|
|
And the widget text should contain "Allow once"
|
|
And the widget text should contain "Reject once"
|
|
|
|
Scenario: Widget creation shows diff hint when no diff
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
Then the widget text should contain "PermissionsScreen"
|
|
|
|
Scenario: Widget creation with diff content shows diff hint
|
|
Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1"
|
|
Then the widget text should contain "PermissionsScreen"
|
|
|
|
Scenario: Widget creation with diff content renders diff by default
|
|
Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1"
|
|
Then the widget text should contain "── diff ──"
|
|
And the widget text should contain "+x=1"
|
|
And the widget show_diff property should be True
|
|
|
|
Scenario: Widget diff visibility can be toggled off
|
|
Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1"
|
|
When I set the widget show_diff flag to False
|
|
Then the widget text should not contain "── diff ──"
|
|
And the widget show_diff property should be False
|
|
|
|
Scenario: Widget diff visibility can be toggled on after hiding
|
|
Given a PermissionQuestionWidget for "src/main.py" with type "file_write" and diff "@@ -1 +1 @@\n+x=1"
|
|
When I set the widget show_diff flag to False
|
|
And I set the widget show_diff flag to True
|
|
Then the widget text should contain "── diff ──"
|
|
And the widget show_diff property should be True
|
|
|
|
Scenario: Widget show_diff property stays False without diff content
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
Then the widget show_diff property should be False
|
|
When I set the widget show_diff flag to True
|
|
Then the widget show_diff property should be False
|
|
|
|
# ── Allow action ──────────────────────────────────────────────────────────
|
|
|
|
Scenario: Allow once via key "a"
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "a" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "allow_once"
|
|
|
|
Scenario: Allow always via key "A"
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "A" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "allow_always"
|
|
|
|
Scenario: Allow once via enter on first option
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "enter" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "allow_once"
|
|
|
|
# ── Reject action ─────────────────────────────────────────────────────────
|
|
|
|
Scenario: Reject once via key "r"
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "r" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "reject_once"
|
|
|
|
Scenario: Reject always via key "R"
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "R" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "reject_always"
|
|
|
|
# ── Navigation ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: Navigate down moves selection
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "down" on the widget
|
|
Then the widget selected index should be 1
|
|
And no decision event should be returned
|
|
|
|
Scenario: Navigate up wraps around
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "up" on the widget
|
|
Then the widget selected index should be 3
|
|
|
|
Scenario: Navigate down then enter selects second option
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "down" on the widget
|
|
And I press key "enter" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "allow_always"
|
|
|
|
Scenario: Navigate down twice then enter selects third option
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "down" on the widget
|
|
And I press key "down" on the widget
|
|
And I press key "enter" on the widget
|
|
Then a PermissionDecisionEvent should be returned
|
|
And the decision should be "reject_once"
|
|
|
|
# ── Open full screen ──────────────────────────────────────────────────────
|
|
|
|
Scenario: Press v sets open_full_screen flag
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "v" on the widget
|
|
Then the open_full_screen flag should be True
|
|
And no decision event should be returned
|
|
|
|
# ── Unknown key ───────────────────────────────────────────────────────────
|
|
|
|
Scenario: Unknown key returns None
|
|
When I create a PermissionQuestionWidget for "src/auth/handler.py" with type "file_write"
|
|
And I press key "x" on the widget
|
|
Then no decision event should be returned
|
|
|
|
# ── Inline rendering in conversation ─────────────────────────────────────
|
|
|
|
Scenario: render_permission_question returns correct structure
|
|
When I render a permission question for "src/auth/handler.py" with type "file_write"
|
|
Then the permission question rendered text should contain "Permission Required"
|
|
And the permission question rendered text should contain "src/auth/handler.py"
|
|
And the permission question rendered text should contain "Allow once"
|
|
|
|
Scenario: render_permission_question with selected_index 2 highlights third option
|
|
When I render a permission question for "src/auth/handler.py" with type "file_write" at index 2
|
|
Then the permission question rendered text should contain "Reject once"
|
|
|
|
Scenario: render_permission_question with diff shows diff content when show_diff is True
|
|
Given a permission question for "src/main.py" with type "file_write" and diff "+import os" rendered at index 0 with show_diff
|
|
Then the permission question rendered text should contain "+import os"
|
|
|
|
# ── Widget exports ────────────────────────────────────────────────────────
|
|
|
|
Scenario: PermissionQuestionWidget is exported from tui.widgets
|
|
Then PermissionQuestionWidget should be importable from tui.widgets
|
|
And PermissionDecisionEvent should be importable from tui.widgets
|
|
And render_permission_question should be importable from tui.widgets
|
|
|
|
# ── Domain model exports ──────────────────────────────────────────────────
|
|
|
|
Scenario: InlinePermissionQuestion is exported from domain.models.core
|
|
Then InlinePermissionQuestion should be importable from domain.models.core
|
|
And PermissionDecision should be importable from domain.models.core
|
|
And PermissionRequestType should be importable from domain.models.core
|