Skip to content

Commit

Permalink
chore: Add protobuf async message example
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed Jan 13, 2024
1 parent 97fdfd8 commit 95ed5ab
Show file tree
Hide file tree
Showing 12 changed files with 348 additions and 3 deletions.
11 changes: 8 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,16 @@
"GeneratorsConsumer\\Tests\\": "example/generators/consumer/tests",
"GeneratorsProvider\\Tests\\": "example/generators/provider/tests",
"": [
"example/protobuf-sync-message/library/src"
"example/protobuf-sync-message/library/src",
"example/protobuf-async-message/library/src"
],
"ProtobufSyncMessageConsumer\\": "example/protobuf-sync-message/consumer/src",
"ProtobufSyncMessageConsumer\\Tests\\": "example/protobuf-sync-message/consumer/tests",
"ProtobufSyncMessageProvider\\": "example/protobuf-sync-message/provider/src",
"ProtobufSyncMessageProvider\\Tests\\": "example/protobuf-sync-message/provider/tests"
"ProtobufSyncMessageProvider\\Tests\\": "example/protobuf-sync-message/provider/tests",
"ProtobufAsyncMessageConsumer\\": "example/protobuf-async-message/consumer/src",
"ProtobufAsyncMessageConsumer\\Tests\\": "example/protobuf-async-message/consumer/tests",
"ProtobufAsyncMessageProvider\\Tests\\": "example/protobuf-async-message/provider/tests"
}
},
"scripts": {
Expand All @@ -92,7 +96,8 @@
"phpunit --debug"
],
"gen-lib": [
"protoc --php_out=example/protobuf-sync-message/library/src example/protobuf-sync-message/library/proto/area_calculator.proto"
"protoc --php_out=example/protobuf-sync-message/library/src example/protobuf-sync-message/library/proto/area_calculator.proto",
"protoc --php_out=example/protobuf-async-message/library/src example/protobuf-async-message/library/proto/say_hello.proto"
],
"check-compatibility": "behat"
},
Expand Down
11 changes: 11 additions & 0 deletions example/protobuf-async-message/consumer/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="../../../vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="PhpPact Example Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
<php>
<env name="PACT_LOGLEVEL" value="DEBUG"/>
</php>
</phpunit>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace ProtobufAsyncMessageConsumer\MessageHandler;

use Library\Person;
use ProtobufAsyncMessageConsumer\Service\SayHelloService;

