77a0a95dc3
CI / lint (pull_request) Successful in 26s
CI / security (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 1m2s
CI / quality (pull_request) Successful in 17s
CI / build (pull_request) Successful in 25s
CI / integration_tests (pull_request) Failing after 3m2s
CI / lint (push) Successful in 23s
CI / unit_tests (pull_request) Failing after 17m24s
CI / docker (pull_request) Has been skipped
CI / typecheck (push) Successful in 40s
CI / security (push) Successful in 37s
CI / quality (push) Successful in 25s
CI / build (push) Successful in 16s
CI / integration_tests (push) Failing after 7m16s
CI / unit_tests (push) Failing after 24m35s
CI / docker (push) Has been skipped
CI / coverage (pull_request) Failing after 37m0s
CI / coverage (push) Failing after 37m15s
350 lines
21 KiB
Gherkin
350 lines
21 KiB
Gherkin
@unit
|
||
Feature: Repository uncovered lines coverage
|
||
Target the remaining uncovered lines in repositories.py to boost
|
||
line and branch coverage.
|
||
|
||
# -------------------------------------------------------------------
|
||
# LinkNotFoundError (lines 1595-1598)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: LinkNotFoundError stores parent and child IDs
|
||
Given a LinkNotFoundError for parent "P1" and child "C1"
|
||
Then the LinkNotFoundError message should contain "P1" and "C1"
|
||
And the LinkNotFoundError parent_id should be "P1"
|
||
And the LinkNotFoundError child_id should be "C1"
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceTypeRepository – DuplicateResourceTypeError from UNIQUE IntegrityError (line 1708)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceTypeRepository create raises DuplicateResourceTypeError on UNIQUE IntegrityError
|
||
Given a resource type repository backed by an in-memory database for uncovered lines
|
||
And a resource type "test/dup-type" exists in the database for uncovered lines
|
||
When the same resource type "test/dup-type" is created again for uncovered lines
|
||
Then a DuplicateResourceTypeError should be raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceTypeRepository._to_domain – equivalence_json not None (line 1923)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceTypeRepository _to_domain parses equivalence_json when present
|
||
Given a resource type repository backed by an in-memory database for uncovered lines
|
||
And a resource type row with equivalence_json set to '{"field": "name"}'
|
||
When the resource type is retrieved by name "test/equiv-type" for uncovered lines
|
||
Then the resource type equivalence should contain key "field"
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository.list_resources – namespace filter (line 2114)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceRepository list_resources filters by namespace
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And resources exist in namespace "ns-alpha" and "ns-beta" for uncovered lines
|
||
When resources are listed with namespace "ns-alpha" for uncovered lines
|
||
Then only resources from namespace "ns-alpha" should be returned
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository.unlink_child – parent not found (line 2385)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceRepository unlink_child raises error when parent not found
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
When unlink_child is called with non-existent parent "NOPARENT" and child "NOCHILD" for uncovered lines
|
||
Then a ResourceNotFoundRepoError should be raised for the unlink parent
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository.unlink_child – child not found (line 2391)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceRepository unlink_child raises error when child not found
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource "parent-res" exists for uncovered unlink tests
|
||
When unlink_child is called with existing parent and non-existent child "NOCHILD" for uncovered lines
|
||
Then a ResourceNotFoundRepoError should be raised for the unlink child
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository.unlink_child – link not found (line 2399)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceRepository unlink_child raises LinkNotFoundError when no link exists
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And two resources "parent-ul" and "child-ul" exist but are not linked for uncovered lines
|
||
When unlink_child is called for "parent-ul" and "child-ul" for uncovered lines
|
||
Then a LinkNotFoundError should be raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository.unlink_child – re-raise domain errors (line 2407)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceRepository unlink_child re-raises domain errors unchanged
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
When unlink_child is called with non-existent parent "GHOST" and child "GHOST2" for uncovered lines re-raise
|
||
Then a ResourceNotFoundRepoError should be raised and re-raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository.auto_discover_children – type_row is None (line 2524)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children returns empty when parent type not in DB
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with type "missing-type" that has no type row in DB for uncovered lines
|
||
When auto_discover_children is called for that resource for uncovered lines
|
||
Then an empty list should be returned from auto_discover for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# auto_discover_children – auto_disc not enabled (lines 2528-2533)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children returns empty when auto_discover_json is null
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with type that has null auto_discover_json for uncovered lines
|
||
When auto_discover_children is called for that typed resource for uncovered lines null
|
||
Then an empty list should be returned from auto_discover for uncovered lines
|
||
|
||
Scenario: auto_discover_children returns empty when auto_discover is disabled
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with type that has auto_discover disabled for uncovered lines
|
||
When auto_discover_children is called for that typed resource for uncovered lines disabled
|
||
Then an empty list should be returned from auto_discover for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# auto_discover_children – rules empty (lines 2535-2537)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children returns empty when rules list is empty
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with type that has auto_discover enabled but empty rules for uncovered lines
|
||
When auto_discover_children is called for that typed resource for uncovered lines empty rules
|
||
Then an empty list should be returned from auto_discover for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# auto_discover_children – child type not in DB (line 2560)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children skips rule when child type not in DB
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with auto_discover rules referencing non-existent child type for uncovered lines
|
||
When auto_discover_children is called for that resource with missing child type for uncovered lines
|
||
Then an empty list should be returned from auto_discover for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# auto_discover_children – child type not in allowed list (line 2564)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children skips rule when child type not in allowed list
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with auto_discover rules where child type is not in allowed list for uncovered lines
|
||
When auto_discover_children is called for that resource with disallowed child type for uncovered lines
|
||
Then an empty list should be returned from auto_discover for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# auto_discover_children – successful discovery (lines 2567-2616)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children creates child resources and links
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource with auto_discover rules that match an existing child type for uncovered lines
|
||
When auto_discover_children is called for that resource for full discovery for uncovered lines
|
||
Then the discovered children list should not be empty for uncovered lines
|
||
And the child resource should be linked to the parent for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# auto_discover_children – OperationalError (lines 2619-2624)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: auto_discover_children wraps OperationalError in DatabaseError
|
||
Given a resource repository with session raising OperationalError on auto_discover for uncovered lines
|
||
When auto_discover_children is called and an OperationalError occurs for uncovered lines
|
||
Then a DatabaseError should be raised mentioning auto-discover for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# _get_ancestors – current in visited branch (line 2641)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: _get_ancestors handles cycles in visited set
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And resources forming a diamond graph for ancestor traversal for uncovered lines
|
||
When _get_ancestors is called on the bottom resource for uncovered lines
|
||
Then all ancestor IDs should be returned including the bottom resource for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ResourceRepository._to_domain – sandbox_strategy not None (line 2707)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ResourceRepository _to_domain converts sandbox_strategy when present
|
||
Given a resource repository backed by an in-memory database for uncovered lines
|
||
And a resource row with sandbox_strategy set to "git_worktree" for uncovered lines
|
||
When the resource is retrieved by ID for uncovered lines sandbox
|
||
Then the resource sandbox_strategy should be SandboxStrategy.GIT_WORKTREE
|
||
|
||
# -------------------------------------------------------------------
|
||
# ToolRepository.add – invalid tool_type (line 3174)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ToolRepository add raises InvalidToolTypeError for bad tool_type
|
||
Given a tool repository backed by an in-memory database for uncovered lines
|
||
And a tool domain object with tool_type "bogus" for uncovered lines
|
||
When the tool is added to the repository for uncovered lines invalid type
|
||
Then an InvalidToolTypeError should be raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ToolRepository.add – schema serialization + resource slots (lines 3196-3261)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ToolRepository add persists input/output schemas and resource slots
|
||
Given a tool repository backed by an in-memory database for uncovered lines
|
||
And a tool domain object with schemas and resource slots for uncovered lines
|
||
When the tool is added to the repository for uncovered lines with schemas
|
||
Then the tool should be retrievable and have schemas and bindings for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ToolRepository.get – fetch by ULID (lines 3286-3293)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ToolRepository get returns tool by ULID
|
||
Given a tool repository backed by an in-memory database for uncovered lines
|
||
And a tool has been persisted and its ULID captured for uncovered lines
|
||
When the tool is fetched by ULID for uncovered lines
|
||
Then the tool domain object should be returned for uncovered lines
|
||
|
||
Scenario: ToolRepository get returns None for unknown ULID
|
||
Given a tool repository backed by an in-memory database for uncovered lines
|
||
When a tool is fetched by ULID "00000000000000000000000000" for uncovered lines
|
||
Then None should be returned for the tool get for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ToolRepository._to_domain – input/output schema JSON parse (lines 3433, 3438)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ToolRepository _to_domain parses input and output schemas
|
||
Given a tool repository backed by an in-memory database for uncovered lines
|
||
And a tool with input_schema and output_schema stored as JSON for uncovered lines
|
||
When the tool is retrieved by name for uncovered lines schemas
|
||
Then the tool should have parsed input_schema and output_schema for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# ValidationAttachment.attach – duplicate detection (lines 3517-3520)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ValidationAttachment attach raises DuplicateValidationAttachmentError on duplicate
|
||
Given a validation attachment repository backed by an in-memory database for uncovered lines
|
||
And a validation "val-check" is already attached to resource "res-1" for uncovered lines
|
||
When the same validation "val-check" is attached again to resource "res-1" for uncovered lines
|
||
Then a DuplicateValidationAttachmentError should be raised for uncovered lines attach
|
||
|
||
# -------------------------------------------------------------------
|
||
# ValidationAttachment.attach – re-raise (line 3538)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: ValidationAttachment attach re-raises DuplicateValidationAttachmentError
|
||
Given a validation attachment repository backed by an in-memory database for uncovered lines
|
||
And a validation "val-dup" is already attached to resource "res-2" for uncovered lines
|
||
When the same validation "val-dup" is attached again to resource "res-2" for uncovered lines re-raise
|
||
Then the DuplicateValidationAttachmentError should propagate for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.get_by_name – row is None (line 3663)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository get_by_name returns None when not found
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
When a profile is fetched by name "nonexistent-profile" for uncovered lines
|
||
Then None should be returned for the profile get for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.get_by_name – _to_domain (line 3665)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository get_by_name returns domain object
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And a profile "test-profile" has been upserted for uncovered lines
|
||
When a profile is fetched by name "test-profile" for uncovered lines
|
||
Then the profile domain object should be returned for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.list_all – _to_domain mapping (line 3686)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository list_all returns domain objects
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And profiles "prof-a" and "prof-b" have been upserted for uncovered lines
|
||
When all profiles are listed for uncovered lines
|
||
Then two profile domain objects should be returned for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.upsert – existing row update (lines 3722-3732)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository upsert updates existing profile
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And a profile "update-prof" has been upserted for uncovered lines
|
||
When the profile "update-prof" is upserted again with changed description for uncovered lines
|
||
Then the profile should have the updated description for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.upsert – schema version mismatch (lines 3723-3731)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository upsert raises on schema version mismatch
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And a profile "versioned-prof" has been upserted with schema_version "1.0" for uncovered lines
|
||
When the profile "versioned-prof" is upserted with expected_schema_version "2.0" for uncovered lines
|
||
Then an AutomationProfileSchemaVersionError should be raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.upsert – new row insert (lines 3733-3735)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository upsert inserts new profile
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
When a new profile "brand-new" is upserted for uncovered lines
|
||
Then the profile "brand-new" should be retrievable for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.upsert – IntegrityError (lines 3739-3743)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository upsert wraps IntegrityError in DuplicateAutomationProfileError
|
||
Given an automation profile repository with session raising IntegrityError on flush for uncovered lines
|
||
When a profile is upserted and IntegrityError occurs for uncovered lines
|
||
Then a DuplicateAutomationProfileError should be raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.delete – row not found (lines 3766-3767)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository delete raises NotFoundError when missing
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
When a profile "ghost" is deleted for uncovered lines
|
||
Then an AutomationProfileNotFoundError should be raised for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository.delete – success path (lines 3768-3769)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository delete removes existing profile
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And a profile "delete-me" has been upserted for uncovered lines
|
||
When the profile "delete-me" is deleted for uncovered lines
|
||
Then the profile "delete-me" should no longer exist for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository._to_domain full field coverage (lines 3784-3806)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository _to_domain maps all fields correctly
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And a profile "full-fields" with all fields set has been upserted for uncovered lines
|
||
When a profile is fetched by name "full-fields" for uncovered lines
|
||
Then all profile fields should match the original values for uncovered lines
|
||
|
||
# -------------------------------------------------------------------
|
||
# AutomationProfileRepository._from_domain + _update_row (lines 3808-3855)
|
||
# -------------------------------------------------------------------
|
||
|
||
Scenario: AutomationProfileRepository _from_domain and _update_row cover all fields
|
||
Given an automation profile repository backed by an in-memory database for uncovered lines
|
||
And a profile "roundtrip" with specific field values has been upserted for uncovered lines
|
||
When the profile "roundtrip" is upserted again with different field values for uncovered lines
|
||
Then the profile "roundtrip" should have the new field values for uncovered lines
|