test(oauth): cover static client-information + client-secret resolver - #281
test(oauth): cover static client-information + client-secret resolver#281KrasimirKralev wants to merge 1 commit into
Conversation
|
Codex review: needs changes before merge. Reviewed August 6, 2026, 9:17 AM ET / 13:17 UTC. ClawSweeper reviewWhat this changesThe PR adds 112 lines of direct Vitest coverage for static OAuth client metadata construction and client-secret resolution. Merge readinessKeep open: the focused coverage is useful, but the unchanged test file still deletes any caller-provided secret environment value and does not explicitly establish the unset precondition. Priority: P3 Review scores
Verification
How this fits togetherMCPorter builds static OAuth client metadata from a configured server definition and resolves secrets from environment variables or inline configuration. The resulting metadata is consumed by OAuth authorization and token-refresh flows. flowchart LR
A[Server definition] --> B[OAuth client metadata builder]
C[Environment secret] --> B
B --> D[Static client information]
D --> E[Authorization flow]
D --> F[Token refresh flow]
Before merge
Findings
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Copy recommended automerge instructionTechnical reviewBest possible solution: Keep the direct coverage, but snapshot the environment value, clear it before each test, and restore it afterward while leaving production OAuth behavior unchanged. Do we have a high-confidence way to reproduce the issue? Yes, from source: start the focused suite with Is this the best way to solve the issue? No. Direct coverage is the right approach, but hermetic environment setup and restoration are needed for a reliable regression suite. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4219927ec680. LabelsLabel justifications:
EvidenceAcceptance criteria:
What I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (2 earlier review cycles) |
What Problem This Solves
src/oauth-client-info.tsexports the two helpers that assemble a static OAuth client information object and resolve its client secret, and the module shipped with no direct test coverage — notests/oauth-client-info.test.tsexists onmain. Both helpers carry contracts a plausible refactor could silently break:resolveOAuthClientSecret(definition, options)— whenoauthClientSecretEnvis set it reads the env var and throws a labeled error if the value is missing (!value) or, underrejectBlank, blank; otherwise it returns the env value (whitespace preserved whenrejectBlankis off). With no env ref it falls back to the inlineoauthClientSecret, orundefined.buildStaticClientInformation(definition, options)— returnsundefinedwith nooauthClientId; otherwise emits fixedgrant_types/response_types, conditionally includesclient_secret(via the resolver),redirect_uris(from aURLor string), andtoken_endpoint_auth_method, and propagates the resolver's throw.A regression in any of these — dropping the
!valueguard, inverting a conditional-spread ternary, or losing the required-secret throw — would ship green today because nothing executes the module.Why This Change Was Made
Coverage-only. This adds one new file,
tests/oauth-client-info.test.ts(+112, no production code touched), pinning both helpers' currentmainbehavior. The tests import the real exported functions and drive them directly — no stubs — so they exercise the production path callers actually hit. Both the primary and negative/omit paths are pinned for each helper: the resolver's env/inline/undefined returns plus its three throw paths, and the builder'sundefinedgate, each conditional field's include-and-omit pair, and the propagated throw. No new config, defaults, or dependencies.User Impact
No user-visible or runtime change. For maintainers, the static-client-information contract now regresses loudly instead of silently: a future edit that drops the required-secret throw, breaks a conditional-field spread, or loses the env/inline resolver fallback will fail this suite.
Evidence
Linux, Node 22.22,
pnpm install --frozen-lockfilefrom source. Branched off currentmain(base4219927); the module under test,src/oauth-client-info.ts, is byte-identical to its state at the earlier-verified base58986a7(the only change between them isCHANGELOG.md), so the pinned behavior is current.15/15 pass on current
main:Non-vacuous — the suite bites when the target is mutated (each mutation applied to
src/oauth-client-info.ts, suite re-run, then reverted byte-identical). The representative M1 case was re-confirmed on this exact rebased head; the full matrix was validated against the byte-identical source:oauth-client-info.ts!valuerequired-secret guardrejectBlankblank-value clauseoauthClientIdundefinedgateclient_secretconditional spreadredirect_urisconditional spreadtoken_endpoint_auth_methodspreadgrant_typesarrayFormat / lint / types clean on the new file:
Scope note: one new
*.test.tsfile undertests/,+112 / -0, no production code touched. Direct sibling of the just-landed #246 (OAuth token-generation coverage) — same module family, mirror side.Opened from a fork via the API; if GitHub's Allow edits by maintainers toggle isn't honored on this PR, a maintainer can still push to the branch or supersede-and-land.
Generated by Claude Code