Feature: PlanLifecycleService error and persistence branch coverage (round 2) As a developer maintaining PlanLifecycleService I want every partial branch fully exercised So that plan_lifecycle_service.py branch coverage reaches 100% # Targets the following partial branches: # Line 100 – InvalidPhaseTransitionError.__init__ `if not message:` False branch # Line 216 – _commit_plan `if self._persisted …` True branch (via mock UoW) # Line 327 – create_action `if self._persisted …` True branch # Line 364 – get_action `if self._persisted …` True branch (not-found fallback) # Line 461 – archive_action `if self._persisted …` True branch # Line 570 – use_action `if self._persisted …` True branch # Line 607 – get_plan `if self._persisted …` True branch (not-found fallback) # ------------------------------------------------------------------- # In-memory mode (no UoW) – validates False side of _persisted checks # ------------------------------------------------------------------- Background: Given r2plc-a fresh plan lifecycle service with mock UoW # ------------------------------------------------------------------- # InvalidPhaseTransitionError with custom message (line 100 False) # ------------------------------------------------------------------- Scenario: InvalidPhaseTransitionError raised with explicit custom message When r2plc-I construct InvalidPhaseTransitionError with a custom message Then r2plc-the error message should be the custom message And r2plc-the from_phase should be STRATEGIZE And r2plc-the to_phase should be APPLY Scenario: InvalidPhaseTransitionError raised with default message When r2plc-I construct InvalidPhaseTransitionError without a message Then r2plc-the error message should contain "Invalid phase transition" And r2plc-the from_phase should be STRATEGIZE And r2plc-the to_phase should be EXECUTE Scenario: revert_plan raises InvalidPhaseTransitionError with custom message Given r2plc-a plan in STRATEGIZE phase When r2plc-I attempt to revert the plan to APPLY phase Then r2plc-an InvalidPhaseTransitionError should have been raised And r2plc-the caught error message should contain "Cannot revert" # ------------------------------------------------------------------- # _commit_plan in persisted mode (line 216 True) # ------------------------------------------------------------------- Scenario: _commit_plan persists via UoW when persisted mode is active Given r2plc-a plan in STRATEGIZE phase When r2plc-I start strategize on the plan Then r2plc-the mock UoW should have received a plan update call Scenario: fail_strategize commits plan via persisted _commit_plan Given r2plc-a plan in STRATEGIZE PROCESSING state When r2plc-I fail the strategize with error "something broke" Then r2plc-the mock UoW should have received a plan update call And r2plc-the plan processing state should be "errored" # ------------------------------------------------------------------- # create_action persisted mode (line 327 True) # ------------------------------------------------------------------- Scenario: create_action persists via UoW when persisted When r2plc-I create an action "local/r2-persist-test" in persisted mode Then r2plc-the mock UoW should have received an action create call And r2plc-the action should also be in the in-memory cache # ------------------------------------------------------------------- # use_action persisted mode (line 570 True) # ------------------------------------------------------------------- Scenario: use_action persists the new plan via UoW Given r2plc-an action "local/r2-use-persist" exists When r2plc-I use the action to create a plan in persisted mode Then r2plc-the mock UoW should have received a plan create call And r2plc-the plan should also be in the in-memory plan cache # ------------------------------------------------------------------- # archive_action persisted mode (line 461 True) # ------------------------------------------------------------------- Scenario: archive_action persists via UoW when persisted Given r2plc-an action "local/r2-archive-persist" exists When r2plc-I archive the action "local/r2-archive-persist" in persisted mode Then r2plc-the mock UoW should have received an action update call And r2plc-the action state should be archived # ------------------------------------------------------------------- # get_action persistence fallback returns None (line 364-370) # ------------------------------------------------------------------- Scenario: get_action raises NotFoundError when persistence also returns None When r2plc-I attempt to get action "local/nonexistent-r2" in persisted mode Then r2plc-a NotFoundError should have been raised for action # ------------------------------------------------------------------- # get_plan persistence fallback returns None (line 607-613) # ------------------------------------------------------------------- Scenario: get_plan raises NotFoundError when persistence also returns None When r2plc-I attempt to get plan "01ZZZZZZZZZZZZZZZZZZZZZZZZ" in persisted mode Then r2plc-a NotFoundError should have been raised for plan # ------------------------------------------------------------------- # update_error_details in persisted mode (hits _commit_plan True) # ------------------------------------------------------------------- Scenario: update_error_details merges details and persists Given r2plc-a plan in STRATEGIZE phase When r2plc-I update error details with key "reason" value "timeout" Then r2plc-the plan error_details should contain key "reason" And r2plc-the mock UoW should have received a plan update call Scenario: update_error_details merges into existing error_details Given r2plc-a plan in STRATEGIZE phase with existing error_details When r2plc-I update error details with key "extra" value "info" Then r2plc-the plan error_details should contain key "extra" And r2plc-the plan error_details should contain key "original"