Files
cleveragents-core/features/db_repositories_cov_r3.feature
freemo 31472b5413
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 21s
CI / helm (pull_request) Successful in 22s
CI / lint (pull_request) Successful in 3m20s
CI / quality (pull_request) Successful in 3m43s
CI / typecheck (pull_request) Successful in 3m58s
CI / security (pull_request) Successful in 4m8s
CI / integration_tests (pull_request) Successful in 9m33s
CI / unit_tests (pull_request) Successful in 10m12s
CI / docker (pull_request) Successful in 1m28s
CI / coverage (pull_request) Successful in 12m18s
CI / e2e_tests (pull_request) Successful in 19m51s
CI / status-check (pull_request) Successful in 1s
CI / build (push) Successful in 15s
CI / helm (push) Successful in 22s
CI / lint (push) Successful in 3m18s
CI / quality (push) Successful in 3m41s
CI / typecheck (push) Successful in 3m57s
CI / benchmark-regression (push) Has been skipped
CI / security (push) Successful in 4m10s
CI / unit_tests (push) Failing after 6m58s
CI / docker (push) Has been skipped
CI / integration_tests (push) Successful in 9m15s
CI / coverage (push) Successful in 12m26s
CI / e2e_tests (push) Successful in 23m11s
CI / status-check (push) Failing after 1s
CI / benchmark-publish (push) Successful in 28m31s
CI / benchmark-regression (pull_request) Successful in 54m53s
test(coverage): add Behave scenarios for 39 under-covered modules
Add Behave feature/step pairs that exercise uncovered branches across handlers, LSP, CLI, and service layers to reach the coverage gate.

ISSUES CLOSED: #1232
2026-03-31 21:47:12 +00:00

363 lines
17 KiB
Gherkin

