Skip to content

Commit

Permalink
chore: Add status code matcher example
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed Nov 28, 2023
1 parent 8711756 commit 4cc3355
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 30 deletions.
21 changes: 17 additions & 4 deletions example/matchers/consumer/src/Service/HttpClientService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,39 @@
namespace MatchersConsumer\Service;

use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;

class HttpClientService
{
private Client $httpClient;

private string $baseUri;

private ResponseInterface $response;

public function __construct(string $baseUri)
{
$this->httpClient = new Client();
$this->baseUri = $baseUri;
$this->sendRequest();
}

public function getResponseStatusCode(): int
{
return $this->response->getStatusCode();
}

public function getMatchers(): array
{
$response = $this->httpClient->get("{$this->baseUri}/matchers", [
return \json_decode($this->response->getBody(), true, 512, JSON_THROW_ON_ERROR);
}

private function sendRequest(): void
{
$this->response = $this->httpClient->get("{$this->baseUri}/matchers", [
'headers' => ['Accept' => 'application/json'],
'query' => 'ignore=statusCode&pages=2&pages=3&locales[]=fr-BE&locales[]=ru-RU',
'query' => 'pages=2&pages=3&locales[]=fr-BE&locales[]=ru-RU',
'http_errors' => false,
]);

return \json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
}
}
10 changes: 4 additions & 6 deletions example/matchers/consumer/tests/Service/MatchersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use MatchersConsumer\Service\HttpClientService;
use PhpPact\Consumer\InteractionBuilder;
use PhpPact\Consumer\Matcher\HttpStatus;
use PhpPact\Consumer\Matcher\Matcher;
use PhpPact\Consumer\Model\ConsumerRequest;
use PhpPact\Consumer\Model\ProviderResponse;
Expand All @@ -26,7 +27,6 @@ public function testGetMatchers()
->setMethod('GET')
->setPath($this->matcher->regex('/matchers', '^\/matchers$'))
->setQuery([
'ignore' => 'statusCode',
'pages' => [ // Consumer send multiple values, but provider receive single (last) value
json_encode($this->matcher->regex([1, 22], '\d+')),
],
Expand All @@ -38,7 +38,7 @@ public function testGetMatchers()

$response = new ProviderResponse();
$response
->setStatus(200)
->setStatus($this->matcher->statusCode(HttpStatus::SERVER_ERROR, 512))
->addHeader('Content-Type', 'application/json')
->setBody([
'like' => $this->matcher->like(['key' => 'value']),
Expand Down Expand Up @@ -104,7 +104,6 @@ public function testGetMatchers()
[$this->matcher->regex(null, 'car|bike|motorbike')]
),
'query' => [
'ignore' => 'statusCode',
'pages' => '22',
'locales' => ['en-US', 'en-AU'],
],
Expand All @@ -127,10 +126,10 @@ public function testGetMatchers()
->willRespondWith($response);

$service = new HttpClientService($config->getBaseUri());
$matchersResult = $service->getMatchers();
$verifyResult = $builder->verify();

$this->assertTrue($verifyResult);
$this->assertSame(512, $service->getResponseStatusCode());
$this->assertEquals([
'like' => ['key' => 'value'],
'likeNull' => null,
Expand Down Expand Up @@ -193,10 +192,9 @@ public function testGetMatchers()
'vehicle 1' => 'car',
],
'query' => [
'ignore' => 'statusCode',
'pages' => '22',
'locales' => ['en-US', 'en-AU'],
],
], $matchersResult);
], $service->getMatchers());
}
}
23 changes: 15 additions & 8 deletions example/matchers/pacts/matchersConsumer-matchersProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@
"method": "GET",
"path": "/matchers",
"query": {
"ignore": [
"statusCode"
],
"locales[]": [
"en-US",
"en-AU"
Expand Down Expand Up @@ -132,7 +129,6 @@
"nullValue": null,
"number": 123,
"query": {
"ignore": "statusCode",
"locales": [
"en-US",
"en-AU"
Expand Down Expand Up @@ -564,19 +560,30 @@
]
}
},
"header": {}
"header": {},
"status": {
"$": {
"combine": "AND",
"matchers": [
{
"match": "statusCode",
"status": "serverError"
}
]
}
}
},
"status": 200
"status": 512
},
"transport": "http",
"type": "Synchronous/HTTP"
}
],
"metadata": {
"pactRust": {
"ffi": "0.4.10",
"ffi": "0.4.11",
"mockserver": "1.2.4",
"models": "1.1.11"
"models": "1.1.12"
},
"pactSpecification": {
"version": "4.0"
Expand Down
4 changes: 3 additions & 1 deletion example/matchers/provider/public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@
'query' => $request->getQueryParams(),
]));

