test(core): backfill coverage on inspectorClient + remote server#1317
Conversation
Resolves #1310. Drops the two TODO(#1310) exclusions from clients/web/vite.config.ts (coverage.exclude); both files now pass the per-file gate (lines >=90, statements >=85, functions >=80, branches >=50). core/mcp/remote/node/server.ts (88.15 / 78.37 -> 97.29 / 100): - Extract createTokenAuthProvider to its own file (core/mcp/remote/node/tokenAuthProvider.ts) so the 7 no-op OAuthClientProvider stubs can be unit-tested directly. - Add focused integration tests covering the remaining gaps: * createTransportNode failure path on POST /api/mcp/connect * /api/mcp/send when transport is dead * /api/log non-JSON body (catch fallback) * forwardLogEvent unknown-level / no-messages / string-first-message fallbacks (lines 232, 240-242, 257-265 in the original) * /api/fetch missing-url + upstream-throw paths * /api/storage POST invalid storeId + invalid JSON body * /api/storage GET when the on-disk store is unparseable core/mcp/inspectorClient.ts (73.48 / 72.09 -> 91.16 / 89.92): Added a single "Coverage backfill (#1310)" describe block to the existing integration test, plus a few unit-style cases: - OAuth getters / setOAuthConfig / authenticate when oauthManager is unset. - Simple session, roots, subscription, and instructions accessors. - subscribe / unsubscribe error paths against a server without the subscribe capability; happy path against one with it. - getPrompt + readResourceFromTemplate happy path + expansion-failure. - setLoggingLevel "Server does not support logging" guard. - getAppRendererClient (null before connect, cached proxy after). - OAuth + stdio: authenticate() throws via getServerUrl()'s stdio check. - listChanged notifications: tools/resources/prompts handlers via the fixture add_tool / add_resource / add_prompt tools. - Misc tiny branches: re-connect no-op, elicit form mode, getTaskCapabilities on a tasks-less server, receiver-task TTL cleanup + cancel via the private surface (the focused-unit pass the issue describes). - defensive `if (!this.client) throw` guards: one nullify-and-call test exercises 16 of them via a single instance, plus the connect() entry guard. The receiver-task internals test uses (instance as unknown as { private fields... }) to drive createReceiverTask / cancelReceiverTask / TTL cleanup directly; per the issue, refactoring private helpers to be testable from a unit test was authorized. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@claude review |
|
Claude finished @cliffhall's task in 1m 28s —— View job Claude PR Review
SummarySolid, focused coverage backfill. The extraction of Strengths
Suggestions / Nits
Things explicitly not an issue
VerdictLGTM modulo the naming issue in (1). The refactor is clean, the tests target the right gaps, and the stated coverage delta is realistic for the scope of changes. |
- Rename the misnamed "listChanged notifications" describe in inspectorClient.test.ts to "capability detection after connect", since the test asserts only on getCapabilities() round-tripping and never triggers or observes a notification dispatch. Real dispatch coverage lives in the adjacent "list_changed + resourceUpdated notifications" block. Kept the resources/prompts fixtures with a note explaining why they are required for the server to advertise the matching capabilities. - Expand the comment on the 250ms wait in remote-transport.test.ts' /api/mcp/send dead-transport test so it is clear the >= 500 assertion is intentionally permissive across both the dead-transport short- circuit and the downstream send-failure branches. - Add a "keep this in sync" pointer on the nullify() helper so a future cleanup that removes any of the defensive `if (!this.client) throw` guards in inspectorClient.ts is reminded to drop the matching call here rather than silently under-covering. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks for the review. Applied the three actionable nits in 2f7230d. 1. Misnamed 2. 250 ms sleep in the dead-transport test. Expanded the comment to call out that the 3. 4 + 5 (the SDK type cast in tokenAuthProvider + the anonymous
|
|
@claude review |
|
Claude finished @cliffhall's task in 51s —— View job Re-review of follow-up commit 2f7230d
Verdict: LGTM ✅All three actionable nits from the prior review are addressed cleanly. No new concerns on the rest of the diff. What was addressed
Items intentionally left as-isThe prior nits 4 ( Everything else in the PRSpot-checked the unchanged parts of the PR (receiver-task private-surface drive, Ship it. |
Closes #1310.
Drops the two
TODO(#1310)entries fromclients/web/vite.config.ts(coverage.exclude). Both files now pass the per-file gate (lines >= 90, statements >= 85, functions >= 80, branches >= 50).Coverage delta
core/mcp/inspectorClient.tscore/mcp/remote/node/server.ts(lines / statements / functions / branches)
What changed
core/mcp/remote/node/server.tscreateTokenAuthProviderto its own file (core/mcp/remote/node/tokenAuthProvider.ts) so the 7 no-opOAuthClientProviderstubs can be unit-tested directly —remote-tokenAuthProvider.test.tsexercises all of them. (The issue authorizes refactoring private helpers to be testable.)remote-transport.test.tsfor the remaining server.ts gaps:createTransportNodesync-throw on connect, transport-dead path on send,/api/lognon-JSON catch,forwardLogEventunknown-level / no-messages / string-first-message fallbacks,/api/fetchmissing-url + upstream-throw,/api/storagePOST invalid storeId / invalid JSON, and/api/storageGET on a corrupt store file. 11 new tests, all green.core/mcp/inspectorClient.tsAdded a single "Coverage backfill (#1310)" describe block to
inspectorClient.test.tswith focused tests for the previously-uncovered paths:environment.oauth; the trivial session / roots / subscription / instructions accessors before connect;setOAuthConfigandauthenticate/runGuidedAuth/proceedOAuthStepthrows viaensureOAuthManager;authenticate()on stdio transports (coversgetServerUrl()'s stdio throw).test://resource_1to matchcreateNumberedResources).getPrompt+readResourceFromTemplate: happy path against a server with prompts and templates, plus the URI-template expansion-failure path.setLoggingLevel: "Server does not support logging" guard against a logging-less server.getAppRendererClient: null before connect, cached proxy after.add_tool/add_resource/add_prompttools to make the server emittools/list_changed/resources/list_changed/prompts/list_changedand asserts the matching dispatched events. (I triedresources/updatedtoo but the streamable-http delivery was flaky in 5s; the other three are enough to lift the gate.)connect()no-op when already connected,connect()throwing whenthis.clientis null (nullify),getTaskCapabilities()returningundefinedagainst a server without a tasks capability, theelicit: { form: true }constructor branch.createReceiverTask/listReceiverTasks/getReceiverTask/getReceiverTaskPayload/cancelReceiverTaskvia(instance as unknown as { ... })to exercise the entirecancelReceiverTaskbody plus the TTL setTimeout cleanup branch. Includes the terminal-status fast-path and the unknown-taskId throws.if (!this.client) throwguards: one nullify-and-call test that exercises 16 sites in a single instance —listTools,listResources,listResourceTemplates,listPrompts,callTool,callToolStream,readResource,readResourceFromTemplate,getPrompt,setLoggingLevel,setRoots,subscribeToResource,unsubscribeFromResource,getRequestorTask/getRequestorTaskResult/cancelRequestorTask/listRequestorTasks,ping, plusgetCompletions's{ values: [] }short-circuit.Test plan
npm run validate(format + lint + build + unit + integration coverage; per-file gate now enforced on both files)npm run test:storybook(67 stories / 298 play-tests)remote-transport.test.ts, 22 ininspectorClient.test.ts, 3 in the newremote-tokenAuthProvider.test.ts— all greenOut of scope
coverage.includeexpansion beyond what Run v1.5-ported integration tests under a node-env vitest project (#1302 follow-up) #1307 already added.🤖 Generated with Claude Code