Skip to content

Tests Phase 3: TUI flow tests + remove ActiveHubProjects dead branch#4

Merged
schneik80 merged 1 commit into
mainfrom
tests-phase-3
May 2, 2026
Merged

Tests Phase 3: TUI flow tests + remove ActiveHubProjects dead branch#4
schneik80 merged 1 commit into
mainfrom
tests-phase-3

Conversation

@schneik80
Copy link
Copy Markdown
Owner

Summary

Final phase of the test-suite buildout. Phase 3 covers the L3 layer per the test plan: bubbletea state-machine transitions driven by direct Update(msg) calls, plus one cross-layer test that drives the full UI → tea.Cmdapi package → mocked APS server chain.

Also removes a dead branch in fusion.ActiveHubProjects flagged during Phase 2 review.

Coverage

Package Phase 2 Phase 3 Δ
ui 24.5% 32.5% +8pp
fusion 83.8% 84.2% +0.4pp (from dead-code removal)
total 38.5% 43.1% +4.6pp

Test additions (ui/app_test.go)

  • TestUpdate_TokenReadyMsg_TransitionsToLoading / ..._EmptyTokenGoesAuthNeeded — auth state branching
  • TestUpdate_KeyQuitq in stateBrowsing returns tea.QuitMsg
  • TestUpdate_NavigateRight_LoadsContents (cross-layer L2/L3) — drives a project NavigateRight through the ui state machine into the fan-out cmd that calls api.GetFolders + api.GetProjectItems concurrently against an httptest GraphQL fake; asserts the contentsLoadedMsg has folders before items and decodes into NavItems with the right Kind/IsContainer. End-to-end coverage of the most complex user action.
  • TestVerifySameHub — 4 sub-cases (exact id match, name fallback when id unparseable, no match, empty-skips-check) against a fake MCP server
  • TestRecoverFromError_AuthError_DeletesTokens — saves a token, triggers recovery from a "401 unauthorized" error, asserts state reset + tokens.json deleted from disk
  • TestBreadcrumb_HitDetectionbuildBreadcrumb produces 4 hits with right kinds, indices, monotonic x-bounds

Production changes

  • api.SetGraphqlEndpointForTesting added so the ui flow test can swap the GraphQL endpoint without making the var itself exported. Doc explicitly says "production code MUST NOT call this".
  • fusion.ActiveHubProjects dead branch removed (the payload.Success == false guard was unreachable — parseToolErrorText in callTool catches that case upstream and surfaces it via the err returned by c.invoke). TestActiveHubProjects_SuccessFalse tightened to assert the actual upstream error message ("tool reported failure") instead of accepting either branch as it did before.

Cumulative test-suite picture (3 phases)

Package Final Coverage
config 90.6%
fusion 84.2%
auth 73.9%
api 69.7%
ui 32.5%
total 43.1%

Full go test -race -count=1 ./... runs in under 5s. CI workflow .github/workflows/test.yml (added in Phase 1) gates every PR.

Test plan

  • make check passes locally
  • TestUpdate_NavigateRight_LoadsContents confirmed to exercise the cross-layer chain (verified by inspecting captured GraphQL request bodies in the handler)
  • TestRecoverFromError_AuthError_DeletesTokens confirmed to actually unlink the file (read it back returns (nil, nil))
  • Confirm test workflow runs green on this PR

🤖 Generated with Claude Code

Final phase of the test-suite buildout. Phase 3 covers the L3 layer per
the test plan: bubbletea state-machine transitions driven by direct
Update(msg) calls, plus one cross-layer test that drives the full
UI -> tea.Cmd -> api package -> mocked APS server chain.

Coverage:
  ui     24.5% -> 32.5%  (+8pp)
  total  38.5% -> 43.1%  (+4.6pp)

Coverage by package across all three phases:
  config   90.6%  (Phase 1)
  fusion   84.2%  (Phase 1+2, +2 from dead-code removal here)
  auth     73.9%  (Phase 1+2)
  api      69.7%  (Phase 1+2)
  ui       32.5%  (Phase 1+3 — view/render code intentionally untested)
  total    43.1%

ui/app_test.go adds 7 tests:
  - TestUpdate_TokenReadyMsg_TransitionsToLoading: empty/non-empty
    token paths
  - TestUpdate_TokenReadyMsg_EmptyTokenGoesAuthNeeded
  - TestUpdate_KeyQuit: 'q' in stateBrowsing returns tea.QuitMsg
  - TestUpdate_NavigateRight_LoadsContents (cross-layer L2/L3): drives
    a project NavigateRight through the ui state machine into the
    fan-out cmd that calls api.GetFolders + api.GetProjectItems
    concurrently against an httptest GraphQL fake; asserts the
    contentsLoadedMsg has folders before items, decoded into NavItems
    with the right Kind/IsContainer
  - TestVerifySameHub: 4 sub-cases (id match, name fallback, no match,
    empty skips check) against a fake MCP server
  - TestRecoverFromError_AuthError_DeletesTokens: t.Setenv-redirected
    HOME; saves a token, drives recovery from a "401 unauthorized"
    error, asserts state reset + tokens.json deleted from disk
  - TestBreadcrumb_HitDetection: pure unit on buildBreadcrumb; asserts
    4 hits (hub + project + 2 folders) with right kinds, indices, and
    monotonically increasing x-bounds

Production change: api.SetGraphqlEndpointForTesting added so ui flow
tests can swap the GraphQL endpoint without exporting the var. Function
doc explicitly says "production code MUST NOT call this".

Cleanup: removed the success:false guard in fusion.ActiveHubProjects
(was unreachable — parseToolErrorText in callTool catches that case
upstream and surfaces it via the err returned by c.invoke). Tightened
TestActiveHubProjects_SuccessFalse to assert the actual upstream error
message ("tool reported failure") instead of accepting either branch.

All tests run in under 5s with -race -count=1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@schneik80 schneik80 merged commit d46a7ad into main May 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant