Context
A recurring pattern in consumer test suites (found while reviewing services/incentives's LexusIncentivesServiceTest) is: find the one GuzzleTapper-captured request matching a method+URL, decode its JSON body, and assert on specific fields — to prove the actual outbound request carried the right data, not just that a mocked response was returned correctly.
Current code to do this (4 lines, every time):
$offersCall = $tapper->getCalls()
->first(fn ($request) => str_contains((string) $request->getUri(), 'inventoryservices.lexusdealerdigital.com'));
$this->assertNotNull($offersCall, 'Expected a call to the Lexus offers API.');
$sentBody = json_decode((string) $offersCall->getBody(), true);
$this->assertSame('08052', $sentBody['zip'], 'Zip sent to Lexus must come from Customer API, not the request.');
Proposal
Add a helper to Carsdotcom\ApiRequest\Testing\RequestClassAssertions (the existing trait that already holds assertRequestCacheBodyContains), something like:
protected static function assertTapperSentJsonBodyLike(
GuzzleTapper $tapper,
string $method,
string $urlPattern,
array $expectedBodySubset,
string $message = '',
): void
- Reuses
GuzzleTapper::getCalls() and the same preg_match($urlPattern, ...) matching convention GuzzleTapper::getCountLike() already uses, so behavior stays consistent with the rest of the class.
- Fails clearly if no request matched method+urlPattern at all (distinct from "matched, but body was wrong").
- Asserts
$expectedBodySubset as a subset of the decoded JSON body (like assertArraySubset/Laravel's assertJson), not an exact match — so a caller only pins down the field(s) they actually care about.
Collapses the 4-line pattern above to:
$this->assertTapperSentJsonBodyLike(
$tapper,
'POST',
'#inventoryservices\.lexusdealerdigital\.com#',
['zip' => '08052'],
'Zip sent to Lexus must come from Customer API, not the request.',
);
Happy to put up a PR with this if the shape looks right — mostly wanted to check the API design before writing it, since it needs to fit alongside GuzzleTapper's existing getCountLike()/getCount() conventions.
Context
A recurring pattern in consumer test suites (found while reviewing
services/incentives'sLexusIncentivesServiceTest) is: find the oneGuzzleTapper-captured request matching a method+URL, decode its JSON body, and assert on specific fields — to prove the actual outbound request carried the right data, not just that a mocked response was returned correctly.Current code to do this (4 lines, every time):
Proposal
Add a helper to
Carsdotcom\ApiRequest\Testing\RequestClassAssertions(the existing trait that already holdsassertRequestCacheBodyContains), something like:GuzzleTapper::getCalls()and the samepreg_match($urlPattern, ...)matching conventionGuzzleTapper::getCountLike()already uses, so behavior stays consistent with the rest of the class.$expectedBodySubsetas a subset of the decoded JSON body (likeassertArraySubset/Laravel'sassertJson), not an exact match — so a caller only pins down the field(s) they actually care about.Collapses the 4-line pattern above to:
Happy to put up a PR with this if the shape looks right — mostly wanted to check the API design before writing it, since it needs to fit alongside
GuzzleTapper's existinggetCountLike()/getCount()conventions.