Created
July 8, 2020 22:14
-
-
Save DavertMik/5caf209236356ce6c2af036de6d06cdd to your computer and use it in GitHub Desktop.
Pact Helper for Codeception
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Codeception\Module; | |
use Codeception\Exception\ConfigurationException; | |
use Codeception\Exception\ModuleException; | |
use Codeception\Test\Test; | |
use Codeception\TestInterface; | |
use PhpPact\Consumer\Model\Interaction; | |
use PhpPact\Exception\ConnectionException; | |
use PhpPact\Http\GuzzleClient; | |
use PhpPact\Standalone\MockService\MockServerConfig; | |
use PhpPact\Standalone\MockService\Service\MockServerHttpService; | |
use PhpPact\Consumer\InteractionBuilder; | |
use PhpPact\Consumer\Model\ConsumerRequest; | |
use PhpPact\Consumer\Model\ProviderResponse; | |
use PhpPact\Standalone\MockService\MockServerConfigInterface; | |
use PhpPact\Standalone\MockService\MockServerEnvConfig; | |
use PhpPact\Standalone\MockService\Service\MockServerHttpServiceInterface; | |
class Pact extends \Codeception\Module | |
{ | |
protected $requiredFields = [ | |
'consumer', | |
'providers' | |
]; | |
protected $config = [ | |
'consumer' => null, | |
'providers' => [] | |
]; | |
/** @var MockServerHttpServiceInterface[] **/ | |
protected $mockServices = []; | |
protected function validateConfig() | |
{ | |
parent::validateConfig(); | |
foreach ($this->config['providers'] as $providerConfig) { | |
$provider = key($providerConfig); | |
$serviceConfig = reset($providerConfig); | |
if (!isset($serviceConfig['mock_server_host'])) { | |
throw new ConfigurationException('mock_server_host required. Current config: ' . implode(', ', array_keys($serviceConfig))); | |
} | |
if (!isset($serviceConfig['mock_server_port'])) { | |
throw new ConfigurationException('mock_server_port required'); | |
} | |
$config = new MockServerConfig(); | |
$config->setHost($serviceConfig['mock_server_host']); | |
$config->setPort($serviceConfig['mock_server_port']); | |
$config->setConsumer($this->config['consumer']); | |
$config->setProvider($provider); | |
$this->debug("Provider mock for '$provider': " . json_encode($serviceConfig)); | |
$this->mockServices[$provider] = new MockServerHttpService(new GuzzleClient(), $config); | |
} | |
} | |
public function _before(TestInterface $test) | |
{ | |
foreach ($this->mockServices as $provider => $mockService) { | |
$mockService->deleteAllInteractions(); | |
} | |
} | |
/** | |
* @param null $provider | |
* @return \Codeception\Pact\PactInteraction | |
*/ | |
public function haveRequestTo($provider, $description) | |
{ | |
if (!isset($this->mockServices[$provider])) { | |
throw new ModuleException("No mock service started for provider $provider"); | |
} | |
return new PactInteraction($this->mockServices[$provider], $description); | |
} | |
public function _after(TestInterface $test) | |
{ | |
foreach ($this->mockServices as $provider => $mockService) { | |
$mockService->verifyInteractions(); | |
$this->assertTrue(true, 'interaction check'); | |
$mockService->getPactJson(); | |
} | |
} | |
} | |
class PactInteraction | |
{ | |
protected $headers = []; | |
/** @var ConsumerRequest **/ | |
protected $request; | |
/** @var ProviderResponse **/ | |
protected $response; | |
/** @var MockServerEnvConfig **/ | |
protected $config; | |
/** @var $given **/ | |
protected $given; | |
private $description; | |
/** @var Interaction **/ | |
private $interaction; | |
/** @var MockServerHttpServiceInterface **/ | |
private $server; | |
public function __construct(MockServerHttpServiceInterface $server, $description) | |
{ | |
$this->server = $server; | |
$this->interaction = new Interaction(); | |
$this->description = $description; | |
} | |
public function haveHttpHeader($header, $value) | |
{ | |
$this->headers[$header] = $value; | |
return $this; | |
} | |
public function request($method, $path, $body = null) | |
{ | |
$request = new ConsumerRequest(); | |
$request | |
->setMethod(strtoupper($method)) | |
->setPath($path); | |
if ($body) { | |
$request->setBody($body); | |
} | |
foreach ($this->headers as $header => $val) { | |
$request->addHeader($header, $val); | |
} | |
$this->request = $request; | |
codecept_debug('Mocked Request: ' . json_encode($request->jsonSerialize())); | |
return $this; | |
} | |
public function resetHeaders() | |
{ | |
$this->headers = []; | |
return $this; | |
} | |
public function requires($providerState) | |
{ | |
$this->given = $providerState; | |
return $this; | |
} | |
public function response($code, $responseBody) | |
{ | |
$response = new ProviderResponse(); | |
$response | |
->setStatus($code) | |
->setBody($responseBody); | |
foreach ($this->headers as $header => $val) { | |
$response->addHeader($header, $val); | |
} | |
$this->response = $response; | |
$this->interaction | |
->setRequest($this->request) | |
->setResponse($this->response) | |
->setDescription($this->description); | |
if ($this->given) { | |
$this->interaction->setProviderState($this->given); | |
} | |
codecept_debug('Mocked Response: ' . json_encode($response->jsonSerialize())); | |
$this->server->registerInteraction($this->interaction); | |
codecept_debug('Interaction saved'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment