Skip to content
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
26 changes: 18 additions & 8 deletions src/EventServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected function registerSnsBroadcaster()
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createSnsDriver(array $config)
public function createSnsDriver(array $config)
{
$config = self::prepareConfigurationCredentials($config);

Expand Down Expand Up @@ -81,9 +81,7 @@ protected function registerEventBridgeBroadcaster()
{
$this->app->resolving(BroadcastManager::class, function (BroadcastManager $manager) {
$manager->extend('eventbridge', function (Container $app, array $config) {
return $this->createEventBridgeDriver(array_merge($config, [
'version' => '2015-10-07',
]));
return $this->createEventBridgeDriver($config);
});
});
}
Expand All @@ -94,12 +92,12 @@ protected function registerEventBridgeBroadcaster()
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createEventBridgeDriver(array $config)
public function createEventBridgeDriver(array $config)
{
$config = self::prepareConfigurationCredentials($config);

return new EventBridgeBroadcaster(
new EventBridgeClient($config),
new EventBridgeClient(array_merge($config, ['version' => '2015-10-07'])),
$config['source'] ?? ''
);
}
Expand All @@ -110,12 +108,24 @@ protected function createEventBridgeDriver(array $config)
* @param array $config
* @return array
*/
public static function prepareConfigurationCredentials(array $config)
public static function prepareConfigurationCredentials(array $config): array
{
if (Arr::has($config, ['key', 'secret'])) {
if (static::configHasCredentials($config)) {
$config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
}

return $config;
}

/**
* Make sure some AWS credentials were provided to the configuration array.
*
* @return bool
*/
private static function configHasCredentials(array $config): bool
{
return Arr::has($config, ['key', 'secret'])
&& is_string(Arr::get($config, 'key'))
&& is_string(Arr::get($config, 'secret'));
}
}
21 changes: 15 additions & 6 deletions tests/Console/ListenerMakeCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace PodPoint\AwsPubSub\Tests\Console;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Str;
use PodPoint\AwsPubSub\Tests\TestCase;

class ListenerMakeCommandTest extends TestCase
Expand All @@ -25,20 +27,27 @@ public function it_can_generate_pubsub_event_listeners()
{
$this->assertFileDoesNotExist(app_path('Listeners/PubSub/SomeListener.php'));

$this->artisan('pubsub:make:listener SomeListener')
->expectsOutput('Listener created successfully.');
$exitCode = $this->withoutMockingConsoleOutput()
->artisan('pubsub:make:listener SomeListener');

$this->assertEquals(0, $exitCode);
Str::contains(Artisan::output(), 'created successfully');
$this->assertFileExists(app_path('Listeners/PubSub/SomeListener.php'));
}

/** @test */
public function it_cannot_generate_pubsub_event_listeners_which_already_exist()
{
$this->artisan('pubsub:make:listener SomeListener')
->expectsOutput('Listener created successfully.');
$this->assertFileDoesNotExist(app_path('Listeners/PubSub/SomeListener.php'));
$this->artisan('pubsub:make:listener SomeListener')->assertSuccessful();
$this->assertFileExists(app_path('Listeners/PubSub/SomeListener.php'));

$this->artisan('pubsub:make:listener SomeListener')
->expectsOutput('Listener already exists!');
$exitCode = $this->withoutMockingConsoleOutput()
->artisan('pubsub:make:listener SomeListener');

$this->assertEquals(0, $exitCode);
Str::contains(Artisan::output(), 'already exists');
$this->assertFileExists(app_path('Listeners/PubSub/SomeListener.php'));
}

private function cleanup()
Expand Down
80 changes: 39 additions & 41 deletions tests/Pub/BasicEvents/EventBridgeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

namespace PodPoint\AwsPubSub\Tests\Pub\BasicEvents;

use Illuminate\Foundation\Application;
use Mockery;
use Mockery as m;
use Mockery\MockInterface;
use PodPoint\AwsPubSub\Tests\Pub\Concerns\InteractsWithEventBridge;
use PodPoint\AwsPubSub\Tests\Pub\TestClasses\Events\UserRetrieved;
Expand All @@ -17,28 +16,16 @@ class EventBridgeTest extends TestCase
{
use InteractsWithEventBridge;

/**
* @param Application $app
*/
protected function getEnvironmentSetUp($app)
{
$this->setEventBridgeBroadcaster($app);

$this->setTestDatabase($app);
}

/** @test */
public function it_broadcasts_basic_event_with_the_event_name_as_the_detail_type_and_serialised_event_as_the_detail()
{
$jane = $this->createJane();

$janeRetrieved = new UserRetrieved($jane);
$janeRetrieved = new UserRetrieved($this->createJane());

$this->mockEventBridge(function (MockInterface $eventBridge) use ($janeRetrieved) {
$eventBridge
->shouldReceive('putEvents')
->once()
->with(Mockery::on(function ($arg) use ($janeRetrieved) {
->with(m::on(function ($arg) use ($janeRetrieved) {
return $arg['Entries'][0]['Detail'] === json_encode($janeRetrieved)
&& $arg['Entries'][0]['DetailType'] === UserRetrieved::class
&& $arg['Entries'][0]['EventBusName'] === 'users'
Expand All @@ -52,19 +39,15 @@ public function it_broadcasts_basic_event_with_the_event_name_as_the_detail_type
/** @test */
public function it_broadcasts_basic_event_with_action()
{
$jane = $this->createJane();

$janeRetrieved = new UserRetrievedWithCustomName($jane);
$janeRetrieved = new UserRetrievedWithCustomName($this->createJane());

$this->mockEventBridge(function (MockInterface $eventBridge) use ($janeRetrieved) {
$eventBridge
->shouldReceive('putEvents')
->once()
->with(Mockery::on(function ($arg) use ($janeRetrieved) {
->with(m::on(function ($arg) use ($janeRetrieved) {
return $arg['Entries'][0]['Detail'] === json_encode($janeRetrieved)
&& $arg['Entries'][0]['DetailType'] === 'user.retrieved'
&& $arg['Entries'][0]['EventBusName'] === 'users'
&& $arg['Entries'][0]['Source'] === 'my-app';
&& $arg['Entries'][0]['DetailType'] === 'user.retrieved';
}));
});

Expand All @@ -74,21 +57,18 @@ public function it_broadcasts_basic_event_with_action()
/** @test */
public function it_broadcasts_basic_event_with_action_and_custom_payload()
{
$jane = $this->createJane();

$janeRetrieved = new UserRetrievedWithCustomPayload($jane);
$janeRetrieved = new UserRetrievedWithCustomPayload($this->createJane());

$this->mockEventBridge(function (MockInterface $eventBridge) use ($janeRetrieved) {
$eventBridge
->shouldReceive('putEvents')
->once()
->with(Mockery::on(function ($arg) use ($janeRetrieved) {
->with(m::on(function ($arg) use ($janeRetrieved) {
$customPayload = array_merge($janeRetrieved->broadcastWith(), ['socket' => null]);

return $arg['Entries'][0]['Detail'] === json_encode($customPayload)
&& $arg['Entries'][0]['DetailType'] === UserRetrievedWithCustomPayload::class
&& $arg['Entries'][0]['EventBusName'] === 'users'
&& $arg['Entries'][0]['Source'] === 'my-app';
&& $arg['Entries'][0]['EventBusName'] === 'users';
}));
});

Expand All @@ -98,37 +78,55 @@ public function it_broadcasts_basic_event_with_action_and_custom_payload()
/** @test */
public function it_broadcasts_basic_event_to_multiple_channels_as_buses()
{
$jane = $this->createJane();

$janeRetrieved = new UserRetrievedWithMultipleChannels($jane);
$janeRetrieved = new UserRetrievedWithMultipleChannels($this->createJane());

$this->mockEventBridge(function (MockInterface $eventBridge) use ($janeRetrieved) {
$eventBridge
->shouldReceive('putEvents')
->once()
->with(Mockery::on(function ($arg) use ($janeRetrieved) {
->with(m::on(function ($arg) use ($janeRetrieved) {
return collect($janeRetrieved->broadcastOn())
->map(function ($channel, $key) use ($arg, $janeRetrieved) {
return $arg['Entries'][$key]['Detail'] === json_encode($janeRetrieved)
&& $arg['Entries'][$key]['DetailType'] === UserRetrievedWithMultipleChannels::class
&& $arg['Entries'][$key]['EventBusName'] === $channel
&& $arg['Entries'][$key]['Source'] === 'my-app';
&& $arg['Entries'][$key]['EventBusName'] === $channel;
})
->filter()
->count() > 0;
->count() === 2;
}));
});

event($janeRetrieved);
}

/** @test */
public function it_can_use_a_source()
{
config(['broadcasting.connections.eventbridge.source' => 'some-other-source']);

$janeRetrieved = new UserRetrievedWithMultipleChannels($this->createJane());

$this->mockEventBridge(function (MockInterface $eventBridge) use ($janeRetrieved) {
$eventBridge
->shouldReceive('putEvents')
->once()
->with(m::on(function ($arg) use ($janeRetrieved) {
return collect($janeRetrieved->broadcastOn())
->map(function ($channel, $key) use ($arg) {
return $arg['Entries'][$key]['Source'] === 'some-other-source';
})
->filter()
->count() > 0;
}));
});

event($janeRetrieved);
}

/**
* @return User
*/
protected function createJane()
protected function createJane(): User
{
return User::create([
'name' => 'Jane',
'name' => 'Jane Doe',
'email' => 'jane@doe.com',
'password' => 'shh',
])->fresh();
Expand Down
29 changes: 26 additions & 3 deletions tests/Pub/BasicEvents/SnsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ public function it_broadcasts_basic_event()
->with(m::on(function ($argument) {
$message = json_decode($argument['Message'], true);

return $message['user']['email'] === 'john@doe.com'
return $message['user']['name'] === 'John Doe'
&& $message['user']['email'] === 'john@doe.com'
&& $message['user']['password'] === 'secret'
&& $message['foo'] = 'bar';
}));
});

event(new UserRetrieved(User::create([
'name' => $this->faker->name(),
'name' => 'John Doe',
'email' => 'john@doe.com',
'password' => $this->faker->password(),
'password' => 'secret',
])));
}

Expand Down Expand Up @@ -144,4 +146,25 @@ public function it_broadcasts_basic_event_name_as_subject_if_specified()
'password' => $this->faker->password(),
])));
}

/** @test */
public function it_can_use_an_arn_prefix_and_suffix()
{
config(['broadcasting.connections.sns.arn-prefix' => 'some-prefix:']);
config(['broadcasting.connections.sns.arn-suffix' => '-some-suffix']);

$this->mockSns(function (MockInterface $sns) {
$sns->shouldReceive('publish')
->once()
->with(m::on(function ($argument) {
return $argument['TopicArn'] === 'some-prefix:users-some-suffix';
}));
});

event(new UserRetrieved(User::create([
'name' => $this->faker->name(),
'email' => $this->faker->email(),
'password' => $this->faker->password(),
])));
}
}
53 changes: 53 additions & 0 deletions tests/Pub/Broadcasting/Broadcasters/EventBridgeBroadcasterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace PodPoint\AwsPubSub\Tests\Pub\Broadcasting\Broadcasters;

use PodPoint\AwsPubSub\EventServiceProvider;
use PodPoint\AwsPubSub\Pub\Broadcasting\Broadcasters\EventBridgeBroadcaster;
use PodPoint\AwsPubSub\Tests\TestCase;

class EventBridgeBroadcasterTest extends TestCase
{
/** @test */
public function it_can_instantiate_the_broadcaster()
{
$broadcaster = (new EventServiceProvider($this->app))->createEventBridgeDriver([
'driver' => 'eventbridge',
'key' => 'dummy-key',
'secret' => 'dummy-secret',
'region' => 'eu-west-1',
'event_bus' => 'default',
'source' => 'my-app',
]);

$this->assertInstanceOf(EventBridgeBroadcaster::class, $broadcaster);
}

/** @test */
public function it_supports_optional_aws_credentials()
{
$broadcaster = (new EventServiceProvider($this->app))->createEventBridgeDriver([
'driver' => 'eventbridge',
'region' => 'eu-west-1',
'event_bus' => 'default',
'source' => 'my-app',
]);

$this->assertInstanceOf(EventBridgeBroadcaster::class, $broadcaster);
}

/** @test */
public function it_supports_null_aws_credentials()
{
$broadcaster = (new EventServiceProvider($this->app))->createEventBridgeDriver([
'driver' => 'eventbridge',
'key' => null,
'secret' => null,
'region' => 'eu-west-1',
'event_bus' => 'default',
'source' => 'my-app',
]);

$this->assertInstanceOf(EventBridgeBroadcaster::class, $broadcaster);
}
}
Loading