Tests Phase 3: TUI flow tests + remove ActiveHubProjects dead branch#4
Merged
Conversation
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>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.Cmd→apipackage → mocked APS server chain.Also removes a dead branch in
fusion.ActiveHubProjectsflagged during Phase 2 review.Coverage
uifusionTest additions (
ui/app_test.go)TestUpdate_TokenReadyMsg_TransitionsToLoading/..._EmptyTokenGoesAuthNeeded— auth state branchingTestUpdate_KeyQuit—qinstateBrowsingreturnstea.QuitMsgTestUpdate_NavigateRight_LoadsContents(cross-layer L2/L3) — drives a project NavigateRight through the ui state machine into the fan-out cmd that callsapi.GetFolders+api.GetProjectItemsconcurrently against an httptest GraphQL fake; asserts thecontentsLoadedMsghas folders before items and decodes intoNavItems with the rightKind/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 serverTestRecoverFromError_AuthError_DeletesTokens— saves a token, triggers recovery from a"401 unauthorized"error, asserts state reset +tokens.jsondeleted from diskTestBreadcrumb_HitDetection—buildBreadcrumbproduces 4 hits with right kinds, indices, monotonic x-boundsProduction changes
api.SetGraphqlEndpointForTestingadded 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.ActiveHubProjectsdead branch removed (thepayload.Success == falseguard was unreachable —parseToolErrorTextincallToolcatches that case upstream and surfaces it via the err returned byc.invoke).TestActiveHubProjects_SuccessFalsetightened 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)
configfusionauthapiuiFull
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 checkpasses locallyTestUpdate_NavigateRight_LoadsContentsconfirmed to exercise the cross-layer chain (verified by inspecting captured GraphQL request bodies in the handler)TestRecoverFromError_AuthError_DeletesTokensconfirmed to actually unlink the file (read it back returns(nil, nil))testworkflow runs green on this PR🤖 Generated with Claude Code