Files
cleveragents-core/features/resource_handler_crud.feature
freemo 02250473ad fix(ci): restore all CI quality gates to passing on master
Fix all failing CI quality gates (lint, unit_tests, format) without
suppressing any quality enforcement.

Root causes and fixes:

1. Format: features/steps/plan_namespaced_name_tdd_steps.py had trailing
   whitespace; fixed by running ruff format.

2. Unit tests - A2A JSON-RPC 2.0 migration (commit 9c6d6915) renamed
   A2aRequest fields (operation→method, request_id→id, a2a_version→jsonrpc)
   and A2aResponse fields (status+data→result, request_id→id) but did not
   update all step files and feature files:
   - a2a_jsonrpc_wire_format_steps.py: added use_step_matcher('re') and
     reset to 'parse' at end to prevent parallel test interference
   - a2a_facade_wiring_steps.py: updated operation= to method=, .status/.data
     to .result
   - a2a_facade_steps.py: updated request_id→id, a2a_version→jsonrpc,
     A2aResponse(request_id=..., status=...) to new API
   - m6_facade_steps.py: updated all old API usage
   - devcontainer_cleanup_steps.py: updated A2aRequest(operation=...)
   - plan_prompt_command_steps.py: updated A2aRequest(operation=...)
   - wf03_plan_prompt_confidence_steps.py: updated A2aRequest(operation=...)
   - consolidated_misc.feature: updated old A2aRequest/A2aResponse scenarios

3. Unit tests - Session CLI output changed (commit 0d5d9cf0 and others):
   - 'Session Created' → 'Session created' (lowercase)
   - 'Session Details' → 'Session Summary'
   - 'Sessions (N total)' → 'Sessions'
   - session list JSON: top-level 'total' → nested 'summary.total'
   - Fixed in: session_cli.feature, session_cli_coverage_boost.feature,
     session_cli_uncovered_branches.feature, session_list_error.feature,
     tdd_session_create_persist_steps.py

4. Unit tests - Plan list output changed (commit 1a07a891):
   - 'V3 Lifecycle Plans' → 'Plans'
   - 'Lifecycle Plans' → 'Plans'
   - Name column removed (restored in source)
   - Invariants column removed (restored in source)
   - Project truncation removed (restored in source)
   - Fixed in: plan_cli_cancel_revert_coverage.feature,
     plan_lifecycle_cli_coverage.feature, plan_cli_coverage_boost_steps.py,
     plan.py (source code restored)

5. Unit tests - Plan apply command now requires ULID (commit 300a5d6d):
   - plan_cli_coverage_r3.feature: updated 'PLAN-001' to valid ULID
   - plan_cli_coverage_r3_steps.py: added --yes flag, added new step for
     no-eligible-plans path

6. Unit tests - Various source code bugs:
   - ThoughtBlock: converted from @dataclass to Pydantic BaseModel
     (architecture test requires all dataclasses to use Pydantic)
   - session.py: added DatabaseError handling to export, import, tell commands
   - database.py: fixed rollback_to() to reuse checkpoint connection for writes
   - database.py: added _get_checkpoint_conn() helper
   - check-tls-cert.py: fixed SSLCertVerificationError.reason AttributeError

7. Unit tests - Test step bugs:
   - error_recovery_coverage_boost_steps.py: fixed invalid ULID _PLAN_ID
   - session_service_coverage_steps.py: fixed 'sha256:' prefix bug in checksum
   - database_models_new_coverage_steps.py: added 'name' field to session mock
   - async_audit_recording_steps.py: fixed Settings(audit_async=False) via env var
   - coverage_threshold_config_steps.py: added --coverage-min pattern support
   - m5_acms_smoke_steps.py: updated usage hint text
   - actor_cli_yaml_steps.py: updated 'Removed actor' → 'Actor removed'
   - aimodelscredentials_steps.py: set context.imported_class in import step
   - domain_base_model.feature: added missing 'When I examine model_config' step
   - tui_first_run_steps.py: fixed module reload to restore cleveragents.tui.*
     modules after test (prevented patch interference in subsequent tests)
   - tui_first_run_steps.py: added set_search('') step for empty string
   - resource_handler_base_coverage_r3_steps.py: use _MinimalHandler instead
     of DatabaseResourceHandler for NotImplementedError tests
   - resource_handler_crud.feature: updated to test new DatabaseHandler behavior
   - resource_handler_sandbox.feature: updated to test new DatabaseHandler behavior
   - tdd_json_decode_crash_persistence.feature: fixed @tdd_bug → @tdd_issue tags

