diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index dfd2056..956ede9 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -14,12 +14,9 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: [8.1, 8.2] - laravel: ['9.*', '10.*', '11.*'] + php: [8.2, 8.3, 8.4] + laravel: ['11.*', '12.*'] dependency-version: [prefer-lowest, prefer-stable] - exclude: - - laravel: 11.* - php: 8.1 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} diff --git a/composer.json b/composer.json index a218c9e..d27ef2d 100644 --- a/composer.json +++ b/composer.json @@ -12,15 +12,16 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.2", "aws/aws-sdk-php": "^3.69.11", "guzzlehttp/guzzle": "^6.2.1 || ^7.0", - "illuminate/notifications": "^9.0|^10.0 || ^11.0", - "illuminate/support": "^9.0|^10.0 || ^11.0" + "illuminate/notifications": "^11.0||^12.0", + "illuminate/support": "^11.0||^12.0" }, "require-dev": { - "mockery/mockery": "^1.5.1", - "phpunit/phpunit": "^9.5.10 || ^10.5" + "laravel/pint": "^1.20", + "mockery/mockery": "^1.6", + "phpunit/phpunit": "^11.0" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 06d6943..8c49f8d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,29 +1,15 @@ - + stopOnError="false" + stopOnFailure="false" +> - - tests + + ./tests - - - src/ - - - - - - - - - \ No newline at end of file diff --git a/src/Sns.php b/src/Sns.php index 4605ba2..93391b0 100644 --- a/src/Sns.php +++ b/src/Sns.php @@ -2,28 +2,25 @@ namespace NotificationChannels\AwsSns; -use Aws\Exception\AwsException; -use Aws\Sns\SnsClient as SnsService; +use Aws\Result; +use Aws\Sns\SnsClient; class Sns { /** - * @var SnsService + * Create a new instance of the class. */ - protected $snsService; - - public function __construct(SnsService $snsService) + public function __construct(protected SnsClient $sns) { - $this->snsService = $snsService; + // } /** - * @param string $destination Phone number as described by the E.164 format. - * @return \Aws\Result + * Send the message to the given E.164 destination phone number. * - * @throws AwsException + * @throws Aws\Exception\AwsException */ - public function send(SnsMessage $message, $destination) + public function send(SnsMessage $message, string $destination): Result { $attributes = [ 'AWS.SNS.SMS.SMSType' => [ @@ -56,6 +53,6 @@ public function send(SnsMessage $message, $destination) 'MessageAttributes' => $attributes, ]; - return $this->snsService->publish($parameters); + return $this->sns->publish($parameters); } } diff --git a/src/SnsChannel.php b/src/SnsChannel.php index b191589..5b6babb 100644 --- a/src/SnsChannel.php +++ b/src/SnsChannel.php @@ -2,6 +2,8 @@ namespace NotificationChannels\AwsSns; +use Aws\Result; +use Exception; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Notifications\Events\NotificationFailed; use Illuminate\Notifications\Notification; @@ -9,42 +11,30 @@ class SnsChannel { - /** - * @var Sns - */ - protected $sns; - - /** - * @var Dispatcher - */ - protected $events; - - public function __construct(Sns $sns, Dispatcher $events) + public function __construct(protected Sns $sns, protected Dispatcher $events) { - $this->sns = $sns; - $this->events = $events; + // } /** * Send the given notification. - * - * @return \Aws\Result */ - public function send($notifiable, Notification $notification) + public function send($notifiable, Notification $notification): ?Result { try { $destination = $this->getDestination($notifiable, $notification); $message = $this->getMessage($notifiable, $notification); return $this->sns->send($message, $destination); - } catch (\Exception $e) { - $event = new NotificationFailed( + } catch (Exception $e) { + $this->events->dispatch(new NotificationFailed( $notifiable, $notification, 'sns', ['message' => $e->getMessage(), 'exception' => $e] - ); - $this->events->dispatch($event); + )); + + return null; } } diff --git a/src/SnsServiceProvider.php b/src/SnsServiceProvider.php index af69cdb..5e18d97 100644 --- a/src/SnsServiceProvider.php +++ b/src/SnsServiceProvider.php @@ -13,11 +13,9 @@ class SnsServiceProvider extends ServiceProvider */ public function boot() { - $this->app->when(SnsChannel::class) - ->needs(Sns::class) - ->give(function () { - return new Sns($this->app->make(SnsService::class)); - }); + $this->app->bind(Sns::class, function () { + return new Sns($this->app->make(SnsService::class)); + }); $this->app->bind(SnsService::class, function () { $config = array_merge(['version' => 'latest'], $this->app['config']['services.sns']); diff --git a/tests/SnsChannelTest.php b/tests/SnsChannelTest.php index 79d1d35..22feb1a 100644 --- a/tests/SnsChannelTest.php +++ b/tests/SnsChannelTest.php @@ -10,12 +10,9 @@ use NotificationChannels\AwsSns\Sns; use NotificationChannels\AwsSns\SnsChannel; use NotificationChannels\AwsSns\SnsMessage; -use PHPUnit\Framework\TestCase; class SnsChannelTest extends TestCase { - use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; - /** * @var Mockery\LegacyMockInterface|Mockery\MockInterface|Sns */ @@ -40,14 +37,14 @@ protected function setUp(): void $this->channel = new SnsChannel($this->sns, $this->dispatcher); } - /** @test */ - public function it_will_not_send_a_message_without_known_receiver() + public function test_it_will_not_send_a_message_without_known_receiver() { - $notifiable = new Notifiable(); + $notifiable = new Notifiable; $notification = Mockery::mock(Notification::class); $this->dispatcher->shouldReceive('dispatch') - ->atLeast()->once() + ->atLeast() + ->once() ->with(Mockery::type(NotificationFailed::class)); $result = $this->channel->send($notifiable, $notification); @@ -55,10 +52,9 @@ public function it_will_not_send_a_message_without_known_receiver() $this->assertNull($result); } - /** @test */ - public function it_will_send_a_sms_message_to_the_result_of_the_route_method_of_the_notifiable() + public function test_it_will_send_a_sms_message_to_the_result_of_the_route_method_of_the_notifiable() { - $notifiable = new NotifiableWithMethod(); + $notifiable = new NotifiableWithMethod; $message = new SnsMessage('Message text'); $notification = Mockery::mock(Notification::class); @@ -71,10 +67,9 @@ public function it_will_send_a_sms_message_to_the_result_of_the_route_method_of_ $this->channel->send($notifiable, $notification); } - /** @test */ - public function it_will_make_a_call_to_the_phone_number_attribute_of_the_notifiable() + public function test_it_will_make_a_call_to_the_phone_number_attribute_of_the_notifiable() { - $notifiable = new NotifiableWithAttribute(); + $notifiable = new NotifiableWithAttribute; $message = new SnsMessage('Some content to send'); $notification = Mockery::mock(Notification::class); @@ -87,10 +82,9 @@ public function it_will_make_a_call_to_the_phone_number_attribute_of_the_notifia $this->channel->send($notifiable, $notification); } - /** @test */ - public function it_will_convert_a_string_to_a_sms_message() + public function test_it_will_convert_a_string_to_a_sms_message() { - $notifiable = new NotifiableWithAttribute(); + $notifiable = new NotifiableWithAttribute; $notification = Mockery::mock(Notification::class); $notification->shouldReceive('toSns')->andReturn('Message text'); @@ -102,10 +96,9 @@ public function it_will_convert_a_string_to_a_sms_message() $this->channel->send($notifiable, $notification); } - /** @test */ - public function it_will_dispatch_an_event_in_case_of_an_invalid_message() + public function test_it_will_dispatch_an_event_in_case_of_an_invalid_message() { - $notifiable = new NotifiableWithAttribute(); + $notifiable = new NotifiableWithAttribute; $notification = Mockery::mock(Notification::class); $notification->shouldReceive('toSns')->andReturn(-1); @@ -117,8 +110,7 @@ public function it_will_dispatch_an_event_in_case_of_an_invalid_message() $this->channel->send($notifiable, $notification); } - /** @test */ - public function it_will_send_a_sms_to_an_anonymous_notifiable() + public function test_it_will_send_a_sms_to_an_anonymous_notifiable() { $notification = Mockery::mock(Notification::class); $notification->shouldReceive('toSns')->andReturn('Message text'); @@ -140,6 +132,7 @@ class Notifiable public function routeNotificationFor() { + // } } @@ -157,5 +150,6 @@ class NotifiableWithAttribute public function routeNotificationFor() { + // } } diff --git a/tests/SnsMessageTest.php b/tests/SnsMessageTest.php index 77e70c2..28acb50 100644 --- a/tests/SnsMessageTest.php +++ b/tests/SnsMessageTest.php @@ -2,37 +2,29 @@ namespace NotificationChannels\AwsSns\Test; -use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use NotificationChannels\AwsSns\SnsMessage; -use PHPUnit\Framework\TestCase; class SnsMessageTest extends TestCase { - use MockeryPHPUnitIntegration; - - /** @test */ - public function it_can_accept_a_plain_string_when_constructing_a_message() + public function test_it_can_accept_a_plain_string_when_constructing_a_message() { $message = new SnsMessage('Do not touch my booty'); $this->assertEquals('Do not touch my booty', $message->getBody()); } - /** @test */ - public function it_can_accept_some_initial_content_when_constructing_a_message() + public function test_it_can_accept_some_initial_content_when_constructing_a_message() { $message = new SnsMessage(['body' => 'My message body']); $this->assertEquals('My message body', $message->getBody()); } - /** @test */ - public function it_provides_a_create_method() + public function test_it_provides_a_create_method() { $message = SnsMessage::create(['body' => 'My body from create']); $this->assertEquals('My body from create', $message->getBody()); } - /** @test */ - public function the_body_content_can_be_set_using_a_proper_method() + public function test_the_body_content_can_be_set_using_a_proper_method() { $message = SnsMessage::create(); $this->assertEmpty($message->getBody()); @@ -40,43 +32,37 @@ public function the_body_content_can_be_set_using_a_proper_method() $this->assertEquals('The brand new body', $message->getBody()); } - /** @test */ - public function the_default_sms_delivery_type_is_promotional() + public function test_the_default_sms_delivery_type_is_promotional() { $message = SnsMessage::create(); $this->assertEquals('Promotional', $message->getDeliveryType()); } - /** @test */ - public function the_sms_delivery_type_can_be_changed_using_a_proper_method() + public function test_the_sms_delivery_type_can_be_changed_using_a_proper_method() { $message = SnsMessage::create()->transactional(); $this->assertEquals('Transactional', $message->getDeliveryType()); } - /** @test */ - public function the_sms_delivery_type_can_be_explicitly_as_promotional() + public function test_the_sms_delivery_type_can_be_explicitly_as_promotional() { $message = SnsMessage::create()->promotional(); $this->assertEquals('Promotional', $message->getDeliveryType()); } - /** @test */ - public function the_default_sms_sender_id_is_empty() + public function test_the_default_sms_sender_id_is_empty() { $message = SnsMessage::create(); $this->assertEmpty($message->getSender()); } - /** @test */ - public function the_sms_sender_id_can_be_changed_using_a_proper_method() + public function test_the_sms_sender_id_can_be_changed_using_a_proper_method() { $message = SnsMessage::create()->sender('Test'); $this->assertEquals('Test', $message->getSender()); } - /** @test */ - public function it_can_accept_all_the_contents_when_constructing_a_message() + public function test_it_can_accept_all_the_contents_when_constructing_a_message() { $message = SnsMessage::create([ 'body' => 'My mass body', @@ -88,8 +74,7 @@ public function it_can_accept_all_the_contents_when_constructing_a_message() $this->assertEquals('Test', $message->getSender()); } - /** @test */ - public function it_can_send_sms_message_with_origination_number() + public function test_it_can_send_sms_message_with_origination_number() { $originationNumber = '+13347814073'; $message = SnsMessage::create([ diff --git a/tests/SnsServiceProviderTest.php b/tests/SnsServiceProviderTest.php deleted file mode 100644 index 89d64c3..0000000 --- a/tests/SnsServiceProviderTest.php +++ /dev/null @@ -1,140 +0,0 @@ -app = Mockery::mock(App::class); - $this->provider = new SnsServiceProvider($this->app); - } - - /** @test */ - public function it_gives_an_instantiated_sns_object_when_the_channel_asks_for_it() - { - $configArray = [ - 'key' => 'aws-key-123', - 'secret' => 'aws-secret-ashd1i26312873asw', - 'region' => 'us-east-1', - 'version' => 'latest', - ]; - - $this->app->shouldReceive('offsetGet') - ->with('config') - ->andReturn([ - 'services.sns' => $configArray, - ]); - - $this->app->shouldReceive('make') - ->with(SnsService::class) - ->andReturn(Mockery::mock(SnsService::class)); - - $this->app->shouldReceive('when') - ->with(SnsChannel::class) - ->once() - ->andReturn($this->app); - - $this->app->shouldReceive('needs') - ->with(Sns::class) - ->once() - ->andReturn($this->app); - - $this->app->shouldReceive('give') - ->with(Mockery::on(function ($sns) { - return $sns() instanceof Sns; - })) - ->once(); - - $this->app->shouldReceive('bind') - ->with(SnsService::class, Mockery::on(function ($sns) { - return $sns() instanceof SnsService; - })) - ->once() - ->andReturn($this->app); - - $this->provider->boot(); - } - - /** @test */ - public function it_creates_the_aws_credentials_from_the_key_and_secret_options() - { - $this->app->shouldReceive('when') - ->with(SnsChannel::class) - ->once() - ->andReturn($this->app); - - $this->app->shouldReceive('needs') - ->with(Sns::class) - ->once() - ->andReturn($this->app); - - $this->app->shouldReceive('give') - ->with(Mockery::on(function ($sns) { - return $sns() instanceof Sns; - })) - ->once(); - - $this->app->shouldReceive('make') - ->with(SnsService::class) - ->andReturn(Mockery::mock(SnsService::class)); - - $this->app->shouldReceive('bind') - ->with(SnsService::class, Mockery::on(function ($sns) { - /** @var SnsClient $snsClient */ - $snsClient = $sns(); - $credentials = $snsClient->getCredentials()->wait(); - $this->assertSame([ - 'key' => 'aws-key-123', - 'secret' => 'aws-secret-ashd1i26312873asw', - 'token' => null, - 'expires' => null, - ], $credentials->toArray()); - - return true; - })) - ->once() - ->andReturn($this->app); - - $configArray = [ - 'key' => 'aws-key-123', - 'secret' => 'aws-secret-ashd1i26312873asw', - 'region' => 'us-east-1', - ]; - - $this->app->shouldReceive('offsetGet') - ->with('config') - ->andReturn([ - 'services.sns' => $configArray, - ]); - - $this->provider->boot(); - } -} - -interface App extends Application, \ArrayAccess -{ -} diff --git a/tests/SnsTest.php b/tests/SnsTest.php index aadd4e5..814afa0 100644 --- a/tests/SnsTest.php +++ b/tests/SnsTest.php @@ -2,17 +2,15 @@ namespace NotificationChannels\AwsSns\Test; +use Aws\Result; use Aws\Sns\SnsClient as SnsService; use Illuminate\Contracts\Events\Dispatcher; use Mockery; use NotificationChannels\AwsSns\Sns; use NotificationChannels\AwsSns\SnsMessage; -use PHPUnit\Framework\TestCase; class SnsTest extends TestCase { - use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; - /** * @var Mockery\LegacyMockInterface|Mockery\MockInterface|SnsService */ @@ -38,13 +36,13 @@ protected function setUp(): void $this->sns = new Sns($this->snsService); } - /** @test */ - public function it_can_send_a_promotional_sms_message_to_sns() + public function test_it_can_send_a_promotional_sms_message_to_sns() { $message = new SnsMessage('Message text'); $this->snsService->shouldReceive('publish') - ->atLeast()->once() + ->atLeast() + ->once() ->with([ 'Message' => 'Message text', 'PhoneNumber' => '+1111111111', @@ -55,18 +53,18 @@ public function it_can_send_a_promotional_sms_message_to_sns() ], ], ]) - ->andReturn(true); + ->andReturn(new Result); $this->sns->send($message, '+1111111111'); } - /** @test */ - public function it_can_send_a_transactional_sms_message_to_sns() + public function test_it_can_send_a_transactional_sms_message_to_sns() { $message = new SnsMessage(['body' => 'Message text', 'transactional' => true]); $this->snsService->shouldReceive('publish') - ->atLeast()->once() + ->atLeast() + ->once() ->with([ 'Message' => 'Message text', 'PhoneNumber' => '+22222222222', @@ -77,18 +75,18 @@ public function it_can_send_a_transactional_sms_message_to_sns() ], ], ]) - ->andReturn(true); + ->andReturn(new Result); $this->sns->send($message, '+22222222222'); } - /** @test */ - public function it_can_send_a_sms_message_with_sender_id() + public function test_it_can_send_a_sms_message_with_sender_id() { $message = new SnsMessage(['body' => 'Message text', 'sender' => 'CompanyInc']); $this->snsService->shouldReceive('publish') - ->atLeast()->once() + ->atLeast() + ->once() ->with([ 'Message' => 'Message text', 'PhoneNumber' => '+33333333333', @@ -103,7 +101,7 @@ public function it_can_send_a_sms_message_with_sender_id() ], ], ]) - ->andReturn(true); + ->andReturn(new Result); $this->sns->send($message, '+33333333333'); } diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..6da9e6c --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,11 @@ +