Feature: Namespaced project repository operations As a developer I want project and resource-link repositories So that namespaced projects and their resource links are persisted correctly Background: Given a project repository in-memory database is initialized # ---------- NamespacedProjectRepository ---------- Scenario: Create a namespaced project When I create a namespaced project "local/test-project" via the repository Then the project "local/test-project" should exist in the repository Scenario: Get a namespaced project by primary key Given a namespaced project "local/get-project" exists in the repository When I get the project "local/get-project" from the repository Then the returned project name should be "get-project" And the returned project namespace should be "local" Scenario: Get a non-existent project raises ProjectNotFoundError When I get the project "local/no-such-project" from the repository expecting an error Then the repository error should be "ProjectNotFoundError" Scenario: List projects returns all projects Given a namespaced project "local/alpha" exists in the repository And a namespaced project "local/beta" exists in the repository When I list all projects from the repository Then the project list should contain 2 projects Scenario: List projects filtered by namespace Given a namespaced project "local/ns-a" exists in the repository And a namespaced project "team/ns-b" exists in the repository When I list projects with namespace "local" from the repository Then the project list should contain 1 projects And the first project in the list should be "local/ns-a" Scenario: List projects respects limit Given a namespaced project "local/lim-a" exists in the repository And a namespaced project "local/lim-b" exists in the repository And a namespaced project "local/lim-c" exists in the repository When I list projects with limit 2 from the repository Then the project list should contain 2 projects Scenario: Update a namespaced project description Given a namespaced project "local/update-me" exists in the repository When I update the project "local/update-me" description to "Updated desc" Then the project "local/update-me" description should be "Updated desc" Scenario: Update a non-existent project raises ProjectNotFoundError When I update a non-existent project "local/ghost" expecting an error Then the repository error should be "ProjectNotFoundError" Scenario: Delete a namespaced project Given a namespaced project "local/delete-me" exists in the repository When I delete the project "local/delete-me" from the repository Then the delete result should be True And getting "local/delete-me" should raise ProjectNotFoundError Scenario: Delete a non-existent project returns False When I delete the project "local/not-here" from the repository Then the delete result should be False Scenario: Delete cascades to resource links Given a namespaced project "local/cascade-proj" exists in the repository And a resource link exists for project "local/cascade-proj" When I delete the project "local/cascade-proj" from the repository Then the links for project "local/cascade-proj" should be empty Scenario: Create duplicate project raises error Given a namespaced project "local/dup-proj" exists in the repository When I create a duplicate project "local/dup-proj" expecting an error Then the repository error message should contain "already exists" # ---------- ProjectResourceLinkRepository ---------- Scenario: Create a resource link Given a namespaced project "local/link-proj" exists in the repository And a resource exists with id "00000000000000000000000001" When I create a link for project "local/link-proj" to resource "00000000000000000000000001" without alias Then the link should have a valid link_id And the link project_name should be "local/link-proj" Scenario: Create a resource link with alias Given a namespaced project "local/alias-proj" exists in the repository And a resource exists with id "00000000000000000000000002" When I create an aliased link for project "local/alias-proj" resource "00000000000000000000000002" alias "my-repo" Then the link alias should be "my-repo" Scenario: Duplicate alias within same project raises DuplicateLinkError Given a namespaced project "local/dup-alias" exists in the repository And a resource exists with id "00000000000000000000000003" And a resource exists with id "00000000000000000000000004" And an aliased link exists for project "local/dup-alias" resource "00000000000000000000000003" alias "dupe" When I create a duplicate alias link for project "local/dup-alias" resource "00000000000000000000000004" alias "dupe" Then the repository error should be "DuplicateLinkError" Scenario: List links for a project Given a namespaced project "local/list-links" exists in the repository And a resource exists with id "00000000000000000000000005" And a resource exists with id "00000000000000000000000006" And a link exists for project "local/list-links" to resource "00000000000000000000000005" without alias And a link exists for project "local/list-links" to resource "00000000000000000000000006" without alias When I list links for project "local/list-links" Then the link list should contain 2 links Scenario: Get a specific link by id Given a namespaced project "local/get-link" exists in the repository And a resource exists with id "00000000000000000000000007" And a link exists for project "local/get-link" to resource "00000000000000000000000007" without alias When I get the link by its stored id Then the returned link should not be None Scenario: Get a non-existent link returns None When I get a link with id "00000000000000000000000099" Then the returned link should be None Scenario: Remove a link Given a namespaced project "local/rm-link" exists in the repository And a resource exists with id "00000000000000000000000008" And a link exists for project "local/rm-link" to resource "00000000000000000000000008" without alias When I remove the link by its stored id Then the remove result should be True And the link list for project "local/rm-link" should be empty Scenario: Remove a non-existent link returns False When I remove a link with id "00000000000000000000000099" Then the project repo remove result should be False Scenario: Create link with read_only flag Given a namespaced project "local/ro-proj" exists in the repository And a resource exists with id "00000000000000000000000009" When I create a read-only link for project "local/ro-proj" to resource "00000000000000000000000009" Then the link read_only flag should be True Scenario: Created link is visible in a new session (cross-session persistence) Given a namespaced project "local/xsess-proj" exists in the repository And a resource exists with id "00000000000000000000000010" When I create a link for project "local/xsess-proj" to resource "00000000000000000000000010" without alias Then the link should be visible in a new session from the same engine Scenario: Removed link is absent in a new session (cross-session persistence) Given a namespaced project "local/xsess-rm" exists in the repository And a resource exists with id "00000000000000000000000011" And a link exists for project "local/xsess-rm" to resource "00000000000000000000000011" without alias When I remove the link by its stored id Then the remove result should be True And the removed link should be absent in a new session from the same engine # ---------- Data integrity: rollback removal verification ---------- @tdd_issue @tdd_issue_8179 Scenario: IntegrityError raises DatabaseError through repository create method (no explicit rollback) Given a namespaced project "local/integrity-verify" exists in the repository When I create a namespaced project "local/integrity-verify" via the repository expecting an error Then the repository error should be "DatabaseError" @tdd_issue @tdd_issue_8179 Scenario: Update non-existent project raises ProjectNotFoundError without leaving transaction dirty When I update a non-existent project "local/missing-update-check" expecting an error Then the repository error should be "ProjectNotFoundError"