Skip to content

Commit

Permalink
Merge pull request #516 from tienvx/test-verifier
Browse files Browse the repository at this point in the history
test: Test Verifier
  • Loading branch information
tienvx authored Mar 7, 2024
2 parents a63d563 + d2c8f80 commit 7dad9bb
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 70 deletions.
59 changes: 20 additions & 39 deletions src/PhpPact/Standalone/ProviderVerifier/Verifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,30 @@ class Verifier
protected ClientInterface $client;
protected CData $handle;

public function __construct(VerifierConfigInterface $config, private ?LoggerInterface $logger = null)
public function __construct(VerifierConfigInterface $config, private ?LoggerInterface $logger = null, ?ClientInterface $client = null)
{
$this->client = new Client();
$this
->newHandle($config)
->setProviderInfo($config)
->setProviderTransports($config)
->setFilterInfo($config)
->setProviderState($config)
->setVerificationOptions($config)
->setPublishOptions($config)
->setConsumerFilters($config)
->setLogLevel($config);
$this->client = $client ?? new Client();
$this->newHandle($config);
$this->setProviderInfo($config);
$this->setProviderTransports($config);
$this->setFilterInfo($config);
$this->setProviderState($config);
$this->setVerificationOptions($config);
$this->setPublishOptions($config);
$this->setConsumerFilters($config);
$this->setLogLevel($config);
}

private function newHandle(VerifierConfigInterface $config): self
private function newHandle(VerifierConfigInterface $config): void
{
$this->handle = $this->client->call(
'pactffi_verifier_new_for_application',
$config->getCallingApp()->getName(),
$config->getCallingApp()->getVersion()
);

return $this;
}

private function setProviderInfo(VerifierConfigInterface $config): self
private function setProviderInfo(VerifierConfigInterface $config): void
{
$this->client->call(
'pactffi_verifier_set_provider_info',
Expand All @@ -53,11 +50,9 @@ private function setProviderInfo(VerifierConfigInterface $config): self
$config->getProviderInfo()->getPort(),
$config->getProviderInfo()->getPath()
);

return $this;
}

private function setProviderTransports(VerifierConfigInterface $config): self
private function setProviderTransports(VerifierConfigInterface $config): void
{
foreach ($config->getProviderTransports() as $transport) {
$this->client->call(
Expand All @@ -69,11 +64,9 @@ private function setProviderTransports(VerifierConfigInterface $config): self
$transport->getScheme()
);
}

return $this;
}

private function setFilterInfo(VerifierConfigInterface $config): self
private function setFilterInfo(VerifierConfigInterface $config): void
{
$this->client->call(
'pactffi_verifier_set_provider_state',
Expand All @@ -82,11 +75,9 @@ private function setFilterInfo(VerifierConfigInterface $config): self
$config->getProviderState()->isStateChangeTeardown(),
$config->getProviderState()->isStateChangeAsBody()
);

return $this;
}

private function setProviderState(VerifierConfigInterface $config): self
private function setProviderState(VerifierConfigInterface $config): void
{
$this->client->call(
'pactffi_verifier_set_filter_info',
Expand All @@ -95,23 +86,19 @@ private function setProviderState(VerifierConfigInterface $config): self
$config->getFilterInfo()->getFilterState(),
$config->getFilterInfo()->getFilterNoState()
);

return $this;
}

private function setVerificationOptions(VerifierConfigInterface $config): self
private function setVerificationOptions(VerifierConfigInterface $config): void
{
$this->client->call(
'pactffi_verifier_set_verification_options',
$this->handle,
$config->getVerificationOptions()->isDisableSslVerification(),
$config->getVerificationOptions()->getRequestTimeout()
);

return $this;
}

private function setPublishOptions(VerifierConfigInterface $config): self
private function setPublishOptions(VerifierConfigInterface $config): void
{
if ($config->isPublishResults()) {
$providerTags = ArrayData::createFrom($config->getPublishOptions()->getProviderTags());
Expand All @@ -125,11 +112,9 @@ private function setPublishOptions(VerifierConfigInterface $config): self
$config->getPublishOptions()->getProviderBranch()
);
}

return $this;
}

private function setConsumerFilters(VerifierConfigInterface $config): self
private function setConsumerFilters(VerifierConfigInterface $config): void
{
$filterConsumerNames = ArrayData::createFrom($config->getConsumerFilters()->getFilterConsumerNames());
$this->client->call(
Expand All @@ -138,17 +123,13 @@ private function setConsumerFilters(VerifierConfigInterface $config): self
$filterConsumerNames?->getItems(),
$filterConsumerNames?->getSize()
);

return $this;
}

private function setLogLevel(VerifierConfigInterface $config): self
private function setLogLevel(VerifierConfigInterface $config): void
{
if ($logLevel = $config->getLogLevel()) {
$this->client->call('pactffi_init_with_log_level', $logLevel);
}

return $this;
}

