specs/011-dashboard-testing/tasks.md
Ref: Size: 8.2 KiB
# Tasks: Dashboard Testing Infrastructure
**Input**: Design documents from `/specs/011-dashboard-testing/`
**Prerequisites**: plan.md (required), spec.md (required for user stories)
**Tests**: Tests ARE the deliverable for this feature. All phases include test tasks.
**Organization**: Tasks are grouped by phase matching the plan, with user story traceability.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
---
## Phase 1: Setup -- Refactor for Testability
**Purpose**: Extract handle_key() and prepare App for direct testing from in-module tests.
- [ ] T001 [US1] Extract key-handling logic from `run_loop()` inline match into `App::handle_key(&mut self, code: KeyCode, modifiers: KeyModifiers) -> bool` in `src/tui.rs` (returns false on quit)
- [ ] T002 [US1] Update `run_loop()` in `src/tui.rs` to call `app.handle_key(key.code, key.modifiers)` instead of inline match
- [ ] T003 [US1] Add `#[cfg(test)] mod tests` block at the bottom of `src/tui.rs` with test helper functions: `make_test_issues(n)`, `make_test_patches(n)`, `make_app(issues, patches)`
- [ ] T004 [US1] Verify `cargo test` and `cargo clippy` pass after refactor (no behavioral changes)
**Checkpoint**: handle_key() is callable directly; test helpers exist; all existing behavior preserved.
---
## Phase 2: User Story 1 -- Unit Tests for State Transitions (Priority: P1)
**Goal**: Cover all state-mutating methods with fast, isolated unit tests in `src/tui.rs` `mod tests`.
**Independent Test**: Construct App with known data, call state-mutating methods, assert field values.
### App Construction Tests
- [ ] T005 [P] [US1] Test `test_new_app_defaults` -- initial state: tab=Issues, selection=Some(0), scroll=0, pane=ItemList, mode=Details, show_all=false in `src/tui.rs`
- [ ] T006 [P] [US1] Test `test_new_app_empty` -- empty issues/patches yields selection=None in `src/tui.rs`
### Selection Movement Tests
- [ ] T007 [P] [US1] Test `test_move_selection_down` -- move_selection(1) increments selected index in `src/tui.rs`
- [ ] T008 [P] [US1] Test `test_move_selection_up` -- move_selection(-1) decrements selected index in `src/tui.rs`
- [ ] T009 [P] [US1] Test `test_move_selection_clamp_bottom` -- move_selection(1) at last index stays at last in `src/tui.rs`
- [ ] T010 [P] [US1] Test `test_move_selection_clamp_top` -- move_selection(-1) at index 0 stays at 0 in `src/tui.rs`
- [ ] T011 [P] [US1] Test `test_move_selection_empty_list` -- move_selection on empty list is a no-op in `src/tui.rs`
### Tab Switching Tests
- [ ] T012 [P] [US1] Test `test_switch_tab_issues_to_patches` -- switch_tab resets selection, scroll, mode, pane in `src/tui.rs`
- [ ] T013 [P] [US1] Test `test_switch_tab_same_tab_noop` -- switch_tab to current tab is a no-op in `src/tui.rs`
### Filtering Tests
- [ ] T014 [P] [US1] Test `test_toggle_show_all` -- toggling show_all changes visible count and resets selection in `src/tui.rs`
- [ ] T015 [P] [US1] Test `test_visible_issues_filters_closed` -- visible_issues() excludes closed when show_all=false in `src/tui.rs`
- [ ] T016 [P] [US1] Test `test_visible_patches_filters_closed` -- visible_patches() excludes non-open when show_all=false in `src/tui.rs`
### handle_key() Tests
- [ ] T017 [P] [US1] Test `test_handle_key_quit` -- handle_key('q') returns false in `src/tui.rs`
- [ ] T018 [P] [US1] Test `test_handle_key_tab_switch` -- handle_key('1'/'2') switches tabs in `src/tui.rs`
- [ ] T019 [P] [US1] Test `test_handle_key_diff_toggle_patches` -- handle_key('d') on Patches tab toggles ViewMode in `src/tui.rs`
- [ ] T020 [P] [US1] Test `test_handle_key_diff_noop_issues` -- handle_key('d') on Issues tab does nothing in `src/tui.rs`
- [ ] T021 [P] [US1] Test `test_handle_key_pane_toggle` -- handle_key(Tab/Enter) toggles pane in `src/tui.rs`
- [ ] T022 [P] [US1] Test `test_scroll_in_detail_pane` -- j/k in Detail pane changes scroll, not selection in `src/tui.rs`
### Edge Case Tests
- [ ] T023 [P] [US1] Test `test_navigate_empty_after_filter` -- selection remains None when all items filtered out in `src/tui.rs`
- [ ] T024 [P] [US1] Test `test_show_all_persists_across_tab_switch` -- show_all stays true after switch_tab in `src/tui.rs`
- [ ] T025 [P] [US1] Test `test_toggle_show_all_clamps_selection` -- if selection > new visible count, clamp to last in `src/tui.rs`
**Checkpoint**: At least 10 unit tests pass covering all state transition methods. SC-001 satisfied.
---
## Phase 3: User Story 2 -- Snapshot/Render Tests (Priority: P2)
**Goal**: Verify TUI layout renders correctly for known states using ratatui TestBackend.
**Independent Test**: Create App, render via Terminal<TestBackend>, assert buffer contents.
- [ ] T026 [US2] Add `buffer_to_string()` and `assert_buffer_contains()` helper functions in `src/tui.rs` `mod tests`
- [ ] T027 [P] [US2] Test `test_render_issues_tab` -- tab bar shows "1:Issues", list shows issue titles, detail shows selected issue in `src/tui.rs`
- [ ] T028 [P] [US2] Test `test_render_patches_tab` -- tab bar highlights "2:Patches", list shows patch titles in `src/tui.rs`
- [ ] T029 [P] [US2] Test `test_render_empty_state` -- detail pane shows "No issues to display." in `src/tui.rs`
- [ ] T030 [P] [US2] Test `test_render_footer_keys` -- footer contains key hints (j/k, Tab, q) in `src/tui.rs`
- [ ] T031 [P] [US2] Test `test_render_show_all_title` -- list block title contains "(all)" when show_all=true in `src/tui.rs`
- [ ] T032 [P] [US2] Test `test_render_small_terminal` -- rendering to 20x10 TestBackend does not panic in `src/tui.rs`
**Checkpoint**: At least 3 render tests verify TUI layout. SC-002 satisfied.
---
## Phase 4: User Story 3 -- Integration Tests with Key Sequences (Priority: P3)
**Goal**: Verify realistic multi-step user interactions produce correct final state.
**Independent Test**: Construct App, feed key sequence through handle_key(), assert final state.
- [ ] T033 [US3] Add `apply_keys(app, keys: &[(KeyCode, KeyModifiers)])` helper in `src/tui.rs` `mod tests`
- [ ] T034 [P] [US3] Test `test_navigate_to_patch_and_view_diff` -- key sequence [j, j, 2, j, d] produces Patches tab, idx 1, Diff mode in `src/tui.rs`
- [ ] T035 [P] [US3] Test `test_toggle_filter_and_navigate` -- key sequence [a, j, j] with mixed statuses, show_all=true, selection at 2 in `src/tui.rs`
- [ ] T036 [P] [US3] Test `test_pane_switching_scroll_isolation` -- Tab into detail, scroll down, Tab back, selection unchanged in `src/tui.rs`
**Checkpoint**: At least 2 integration tests verify multi-step key sequences. SC-003 satisfied.
---
## Phase 5: Polish -- CI and Cross-Cutting
**Purpose**: Ensure all tests are CI-ready and meet quality bar.
- [ ] T037 Run `cargo clippy` and fix any warnings in test code in `src/tui.rs`
- [ ] T038 Run full `cargo test` and verify all tests pass in under 5 seconds (SC-004)
- [ ] T039 Verify tests work headless (no real terminal required) -- confirm TestBackend usage throughout (SC-006)
---
## Dependencies & Execution Order
### Phase Dependencies
- **Phase 1 (Setup)**: No dependencies -- start immediately
- **Phase 2 (US1)**: Depends on Phase 1 (T001-T003 for handle_key and helpers)
- **Phase 3 (US2)**: Depends on Phase 1 (T003 for helpers); can run in parallel with Phase 2
- **Phase 4 (US3)**: Depends on Phase 1 (T001 for handle_key) and T033 helper
- **Phase 5 (Polish)**: Depends on all previous phases
### Parallel Opportunities
- All tests within Phase 2 (T005-T025) are independent and can be written in parallel
- All tests within Phase 3 (T027-T032) are independent and can be written in parallel
- Phase 2 and Phase 3 can proceed in parallel after Phase 1 completes
- All tests within Phase 4 (T034-T036) are independent and can be written in parallel
### Within Each Phase
- Helper functions must be written before tests that use them
- All test code lives in `src/tui.rs` `#[cfg(test)] mod tests` block
---
## Notes
- All test code lives in-module (`#[cfg(test)] mod tests` in `src/tui.rs`) to access private types
- No new dependencies needed -- ratatui 0.30 includes TestBackend, tempfile already in dev-deps
- No visibility changes to App/Tab/Pane/ViewMode required (in-module tests have access)
- Commit after each phase or logical group