From b777f419dec6f1ef96263c2cf63cb288a36752f2 Mon Sep 17 00:00:00 2001 From: Dwight Watson Date: Tue, 12 Nov 2024 10:01:16 +1100 Subject: [PATCH 1/2] Dispatch additional events --- src/FcmChannel.php | 43 ++++++++++++++++++++++------------------ tests/FcmChannelTest.php | 30 +++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/FcmChannel.php b/src/FcmChannel.php index b0d667d..e828ef7 100644 --- a/src/FcmChannel.php +++ b/src/FcmChannel.php @@ -4,6 +4,8 @@ use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Notifications\Events\NotificationFailed; +use Illuminate\Notifications\Events\NotificationSending; +use Illuminate\Notifications\Events\NotificationSent; use Illuminate\Notifications\Notification; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -35,37 +37,40 @@ public function send(mixed $notifiable, Notification $notification): ?Collection { $tokens = Arr::wrap($notifiable->routeNotificationFor('fcm', $notification)); - if (empty($tokens)) { - return null; - } - - $fcmMessage = $notification->toFcm($notifiable); - return Collection::make($tokens) ->chunk(self::TOKENS_PER_REQUEST) - ->map(fn ($tokens) => ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all())) - ->map(fn (MulticastSendReport $report) => $this->checkReportForFailures($notifiable, $notification, $report)); + ->map(fn ($tokens) => $this->sendNotifications($notifiable, $notification, $tokens)) + ->map(fn (MulticastSendReport $report) => $this->dispatchEvents($notifiable, $notification, $report)); } /** - * Handle the report for the notification and dispatch any failed notifications. + * Send the notification with the provided tokens. */ - protected function checkReportForFailures(mixed $notifiable, Notification $notification, MulticastSendReport $report): MulticastSendReport + protected function sendNotifications(mixed $notifiable, Notification $notification, Collection $tokens): MulticastSendReport { - Collection::make($report->getItems()) - ->filter(fn (SendReport $report) => $report->isFailure()) - ->each(fn (SendReport $report) => $this->dispatchFailedNotification($notifiable, $notification, $report)); + $fcmMessage = $notification->toFcm($notifiable); - return $report; + $this->events->dispatch( + new NotificationSending($notifiable, $notification, self::class) + ); + + return ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all()); } /** - * Dispatch failed event. + * Handle the report for the notification and dispatch any failed notifications. */ - protected function dispatchFailedNotification(mixed $notifiable, Notification $notification, SendReport $report): void + protected function dispatchEvents(mixed $notifiable, Notification $notification, MulticastSendReport $report): MulticastSendReport { - $this->events->dispatch(new NotificationFailed($notifiable, $notification, self::class, [ - 'report' => $report, - ])); + Collection::make($report->getItems()) + ->each(function (SendReport $report) use ($notifiable, $notification) { + $event = $report->isSuccess() + ? new NotificationSent($notifiable, $notification, self::class, compact('report')) + : new NotificationFailed($notifiable, $notification, self::class, compact('report')); + + $this->events->dispatch($event); + }); + + return $report; } } diff --git a/tests/FcmChannelTest.php b/tests/FcmChannelTest.php index 132262e..0a7d54c 100644 --- a/tests/FcmChannelTest.php +++ b/tests/FcmChannelTest.php @@ -5,6 +5,9 @@ use Exception; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Notifications\Notifiable; +use Illuminate\Notifications\Events\NotificationFailed; +use Illuminate\Notifications\Events\NotificationSending; +use Illuminate\Notifications\Events\NotificationSent; use Illuminate\Notifications\Notification; use Illuminate\Support\Collection; use Kreait\Firebase\Contract\Messaging; @@ -36,7 +39,14 @@ public function test_it_can_be_instantiated() public function test_it_can_send_notifications() { $events = Mockery::mock(Dispatcher::class); - $events->shouldNotReceive('dispatch'); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSending::class)); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSent::class)); + $events->shouldNotReceive('dispatch') + ->with(Mockery::type(NotificationFailed::class)); $firebase = Mockery::mock(Messaging::class); $firebase->shouldReceive('sendMulticast') @@ -56,7 +66,14 @@ public function test_it_can_send_notifications() public function test_it_can_send_notifications_with_custom_client() { $events = Mockery::mock(Dispatcher::class); - $events->shouldNotReceive('dispatch'); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSending::class)); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSent::class)); + $events->shouldNotReceive('dispatch') + ->with(Mockery::type(NotificationFailed::class)); $firebase = Mockery::mock(Messaging::class); $events->shouldNotReceive('sendMulticast'); @@ -78,7 +95,14 @@ public function test_it_can_send_notifications_with_custom_client() public function test_it_can_dispatch_events() { $events = Mockery::mock(Dispatcher::class); - $events->shouldReceive('dispatch')->once(); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationSending::class)); + $events->shouldNotReceive('dispatch') + ->with(Mockery::type(NotificationSent::class)); + $events->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(NotificationFailed::class)); $firebase = Mockery::mock(Messaging::class); $firebase->shouldReceive('sendMulticast') From f1738a5ef26b722040eea75a30fb4cd9abff01c4 Mon Sep 17 00:00:00 2001 From: Dwight Watson Date: Tue, 12 Nov 2024 10:03:08 +1100 Subject: [PATCH 2/2] Style --- tests/FcmChannelTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FcmChannelTest.php b/tests/FcmChannelTest.php index 0a7d54c..868d574 100644 --- a/tests/FcmChannelTest.php +++ b/tests/FcmChannelTest.php @@ -4,10 +4,10 @@ use Exception; use Illuminate\Contracts\Events\Dispatcher; -use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Events\NotificationFailed; use Illuminate\Notifications\Events\NotificationSending; use Illuminate\Notifications\Events\NotificationSent; +use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notification; use Illuminate\Support\Collection; use Kreait\Firebase\Contract\Messaging;