public function addFile(string $file): self
Expand Down
6 changes: 5 additions & 1 deletion tests/PhpPact/Helper/FFI/ClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace PhpPactTest\Helper\FFI;

use PhpPact\FFI\ClientInterface;
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\Constraint\IsIdentical;
use PHPUnit\Framework\MockObject\MockObject;

trait ClientTrait
Expand All @@ -17,7 +19,9 @@ protected function assertClientCalls(array $calls): void
->willReturnCallback(function (...$args) use (&$calls) {
$call = array_shift($calls);
$return = array_pop($call);
$this->assertSame($call, $args);
foreach ($args as $key => $arg) {
$this->assertThat($arg, $call[$key] instanceof Constraint ? $call[$key] : new IsIdentical($call[$key]));
}

return $return;
});
Expand Down
183 changes: 163 additions & 20 deletions tests/PhpPact/Standalone/ProviderVerifier/VerifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,187 @@

namespace PhpPactTest\Standalone\ProviderVerifier;

use FFI;
use FFI\CData;
use GuzzleHttp\Psr7\Uri;
use PhpPact\FFI\ClientInterface;
use PhpPact\Service\LoggerInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ProviderTransport;
use PhpPact\Standalone\ProviderVerifier\Model\Config\PublishOptions;
use PhpPact\Standalone\ProviderVerifier\Model\ConsumerVersionSelectors;
use PhpPact\Standalone\ProviderVerifier\Model\Selector\Selector;
use PhpPact\Standalone\ProviderVerifier\Model\Source\Broker;
use PhpPact\Standalone\ProviderVerifier\Model\Source\Url;
use PhpPact\Standalone\ProviderVerifier\Model\VerifierConfig;
use PhpPact\Standalone\ProviderVerifier\Model\VerifierConfigInterface;
use PhpPact\Standalone\ProviderVerifier\Verifier;
use PhpPactTest\Helper\FFI\ClientTrait;
use PhpPactTest\Helper\PhpProcess;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class VerifierTest extends TestCase
{
private PhpProcess $process;
use ClientTrait;

private Verifier $verifier;
private VerifierConfigInterface $config;
private LoggerInterface|MockObject $logger;
private CData $handle;
private array $calls;

protected function setUp(): void
{
$this->process = new PhpProcess(__DIR__ . '/../../../_public/');
$this->process->start();
$this->config = new VerifierConfig();
$this->logger = $this->createMock(LoggerInterface::class);
$this->client = $this->createMock(ClientInterface::class);
$this->handle = FFI::new('int');
$this->config->getCallingApp()
->setName($callingAppName = 'calling app name')
->setVersion($callingAppVersion = '1.2.3');
$this->config->getProviderInfo()
->setName($providerName = 'provider name')
->setScheme($providerScheme = 'https')
->setHost($providerHost = 'provider.domain')
->setPort($providerPort = 123)
->setPath($providerPath = '/provider/path');
$transport = new ProviderTransport();
$transport->setProtocol($transportProtocol = 'message')
->setPort($transportPort = 234)
->setPath($transportPath = '/provider-messages')
->setScheme($transportScheme = 'http');
$this->config->getProviderState()
->setStateChangeUrl($stateChangeUrl = new Uri('http://provider.host:432/pact-change-state'))
->setStateChangeTeardown($stateChangeTearDown = true)
->setStateChangeAsBody($stateChangeAsBody = true);
$this->config->addProviderTransport($transport);
$this->config->getFilterInfo()
->setFilterDescription($filterDescription = 'request to /hello')
->setFilterNoState($filterNoState = true)
->setFilterState($filterState = 'given state');
$this->config->getVerificationOptions()
->setRequestTimeout($requestTimeout = 500)
->setDisableSslVerification($disableSslVerification = true);
$publishOptions = new PublishOptions();
$publishOptions
->setProviderTags($providerTags = ['feature-x', 'master', 'test', 'prod'])
->setProviderVersion($providerVersion = '1.2.3')
->setBuildUrl($buildUrl = new Uri('http://ci/build/1'))
->setProviderBranch($providerBranch = 'some-branch');
$this->config->setPublishOptions($publishOptions);
$this->config->getConsumerFilters()
->setFilterConsumerNames($filterConsumerNames = ['http-consumer-1', 'http-consumer-2', 'message-consumer-2']);
$this->config->setLogLevel($logLevel = 'info');
$this->calls = [
['pactffi_verifier_new_for_application', $callingAppName, $callingAppVersion, $this->handle],
['pactffi_verifier_set_provider_info', $this->handle, $providerName, $providerScheme, $providerHost, $providerPort, $providerPath, null],
['pactffi_verifier_add_provider_transport', $this->handle, $transportProtocol, $transportPort, $transportPath, $transportScheme, null],
['pactffi_verifier_set_provider_state', $this->handle, (string) $stateChangeUrl, $stateChangeTearDown, $stateChangeAsBody, null],
['pactffi_verifier_set_filter_info', $this->handle, $filterDescription, $filterState, $filterNoState, null],
['pactffi_verifier_set_verification_options', $this->handle, $disableSslVerification, $requestTimeout, null],
['pactffi_verifier_set_publish_options', $this->handle, $providerVersion, $buildUrl, $this->isInstanceOf(CData::class), count($providerTags), $providerBranch, null],
['pactffi_verifier_set_consumer_filters', $this->handle, $this->isInstanceOf(CData::class), count($filterConsumerNames), null],
['pactffi_init_with_log_level', strtoupper($logLevel), null],
];
}

protected function tearDown(): void
public function testConstruct(): void
{
$this->process->stop();
$this->assertClientCalls($this->calls);
$this->verifier = new Verifier($this->config, $this->logger, $this->client);
}

public function testVerify(): void
public function testAddFile(): void
{
$config = new VerifierConfig();
$config->getProviderInfo()
->setName('someProvider')
->setHost('localhost')
->setPort($this->process->getPort())
->setScheme('http')
->setPath('/');
if ($level = \getenv('PACT_LOGLEVEL')) {
$config->setLogLevel($level);
}
$file = '/path/to/file.json';
$this->calls[] = ['pactffi_verifier_add_file_source', $this->handle, $file, null];
$this->assertClientCalls($this->calls);
$this->verifier = new Verifier($this->config, $this->logger, $this->client);
$this->assertSame($this->verifier, $this->verifier->addFile($file));
}

public function testAddDirectory(): void
{
$directory = '/path/to/directory';
$this->calls[] = ['pactffi_verifier_add_directory_source', $this->handle, $directory, null];
$this->assertClientCalls($this->calls);
$this->verifier = new Verifier($this->config, $this->logger, $this->client);
$this->assertSame($this->verifier, $this->verifier->addDirectory($directory));
}

$verifier = new Verifier($config);
$verifier->addFile(__DIR__ . '/../../../_resources/someconsumer-someprovider.json');
public function testAddUrl(): void
{
$source = new Url();
$source
->setUrl($url = new Uri('http://example.test/path/to/file.json'))
->setToken($token = 'secret token')
->setUsername($username = 'my username')
->setPassword($password = 'secret password');
$this->calls[] = ['pactffi_verifier_url_source', $this->handle, (string) $url, $username, $password, $token, null];
$this->assertClientCalls($this->calls);
$this->verifier = new Verifier($this->config, $this->logger, $this->client);
$this->assertSame($this->verifier, $this->verifier->addUrl($source));
}

$verifyResult = $verifier->verify();
public function testAddBroker(): void
{
$consumerVersionSelectors = (new ConsumerVersionSelectors())
->addSelector(new Selector(tag: 'foo', latest: true))
->addSelector('{"tag":"bar","latest":true}');
$source = new Broker();
$source
->setUrl($url = new Uri('http://example.test/path/to/file.json'))
->setToken($token = 'secret token')
->setUsername($username = 'my username')
->setPassword($password = 'secret password')
->setEnablePending($enablePending = true)
->setIncludeWipPactSince($wipPactSince = '2020-01-30')
->setProviderTags($providerTags = ['prod', 'staging'])
->setProviderBranch($providerBranch = 'main')
->setConsumerVersionSelectors($consumerVersionSelectors)
->setConsumerVersionTags($consumerVersionTags = ['dev']);
$this->calls[] = [
'pactffi_verifier_broker_source_with_selectors',
$this->handle,
(string) $url,
$username,
$password,
$token,
$enablePending,
$wipPactSince,
$this->isInstanceOf(CData::class),
count($providerTags),
$providerBranch,
$this->isInstanceOf(CData::class),
count($consumerVersionSelectors),
$this->isInstanceOf(CData::class),
count($consumerVersionTags),
null
];
$this->assertClientCalls($this->calls);
$this->verifier = new Verifier($this->config, $this->logger, $this->client);
$this->assertSame($this->verifier, $this->verifier->addBroker($source));
}

$this->assertTrue($verifyResult);
#[TestWith([0, true, false])]
#[TestWith([0, true, true])]
#[TestWith([1, false, false])]
#[TestWith([2, false, false])]
public function testVerify(int $error, bool $success, bool $hasLogger): void
{
$json = '{"key": "value"}';
$this->calls[] = ['pactffi_verifier_execute', $this->handle, $error];
$this->logger
->expects($this->exactly($hasLogger))
->method('log')
->with($json);
if ($hasLogger) {
$this->calls[] = ['pactffi_verifier_json', $this->handle, $json];
}
$this->calls[] = ['pactffi_verifier_shutdown', $this->handle, null];
$this->assertClientCalls($this->calls);
$this->verifier = new Verifier($this->config, $hasLogger ? $this->logger : null, $this->client);
$this->assertSame($success, $this->verifier->verify());
}
}
10 changes: 0 additions & 10 deletions tests/_public/index.php

This file was deleted.

0 comments on commit 7dad9bb

Please sign in to comment.