class PersonMessageHandler
{
public function __construct(private SayHelloService $service)
{
}

public function __invoke(Person $person): void
{
$this->service->sayHello($person->getName()->getGiven(), $person->getName()->getSurname());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace ProtobufAsyncMessageConsumer\Service;

class SayHelloService
{
public function sayHello(string $given, string $surname): void
{
print "Hello {$given} {$surname}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace ProtobufAsyncMessageConsumer\Tests\MessageHandler;

use Library\Person;
use PhpPact\Consumer\MessageBuilder;
use PhpPact\Consumer\Model\Body\Text;
use PhpPact\Plugins\Protobuf\Factory\ProtobufMessageDriverFactory;
use PhpPact\Standalone\PactMessage\PactMessageConfig;
use PHPUnit\Framework\TestCase;
use ProtobufAsyncMessageConsumer\MessageHandler\PersonMessageHandler;
use ProtobufAsyncMessageConsumer\Service\SayHelloService;

class PersonMessageHandlerTest extends TestCase
{
private SayHelloService $service;
private string $given = 'Given';
private string $surname = 'Surname';

protected function setUp(): void
{
$service = $this->createMock(SayHelloService::class);
$service
->expects($this->once())
->method('sayHello')
->with($this->given, $this->surname);
$this->service = $service;
}

public function testInvoke(): void
{
$id = 'd1f077b5-0f91-40aa-b8f9-568b50ee4dd9';

$config = (new PactMessageConfig())
->setConsumer('protobufAsyncMessageConsumer')
->setProvider('protobufAsyncMessageProvider')
->setPactSpecificationVersion('4.0.0')
->setPactDir(__DIR__.'/../../../pacts');
if ($logLevel = \getenv('PACT_LOGLEVEL')) {
$config->setLogLevel($logLevel);
}

$builder = new MessageBuilder($config, new ProtobufMessageDriverFactory());

$builder
->given('A person with fixed id exists', ['id' => $id, 'reuse' => '0'])
->expectsToReceive('Person message sent')
->withContent(new Text(
json_encode([
'pact:proto' => __DIR__ . '/../../../library/proto/say_hello.proto',
'pact:message-type' => 'Person',
'pact:content-type' => 'application/protobuf',
'id' => "matching(regex, '^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$', '{$id}')",
'name' => [
'given' => "matching(type, '{$this->given}')",
'surname' => "matching(type, '{$this->surname}')"
],
]),
'application/protobuf'
));

$builder->setCallback(function (string $pactJson): void {
$message = \json_decode($pactJson);
$person = new Person();
$decoded = base64_decode($message->contents->content);
$person->mergeFromString($decoded);
$handler = new PersonMessageHandler($this->service);
$handler($person);
});

$this->assertTrue($builder->verify());
}
}
13 changes: 13 additions & 0 deletions example/protobuf-async-message/library/proto/say_hello.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

package library;

message Person {
string id = 1;
Name name = 2;
}

message Name {
string given = 1;
string surname = 2;
}
1 change: 1 addition & 0 deletions example/protobuf-async-message/library/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
"consumer": {
"name": "protobufAsyncMessageConsumer"
},
"interactions": [
{
"contents": {
"content": "CiRkMWYwNzdiNS0wZjkxLTQwYWEtYjhmOS01NjhiNTBlZTRkZDkSEAoFR2l2ZW4SB1N1cm5hbWU=",
"contentType": "application/protobuf;message=Person",
"contentTypeHint": "BINARY",
"encoded": "base64"
},
"description": "Person message sent",
"interactionMarkup": {
"markup": "```protobuf\nmessage Person {\n string id = 1;\n message .library.Name name = 2;\n}\n```\n",
"markupType": "COMMON_MARK"
},
"matchingRules": {
"body": {
"$.id": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$"
}
]
},
"$.name.given": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$.name.surname": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
}
},
"metadata": {
"contentType": "application/protobuf;message=Person"
},
"pending": false,
"pluginConfiguration": {
"protobuf": {
"descriptorKey": "f77f40284a5ed1f38188ed943aca6938",
"message": "Person"
}
},
"providerStates": [
{
"name": "A person with fixed id exists",
"params": {
"id": "d1f077b5-0f91-40aa-b8f9-568b50ee4dd9",
"reuse": 0
}
}
],
"type": "Asynchronous/Messages"
}
],
"metadata": {
"pactRust": {
"ffi": "0.4.11",
"models": "1.1.12"
},
"pactSpecification": {
"version": "4.0"
},
"plugins": [
{
"configuration": {
"f77f40284a5ed1f38188ed943aca6938": {
"protoDescriptors": "CpcBCg9zYXlfaGVsbG8ucHJvdG8SB2xpYnJhcnkiOwoGUGVyc29uEg4KAmlkGAEgASgJUgJpZBIhCgRuYW1lGAIgASgLMg0ubGlicmFyeS5OYW1lUgRuYW1lIjYKBE5hbWUSFAoFZ2l2ZW4YASABKAlSBWdpdmVuEhgKB3N1cm5hbWUYAiABKAlSB3N1cm5hbWViBnByb3RvMw==",
"protoFile": "syntax = \"proto3\";\n\npackage library;\n\nmessage Person {\n string id = 1;\n Name name = 2;\n}\n\nmessage Name {\n string given = 1;\n string surname = 2;\n}\n"
}
},
"name": "protobuf",
"version": "0.3.8"
}
]
},
"provider": {
"name": "protobufAsyncMessageProvider"
}
}
11 changes: 11 additions & 0 deletions example/protobuf-async-message/provider/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="../../../vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="PhpPact Example Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
<php>
<env name="PACT_LOGLEVEL" value="DEBUG"/>
</php>
</phpunit>
50 changes: 50 additions & 0 deletions example/protobuf-async-message/provider/public/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

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

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