Feature: Database repositories coverage round 3
Targets uncovered lines in repositories.py for:
- ActionRepository.list_all (lines 1005-1017)
- NamespacedProjectRepository.get_context_policy all branches (lines 2982-3012)
- ToolRegistryRepository create IntegrityError UNIQUE (line 3378)
- ToolRepository.get, get_by_name, remove, update (lines 3690-3717)
- SessionRepository list_all, delete error, update error (lines 4063-4173)
- SessionMessageRepository append error, get, count (lines 4227-4298)
- AutomationProfileRepository._to_domain legacy safety fallback (lines 4509-4514)
- SkillRepository update return, delete, flattened tool cache (lines 4851-5085)
- DecisionRepository full CRUD (lines 5153-5519)
- CheckpointRepository full CRUD (lines 5564-5717)
- CorrectionAttemptRepository full CRUD + state transitions (lines 5789-6018)
# -- ActionRepository.list_all --
Scenario: ActionRepository list_all returns ordered actions
Given drcov3 an in-memory database with schema
And drcov3 an ActionRepository instance
And drcov3 two actions exist in different namespaces
When drcov3 I call list_all on the action repository
Then drcov3 it returns actions ordered by namespace then name
Scenario: ActionRepository list_all raises DatabaseError on failure
Given drcov3 an in-memory database with schema
And drcov3 an ActionRepository with a broken session
When drcov3 I call list_all expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to list all actions"
# -- NamespacedProjectRepository.get_context_policy --
Scenario: get_context_policy returns default when project not found
Given drcov3 an in-memory database with schema
And drcov3 a NamespacedProjectRepository instance
When drcov3 I call get_context_policy for "ns/nonexistent"
Then drcov3 the result is a default ProjectContextPolicy
Scenario: get_context_policy returns default when context_policy_json is None
Given drcov3 an in-memory database with schema
And drcov3 a NamespacedProjectRepository instance
And drcov3 a project "ns/proj1" exists with null context_policy_json
When drcov3 I call get_context_policy for "ns/proj1"
Then drcov3 the result is a default ProjectContextPolicy
Scenario: get_context_policy returns parsed policy from valid JSON
Given drcov3 an in-memory database with schema
And drcov3 a NamespacedProjectRepository instance
And drcov3 a project "ns/proj2" exists with valid context_policy_json
When drcov3 I call get_context_policy for "ns/proj2"
Then drcov3 the result is a valid ProjectContextPolicy
Scenario: get_context_policy returns default when payload is not a dict
Given drcov3 an in-memory database with schema
And drcov3 a NamespacedProjectRepository instance
And drcov3 a project "ns/proj3" exists with non-dict context_policy_json
When drcov3 I call get_context_policy for "ns/proj3"
Then drcov3 the result is a default ProjectContextPolicy
Scenario: get_context_policy returns default on ValueError/TypeError
Given drcov3 an in-memory database with schema
And drcov3 a NamespacedProjectRepository instance
And drcov3 a project "ns/proj4" exists with corrupt context_policy_json
When drcov3 I call get_context_policy for "ns/proj4"
Then drcov3 the result is a default ProjectContextPolicy
Scenario: get_context_policy raises DatabaseError on DB failure
Given drcov3 an in-memory database with schema
And drcov3 a NamespacedProjectRepository with broken session
When drcov3 I call get_context_policy expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to load project context policy"
# -- ToolRepository legacy wrapper --
Scenario: ToolRepository get returns None for missing tool
Given drcov3 an in-memory database with schema
And drcov3 a ToolRepository instance
When drcov3 I call ToolRepository get for "ns/missing-tool"
Then drcov3 the tool result is None
Scenario: ToolRepository get_by_name returns None for missing tool
Given drcov3 an in-memory database with schema
And drcov3 a ToolRepository instance
When drcov3 I call ToolRepository get_by_name for "ns/missing-tool"
Then drcov3 the tool result is None
Scenario: ToolRepository remove raises ToolNotFoundError
Given drcov3 an in-memory database with schema
And drcov3 a ToolRepository instance
When drcov3 I call ToolRepository remove for "ns/missing-tool"
Then drcov3 a ToolNotFoundError was raised
Scenario: ToolRepository update raises ToolNotFoundError for missing tool
Given drcov3 an in-memory database with schema
And drcov3 a ToolRepository instance
When drcov3 I call ToolRepository update with a non-existent tool
Then drcov3 a ToolNotFoundError was raised
# -- SessionRepository --
Scenario: SessionRepository list_all returns sessions
Given drcov3 an in-memory database with schema
And drcov3 a SessionRepository instance
When drcov3 I call session list_all
Then drcov3 the session list result is a list
Scenario: SessionRepository delete raises DatabaseError on failure
Given drcov3 an in-memory database with schema
And drcov3 a SessionRepository with a broken session for delete
When drcov3 I call session delete expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to delete session"
Scenario: SessionRepository update raises DatabaseError on failure
Given drcov3 an in-memory database with schema
And drcov3 a SessionRepository with a broken session for update
When drcov3 I call session update expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to update session"
# -- SessionMessageRepository --
Scenario: SessionMessageRepository append raises DatabaseError on failure
Given drcov3 an in-memory database with schema
And drcov3 a SessionMessageRepository with a broken session
When drcov3 I call message append expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to append message"
Scenario: SessionMessageRepository count_for_session returns zero for empty session
Given drcov3 an in-memory database with schema
And drcov3 a SessionMessageRepository instance
When drcov3 I call count_for_session with a random session id
Then drcov3 the count result is 0
# -- AutomationProfileRepository._to_domain legacy safety fallback --
Scenario: AutomationProfileRepository to_domain uses legacy safety fallback
Given drcov3 an in-memory database with schema
And drcov3 an AutomationProfileModel row without safety_json
When drcov3 I call _to_domain on the row
Then drcov3 the result has a SafetyProfile from legacy columns
# -- SkillRepository flattened tools cache --
Scenario: SkillRepository delete returns True for existing skill
Given drcov3 an in-memory database with schema
And drcov3 a SkillRepository instance
And drcov3 a skill "ns/myskill-del" exists
When drcov3 I call skill delete for "ns/myskill-del"
Then drcov3 the skill delete result is True
Scenario: SkillRepository update_flattened_tools persists cache data
Given drcov3 an in-memory database with schema
And drcov3 a SkillRepository instance
And drcov3 a skill "ns/myskill-flat" exists
When drcov3 I call update_flattened_tools for "ns/myskill-flat"
Then drcov3 the flattened tools are stored
Scenario: SkillRepository get_flattened_tools returns cache data
Given drcov3 an in-memory database with schema
And drcov3 a SkillRepository instance
And drcov3 a skill "ns/myskill-getflat" exists with flattened tools
When drcov3 I call get_flattened_tools for "ns/myskill-getflat"
Then drcov3 the cache dict has expected keys
Scenario: SkillRepository needs_refresh returns True when hash differs
Given drcov3 an in-memory database with schema
And drcov3 a SkillRepository instance
And drcov3 a skill "ns/myskill-refresh" exists with flattening_hash "oldhash"
When drcov3 I call needs_refresh for "ns/myskill-refresh" with hash "newhash"
Then drcov3 the needs_refresh result is True
Scenario: SkillRepository recompute_flattening_hash stores new hash
Given drcov3 an in-memory database with schema
And drcov3 a SkillRepository instance
And drcov3 a skill "ns/myskill-rehash" exists
When drcov3 I call recompute_flattening_hash for "ns/myskill-rehash"
Then drcov3 the returned hash is a sha256 hex string
Scenario: SkillRepository invalidate_cached_summaries nulls cache fields
Given drcov3 an in-memory database with schema
And drcov3 a SkillRepository instance
And drcov3 a skill "ns/myskill-inval" exists with flattened tools
When drcov3 I call invalidate_cached_summaries for "ns/myskill-inval"
Then drcov3 the cached fields are None
# -- DecisionRepository full CRUD --
Scenario: DecisionRepository create and get round-trip
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
When drcov3 I create a decision
And drcov3 I get the decision by id
Then drcov3 the retrieved decision matches the created one
Scenario: DecisionRepository get_by_plan returns ordered decisions
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 multiple decisions exist for the plan
When drcov3 I call get_by_plan
Then drcov3 I get decisions ordered by sequence number
Scenario: DecisionRepository get_tree returns BFS-ordered tree
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 a decision tree exists
When drcov3 I call get_tree on the root
Then drcov3 I get the root and its descendants in BFS order
Scenario: DecisionRepository get_path_to_root walks up to root
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 a decision tree exists
When drcov3 I call get_path_to_root on a leaf
Then drcov3 I get a path from leaf to root
Scenario: DecisionRepository get_superseded returns superseded decisions
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 a superseded decision exists
When drcov3 I call get_superseded
Then drcov3 I get the superseded decisions
Scenario: DecisionRepository update_superseded_by marks a decision
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 two decisions exist for supersede test
When drcov3 I call update_superseded_by
Then drcov3 the decision has superseded_by set
Scenario: DecisionRepository list_by_type filters by type
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 decisions of different types exist
When drcov3 I call list_by_type for strategy_choice
Then drcov3 I only get strategy_choice decisions
Scenario: DecisionRepository delete removes a decision
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 a single decision exists for delete test
When drcov3 I delete the decision
Then drcov3 the delete result is True
Scenario: DecisionRepository get_max_sequence_number returns max
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 multiple decisions exist for the plan
When drcov3 I call get_max_sequence_number
Then drcov3 the max sequence number is correct
Scenario: DecisionRepository count returns the decision count
Given drcov3 an in-memory database with schema
And drcov3 a DecisionRepository instance
And drcov3 a plan exists for decisions
And drcov3 multiple decisions exist for the plan
When drcov3 I call decision count
Then drcov3 the decision count matches expected
# -- CheckpointRepository full CRUD --
Scenario: CheckpointRepository create and get_by_id round-trip
Given drcov3 an in-memory database with schema
And drcov3 a CheckpointRepository instance
And drcov3 a plan exists for checkpoints
When drcov3 I create a checkpoint
And drcov3 I get the checkpoint by id
Then drcov3 the retrieved checkpoint matches
Scenario: CheckpointRepository list_by_plan returns ordered checkpoints
Given drcov3 an in-memory database with schema
And drcov3 a CheckpointRepository instance
And drcov3 a plan exists for checkpoints
And drcov3 multiple checkpoints exist for the plan
When drcov3 I call checkpoint list_by_plan
Then drcov3 I get checkpoints ordered by creation time
Scenario: CheckpointRepository delete removes a checkpoint
Given drcov3 an in-memory database with schema
And drcov3 a CheckpointRepository instance
And drcov3 a plan exists for checkpoints
And drcov3 a checkpoint exists for delete test
When drcov3 I delete the checkpoint
Then drcov3 the checkpoint delete result is True
Scenario: CheckpointRepository prune removes excess checkpoints
Given drcov3 an in-memory database with schema
And drcov3 a CheckpointRepository instance
And drcov3 a plan exists for checkpoints
And drcov3 five checkpoints exist for prune test
When drcov3 I call prune with max_checkpoints 3
Then drcov3 two interior checkpoints are removed
# -- CorrectionAttemptRepository full CRUD --
Scenario: CorrectionAttemptRepository create and get round-trip
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository instance
And drcov3 a plan and decision exist for corrections
When drcov3 I create a correction attempt
And drcov3 I get the correction attempt by id
Then drcov3 the retrieved correction attempt matches
Scenario: CorrectionAttemptRepository list_by_plan returns records
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository instance
And drcov3 a plan and decision exist for corrections
And drcov3 a correction attempt exists for list test
When drcov3 I call correction list_by_plan
Then drcov3 the correction list contains the attempt
Scenario: CorrectionAttemptRepository update_state transitions pending to executing
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository instance
And drcov3 a plan and decision exist for corrections
And drcov3 a pending correction attempt exists for state test
When drcov3 I update correction state to executing
Then drcov3 the correction state is executing
Scenario: CorrectionAttemptRepository delete removes a record
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository instance
And drcov3 a plan and decision exist for corrections
And drcov3 a correction attempt exists for delete test
When drcov3 I delete the correction attempt
Then drcov3 the correction delete result is True
Scenario: CorrectionAttemptRepository create raises DatabaseError on OperationalError
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository with broken session
When drcov3 I call correction create expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to create correction attempt"
Scenario: CorrectionAttemptRepository get raises DatabaseError on OperationalError
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository with broken session for get
When drcov3 I call correction get expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to get correction attempt"
Scenario: CorrectionAttemptRepository list_by_plan raises DatabaseError on failure
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository with broken session for list
When drcov3 I call correction list_by_plan expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to list correction attempts"
Scenario: CorrectionAttemptRepository delete raises DatabaseError on failure
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository with broken session for delete
When drcov3 I call correction delete expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to delete correction attempt"
Scenario: CorrectionAttemptRepository update_state raises DatabaseError on OperationalError
Given drcov3 an in-memory database with schema
And drcov3 a CorrectionAttemptRepository with broken session for update_state
When drcov3 I call correction update_state expecting a DatabaseError
Then drcov3 a DatabaseError was raised containing "Failed to update correction attempt"