Skip to content

Commit

Permalink
Create topic and subscription if not exists with configurable options (
Browse files Browse the repository at this point in the history
…#16)

* Create topic and subscription if not exists with configurable options

* Create topic and subscription if not exists with configurable options

* Replace phpstan with psalm

* Replace PHPCS fixer with ECS

Co-authored-by: Ronald Marfoldi <ronald.marfoldi@petitpress.sk>
  • Loading branch information
marforon and Ronald Marfoldi authored Aug 26, 2022
1 parent 7fe3d1f commit c096aa1
Show file tree
Hide file tree
Showing 23 changed files with 503 additions and 183 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ jobs:
with:
php-version: '7.4'

- name: Validate composer.json and composer.lock
- name: Validate composer.json
run: composer validate

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }}
restore-keys: |
${{ runner.os }}-php-
Expand All @@ -31,10 +31,10 @@ jobs:
run: composer install --prefer-dist --no-progress --no-suggest

- name: Run style tests
run: vendor/bin/php-cs-fixer fix --dry-run -v --diff
run: vendor/bin/ecs check -vv

- name: Run static analyse tests
run: vendor/bin/phpstan analyse Tests Transport --level=5
run: vendor/bin/psalm

- name: Run unit tests
run: vendor/bin/phpunit
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea
.phpunit.result.cache
/vendor/
composer.lock
.php-cs-fixer.cache
66 changes: 0 additions & 66 deletions .php-cs-fixer.dist.php

This file was deleted.

12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,18 @@ framework:
max_messages_pull: 10 # optional (default: 10)
topic: # optional (default name: messages)
name: 'messages'
queue: # optional (default the same as topic.name)
options: # optional create options if not exists (default: []), for all options take at look at https://googleapis.github.io/google-cloud-php/#/docs/google-cloud/v0.188.0/pubsub/topic?method=create
labels:
- label1
- label2
subscription: # optional (default the same as topic.name)
name: 'messages'
options: # optional create options if not exists (default: []), fol all options take a look at https://googleapis.github.io/google-cloud-php/#/docs/google-cloud/v0.188.0/pubsub/subscription?method=create
enableExactlyOnceDelivery: true
labels:
- label1
- label2

```
or:
```yaml
Expand Down
8 changes: 5 additions & 3 deletions Tests/Transport/EnvelopeFactory.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php declare(strict_types=1);
<?php

declare(strict_types=1);

namespace PetitPress\GpsMessengerBundle\Tests\Transport;

Expand All @@ -10,8 +12,8 @@
*/
class EnvelopeFactory
{
public static function create(?StampInterface ...$stamps): Envelope
public static function create(StampInterface ...$stamps): Envelope
{
return new Envelope(new \stdClass(), $stamps ?: []);
return new Envelope(new \stdClass(), $stamps);
}
}
147 changes: 147 additions & 0 deletions Tests/Transport/GpsConfigurationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php

declare(strict_types=1);

namespace PetitPress\GpsMessengerBundle\Tests\Transport;

use PetitPress\GpsMessengerBundle\Transport\GpsConfiguration;
use PetitPress\GpsMessengerBundle\Transport\GpsConfigurationInterface;
use PetitPress\GpsMessengerBundle\Transport\GpsConfigurationResolver;
use PetitPress\GpsMessengerBundle\Transport\GpsConfigurationResolverInterface;
use PHPUnit\Framework\TestCase;