8. Parallel test interference:
   - All step files using use_step_matcher('re') now reset to 'parse' at end
     to prevent global matcher state leaking to subsequent step files
2026-04-04 20:38:16 +00:00

182 lines
9.2 KiB
Gherkin

Feature: Resource handler CRUD and discovery operations
Tests for read, write, delete, list_children, diff, and discover_children
methods on GitCheckoutHandler, FsDirectoryHandler, and base handler
NotImplementedError defaults.
Issue #827: ResourceHandler CRUD and discovery methods.
# ============================================================
# FsDirectoryHandler CRUD
# ============================================================
Scenario: FsDirectory handler read returns file content
Given a temp directory with file "hello.txt" containing "Hello World"
And an fs-directory resource pointing to that directory
When I call read on the fs-directory handler with path "hello.txt"
Then the content data should be "Hello World"
And the content encoding should be "utf-8"
And the content hash should not be empty
Scenario: FsDirectory handler read of root returns directory listing
Given a temp directory with file "a.txt" containing "aaa"
And a temp sub-file "b.txt" containing "bbb"
And an fs-directory resource pointing to that directory
When I call read on the fs-directory handler for the root
Then the content text should contain "a.txt"
And the content text should contain "b.txt"
Scenario: FsDirectory handler read of missing path raises FileNotFoundError
Given a temp directory with file "only.txt" containing "data"
And an fs-directory resource pointing to that directory
When I call read on the fs-directory handler with path "missing.txt"
Then a crud FileNotFoundError should be raised
Scenario: FsDirectory handler write creates a new file
Given an empty temp directory
And an fs-directory resource pointing to that directory
When I call write on the fs-directory handler with path "new.txt" and data "New Content"
Then the write result should be successful
And the write result bytes_written should be 11
And the file "new.txt" should exist in the temp directory with content "New Content"
Scenario: FsDirectory handler write creates parent directories
Given an empty temp directory
And an fs-directory resource pointing to that directory
When I call write on the fs-directory handler with path "sub/dir/file.txt" and data "Nested"
Then the write result should be successful
And the file "sub/dir/file.txt" should exist in the temp directory with content "Nested"
Scenario: FsDirectory handler delete removes a file
Given a temp directory with file "doomed.txt" containing "bye"
And an fs-directory resource pointing to that directory
When I call delete on the fs-directory handler with path "doomed.txt"
Then the delete result should be successful
And the file "doomed.txt" should not exist in the temp directory
Scenario: FsDirectory handler delete of missing path raises FileNotFoundError
Given an empty temp directory
And an fs-directory resource pointing to that directory
When I call delete on the fs-directory handler with path "ghost.txt"
Then a crud FileNotFoundError should be raised
Scenario: FsDirectory handler list_children returns sorted entries
Given a temp directory with file "c.txt" containing "c"
And a temp sub-file "a.txt" containing "a"
And a temp sub-directory "subdir"
And an fs-directory resource pointing to that directory
When I call list_children on the fs-directory handler
Then the children list should equal ["a.txt", "c.txt", "subdir"]
Scenario: FsDirectory handler diff detects changes between directories
Given a temp directory with file "same.txt" containing "same"
And a temp sub-file "changed.txt" containing "original"
And an fs-directory resource pointing to that directory
And a second temp directory with file "same.txt" containing "same"
And a second temp sub-file "changed.txt" containing "modified"
When I call diff on the fs-directory handler against the second directory
Then the diff result should have changes
And the diff files_changed should be 1
And the diff insertions should be greater than 0
Scenario: FsDirectory handler diff detects no changes for identical directories
Given a temp directory with file "same.txt" containing "identical"
And an fs-directory resource pointing to that directory
And a second temp directory with file "same.txt" containing "identical"
When I call diff on the fs-directory handler against the second directory
Then the diff result should have no changes
Scenario: FsDirectory handler discover_children returns subdirectories
Given a temp directory with file "file.txt" containing "data"
And a temp sub-directory "alpha"
And a temp sub-directory "beta"
And an fs-directory resource pointing to that directory
When I call discover_children on the fs-directory handler
Then the discovered children should have 2 items
And the discovered children names should include "alpha"
And the discovered children names should include "beta"
# ============================================================
# GitCheckoutHandler CRUD
# ============================================================
Scenario: GitCheckout handler read returns tracked file content
Given a temp git repo with file "readme.md" containing "# Hello"
And a git-checkout resource pointing to that repo
When I call read on the git-checkout handler with path "readme.md"
Then the content data should be "# Hello"
And the content hash should not be empty
Scenario: GitCheckout handler write creates a new file in the repo
Given a temp git repo with file "initial.txt" containing "start"
And a git-checkout resource pointing to that repo
When I call write on the git-checkout handler with path "added.txt" and data "new file"
Then the write result should be successful
And the file "added.txt" should exist in the temp git repo with content "new file"
Scenario: GitCheckout handler delete removes a tracked file
Given a temp git repo with file "remove_me.txt" containing "deletable"
And a git-checkout resource pointing to that repo
When I call delete on the git-checkout handler with path "remove_me.txt"
Then the delete result should be successful
And the file "remove_me.txt" should not exist in the temp git repo
Scenario: GitCheckout handler list_children returns tracked entries
Given a temp git repo with file "a.py" containing "# a"
And a temp git sub-file "b.py" containing "# b"
And a git-checkout resource pointing to that repo
When I call list_children on the git-checkout handler
Then the children list should contain "a.py"
And the children list should contain "b.py"
Scenario: GitCheckout handler diff detects changes against another location
Given a temp git repo with file "code.py" containing "print('hello')"
And a git-checkout resource pointing to that repo
And a second temp directory with file "code.py" containing "print('world')"
When I call diff on the git-checkout handler against the second directory
Then the diff result should have changes
Scenario: GitCheckout handler discover_children returns top-level directories
Given a temp git repo with file "root.txt" containing "root"
And a temp git sub-directory "src" with file "main.py" containing "# main"
And a git-checkout resource pointing to that repo
When I call discover_children on the git-checkout handler
Then the discovered children names should include "src"
# ============================================================
# BaseResourceHandler NotImplementedError defaults
# ============================================================
Scenario: Database handler read returns content for database resource
Given a database resource handler
And a dummy database resource
When I call read on the database handler
Then a crud read result should be returned without error
Scenario: Database handler write returns result for database resource
Given a database resource handler
And a dummy database resource
When I call write on the database handler with path "table" and data "row"
Then a crud write result should be returned without error
# ============================================================
# Security: path traversal rejection
# ============================================================
Scenario: FsDirectory handler read rejects path traversal
Given a temp directory with file "safe.txt" containing "safe"
And an fs-directory resource pointing to that directory
When I call read on the fs-directory handler with path "../../etc/passwd"
Then a crud PermissionError should be raised
Scenario: FsDirectory handler write rejects path traversal
Given a temp directory with file "safe.txt" containing "safe"
And an fs-directory resource pointing to that directory
When I call write on the fs-directory handler with path "../../tmp/evil.txt" and data "pwned"
Then a crud PermissionError should be raised
Scenario: GitCheckout handler read rejects path traversal
Given a temp git repo with file "safe.txt" containing "safe"
And a git-checkout resource pointing to that repo
When I call read on the git-checkout handler with path "../../etc/passwd"
Then a crud PermissionError should be raised