@unit @repository @coverage Feature: Repository coverage for ActionRepository and LifecyclePlanRepository Exercise uncovered lines and branches in repositories.py to boost line-rate and branch-rate for ActionRepository and LifecyclePlanRepository. Background: Given a repos-cov in-memory database with lifecycle schema And a repos-cov action repository And a repos-cov lifecycle plan repository # --------------------------------------------------------------------------- # ActionRepository.get_by_name – DatabaseError on OperationalError # --------------------------------------------------------------------------- @action @error_handling Scenario: ActionRepository.get_by_name raises DatabaseError on OperationalError Given a repos-cov action repository with a session that raises OperationalError on query When repos-cov get_by_name is called with "local/broken-action" Then repos-cov a DatabaseError should be raised containing "Failed to get action by name" # --------------------------------------------------------------------------- # ActionRepository.get_by_name – success path returns domain object # --------------------------------------------------------------------------- @action Scenario: ActionRepository.get_by_name returns domain object for existing action Given repos-cov an available action "local/findable" exists When repos-cov get_by_name is called with "local/findable" Then repos-cov the returned action should have name "local/findable" # --------------------------------------------------------------------------- # ActionRepository.get_by_namespace – with state filter returning results # --------------------------------------------------------------------------- @action Scenario: ActionRepository.get_by_namespace with state filter returns matching actions Given repos-cov an action "local/active-one" exists with state "available" And repos-cov an action "local/archived-one" exists with state "archived" When repos-cov get_by_namespace is called with namespace "local" and state "available" Then repos-cov exactly 1 action should be in the result list And repos-cov the result list should contain action named "local/active-one" # --------------------------------------------------------------------------- # ActionRepository.get_by_namespace – DatabaseError on OperationalError # --------------------------------------------------------------------------- @action @error_handling Scenario: ActionRepository.get_by_namespace raises DatabaseError on OperationalError Given a repos-cov action repository with a session that raises OperationalError on query When repos-cov get_by_namespace is called with namespace "local" expecting error Then repos-cov a DatabaseError should be raised containing "Failed to list actions in namespace" # --------------------------------------------------------------------------- # ActionRepository.list_available – without namespace filter # --------------------------------------------------------------------------- @action Scenario: ActionRepository.list_available returns all available actions without namespace Given repos-cov an action "ns1/act-a" exists with state "available" And repos-cov an action "ns2/act-b" exists with state "available" And repos-cov an action "ns1/act-c" exists with state "archived" When repos-cov list_available is called without a namespace filter Then repos-cov exactly 2 actions should be in the result list # --------------------------------------------------------------------------- # ActionRepository.list_available – with namespace filter # --------------------------------------------------------------------------- @action Scenario: ActionRepository.list_available returns available actions filtered by namespace Given repos-cov an action "nsx/avail-1" exists with state "available" And repos-cov an action "nsy/avail-2" exists with state "available" When repos-cov list_available is called with namespace "nsx" Then repos-cov exactly 1 action should be in the result list # --------------------------------------------------------------------------- # ActionRepository.list_available – DatabaseError on OperationalError # --------------------------------------------------------------------------- @action @error_handling Scenario: ActionRepository.list_available raises DatabaseError on OperationalError Given a repos-cov action repository with a session that raises OperationalError on query When repos-cov list_available is called and an error is expected Then repos-cov a DatabaseError should be raised containing "Failed to list available actions" # --------------------------------------------------------------------------- # ActionRepository.update – with arguments having min_value and max_value # --------------------------------------------------------------------------- @action @update Scenario: ActionRepository.update persists arguments with min_value and max_value Given repos-cov an available action "local/minmax-action" exists And repos-cov the action has arguments with min_value and max_value set When repos-cov the action is updated via the repository Then repos-cov the update should succeed And repos-cov the retrieved action arguments should have min_value and max_value # --------------------------------------------------------------------------- # ActionRepository.delete – ActionInUseError when plans reference the action # --------------------------------------------------------------------------- @action @delete @error_handling Scenario: ActionRepository.delete raises ActionInUseError when plans reference the action Given repos-cov an available action "local/in-use-action" exists And a repos-cov lifecycle plan references action "local/in-use-action" When repos-cov delete is called for action "local/in-use-action" Then repos-cov an ActionInUseError should be raised for "local/in-use-action" # --------------------------------------------------------------------------- # ActionRepository.delete – successful deletion when no plans reference it # --------------------------------------------------------------------------- @action @delete Scenario: ActionRepository.delete succeeds and returns True for unreferenced action Given repos-cov an available action "local/deletable" exists When repos-cov delete is called for action "local/deletable" Then repos-cov the delete result should be True And repos-cov get_by_id for "local/deletable" should return None # --------------------------------------------------------------------------- # ActionRepository.delete – returns False for non-existent action # --------------------------------------------------------------------------- @action @delete Scenario: ActionRepository.delete returns False for non-existent action When repos-cov delete is called for action "local/ghost" Then repos-cov the delete result should be False # --------------------------------------------------------------------------- # DuplicatePlanError instantiation # --------------------------------------------------------------------------- @plan @error_class Scenario: DuplicatePlanError stores plan_id and message When repos-cov a DuplicatePlanError is created for plan_id "01HGZ6FE0A00000000TESTPLAN" Then repos-cov the error message should contain "01HGZ6FE0A00000000TESTPLAN" And repos-cov the error plan_id attribute should be "01HGZ6FE0A00000000TESTPLAN" # --------------------------------------------------------------------------- # LifecyclePlanRepository.get_by_name – success path # --------------------------------------------------------------------------- @plan Scenario: LifecyclePlanRepository.get_by_name returns domain object for existing plan Given repos-cov an available action "local/plan-target" exists And a repos-cov lifecycle plan linked to "local/plan-target" with name "local/my-plan" has been persisted When repos-cov plan get_by_name is called with "local/my-plan" Then repos-cov the returned plan should not be None # --------------------------------------------------------------------------- # LifecyclePlanRepository.get_by_name – returns None for missing # --------------------------------------------------------------------------- @plan Scenario: LifecyclePlanRepository.get_by_name returns None for non-existent plan When repos-cov plan get_by_name is called with "local/no-such-plan" Then repos-cov the returned plan should be None # --------------------------------------------------------------------------- # LifecyclePlanRepository.get_by_name – DatabaseError on OperationalError # --------------------------------------------------------------------------- @plan @error_handling Scenario: LifecyclePlanRepository.get_by_name raises DatabaseError on OperationalError Given a repos-cov plan repository with a session that raises OperationalError on query When repos-cov plan get_by_name is called with "local/error-plan" expecting error Then repos-cov a DatabaseError should be raised containing "Failed to get plan by name" # --------------------------------------------------------------------------- # LifecyclePlanRepository.update – full update with project_links, arguments, invariants # --------------------------------------------------------------------------- @plan @update Scenario: LifecyclePlanRepository.update persists project links, arguments, and invariants Given repos-cov an available action "local/plan-upd-action" exists And a repos-cov lifecycle plan linked to "local/plan-upd-action" with name "local/upd-plan" has been persisted And repos-cov the plan has project_links, arguments, and invariants with text attribute When repos-cov the plan is updated via the repository Then repos-cov the plan update should succeed And repos-cov the retrieved plan should have project links And repos-cov the retrieved plan should have arguments And repos-cov the retrieved plan should have invariants # --------------------------------------------------------------------------- # LifecyclePlanRepository.update – invariants as plain strings (no .text attr) # --------------------------------------------------------------------------- @plan @update Scenario: LifecyclePlanRepository.update handles invariants as plain strings Given repos-cov an available action "local/plan-str-inv" exists And a repos-cov lifecycle plan linked to "local/plan-str-inv" with name "local/str-inv-plan" has been persisted And repos-cov the plan has invariants as plain strings without text attribute When repos-cov the plan is updated via the repository Then repos-cov the plan update should succeed And repos-cov the retrieved plan should have invariants # --------------------------------------------------------------------------- # LifecyclePlanRepository.update – invariant source with .value attribute # --------------------------------------------------------------------------- @plan @update Scenario: LifecyclePlanRepository.update handles invariant source with .value enum Given repos-cov an available action "local/plan-enum-inv" exists And a repos-cov lifecycle plan linked to "local/plan-enum-inv" with name "local/enum-inv-plan" has been persisted And repos-cov the plan has invariants with InvariantSource enum values When repos-cov the plan is updated via the repository Then repos-cov the plan update should succeed # --------------------------------------------------------------------------- # LifecyclePlanRepository.update – processing_state without .value (plain str) # --------------------------------------------------------------------------- @plan @update Scenario: LifecyclePlanRepository.update handles processing_state as plain string Given repos-cov an available action "local/plan-str-state" exists And a repos-cov lifecycle plan linked to "local/plan-str-state" with name "local/str-state-plan" has been persisted And repos-cov the plan processing_state is set to a plain string "processing" When repos-cov the plan is updated via the repository Then repos-cov the plan update should succeed # --------------------------------------------------------------------------- # LifecyclePlanRepository.update – error_details and changeset_id fields # --------------------------------------------------------------------------- @plan @update Scenario: LifecyclePlanRepository.update persists error_details and changeset_id Given repos-cov an available action "local/plan-err-detail" exists And a repos-cov lifecycle plan linked to "local/plan-err-detail" with name "local/err-detail-plan" has been persisted And repos-cov the plan has error_message, error_details, and changeset_id set When repos-cov the plan is updated via the repository Then repos-cov the plan update should succeed And repos-cov the retrieved plan should have the error_message set