@phase1 @domain @repository @resource_repository Feature: Resource Repository Persistence As a system operator managing resources and resource types I want the resource repositories to reliably persist and retrieve entries So that the resource registry is durable and queryable Background: Given a clean resource repository database And a resource type repository backed by the database And a resource repository backed by the database # --------------------------------------------------------------------------- # ResourceTypeRepository: Creating resource types # --------------------------------------------------------------------------- @resource_type_create Scenario: A new resource type is persisted and retrievable Given a valid resource type spec named "myorg/test-type" When the resource type is saved through the repository Then the resource type repository should not raise an error And the persisted resource type should have name "myorg/test-type" @resource_type_create @error_handling Scenario: Saving a resource type with a duplicate name is rejected Given a valid resource type spec named "myorg/dup-type" And the resource type has already been saved once When a second resource type with the same name "myorg/dup-type" is saved Then a DuplicateResourceTypeError should be raised mentioning "myorg/dup-type" # --------------------------------------------------------------------------- # ResourceTypeRepository: Retrieving resource types # --------------------------------------------------------------------------- @resource_type_read Scenario: A resource type is retrieved by its name Given a valid resource type spec named "myorg/lookup-type" And the resource type has been saved through the repository When the resource type is looked up by name "myorg/lookup-type" Then the returned resource type should have name "myorg/lookup-type" @resource_type_read Scenario: Looking up a non-existent resource type returns nothing When the resource type is looked up by name "myorg/does-not-exist" Then no resource type should be returned # --------------------------------------------------------------------------- # ResourceTypeRepository: Listing resource types # --------------------------------------------------------------------------- @resource_type_list Scenario: All resource types are listed in order Given resource types "myorg/b-type" and "myorg/a-type" have been saved When all resource types are listed Then the resource type list should have 2 entries And the first resource type in the list should be "myorg/a-type" @resource_type_list Scenario: Resource types are filtered by namespace Given resource types "alpha/type-1" and "beta/type-2" have been saved When resource types are listed with namespace "alpha" Then the resource type list should have 1 entries And the first resource type in the list should be "alpha/type-1" @resource_type_list Scenario: Resource types are filtered by user_addable flag Given a resource type "myorg/addable-type" with user_addable true is saved And a resource type "myorg/non-addable" with user_addable false is saved When resource types are listed with user_addable true Then the resource type list should have 1 entries And the first resource type in the list should be "myorg/addable-type" # --------------------------------------------------------------------------- # ResourceTypeRepository: Updating resource types # --------------------------------------------------------------------------- @resource_type_update Scenario: A resource type description is updated Given a valid resource type spec named "myorg/update-type" And the resource type has been saved through the repository When the resource type description is updated to "New description" Then the resource type should be retrievable with description "New description" @resource_type_update @error_handling Scenario: Updating a non-existent resource type raises error When a non-existent resource type "myorg/phantom" is updated Then a ResourceTypeNotFoundError should be raised # --------------------------------------------------------------------------- # ResourceTypeRepository: Deleting resource types # --------------------------------------------------------------------------- @resource_type_delete Scenario: A resource type with no resources is deleted Given a valid resource type spec named "myorg/deletable-type" And the resource type has been saved through the repository When the resource type "myorg/deletable-type" is deleted Then the resource type deletion should return true And the resource type "myorg/deletable-type" should no longer exist @resource_type_delete Scenario: Deleting a non-existent resource type returns false When the resource type "myorg/phantom" is deleted Then the resource type deletion should return false @resource_type_delete @error_handling Scenario: Deleting a resource type with existing resources is rejected Given a valid resource type spec named "myorg/in-use-type" And the resource type has been saved through the repository And a resource of type "myorg/in-use-type" exists in the database When the resource type "myorg/in-use-type" is deleted Then a ResourceTypeHasResourcesError should be raised # --------------------------------------------------------------------------- # ResourceRepository: Creating resources # --------------------------------------------------------------------------- @resource_create Scenario: A new resource is persisted and retrievable Given a resource type "myorg/res-type" exists for resource tests And a valid resource domain object with name "myorg/test-resource" When the resource is saved through the repository Then the resource repository should not raise an error And the persisted resource should have name "myorg/test-resource" @resource_create @error_handling Scenario: Creating a resource with invalid type is rejected Given a valid resource domain object with type "myorg/nonexistent-type" When the resource is saved through the repository Then a ResourceTypeNotFoundError should be raised for type "myorg/nonexistent-type" @resource_create @error_handling Scenario: Creating a resource with duplicate name is rejected Given a resource type "myorg/dup-res-type" exists for resource tests And a resource with name "myorg/dup-resource" has been saved When a second resource with name "myorg/dup-resource" is saved Then a DuplicateResourceError should be raised mentioning "myorg/dup-resource" # --------------------------------------------------------------------------- # ResourceRepository: Retrieving resources # --------------------------------------------------------------------------- @resource_read Scenario: A resource is retrieved by its ULID Given a resource type "myorg/get-type" exists for resource tests And a resource with known ULID has been saved When the resource is looked up by its ULID Then the returned resource should have the correct ULID @resource_read Scenario: A resource is retrieved by its namespaced name Given a resource type "myorg/name-type" exists for resource tests And a resource with name "myorg/named-resource" has been saved When the resource is looked up by name "myorg/named-resource" Then the returned resource should have name "myorg/named-resource" @resource_read Scenario: Looking up a non-existent resource by ULID returns nothing When the resource is looked up by ULID "01ZZZZZZZZZZZZZZZZZZZZZZZZ" Then no resource should be returned @resource_read Scenario: Looking up a non-existent resource by name returns nothing When the resource is looked up by name "myorg/no-such-resource" Then no resource should be returned # --------------------------------------------------------------------------- # ResourceRepository: Listing resources # --------------------------------------------------------------------------- @resource_list Scenario: Resources are listed with pagination Given a resource type "myorg/list-type" exists for resource tests And 5 resources of type "myorg/list-type" have been saved When resources are listed with limit 3 and offset 0 Then the resource list should have 3 entries @resource_list Scenario: Resources are filtered by type_name Given resource types "myorg/type-a" and "myorg/type-b" exist for resource tests And 2 resources of type "myorg/type-a" have been saved And 3 resources of type "myorg/type-b" have been saved When resources are listed with type_name "myorg/type-a" Then the resource list should have 2 entries # --------------------------------------------------------------------------- # ResourceRepository: Updating resources # --------------------------------------------------------------------------- @resource_update Scenario: A resource description is updated Given a resource type "myorg/upd-type" exists for resource tests And a resource with name "myorg/updatable-resource" has been saved When the resource description is updated to "Updated description" Then the resource should be retrievable with description "Updated description" @resource_update @error_handling Scenario: Updating a non-existent resource raises error When a non-existent resource with ULID "01ZZZZZZZZZZZZZZZZZZZZZZZZ" is updated Then a ResourceNotFoundRepoError should be raised # --------------------------------------------------------------------------- # ResourceRepository: Deleting resources # --------------------------------------------------------------------------- @resource_delete Scenario: A resource with no edges is deleted Given a resource type "myorg/del-type" exists for resource tests And a resource with name "myorg/deletable-resource" has been saved When the resource is deleted by its ULID Then the resource deletion should return true And the resource should no longer exist @resource_delete Scenario: Deleting a non-existent resource returns false When the resource with ULID "01ZZZZZZZZZZZZZZZZZZZZZZZZ" is deleted Then the resource deletion should return false @resource_delete @error_handling Scenario: Deleting a resource with edges is rejected Given a resource type "myorg/edge-type" exists for resource tests And a parent and child resource of type "myorg/edge-type" are linked When the parent resource is deleted Then a ResourceHasEdgesError should be raised # --------------------------------------------------------------------------- # ResourceRepository: resolve_namespaced_name helper # --------------------------------------------------------------------------- @resource_resolve Scenario: Resolve by name returns the resource Given a resource type "myorg/resolve-type" exists for resource tests And a resource with name "myorg/resolve-me" has been saved When the resource is resolved by name_or_id "myorg/resolve-me" Then the resolved resource should have name "myorg/resolve-me" @resource_resolve Scenario: Resolve by ULID returns the resource Given a resource type "myorg/resolve-ulid-type" exists for resource tests And a resource with known ULID has been saved for resolve test When the resource is resolved by its ULID Then the resolved resource should have the correct ULID @resource_resolve Scenario: Resolve with unknown name returns nothing When the resource is resolved by name_or_id "myorg/unknown" Then no resolved resource should be returned # --------------------------------------------------------------------------- # ResourceTypeRepository: domain round-trip # --------------------------------------------------------------------------- @resource_type_roundtrip Scenario: Resource type persists and restores all fields Given a full resource type spec with cli_args and capabilities When the full resource type is saved and retrieved Then the restored resource type should match the original fields