/**
* @author Ronald Marfoldi <ronald.marfoldi@petitpress.sk>
*/
final class GpsConfigurationTest extends TestCase
{
private GpsConfigurationResolver $gpsConfigurationResolver;

protected function setUp(): void
{
$this->gpsConfigurationResolver = new GpsConfigurationResolver();
}

/**
* @dataProvider dataProvider
*/
public function testResolve(string $dsn, array $options, GpsConfigurationInterface $expectedConfiguration): void
{
$configuration = $this->gpsConfigurationResolver->resolve($dsn, $options);
$this->assertEquals($expectedConfiguration, $configuration);
}

public function dataProvider(): array
{
return [
'Empty default' => [
'dsn' => 'gps://default',
'options' => [],
'expectedConfiguration' => new GpsConfiguration(
GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME,
GpsConfigurationResolverInterface::DEFAULT_TOPIC_NAME,
GpsConfigurationResolverInterface::DEFAULT_MAX_MESSAGES_PULL,
[],
[],
[]
),
],
'Custom topic/subscription name configured through dsn #1' => [
'dsn' => 'gps://default/something',
'options' => [],
'expectedConfiguration' => new GpsConfiguration(
'something',
'something',
GpsConfigurationResolverInterface::DEFAULT_MAX_MESSAGES_PULL,
[],
[],
[]
),
],
'Custom topic/subscription name configured through dsn #2 (deprecated queue[name])' => [
'dsn' => 'gps://default?topic[name]=topic_name&queue[name]=subscription_name',
'options' => [],
'expectedConfiguration' => new GpsConfiguration(
'topic_name',
'subscription_name',
GpsConfigurationResolverInterface::DEFAULT_MAX_MESSAGES_PULL,
[],
[],
[]
),
],
'Custom topic/subscription name configured through dsn #3' => [
'dsn' => 'gps://default?topic[name]=topic_name&topic[options][labels][]=label_topic1&subscription[name]=subscription_name&subscription[options][labels][]=label_subscription1&subscription[options][enableMessageOrdering]=1&subscription[options][ackDeadlineSeconds]=100&max_messages_pull=5&client_config[apiEndpoint]=https://europe-west3-pubsub.googleapis.com',
'options' => [],
'expectedConfiguration' => new GpsConfiguration(
'topic_name',
'subscription_name',
5,
['apiEndpoint' => 'https://europe-west3-pubsub.googleapis.com'],
['labels' => ['label_topic1']],
['labels' => ['label_subscription1'], 'enableMessageOrdering' => true, 'ackDeadlineSeconds' => 100],
),
],
'Custom topic/subscription name configured through options #1' => [
'dsn' => 'gps://default',
'options' => [
'topic' => ['name' => 'something'],
],
'expectedConfiguration' => new GpsConfiguration(
'something',
'something',
GpsConfigurationResolverInterface::DEFAULT_MAX_MESSAGES_PULL,
[],
[],
[]
),
],
'Custom topic/subscription name configured through options #2' => [
'dsn' => 'gps://default',
'options' => [
'topic' => ['name' => 'topic_name'],
'subscription' => ['name' => 'subscription_name'],
],
'expectedConfiguration' => new GpsConfiguration(
'topic_name',
'subscription_name',
GpsConfigurationResolverInterface::DEFAULT_MAX_MESSAGES_PULL,
[],
[],
[]
),
],
'Custom topic/subscription name configured through options #4' => [
'dsn' => 'gps://default',
'options' => [
'topic' => [
'name' => 'topic_name1',
'options' => [
'labels' => ['label_topic1'],
],
],
'subscription' => [
'name' => 'subscription_name',
'options' => [
'labels' => ['label_subscription1'],
'enableMessageOrdering' => true,
'ackDeadlineSeconds' => 100,
],
],
'client_config' => [
'apiEndpoint' => 'https://europe-west3-pubsub.googleapis.com',
],
'max_messages_pull' => 5,
],
'expectedConfiguration' => new GpsConfiguration(
'topic_name1',
'subscription_name',
5,
['apiEndpoint' => 'https://europe-west3-pubsub.googleapis.com'],
['labels' => ['label_topic1']],
['labels' => ['label_subscription1'], 'enableMessageOrdering' => true, 'ackDeadlineSeconds' => 100],
),
],
];
}
}
65 changes: 45 additions & 20 deletions Tests/Transport/GpsReceiverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,77 @@
use PetitPress\GpsMessengerBundle\Transport\GpsConfigurationInterface;
use PetitPress\GpsMessengerBundle\Transport\GpsReceiver;
use PetitPress\GpsMessengerBundle\Transport\Stamp\GpsReceivedStamp;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\Messenger\Exception\TransportException;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;

/**
* @author Mickael Prévôt <mickael.prevot@ext.adeo.com>
* @author Ronald Marfoldi <ronald.marfoldi@petitpress.sk>
*/
class GpsReceiverTest extends TestCase
{
use ProphecyTrait;

private const SUBSCRIPTION_NAME = 'subscription-name';

private ObjectProphecy $gpsConfigurationProphecy;
/**
* @var GpsConfigurationInterface&MockObject
*/
private MockObject $gpsConfigurationMock;

/**
* @var PubSubClient&MockObject
*/
private MockObject $pubSubClientMock;

/**
* @var Subscription&MockObject
*/
private MockObject $subscriptionMock;

private GpsReceiver $gpsReceiver;
private ObjectProphecy $pubSubClientProphecy;
private ObjectProphecy $serializerProphecy;
private ObjectProphecy $subscriptionProphecy;

protected function setUp(): void
{
$this->gpsConfigurationProphecy = $this->prophesize(GpsConfigurationInterface::class);
$this->pubSubClientProphecy = $this->prophesize(PubSubClient::class);
$this->serializerProphecy = $this->prophesize(SerializerInterface::class);
$this->subscriptionProphecy = $this->prophesize(Subscription::class);
$this->gpsConfigurationMock = $this->createMock(GpsConfigurationInterface::class);
$this->pubSubClientMock = $this->createMock(PubSubClient::class);
$this->subscriptionMock = $this->createMock(Subscription::class);
/** @var SerializerInterface&MockObject $serializerMock */
$serializerMock = $this->createMock(SerializerInterface::class);

$this->gpsReceiver = new GpsReceiver(
$this->pubSubClientProphecy->reveal(),
$this->gpsConfigurationProphecy->reveal(),
$this->serializerProphecy->reveal(),
$this->pubSubClientMock,
$this->gpsConfigurationMock,
$serializerMock,
);
}

public function testItRejects(): void
{
$gpsMessage = $this->prophesize(Message::class);
$gpsMessage = new Message(['data' => '']);

$this->gpsConfigurationProphecy->getSubscriptionName()->willReturn(self::SUBSCRIPTION_NAME)->shouldBeCalledOnce();
$this->gpsConfigurationMock
->expects($this->once())
->method('getSubscriptionName')
->willReturn(self::SUBSCRIPTION_NAME)
;

$this->subscriptionProphecy->modifyAckDeadline($gpsMessage->reveal(), 0)->shouldBeCalledOnce();
$this->subscriptionMock
->expects($this->once())
->method('modifyAckDeadline')
->with($gpsMessage, 0)
;

$this->pubSubClientProphecy->subscription(self::SUBSCRIPTION_NAME)->willReturn($this->subscriptionProphecy->reveal())->shouldBeCalledOnce();
$this->pubSubClientMock
->expects($this->once())
->method('subscription')
->with(self::SUBSCRIPTION_NAME)
->willReturn($this->subscriptionMock)
;

$this->gpsReceiver->reject(EnvelopeFactory::create(new GpsReceivedStamp($gpsMessage->reveal())));
$this->gpsReceiver->reject(
EnvelopeFactory::create(new GpsReceivedStamp($gpsMessage))
);
}

public function testItThrowsAnExceptionInsteadOfRejecting(): void
Expand Down
Loading

0 comments on commit c096aa1

Please sign in to comment.