- Fix CI lint failure: remove unused IntegrityError import in BDD steps - Append session.rollback() before session.close() in all NamespacedProjectRepository methods that own the session outside UoW - Merge duplicate CHANGELOG ### Fixed sections into single header - Apply @tdd_issue @tdd_issue_8179 @tdd_expected_fail tags to new BDD scenarios - Consolidate near-duplicate step definitions; fix misleading docstring (NsP operates outside UoW) ISSUES CLOSED: #8179
This commit is contained in:
@@ -149,11 +149,13 @@ Feature: Namespaced project repository operations
|
||||
|
||||
# ---------- Data integrity: rollback removal verification ----------
|
||||
|
||||
@tdd_issue @tdd_issue_8179 @tdd_expected_fail
|
||||
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 type should be "DatabaseError"
|
||||
Then the repository error should be "DatabaseError"
|
||||
|
||||
@tdd_issue @tdd_issue_8179 @tdd_expected_fail
|
||||
Scenario: Update non-existent project raises ProjectNotFoundError without leaving transaction dirty
|
||||
Given a namespaced project "local/missing-update-check" exists in the repository
|
||||
When I update a non-existent project "local/missing-update-check" expecting an error
|
||||
|
||||
@@ -570,15 +570,20 @@ def step_pr_removed_link_absent_new_session(context: Any) -> None:
|
||||
# Data integrity BDD step extensions (PR #8179)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Note: `step_pr_update_not_found` (line ~236, non-duplicate) already handles the
|
||||
# "when I update a non-existent project … expecting an error" Scenario step.
|
||||
|
||||
|
||||
@when('I create a namespaced project "{ns_name}" via the repository expecting an error')
|
||||
def step_pr_create_with_error(context: Any, ns_name: str) -> None:
|
||||
"""Attempt to create a duplicate project through the repository.
|
||||
|
||||
This exercises the Repository's own IntegrityError handling path,
|
||||
verifying that rollback is delegated to the UoW outer-layer handler.
|
||||
Exercises the NamespacedProjectRepository's own IntegrityError handling path
|
||||
(the repo owns its session via session-factory and is NOT wired into any
|
||||
UnitOfWork). Verifies that error propagation works correctly after the
|
||||
redundant ``session.rollback()`` was removed from exception handlers —
|
||||
``session.rollback()`` now fires in the ``finally`` block instead.
|
||||
"""
|
||||
from sqlalchemy.exc import IntegrityError as _IntegrityError
|
||||
|
||||
project = _make_project(ns_name)
|
||||
try:
|
||||
@@ -586,11 +591,3 @@ def step_pr_create_with_error(context: Any, ns_name: str) -> None:
|
||||
context.pr_error = None
|
||||
except Exception as exc:
|
||||
context.pr_error = exc
|
||||
|
||||
|
||||
@then('the repository error type should be "{error_type}"')
|
||||
def step_pr_check_error_class(context: Any, error_type: str) -> None:
|
||||
"""Verify the caught error is of the expected class."""
|
||||
assert context.pr_error is not None, "Expected an error but none was raised"
|
||||
actual_type = type(context.pr_error).__name__
|
||||
assert actual_type == error_type, f"Expected {error_type}, got {actual_type}"
|
||||
|
||||
@@ -3064,6 +3064,7 @@ class NamespacedProjectRepository(ProjectRepositoryProtocol):
|
||||
except (OperationalError, SQLAlchemyDatabaseError) as exc:
|
||||
raise DatabaseError(f"Failed to create project: {exc}") from exc
|
||||
finally:
|
||||
session.rollback()
|
||||
session.close()
|
||||
|
||||
@database_retry
|
||||
@@ -3157,6 +3158,7 @@ class NamespacedProjectRepository(ProjectRepositoryProtocol):
|
||||
f"Failed to load project context policy for '{namespaced_name}': {exc}"
|
||||
) from exc
|
||||
finally:
|
||||
session.rollback()
|
||||
session.close()
|
||||
|
||||
@database_retry
|
||||
@@ -3208,6 +3210,7 @@ class NamespacedProjectRepository(ProjectRepositoryProtocol):
|
||||
except (OperationalError, SQLAlchemyDatabaseError) as exc:
|
||||
raise DatabaseError(f"Failed to update project '{ns_name}': {exc}") from exc
|
||||
finally:
|
||||
session.rollback()
|
||||
session.close()
|
||||
|
||||
@database_retry
|
||||
@@ -3243,6 +3246,7 @@ class NamespacedProjectRepository(ProjectRepositoryProtocol):
|
||||
f"Failed to delete project '{namespaced_name}': {exc}"
|
||||
) from exc
|
||||
finally:
|
||||
session.rollback()
|
||||
session.close()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user