return $response->withHeader('Content-Type', 'application/json');
return $response
->withHeader('Content-Type', 'application/json')
->withStatus(503);
});

$app->post('/pact-change-state', function (Request $request, Response $response) {
Expand Down
26 changes: 24 additions & 2 deletions src/PhpPact/Consumer/Matcher/Matcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -625,14 +625,36 @@ public function semver(string $value): array
*
* @return array<string, mixed>
*/
public function statusCode(string $status): array
public function statusCode(string $status, ?int $value = null): array
{
if (!in_array($status, HttpStatus::all())) {
throw new Exception(sprintf("Status '%s' is not supported. Supported status are: %s", $status, implode(', ', HttpStatus::all())));
}

if (null === $value) {
[$min, $max] = match($status) {
HttpStatus::INFORMATION => [100, 199],
HttpStatus::SUCCESS => [200, 299],
HttpStatus::REDIRECT => [300, 399],
HttpStatus::CLIENT_ERROR => [400, 499],
HttpStatus::SERVER_ERROR => [500, 599],
HttpStatus::NON_ERROR => [100, 399],
HttpStatus::ERROR => [400, 599],
default => [100, 199], // Can't happen, just to make PHPStan happy
};

return [
'pact:generator:type' => 'RandomInt',
'min' => $min,
'max' => $max,
'status' => $status,
'pact:matcher:type' => 'statusCode',
];
}

return [
'status' => $status,
'value' => $value,
'status' => $status,
'pact:matcher:type' => 'statusCode',
];
}
Expand Down
8 changes: 4 additions & 4 deletions src/PhpPact/Consumer/Model/Interaction/StatusTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

trait StatusTrait
{
private int $status = 200;
private string $status = '200';

public function getStatus(): int
public function getStatus(): string
{
return $this->status;
}

public function setStatus(int $status): self
public function setStatus(int|array $status): self
{
$this->status = $status;
$this->status = is_array($status) ? json_encode($status, JSON_THROW_ON_ERROR) : (string) $status;

return $this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public function __construct(
parent::__construct($client, $interactionRegistry, $responseBodyRegistry ?? new ResponseBodyRegistry($client, $interactionRegistry));
}

public function withResponse(int $status): self
public function withResponse(string $status): self
{
$this->client->call('pactffi_response_status', $this->getInteractionId(), $status);
$this->client->call('pactffi_response_status_v2', $this->getInteractionId(), $status);

return $this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

interface ResponseRegistryInterface extends PartRegistryInterface
{
public function withResponse(int $status): self;
public function withResponse(string $status): self;
}
7 changes: 5 additions & 2 deletions tests/PhpPact/Consumer/Matcher/MatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -851,8 +851,11 @@ public function testInvalidStatusCode()
public function testValidStatusCode()
{
$expected = [
'status' => 'success',
'pact:matcher:type' => 'statusCode',
'pact:generator:type' => 'RandomInt',
'min' => 200,
'max' => 299,
'status' => 'success',
'pact:matcher:type' => 'statusCode',
];
$actual = $this->matcher->statusCode(HttpStatus::SUCCESS);

Expand Down

0 comments on commit 4cc3355

Please sign in to comment.