5d2e70cff0
CI / lint (pull_request) Successful in 14s
CI / typecheck (pull_request) Successful in 28s
CI / security (pull_request) Successful in 25s
CI / quality (pull_request) Successful in 47s
CI / unit_tests (pull_request) Successful in 16m4s
CI / build (pull_request) Successful in 15s
CI / integration_tests (pull_request) Successful in 9m36s
CI / coverage (pull_request) Successful in 8m43s
CI / docker (pull_request) Successful in 40s
253 lines
14 KiB
Gherkin
253 lines
14 KiB
Gherkin
Feature: Resource registry database tables
|
|
As a developer working on the resource registry infrastructure
|
|
I need database tables for resource types, resources, and resource edges
|
|
So that the resource DAG can be persisted and queried
|
|
|
|
Background:
|
|
Given a resource registry in-memory database is initialized
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Table existence
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Resource registry tables exist after schema creation
|
|
Then the resource registry database should contain table "resource_types"
|
|
And the resource registry database should contain table "resources"
|
|
And the resource registry database should contain table "resource_edges"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ResourceTypeModel CRUD
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Persist and retrieve a physical resource type
|
|
When I create a resource type "builtin/git-checkout" with kind "physical" and user_addable true
|
|
Then I can retrieve resource type "builtin/git-checkout"
|
|
And the retrieved resource type namespace is "builtin"
|
|
And the retrieved resource type kind is "physical"
|
|
And the retrieved resource type user_addable is true
|
|
|
|
Scenario: Persist and retrieve a virtual resource type
|
|
When I create a resource type "builtin/file" with kind "virtual" and user_addable false
|
|
Then I can retrieve resource type "builtin/file"
|
|
And the retrieved resource type kind is "virtual"
|
|
And the retrieved resource type user_addable is false
|
|
|
|
Scenario: Resource type stores JSON fields correctly
|
|
When I create a resource type "builtin/git-checkout" with JSON fields
|
|
Then the resource type args_schema_json round-trips correctly
|
|
And the resource type allowed_parent_types_json round-trips correctly
|
|
And the resource type allowed_child_types_json round-trips correctly
|
|
And the resource type auto_discover_json round-trips correctly
|
|
And the resource type capabilities_json round-trips correctly
|
|
|
|
Scenario: Resource type name uniqueness is enforced
|
|
When I create a resource type "builtin/git-checkout" with kind "physical" and user_addable true
|
|
Then creating a duplicate resource type "builtin/git-checkout" raises an integrity error
|
|
|
|
Scenario: Resource type kind check constraint rejects invalid values
|
|
Then creating a resource type with kind "invalid_kind" raises an integrity error
|
|
|
|
Scenario: List resource types by namespace
|
|
When I create a resource type "builtin/git-checkout" with kind "physical" and user_addable true
|
|
And I create a resource type "builtin/fs-mount" with kind "physical" and user_addable true
|
|
And I create a resource type "custom/database" with kind "physical" and user_addable true
|
|
Then listing resource types by namespace "builtin" returns 2 results
|
|
And listing resource types by namespace "custom" returns 1 result
|
|
|
|
Scenario: List resource types by kind
|
|
When I create a resource type "builtin/git-checkout" with kind "physical" and user_addable true
|
|
And I create a resource type "builtin/file" with kind "virtual" and user_addable false
|
|
Then listing resource types by kind "physical" returns 1 result
|
|
And listing resource types by kind "virtual" returns 1 result
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ResourceModel CRUD
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Persist and retrieve a named resource
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/my-repo" of type "builtin/git-checkout" with location "/home/user/repo"
|
|
Then I can retrieve the resource by id
|
|
And the retrieved resource namespaced_name is "local/my-repo"
|
|
And the retrieved resource namespace is "local"
|
|
And the retrieved resource type_name is "builtin/git-checkout"
|
|
And the retrieved resource kind is "physical"
|
|
And the retrieved resource location is "/home/user/repo"
|
|
|
|
Scenario: Persist a resource without a name (auto-discovered child)
|
|
Given a resource type "builtin/fs-file" exists as virtual
|
|
When I create an unnamed resource of type "builtin/fs-file"
|
|
Then I can retrieve the unnamed resource by id
|
|
And the unnamed resource namespaced_name is null
|
|
|
|
Scenario: Resource stores JSON properties correctly
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource with JSON properties
|
|
Then the resource properties_json round-trips correctly
|
|
And the resource metadata_json round-trips correctly
|
|
|
|
Scenario: Resource kind check constraint rejects invalid values
|
|
Given a resource type "builtin/git-checkout" exists
|
|
Then creating a resource with kind "invalid_kind" raises an integrity error
|
|
|
|
Scenario: Resource type FK prevents orphaned resources
|
|
Then creating a resource with non-existent type raises an integrity error
|
|
|
|
Scenario: Named resource uniqueness is enforced
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/my-repo" of type "builtin/git-checkout" with location "/path/a"
|
|
Then creating a duplicate named resource "local/my-repo" raises an integrity error
|
|
|
|
Scenario: Resource RESTRICT prevents type deletion when resources exist
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/my-repo" of type "builtin/git-checkout" with location "/path"
|
|
Then deleting resource type "builtin/git-checkout" raises an integrity error
|
|
|
|
Scenario: Query resources by type
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-mount" exists as physical
|
|
When I create a resource "local/repo1" of type "builtin/git-checkout" with location "/repo1"
|
|
And I create a resource "local/mount1" of type "builtin/fs-mount" with location "/mnt"
|
|
Then querying resources by type "builtin/git-checkout" returns 1 result
|
|
And querying resources by type "builtin/fs-mount" returns 1 result
|
|
|
|
Scenario: Query resources by namespace
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/repo1" of type "builtin/git-checkout" with location "/repo1"
|
|
And I create a resource "team/repo2" of type "builtin/git-checkout" with location "/repo2"
|
|
Then querying resources by namespace "local" returns 1 result
|
|
And querying resources by namespace "team" returns 1 result
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ResourceEdgeModel (DAG edges)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Create and query parent-child edges
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
When I create an edge from parent to child with link_type "contains"
|
|
Then the edge exists in the database
|
|
And the edge link_type is "contains"
|
|
And querying children of the parent returns 1 result
|
|
And querying parents of the child returns 1 result
|
|
|
|
Scenario: Edge composite PK prevents duplicate edges
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
When I create an edge from parent to child with link_type "contains"
|
|
Then creating a duplicate edge raises an integrity error
|
|
|
|
Scenario: Self-loop check constraint prevents self-referencing edges
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
Then creating a self-loop edge raises an integrity error
|
|
|
|
Scenario: Edge link_type check constraint rejects invalid values
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
Then creating an edge with invalid link_type raises an integrity error
|
|
|
|
Scenario: CASCADE deletes edges when parent resource is deleted
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
And I create an edge from parent to child with link_type "contains"
|
|
When I delete the parent resource
|
|
Then the edge no longer exists in the database
|
|
|
|
Scenario: CASCADE deletes edges when child resource is deleted
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
And I create an edge from parent to child with link_type "contains"
|
|
When I delete the child resource
|
|
Then the edge no longer exists in the database
|
|
|
|
Scenario: Multiple parents for a single child resource
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo-a" of type "builtin/git-checkout"
|
|
And a second parent resource "local/repo-b" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
When I create an edge from parent to child with link_type "contains"
|
|
And I create an edge from second parent to child with link_type "references"
|
|
Then querying parents of the child returns 2 results
|
|
|
|
Scenario: Multiple children for a single parent resource
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a first child resource of type "builtin/fs-directory"
|
|
And a second child resource of type "builtin/fs-directory"
|
|
When I create edges from parent to both children
|
|
Then querying children of the parent returns 2 results
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ORM relationship navigation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Navigate from resource to resource type via relationship
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/repo" of type "builtin/git-checkout" with location "/repo"
|
|
Then navigating from resource to resource_type returns "builtin/git-checkout"
|
|
|
|
Scenario: Navigate from resource type to resources via relationship
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/repo1" of type "builtin/git-checkout" with location "/r1"
|
|
And I create a resource "local/repo2" of type "builtin/git-checkout" with location "/r2"
|
|
Then navigating from resource_type to resources returns 2 items
|
|
|
|
Scenario: Navigate from resource to child edges via relationship
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
And I create an edge from parent to child with link_type "contains"
|
|
Then navigating from parent to child_edges returns 1 edge
|
|
And navigating from child to parent_edges returns 1 edge
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Timestamps and metadata
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Resource type timestamps are stored correctly
|
|
When I create a resource type "builtin/git-checkout" with kind "physical" and user_addable true
|
|
Then the resource type has valid created_at and updated_at timestamps
|
|
|
|
Scenario: Resource timestamps are stored correctly
|
|
Given a resource type "builtin/git-checkout" exists
|
|
When I create a resource "local/repo" of type "builtin/git-checkout" with location "/repo"
|
|
Then the resource has valid created_at and updated_at timestamps
|
|
|
|
Scenario: Edge timestamp is stored correctly
|
|
Given a resource type "builtin/git-checkout" exists
|
|
And a resource type "builtin/fs-directory" exists as physical
|
|
And a parent resource "local/repo" of type "builtin/git-checkout"
|
|
And a child resource of type "builtin/fs-directory"
|
|
When I create an edge from parent to child with link_type "contains"
|
|
Then the edge has a valid created_at timestamp
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Migration smoke tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Resource registry tables exist after migration via init_database
|
|
When I run init_database to simulate migration
|
|
Then the migrated database should contain table "resource_types"
|
|
And the migrated database should contain table "resources"
|
|
And the migrated database should contain table "resource_edges"
|
|
|
|
Scenario: Migration is idempotent for resource registry tables
|
|
When I run init_database twice on the same database file
|
|
Then the migrated database should contain table "resource_types"
|
|
And the migrated database should contain table "resources"
|
|
And the migrated database should contain table "resource_edges"
|