Repository navigation
test(api/federation): register AssertExpectations on the federationHandler mock - #1223
Conversation
…ndler mock federationHandler() stubbed ValidateSession on a MockAuthService but never registered AssertExpectations, so an unmatched On(...) stub in any of the federation IaC tests passed silently. It now takes *testing.T and registers t.Cleanup(mockAuth.AssertExpectations); federationHandlerWithEmail, its copy in the control-character tests, gets the same treatment. TestGetFederationIaC_RequiresAuth sends no Authorization header, so it never reaches the session check and its inherited stub was dead. It now builds the handler without a session stub via the extracted newFederationHandler and asserts ValidateSession is never called. Closes LeanerCloud#44 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 3 billable files and costs up to $0.75. Or wait 58 minutes for your next included review. View limit details
Comment |
|
Independent review 2 (claude-fleet, cold): APPROVE e70dfba Every test still tests what its name says, and nothing was loosened to make the new assertions pass. The new assertion also catches a dropped session lookup that the old tests missed. Findings (none blocking):
Attacked:
Verified locally on the head export, with GOTOOLCHAIN=go1.26.10 and no cloud credentials, under the heavy lock:
Reviewed by an independent agent with no author context (second reviewer). Review only: nothing was pushed, and the GitHub review state is unchanged. |
|
VERDICT: APPROVE e70dfba Base: main (not stacked). Fixes #44: yes. Findings (none blocking):
Attacked:
|
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): VERDICT: APPROVE Blocking:
Non-blocking:
Attacked:
Body-stale: none Reviewer: rB3. Bar while the maintainers are away (set by IAmJSD as acting owner): one approving independent review on the head, two for money, auth and security paths. |
|
Local verification at |
|
Merged by IAmJSD's agent at IAmJSD's request (IAmJSD is acting owner while the maintainers are away), under the bar IAmJSD set: 2 approving independent review(s) on |
LeanerCloud#1223 (on main) gave federationHandler a *testing.T so it can register AssertExpectations. This branch's new renderBundleFiles still called it with no argument, so the internal/api test build broke once main was merged in. Same handler, same assertions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Root cause
federationHandler()ininternal/api/handler_federation_test.gobuilt aMockAuthServicewith aValidateSessionstub but never registeredAssertExpectations. That meant anOn(...)stub that the code under test never called still passed silently, in every federation IaC test that uses the helper (36 call sites acrosshandler_federation_test.goandexchange_helpers_test.go).federationHandlerWithEmailinhandler_federation_controlchar_test.gois a copy of the helper with a different session email, and it had the same gap.Fix (test-only)
federationHandler(t *testing.T)now registerst.Cleanup(func() { mockAuth.AssertExpectations(t) })on a plain localmockAuth, and every call site passest. Subtests pass their own subtestt.CUDLY_SOURCE_CLOUDdefault,grantAdmin,NewHandlerand the pre-warmed source identity) moved into a newnewFederationHandler(mockAuth). It registers no session stub, so a test can choose its own auth expectations.federationHandlerWithEmail(t, email)gets the sameAssertExpectationsregistration and reusesnewFederationHandler.ValidateSessionstub is still a hard expectation. Nothing was blanket-.Maybe()'d. The permission stubs thatgrantAdminregisters were already.Maybe()and are unchanged, for the reason documented ongrantPermissionsScoped.Tests that needed changes once expectations were asserted
TestGetFederationIaC_RequiresAuthAuthorizationheader, sorequirePermissionrejects it with a 401 before any session lookup. Theadmin-tokenstub it inherited was never called, and the test failed withFAIL: ValidateSession(string,string)..Maybe(). Skipping the call is the behavior under test, so the test now builds its handler withnewFederationHandlerand no session stub. It registersAssertExpectationsand also assertsmockAuth.AssertNotCalled(t, "ValidateSession", mock.Anything, mock.Anything). This is stronger than before.Every other federation test, including all
federationHandlerWithEmailcalls (auth runs first ingetFederationIaC, even for combinations that aren't offered), already callsValidateSession. So no other test needed.Maybe()or a stub removed.Verification
All of this is unit/mock evidence. The change is test-only, and no real-cloud path is exercised.
Tests ran with
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null, because the local~/.aws/configdefault profile on the dev machine is invalid.Fail before / pass after. I added a probe stub that is never matched,
h.auth.(*MockAuthService).On("ValidateSession", mock.Anything, "probe-never-sent").Return(nil, assert.AnError), toTestHandler_getFederationIaC_SuccessWithoutAccountID. I applied the same text to a copy oforigin/main(5d4ab6b) and a copy of this branch, and then removed it. It is not in the PR.--- PASS: TestHandler_getFederationIaC_SuccessWithoutAccountID(the unmatched stub goes unnoticed)handler_federation_test.go:45: FAIL: ValidateSession(string,string)/FAIL: 4 out of 5 expectation(s) were met./--- FAILAlso, once
AssertExpectationswas registered and beforeTestGetFederationIaC_RequiresAuthwas reworked, that test failed withFAIL: ValidateSession(string,string). That was a dead stub the old helper had been hiding.Out of scope (noted, not changed)
newFederationHandlerstill defaultsCUDLY_SOURCE_CLOUDwithos.Setenv, nott.Setenv, so the value persists across tests in the process. That is the existing behavior. Switching tot.Setenvwould change test isolation and interact witht.Parallel, so it belongs in its own change.Labels
Could a maintainer please mirror the issue's triage labels onto this PR:
impact/internal,type/chore,triaged,priority/p3,severity/low,urgency/eventually,effort/s.Closes #44
🤖 Generated with Claude Code