Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/compatibility-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,19 @@ jobs:

- name: Run Behat
run: vendor/bin/behat compatibility-suite/pact-compatibility-suite/features/V2
v3:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- uses: shivammathur/setup-php@v2
with:
php-version: 8.2
coverage: none

- uses: ramsey/composer-install@v2

- name: Run Behat
run: vendor/bin/behat compatibility-suite/pact-compatibility-suite/features/V3 --name '/^((?!Kafka|binary body \(negative|Message provider).)*$/'
6 changes: 6 additions & 0 deletions behat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@ imports:
- 'compatibility-suite/suites/v1/http/provider.yml'
- 'compatibility-suite/suites/v2/http/consumer.yml'
- 'compatibility-suite/suites/v2/http/provider.yml'
- 'compatibility-suite/suites/v3/http/consumer.yml'
- 'compatibility-suite/suites/v3/http/provider.yml'
- 'compatibility-suite/suites/v3/message/consumer.yml'
- 'compatibility-suite/suites/v3/message/provider.yml'
- 'compatibility-suite/suites/v3/generators.yml'
- 'compatibility-suite/suites/v3/matching-rules.yml'
2 changes: 2 additions & 0 deletions compatibility-suite/public/generators/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.json
*.txt
33 changes: 33 additions & 0 deletions compatibility-suite/public/generators/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../../../vendor/autoload.php';

$app = AppFactory::create();

$app->put('/request-generators', function (Request $request, Response $response) {
file_put_contents(__DIR__ . '/body.json', $request->getBody()->getContents());
file_put_contents(__DIR__ . '/headers.json', json_encode($request->getHeaders()));
file_put_contents(__DIR__ . '/queryParams.json', json_encode($request->getQueryParams()));

return $response;
});

