Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Wrap ffi call > setup mock server methods #659

Merged
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
79 changes: 79 additions & 0 deletions helper/FFI/ClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use PhpPact\Consumer\Driver\Exception\InteractionPendingNotSetException;
use PhpPact\Consumer\Driver\Exception\PactFileNotWrittenException;
use PhpPact\Consumer\Driver\Exception\PactNotModifiedException;
use PhpPact\Consumer\Exception\MockServerNotStartedException;
use PhpPact\Consumer\Exception\MockServerPactFileNotWrittenException;
use PhpPact\FFI\ClientInterface;
use PhpPact\Plugin\Exception\PluginNotLoadedException;
use PHPUnit\Framework\Constraint\Constraint;
Expand Down Expand Up @@ -350,4 +352,81 @@ protected function expectsUsingPlugin(int $pact, string $name, ?string $version,
});
}
}

protected function expectsCleanupMockServer(int $port, bool $result): void
{
$this->client
->expects($this->once())
->method('cleanupMockServer')
->with($port)
->willReturn($result);
}

protected function expectsMockServerMatched(int $port, bool $result): void
{
$this->client
->expects($this->once())
->method('mockServerMatched')
->with($port)
->willReturn($result);
}

protected function expectsMockServerMismatches(int $port, string $result, bool $matched): void
{
if (!$matched) {
$this->client
->expects($this->once())
->method('mockServerMismatches')
->with($port)
->willReturn($result);
} else {
$this->client
->expects($this->never())
->method('mockServerMismatches');
}
}

protected function expectsWritePactFile(int $port, string $directory, bool $overwrite, int $result, bool $matched): void
{
if ($matched) {
$this->client
->expects($this->once())
->method('writePactFile')
->with($port, $directory, $overwrite)
->willReturn($result);
if ($result) {
$this->expectException(MockServerPactFileNotWrittenException::class);
$this->expectExceptionMessage(match ($result) {
1 => 'A general panic was caught',
2 => 'The pact file was not able to be written',
3 => 'A mock server with the provided port was not found',
default => 'Unknown error',
});
}
} else {
$this->client
->expects($this->never())
->method('writePactFile');
}
}

