forked from HAL9000/cleveragents-core
31472b5413
Add Behave feature/step pairs that exercise uncovered branches across handlers, LSP, CLI, and service layers to reach the coverage gate. ISSUES CLOSED: #1232
255 lines
8.3 KiB
Python
255 lines
8.3 KiB
Python
"""Step definitions for ResourceHandler protocol coverage.
|
|
|
|
Targets uncovered lines in src/cleveragents/resource/handlers/protocol.py:
|
|
- Line 76: Content.text raises ValueError for binary (encoding=None)
|
|
- Line 236: ResourceHandler.resolve default stub
|
|
- Line 254: ResourceHandler.read default stub
|
|
- Line 271: ResourceHandler.write default stub
|
|
- Line 288: ResourceHandler.delete default stub
|
|
- Line 299: ResourceHandler.list_children default stub
|
|
- Line 311: ResourceHandler.diff default stub
|
|
- Line 315: ResourceHandler.discover_children default stub
|
|
- Line 327: ResourceHandler.create_sandbox default stub
|
|
- Line 338: ResourceHandler.create_checkpoint default stub
|
|
- Line 349: ResourceHandler.rollback_to default stub
|
|
- Line 360: ResourceHandler.project_access default stub
|
|
|
|
All steps use the ``phcov`` prefix to avoid collisions with other step files.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from behave import given, then, when
|
|
from behave.runner import Context
|
|
|
|
from cleveragents.domain.models.core.resource import PhysVirt, Resource
|
|
from cleveragents.resource.handlers.protocol import Content, ResourceHandler
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# A valid ULID for constructing Resource instances.
|
|
_DUMMY_ULID = "01ARZ3NDEKTSV4RRFFQ69G5FAV"
|
|
|
|
|
|
class _BareResourceHandler(ResourceHandler):
|
|
"""Minimal subclass that inherits all Protocol default stubs.
|
|
|
|
Does NOT override any methods, so calling them executes the ``...``
|
|
body in the Protocol and returns ``None``.
|
|
"""
|
|
|
|
pass
|
|
|
|
|
|
def _make_dummy_resource() -> Resource:
|
|
"""Create a minimal valid Resource for test use."""
|
|
return Resource(
|
|
resource_id=_DUMMY_ULID,
|
|
resource_type_name="test-type",
|
|
classification=PhysVirt.PHYSICAL,
|
|
location="/tmp/test",
|
|
)
|
|
|
|
|
|
def _make_mock_sandbox_manager() -> MagicMock:
|
|
"""Create a MagicMock standing in for SandboxManager."""
|
|
return MagicMock(name="SandboxManager")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Given steps
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@given("phcov a Content instance with binary data and encoding None")
|
|
def step_given_phcov_binary_content(context: Context) -> None:
|
|
context.phcov_content = Content(data=b"\x89PNG\r\n", encoding=None)
|
|
context.phcov_error = None
|
|
|
|
|
|
@given("phcov a bare ResourceHandler protocol subclass instance")
|
|
def step_given_phcov_bare_handler(context: Context) -> None:
|
|
context.phcov_handler = _BareResourceHandler()
|
|
context.phcov_result = None
|
|
context.phcov_error = None
|
|
|
|
|
|
@given("phcov a dummy Resource and SandboxManager")
|
|
def step_given_phcov_dummy_resource_and_manager(context: Context) -> None:
|
|
context.phcov_resource = _make_dummy_resource()
|
|
context.phcov_sandbox_manager = _make_mock_sandbox_manager()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# When steps
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@when("phcov the text property is accessed")
|
|
def step_when_phcov_text_property(context: Context) -> None:
|
|
try:
|
|
_ = context.phcov_content.text
|
|
except ValueError as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the resolve method is called")
|
|
def step_when_phcov_resolve(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.resolve(
|
|
resource=context.phcov_resource,
|
|
plan_id="plan-001",
|
|
slot_name="repo",
|
|
sandbox_manager=context.phcov_sandbox_manager,
|
|
access="read_only",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the read method is called")
|
|
def step_when_phcov_read(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.read(
|
|
resource=context.phcov_resource,
|
|
path="",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the write method is called")
|
|
def step_when_phcov_write(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.write(
|
|
resource=context.phcov_resource,
|
|
path="test.txt",
|
|
data=b"hello",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the delete method is called")
|
|
def step_when_phcov_delete(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.delete(
|
|
resource=context.phcov_resource,
|
|
path="",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the list_children method is called")
|
|
def step_when_phcov_list_children(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.list_children(
|
|
resource=context.phcov_resource,
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the diff method is called")
|
|
def step_when_phcov_diff(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.diff(
|
|
resource=context.phcov_resource,
|
|
other_location="/tmp/other",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the discover_children method is called")
|
|
def step_when_phcov_discover_children(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.discover_children(
|
|
resource=context.phcov_resource,
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the create_sandbox method is called")
|
|
def step_when_phcov_create_sandbox(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.create_sandbox(
|
|
resource=context.phcov_resource,
|
|
plan_id="plan-001",
|
|
sandbox_manager=context.phcov_sandbox_manager,
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the create_checkpoint method is called")
|
|
def step_when_phcov_create_checkpoint(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.create_checkpoint(
|
|
resource=context.phcov_resource,
|
|
plan_id="plan-001",
|
|
sandbox_manager=context.phcov_sandbox_manager,
|
|
phase="execution",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the rollback_to method is called")
|
|
def step_when_phcov_rollback_to(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.rollback_to(
|
|
resource=context.phcov_resource,
|
|
plan_id="plan-001",
|
|
checkpoint_id="chk-001",
|
|
sandbox_manager=context.phcov_sandbox_manager,
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
@when("phcov the project_access method is called")
|
|
def step_when_phcov_project_access(context: Context) -> None:
|
|
try:
|
|
context.phcov_result = context.phcov_handler.project_access(
|
|
resource=context.phcov_resource,
|
|
principal="user-alice",
|
|
action="read",
|
|
project_id="proj-001",
|
|
)
|
|
except Exception as exc:
|
|
context.phcov_error = exc
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Then steps
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@then('phcov a ValueError should be stored with message "{expected_msg}"')
|
|
def step_then_phcov_valueerror(context: Context, expected_msg: str) -> None:
|
|
assert context.phcov_error is not None, (
|
|
"Expected a ValueError but no exception was raised"
|
|
)
|
|
assert isinstance(context.phcov_error, ValueError), (
|
|
f"Expected ValueError, got {type(context.phcov_error).__name__}"
|
|
)
|
|
actual_msg = str(context.phcov_error)
|
|
assert expected_msg in actual_msg, (
|
|
f"Expected message to contain '{expected_msg}', got: '{actual_msg}'"
|
|
)
|
|
|
|
|
|
@then("phcov the result should be None")
|
|
def step_then_phcov_result_none(context: Context) -> None:
|
|
assert context.phcov_error is None, f"Unexpected exception: {context.phcov_error}"
|
|
assert context.phcov_result is None, (
|
|
f"Expected None but got: {context.phcov_result!r}"
|
|
)
|