$app->post('/return-provider-state-values', function (Request $request, Response $response) {
$values = $request->getQueryParams();

$response->getBody()->write(json_encode($values));

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

$app->any('{path:.*}', function ($request, $response, array $args) {
file_put_contents(__DIR__ . '/path.txt', $args['path']);

return $response;
});

$app->run();
28 changes: 28 additions & 0 deletions compatibility-suite/suites/v3/generators.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
default:
suites:
v3_generators:
paths:
- '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/generators.feature'
- '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/http_generators.feature'

contexts:
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\SetUpContext'
- 'PhpPactTest\CompatibilitySuite\Context\V3\BodyGeneratorsContext':
- '@body_validator'
- 'PhpPactTest\CompatibilitySuite\Context\V3\RequestGeneratorsContext':
- '@interaction_builder'
- '@request_generator_builder'
- '@interactions_storage'
- '@pact_writer'
- '@generator_server'
- '@provider_verifier'
- '@body_storage'
- 'PhpPactTest\CompatibilitySuite\Context\V3\ResponseGeneratorsContext':
- '@interaction_builder'
- '@response_generator_builder'
- '@interactions_storage'
- '@server'
- '@client'
- '@body_storage'

services: PhpPactTest\CompatibilitySuite\ServiceContainer\V3
13 changes: 13 additions & 0 deletions compatibility-suite/suites/v3/http/consumer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
default:
suites:
v3_http_consumer:
paths: [ '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/http_consumer.feature' ]

contexts:
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\SetUpContext'
- 'PhpPactTest\CompatibilitySuite\Context\V3\Http\ConsumerContext':
- '@interaction_builder'
- '@pact_writer'
- '@interactions_storage'

services: PhpPactTest\CompatibilitySuite\ServiceContainer\V3
34 changes: 34 additions & 0 deletions compatibility-suite/suites/v3/http/provider.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
default:
suites:
v3_http_provider:
paths: [ '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/http_provider.feature' ]

contexts:
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\SetUpContext'
- 'PhpPactTest\CompatibilitySuite\Context\Shared\InteractionsContext':
- '@interactions_storage'
- '@request_matching_rule_builder'
- '@response_matching_rule_builder'
- '@matching_rules_storage'
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Transform\InteractionsContext':
- '@interaction_builder'
- '@matching_rules_storage'
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\ProviderStateContext':
- '@provider_state_server'
- 'PhpPactTest\CompatibilitySuite\Context\Shared\ProviderContext':
- '@server'
- '@provider_verifier'
- '@provider_state_server'
- 'PhpPactTest\CompatibilitySuite\Context\V1\Http\ProviderContext':
- '@server'
- '@pact_writer'
- '@pact_broker'
- '@response_builder'
- '@interactions_storage'
- '@provider_verifier'
- 'PhpPactTest\CompatibilitySuite\Context\V3\Http\ProviderContext':
- '@pact_writer'
- '@provider_state_server'
- '@provider_verifier'

services: PhpPactTest\CompatibilitySuite\ServiceContainer\V3
18 changes: 18 additions & 0 deletions compatibility-suite/suites/v3/matching-rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
default:
suites:
v3_matching_rules:
paths:
- '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/matching_rules.feature'
- '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/http_matching.feature'

contexts:
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\SetUpContext'
- 'PhpPactTest\CompatibilitySuite\Context\V3\RequestMatchingContext':
- '@interaction_builder'
- '@server'
- '@client'
- '@interactions_storage'
- '@request_builder'
- '@request_matching_rule_builder'

services: PhpPactTest\CompatibilitySuite\ServiceContainer\V3
16 changes: 16 additions & 0 deletions compatibility-suite/suites/v3/message/consumer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
default:
suites:
v3_message_consumer:
paths: [ '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/message_consumer.feature' ]

contexts:
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\SetUpContext'
- 'PhpPactTest\CompatibilitySuite\Context\V3\Message\ConsumerContext':
- '@specification'
- '@message_generator_builder'
- '@parser'
- '@body_validator'
- '@body_storage'
- '@fixture_loader'

services: PhpPactTest\CompatibilitySuite\ServiceContainer\V3
26 changes: 26 additions & 0 deletions compatibility-suite/suites/v3/message/provider.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
default:
suites:
v3_message_provider:
paths: [ '%paths.base%/compatibility-suite/pact-compatibility-suite/features/V3/message_provider.feature' ]

contexts:
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\SetUpContext'
- 'PhpPactTest\CompatibilitySuite\Context\Shared\Hook\ProviderStateContext':
- '@provider_state_server'
- 'PhpPactTest\CompatibilitySuite\Context\Shared\ProviderContext':
- '@server'
- '@provider_verifier'
- '@provider_state_server'
- 'PhpPactTest\CompatibilitySuite\Context\V3\Message\ProviderContext':
- '@server'
- '@interaction_builder'
- '@interactions_storage'
- '@message_pact_writer'
- '@provider_verifier'
- '@parser'
- '@fixture_loader'

services: PhpPactTest\CompatibilitySuite\ServiceContainer\V3

# filters:
# tags: ~@wip
22 changes: 22 additions & 0 deletions compatibility-suite/tests/Context/V3/BodyGeneratorsContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace PhpPactTest\CompatibilitySuite\Context\V3;

use Behat\Behat\Context\Context;
use PhpPactTest\CompatibilitySuite\Service\BodyValidatorInterface;

final class BodyGeneratorsContext implements Context
{
public function __construct(
private BodyValidatorInterface $validator,
) {
}

/**
* @Then the body value for :path will have been replaced with a(n) :type
*/
public function theBodyValueForWillHaveBeenReplacedWithA(string $path, string $type): void
{
$this->validator->validateType($path, $type);
}
}
99 changes: 99 additions & 0 deletions compatibility-suite/tests/Context/V3/Http/ConsumerContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace PhpPactTest\CompatibilitySuite\Context\V3\Http;

use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use PhpPact\Consumer\Model\Interaction;
use PhpPactTest\CompatibilitySuite\Service\InteractionBuilderInterface;
use PhpPactTest\CompatibilitySuite\Service\InteractionsStorageInterface;
use PhpPactTest\CompatibilitySuite\Service\PactWriterInterface;
use PHPUnit\Framework\Assert;

final class ConsumerContext implements Context
{
private Interaction $interaction;
private int $id = 1;

public function __construct(
private InteractionBuilderInterface $builder,
private PactWriterInterface $pactWriter,
private InteractionsStorageInterface $storage,
) {
}

/**
* @Given an integration is being defined for a consumer test
*/
public function anIntegrationIsBeingDefinedForAConsumerTest(): void
{
$this->interaction = $this->builder->build([
'description' => 'interaction for a consumer test',
'method' => 'GET',
'path' => '/provider-states',
]);
$this->storage->add(InteractionsStorageInterface::PACT_WRITER_DOMAIN, $this->id, $this->interaction);
}

/**
* @Given a provider state :state is specified
*/
public function aProviderStateIsSpecified(string $state): void
{
$this->interaction->addProviderState($state, []);
}

/**
* @When the Pact file for the test is generated
*/
public function thePactFileForTheTestIsGenerated(): void
{
$this->pactWriter->write($this->id);
}

/**
* @Then the interaction in the Pact file will contain :states provider state(s)
*/
public function theInteractionInThePactFileWillContainProviderStates(int $states): void
{
$pact = json_decode(file_get_contents($this->pactWriter->getPactPath()), true);
Assert::assertCount($states, $pact['interactions'][0]['providerStates']);
}

/**
* @Then the interaction in the Pact file will contain provider state :name
*/
public function theInteractionInThePactFileWillContainProviderState(string $name): void
{
$pact = json_decode(file_get_contents($this->pactWriter->getPactPath()), true);
Assert::assertNotEmpty(array_filter(
$pact['interactions'][0]['providerStates'],
fn (array $providerState) => $providerState['name'] === $name
));
}

/**
* @Given a provider state :state is specified with the following data:
*/
public function aProviderStateIsSpecifiedWithTheFollowingData(string $state, TableNode $table): void
{
$rows = $table->getHash();
$row = reset($rows);
$this->interaction->addProviderState($state, $row);
}

/**
* @Then the provider state :name in the Pact file will contain the following parameters:
*/
public function theProviderStateInThePactFileWillContainTheFollowingParameters(string $name, TableNode $table): void
{
$rows = $table->getHash();
$row = reset($rows);
$params = json_decode($row['parameters'], true);
$pact = json_decode(file_get_contents($this->pactWriter->getPactPath()), true);
Assert::assertNotEmpty(array_filter(
$pact['interactions'][0]['providerStates'],
fn (array $providerState) => $providerState['name'] === $name && $providerState['params'] === $params
));
}
}
57 changes: 57 additions & 0 deletions compatibility-suite/tests/Context/V3/Http/ProviderContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace PhpPactTest\CompatibilitySuite\Context\V3\Http;

use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use PhpPactTest\CompatibilitySuite\Service\PactWriterInterface;
use PhpPactTest\CompatibilitySuite\Service\ProviderStateServerInterface;
use PhpPactTest\CompatibilitySuite\Service\ProviderVerifierInterface;
use PHPUnit\Framework\Assert;

final class ProviderContext implements Context
{
public function __construct(
private PactWriterInterface $pactWriter,
private ProviderStateServerInterface $providerStateServer,
private ProviderVerifierInterface $providerVerifier,
) {
}

/**
* @Given a Pact file for interaction :id is to be verified with the following provider states defined:
*/
public function aPactFileForInteractionIsToBeVerifiedWithTheFollowingProviderStatesDefined(int $id, TableNode $table): void
{
$this->pactWriter->write($id);
$pact = json_decode(file_get_contents($this->pactWriter->getPactPath()), true);
$rows = $table->getHash();
$pact['interactions'][0]['providerStates'] = array_map(fn (array $row): array => ['name' => $row['State Name'], 'params' => json_decode($row['Parameters'] ?? '{}', true)], $rows);
file_put_contents($this->pactWriter->getPactPath(), json_encode($pact));
$this->providerVerifier->addSource($this->pactWriter->getPactPath());
}

/**
* @Then the provider state callback will receive a setup call with :state and the following parameters:
*/
public function theProviderStateCallbackWillReceiveASetupCallWithAndTheFollowingParameters(string $state, TableNode $table): void
{
$params = $table->getHash()[0];
foreach ($params as &$value) {
$value = trim($value, '"');
}
Assert::assertTrue($this->providerStateServer->hasState(ProviderStateServerInterface::ACTION_SETUP, $state, $params));
}

/**
* @Then the provider state callback will receive a teardown call :state and the following parameters:
*/
public function theProviderStateCallbackWillReceiveATeardownCallAndTheFollowingParameters(string $state, TableNode $table): void
{
$params = $table->getHash()[0];
foreach ($params as &$value) {
$value = trim($value, '"');
}
Assert::assertTrue($this->providerStateServer->hasState(ProviderStateServerInterface::ACTION_TEARDOWN, $state, $params));
}
}
Loading