protected function expectsCreateMockServerForTransport(int $pact, string $host, int $port, string $transport, ?string $transportConfig, int $result): void
{
$this->client
->expects($this->once())
->method('createMockServerForTransport')
->with($pact, $host, $port, $transport, $transportConfig)
->willReturn($result);
if ($result < 0) {
$this->expectException(MockServerNotStartedException::class);
$this->expectExceptionMessage(match ($result) {
-1 => 'An invalid handle was received. Handles should be created with `pactffi_new_pact`',
-2 => 'Transport_config is not valid JSON',
-3 => 'The mock server could not be started',
-4 => 'The method panicked',
-5 => 'The address is not valid',
default => 'Unknown error',
});
}
}
}
17 changes: 8 additions & 9 deletions src/PhpPact/Consumer/Service/MockServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ public function __construct(

public function start(): void
{
$port = $this->client->call(
'pactffi_create_mock_server_for_transport',
$port = $this->client->createMockServerForTransport(
$this->pactDriver->getPact()->handle,
$this->config->getHost(),
$this->config->getPort(),
Expand Down Expand Up @@ -66,8 +65,7 @@ protected function getTransportConfig(): ?string

public function writePact(): void
{
$error = $this->client->call(
'pactffi_write_pact_file',
$error = $this->client->writePactFile(
$this->config->getPort(),
$this->config->getPactDir(),
$this->config->getPactFileWriteMode() === PactConfigInterface::MODE_OVERWRITE
Expand All @@ -79,19 +77,20 @@ public function writePact(): void

public function cleanUp(): void
{
$this->client->call('pactffi_cleanup_mock_server', $this->config->getPort());
$success = $this->client->cleanupMockServer($this->config->getPort());
if (!$success) {
trigger_error(sprintf("Can not clean up mock server: Mock server with the given port number '%s' does not exist, or the function panics", $this->config->getPort()), E_USER_WARNING);
}
$this->pactDriver->cleanUp();
}

private function isMatched(): bool
{
return $this->client->call('pactffi_mock_server_matched', $this->config->getPort());
return $this->client->mockServerMatched($this->config->getPort());
}

private function getMismatches(): string
{
$cData = $this->client->call('pactffi_mock_server_mismatches', $this->config->getPort());

return FFI::string($cData);
return $this->client->mockServerMismatches($this->config->getPort());
}
}
53 changes: 53 additions & 0 deletions src/PhpPact/FFI/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,59 @@ public function usingPlugin(int $pact, string $name, ?string $version): int
return $result;
}

public function cleanupMockServer(int $port): bool
{
$method = 'pactffi_cleanup_mock_server';
$result = $this->call($method, $port);
if (!is_bool($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "boolean", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function mockServerMatched(int $port): bool
{
$method = 'pactffi_mock_server_matched';
$result = $this->call($method, $port);
if (!is_bool($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "boolean", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function mockServerMismatches(int $port): string
{
$method = 'pactffi_mock_server_mismatches';
$result = $this->call($method, $port);
if ($result === null) {
return '';
}
if (!$result instanceof CData) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "%s", but got "%s"', $method, CData::class, get_debug_type($result)));
}
return FFI::string($result);
}

public function writePactFile(int $port, string $directory, bool $overwrite): int
{
$method = 'pactffi_write_pact_file';
$result = $this->call($method, $port, $directory, $overwrite);
if (!is_int($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "integer", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function createMockServerForTransport(int $pact, string $host, int $port, string $transport, ?string $transportConfig): int
{
$method = 'pactffi_create_mock_server_for_transport';
$result = $this->call($method, $pact, $host, $port, $transport, $transportConfig);
if (!is_int($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "integer", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function getInteractionPartRequest(): int
{
return $this->getEnum('InteractionPart_Request');
Expand Down
10 changes: 10 additions & 0 deletions src/PhpPact/FFI/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ public function cleanupPlugins(int $pact): void;

public function usingPlugin(int $pact, string $name, ?string $version): int;

public function cleanupMockServer(int $port): bool;

public function mockServerMatched(int $port): bool;

public function mockServerMismatches(int $port): string;

public function writePactFile(int $port, string $directory, bool $overwrite): int;

public function createMockServerForTransport(int $pact, string $host, int $port, string $transport, ?string $transportConfig): int;

public function getInteractionPartRequest(): int;

public function getInteractionPartResponse(): int;
Expand Down
46 changes: 10 additions & 36 deletions tests/PhpPact/Consumer/Service/MockServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace PhpPactTest\Consumer\Service;

use FFI;
use PhpPact\Config\PactConfigInterface;
use PhpPact\Consumer\Driver\Pact\PactDriverInterface;
use PhpPact\Consumer\Exception\MockServerNotStartedException;
use PhpPact\Consumer\Exception\MockServerPactFileNotWrittenException;
use PhpPact\Consumer\Model\Pact\Pact;
use PhpPact\Consumer\Service\MockServer;
Expand Down Expand Up @@ -56,21 +54,7 @@ public function testStart(int $returnedPort, bool $secure): void
->expects($this->once())
->method('getPact')
->willReturn(new Pact($this->pactHandle));
$calls = [
['pactffi_create_mock_server_for_transport', $this->pactHandle, $this->host, $this->port, $this->getTransport($secure), null, $returnedPort],
];
$this->assertClientCalls($calls);
if ($returnedPort < 0) {
$this->expectException(MockServerNotStartedException::class);
$this->expectExceptionMessage(match ($returnedPort) {
-1 => 'An invalid handle was received. Handles should be created with `pactffi_new_pact`',
-2 => 'Transport_config is not valid JSON',
-3 => 'The mock server could not be started',
-4 => 'The method panicked',
-5 => 'The address is not valid',
default => 'Unknown error',
});
}
$this->expectsCreateMockServerForTransport($this->pactHandle, $this->host, $this->port, $this->getTransport($secure), null, $returnedPort);
$this->mockServer->start();
$this->assertSame($returnedPort, $this->config->getPort());
}
Expand All @@ -81,16 +65,10 @@ public function testVerify(bool $matched): void
{
$this->config->setPort($this->port);
$this->config->setPactDir($this->pactDir);
$calls = $matched ? [
['pactffi_mock_server_matched', $this->port, $matched],
['pactffi_write_pact_file', $this->port, $this->pactDir, false, 0],
['pactffi_cleanup_mock_server', $this->port, null],
] : [
['pactffi_mock_server_matched', $this->port, $matched],
['pactffi_mock_server_mismatches', $this->port, FFI::new('char[1]')],
['pactffi_cleanup_mock_server', $this->port, null],
];
$this->assertClientCalls($calls);
$this->expectsMockServerMatched($this->port, $matched);
$this->expectsWritePactFile($this->port, $this->pactDir, false, 0, $matched);
$this->expectsMockServerMismatches($this->port, '', $matched);
$this->expectsCleanupMockServer($this->port, true);
$this->pactDriver
->expects($this->once())
->method('cleanUp');
Expand All @@ -114,10 +92,7 @@ public function testWritePact(int $error, string $writeMode): void
$this->config->setPort($this->port);
$this->config->setPactDir($this->pactDir);
$this->config->setPactFileWriteMode($writeMode);
$calls = [
['pactffi_write_pact_file', $this->port, $this->pactDir, $writeMode === PactConfigInterface::MODE_OVERWRITE, $error],
];
$this->assertClientCalls($calls);
$this->expectsWritePactFile($this->port, $this->pactDir, $writeMode === PactConfigInterface::MODE_OVERWRITE, $error, true);
if ($error) {
$this->expectException(MockServerPactFileNotWrittenException::class);
$this->expectExceptionMessage(match ($error) {
Expand All @@ -130,13 +105,12 @@ public function testWritePact(int $error, string $writeMode): void
$this->mockServer->writePact();
}

public function testCleanUp(): void
#[TestWith([true])]
#[TestWith([false])]
public function testCleanUp(bool $success): void
{
$this->config->setPort($this->port);
$calls = [
['pactffi_cleanup_mock_server', $this->port, null],
];
$this->assertClientCalls($calls);
$this->expectsCleanupMockServer($this->port, $success);
$this->pactDriver
->expects($this->once())
->method('cleanUp');
Expand Down
30 changes: 30 additions & 0 deletions tests/PhpPact/FFI/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,36 @@ public function testUsingPlugin(): void
$this->assertSame(2, $result);
}

public function testCleanupMockServer(): void
{
$result = $this->client->cleanupMockServer(1234);
$this->assertFalse($result);
}

public function testMockServerMatched(): void
{
$result = $this->client->mockServerMatched(1234);
$this->assertFalse($result);
}

public function testMockServerMismatches(): void
{
$result = $this->client->mockServerMismatches(1234);
$this->assertSame('', $result);
}

public function testWritePactFile(): void
{
$result = $this->client->writePactFile(1234, 'test', true);
$this->assertSame(3, $result);
}

public function testCreateMockServerForTransport(): void
{
$result = $this->client->createMockServerForTransport(1, 'localhost', 1234, 'http', null);
$this->assertSame(-1, $result);
}

public function testGetInteractionPartRequest(): void
{
$this->assertSame(0, $this->client->getInteractionPartRequest());
Expand Down