Skip to content

Close crucial test gaps found by a suite audit; fix doc slips - #4

Merged
loevgaard merged 1 commit into
1.xfrom
test-gaps-and-doc-fixes
Aug 6, 2026
Merged

Close crucial test gaps found by a suite audit; fix doc slips#4
loevgaard merged 1 commit into
1.xfrom
test-gaps-and-doc-fixes

Conversation

@loevgaard

Copy link
Copy Markdown
Member

An audit of the test suite (cross-referenced against Infection's escaped mutants) plus a README/CLAUDE.md accuracy pass.

New tests

Gap Why it matters
MappingException on a 2xx body that fails DTO mapping The SDK's known gotcha (one mis-typed nested field fails the whole resource) had no regression guard; now asserts the request context and the MappingError chain
Both supported date formats (Z suffix + fractional seconds) Dates were previously entirely untestedsupportDateFormats() could silently break
2xx body that is valid JSON but not an array Only the invalid-JSON branch of decodeJson() was covered
202 Accepted operation response maps to Payment Pins the live-verified async behavior
Host-pinning guard edges: HTTPS://API.QUICKPAY.NET:443/… allowed The credential-leak guard's case-insensitivity and default-port branches were untested (several escaped mutants)
Content-Type stamping: absent on GET, preset value preserved Escaped LogicalAnd mutant on the stamping condition
3xx → UnexpectedStatusCodeException provider row 418 was covered, redirects weren't
Non-payment callback test asserts the guard's message Removing the type guard previously hid behind the shape-mismatch path (same exception class)

Cleanup / doc fixes

Result

  • Tests: 92 → 103 (all green; PHPStan max, ECS, Rector clean)
  • Mutation score: MSI 72% → 80%, covered MSI 76% → 82% (gate: 70)

New tests, driven by cross-referencing the suite against Infection's
escaped mutants:

- MappingException on a 2xx body that fails DTO mapping (the SDK's
  known gotcha), asserting the request context and MappingError chain
- both supported date formats (Z suffix and fractional seconds) - dates
  were previously entirely untested
- MalformedResponseException when a 2xx body is valid JSON but not an
  array (only the invalid-JSON branch was covered)
- a 202 Accepted operation response maps to Payment (matches the
  live-verified async behavior)
- host-pinning guard edges: uppercase scheme/host and an explicit :443
  default port are allowed
- Content-Type stamping: absent on GET, a preset value is preserved
- a 3xx row in the status-code provider
- the non-payment callback test now asserts the guard's message, so
  removing the type guard can no longer hide behind the shape-mismatch
  path

Also removes the dead $allowEmpty parameter of Client::decodeJson()
(never passed true) and fixes two doc slips: updatePayment()'s docblock
said PUT while the SDK sends PATCH, and the README's ValidationException
example used a 3-char order id that would nowadays fail the 4-20 length
rule instead of the duplicate check it narrates. The README now also
states that unconditionally-required fields are required constructor
arguments.

Mutation score: MSI 72% -> 80%, covered MSI 76% -> 82%.
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.00%. Comparing base (9656a9b) to head (0737ba4).

Additional details and impacted files
@@             Coverage Diff              @@
##                1.x       #4      +/-   ##
============================================
+ Coverage     92.55%   97.00%   +4.45%     
+ Complexity      148      146       -2     
============================================
  Files            24       24              
  Lines           403      401       -2     
============================================
+ Hits            373      389      +16     
+ Misses           30       12      -18     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@loevgaard
loevgaard merged commit 52dd84a into 1.x Aug 6, 2026
35 checks passed
@loevgaard
loevgaard deleted the test-gaps-and-doc-fixes branch August 6, 2026 09:12
loevgaard added a commit that referenced this pull request Aug 6, 2026
The five protected helpers mixed three conventions: getOne/createOne
(semantic verb + One), bare update, the noun operation, and the
abbreviated putSub. Now every helper is either semanticVerb+One (typed
single-resource CRUD) or httpVerb+target (transport helpers):

- update       -> updateOne
- operation    -> postOperation
- putSub       -> putSubResource

Also fixes the class docblock's update() bullet, which said PUT while
the helper sends PATCH (the same slip #4 fixed on updatePayment()).

Internal-only rename: the helpers are protected, endpoint subclassing
is explicitly unsupported, and all call sites live in PaymentsEndpoint.
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