Skip to content

Commit

Permalink
Merge pull request #374 from tienvx/sync-message
Browse files Browse the repository at this point in the history
feat: Support sync message
  • Loading branch information
tienvx committed Dec 17, 2023
2 parents a8673fd + 1db2dd3 commit b1cc3d5
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private function expectsToReceive(string $description): self
/**
* @param ProviderState[] $providerStates
*/
private function given(array $providerStates): self
protected function given(array $providerStates): self
{
foreach ($providerStates as $providerState) {
$this->client->call('pactffi_message_given', $this->id, $providerState->getName());
Expand Down
31 changes: 31 additions & 0 deletions src/PhpPact/SyncMessage/Driver/Interaction/SyncMessageDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace PhpPact\SyncMessage\Driver\Interaction;

use PhpPact\Consumer\Driver\Pact\PactDriverInterface;
use PhpPact\Consumer\Model\Message;
use PhpPact\Consumer\Registry\Interaction\MessageRegistryInterface;
use PhpPact\Consumer\Service\MockServerInterface;

class SyncMessageDriver implements SyncMessageDriverInterface
{
public function __construct(
private PactDriverInterface $pactDriver,
private MessageRegistryInterface $messageRegistry,
private MockServerInterface $mockServer
) {
}

public function verifyMessage(): bool
{
return $this->mockServer->verify();
}

public function registerMessage(Message $message): void
{
$this->pactDriver->setUp();
$this->messageRegistry->registerMessage($message);

$this->mockServer->start();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace PhpPact\SyncMessage\Driver\Interaction;

use PhpPact\Consumer\Model\Message;

interface SyncMessageDriverInterface
{
public function verifyMessage(): bool;

public function registerMessage(Message $message): void;
}
39 changes: 39 additions & 0 deletions src/PhpPact/SyncMessage/Driver/Pact/AbstractPluginPactDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace PhpPact\SyncMessage\Driver\Pact;

use PhpPact\Consumer\Driver\Pact\PactDriver;
use PhpPact\SyncMessage\Exception\PluginNotSupportedBySpecificationException;

abstract class AbstractPluginPactDriver extends PactDriver
{
public function cleanUp(): void
{
$this->client->call('pactffi_cleanup_plugins', $this->pactRegistry->getId());
parent::cleanUp();
}

public function setUp(): void
{
parent::setUp();
$this->usingPlugin();
}

abstract protected function getPluginName(): string;

protected function getPluginVersion(): ?string
{
return null;
}

private function usingPlugin(): self
{
if ($this->getSpecification() < $this->client->get('PactSpecification_V4')) {
throw new PluginNotSupportedBySpecificationException($this->config->getPactSpecificationVersion());
}

$this->client->call('pactffi_using_plugin', $this->pactRegistry->getId(), $this->getPluginName(), $this->getPluginVersion());

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace PhpPact\SyncMessage\Exception;

use Exception;

class InteractionContentNotAddedException extends Exception
{
public function __construct(int $code)
{
$message = match ($code) {
1 => 'A general panic was caught.',
2 => 'The mock server has already been started.',
3 => 'The interaction handle is invalid.',
4 => 'The content type is not valid.',
5 => 'The contents JSON is not valid JSON.',
6 => 'The plugin returned an error.',
default => 'Unknown error',
};
parent::__construct($message, $code);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace PhpPact\SyncMessage\Exception;

use Exception;

class PluginNotSupportedBySpecificationException extends Exception
{
public function __construct(string $specification)
{
parent::__construct(sprintf(
'Plugin is not supported by specification %s, use 4.0.0 or above',
$specification,
));
}
}
26 changes: 26 additions & 0 deletions src/PhpPact/SyncMessage/Factory/SyncMessageDriverFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace PhpPact\SyncMessage\Factory;

use PhpPact\Consumer\Driver\Pact\PactDriver;
use PhpPact\Consumer\Registry\Pact\PactRegistry;
use PhpPact\Consumer\Service\MockServer;
use PhpPact\FFI\Client;
use PhpPact\SyncMessage\Driver\Interaction\SyncMessageDriver;
use PhpPact\SyncMessage\Driver\Interaction\SyncMessageDriverInterface;
use PhpPact\SyncMessage\Registry\Interaction\SyncMessageRegistry;
use PhpPact\Standalone\MockService\MockServerConfigInterface;

class SyncMessageDriverFactory implements SyncMessageDriverFactoryInterface
{
public function create(MockServerConfigInterface $config): SyncMessageDriverInterface
{
$client = new Client();
$pactRegistry = new PactRegistry($client);
$pactDriver = new PactDriver($client, $config, $pactRegistry);
$messageRegistry = new SyncMessageRegistry($client, $pactRegistry);
$mockServer = new MockServer($client, $pactRegistry, $config);

return new SyncMessageDriver($pactDriver, $messageRegistry, $mockServer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace PhpPact\SyncMessage\Factory;

use PhpPact\SyncMessage\Driver\Interaction\SyncMessageDriverInterface;
use PhpPact\Standalone\MockService\MockServerConfigInterface;

interface SyncMessageDriverFactoryInterface
{
public function create(MockServerConfigInterface $config): SyncMessageDriverInterface;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace PhpPact\SyncMessage\Registry\Interaction\Contents;

use PhpPact\Consumer\Registry\Interaction\Body\BodyRegistryInterface;
use PhpPact\FFI\ClientInterface;
use PhpPact\SyncMessage\Exception\InteractionContentNotAddedException;

abstract class AbstractContentsRegistry implements BodyRegistryInterface
{
public function __construct(protected ClientInterface $client)
{
}

public function withContents(?string $contentType = null, ?string $contents = null): void
{
if (is_null($contents) || is_null($contentType)) {
// Pact Plugin require content type to be set, or it will panic.
return;
}
$error = $this->client->call('pactffi_interaction_contents', $this->getInteractionId(), $this->getPart(), $contentType, $contents);
if ($error) {
throw new InteractionContentNotAddedException($error);
}
}

abstract protected function getInteractionId(): int;

abstract protected function getPart(): int;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace PhpPact\SyncMessage\Registry\Interaction;

use PhpPact\Consumer\Model\ProviderState;
use PhpPact\Consumer\Registry\Interaction\MessageRegistry;

class SyncMessageRegistry extends MessageRegistry
{
protected function newInteraction(string $description): self
{
$this->id = $this->client->call('pactffi_new_sync_message_interaction', $this->pactRegistry->getId(), $description);

return $this;
}

/**
* @param ProviderState[] $providerStates
*/
protected function given(array $providerStates): self
{
foreach ($providerStates as $providerState) {
$this->client->call('pactffi_given', $this->id, $providerState->getName());
foreach ($providerState->getParams() as $key => $value) {
$this->client->call('pactffi_given_with_param', $this->id, $providerState->getName(), (string) $key, (string) $value);
}
}

return $this;
}
}
30 changes: 30 additions & 0 deletions src/PhpPact/SyncMessage/SyncMessageBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace PhpPact\SyncMessage;

use PhpPact\Consumer\AbstractMessageBuilder;
use PhpPact\SyncMessage\Driver\Interaction\SyncMessageDriverInterface;
use PhpPact\SyncMessage\Factory\SyncMessageDriverFactory;
use PhpPact\SyncMessage\Factory\SyncMessageDriverFactoryInterface;
use PhpPact\Standalone\MockService\MockServerConfigInterface;

class SyncMessageBuilder extends AbstractMessageBuilder
{
private SyncMessageDriverInterface $driver;

public function __construct(MockServerConfigInterface $config, ?SyncMessageDriverFactoryInterface $driverFactory = null)
{
parent::__construct();
$this->driver = ($driverFactory ?? new SyncMessageDriverFactory())->create($config);
}

public function registerMessage(): void
{
$this->driver->registerMessage($this->message);
}

public function verify(): bool
{
return $this->driver->verifyMessage();
}
}

0 comments on commit b1cc3d5

Please sign in to comment.