$app = AppFactory::create();
$app->addBodyParsingMiddleware();

$app->post('/', function (Request $request, Response $response) {
$body = $request->getParsedBody();
if ($body['description'] === 'Person message sent') {
$person = new Person();
$person->setId('2d5554cd-22da-43ce-8842-2b42cf20661d');
$name = new Name();
$name->setGiven('Hettie');
$name->setSurname('Toy');
$person->setName($name);
$response->getBody()->write($person->serializeToString());

return $response
->withHeader('Content-Type', 'application/protobuf;message=Person')
->withHeader('Pact-Message-Metadata', \base64_encode(\json_encode([])));
}

$response->getBody()->write('Hello world!');

return $response
->withHeader('Content-Type', 'text/plain')
;
});

$app->post('/pact-change-state', function (Request $request, Response $response) {
$body = $request->getParsedBody();
$response->getBody()->write(sprintf('State changed: %s', \json_encode([
'action' => $body['action'],
'state' => $body['state'],
'params' => $body['params'],
])));

return $response
->withHeader('Content-Type', 'text/plain')
;
});

$app->run();
53 changes: 53 additions & 0 deletions example/protobuf-async-message/provider/tests/PactVerifyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace ProtobufAsyncMessageProvider\Tests;

use GuzzleHttp\Psr7\Uri;
use PhpPact\Standalone\ProviderVerifier\Model\VerifierConfig;
use PhpPact\Standalone\ProviderVerifier\Verifier;
use PhpPactTest\Helper\ProviderProcess;
use PHPUnit\Framework\TestCase;

class PactVerifyTest extends TestCase
{
private ProviderProcess $process;

/**
* Run the PHP build-in web server.
*/
protected function setUp(): void
{
$this->process = new ProviderProcess(__DIR__ . '/../public/');
$this->process->start();
}

/**
* Stop the web server process once complete.
*/
protected function tearDown(): void
{
$this->process->stop();
}

public function testPactVerifyConsumer(): void
{
$config = new VerifierConfig();
$config->getProviderInfo()
->setName('protobufAsyncMessageProvider')
->setHost('localhost')
->setPort(7202);
$config->getProviderState()
->setStateChangeUrl(new Uri("http://localhost:7202/pact-change-state"))
->setStateChangeTeardown(true)
->setStateChangeAsBody(true)
;
if ($logLevel = \getenv('PACT_LOGLEVEL')) {
$config->setLogLevel($logLevel);
}

$verifier = new Verifier($config);
$verifier->addFile(__DIR__ . '/../../pacts/protobufAsyncMessageConsumer-protobufAsyncMessageProvider.json');

$this->assertTrue($verifier->verify());
}
}
6 changes: 6 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
<testsuite name="PhpPact Protobuf Sync Message Provider Example Tests">
<directory>./example/protobuf-sync-message/provider/tests</directory>
</testsuite>
<testsuite name="PhpPact Protobuf Async Message Consumer Example Tests">
<directory>./example/protobuf-async-message/consumer/tests</directory>
</testsuite>
<testsuite name="PhpPact Protobuf Async Message Provider Example Tests">
<directory>./example/protobuf-async-message/provider/tests</directory>
</testsuite>
</testsuites>
<logging>
<junit outputFile="./test_results/reports/unit_test_results.xml"/>
Expand Down

0 comments on commit 95ed5ab

Please sign in to comment.