From ec53497ac7514e3fb089cbd98232af48bf85a8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20A=C5=9Fan?= Date: Thu, 1 Aug 2024 10:52:00 +0300 Subject: [PATCH] Add Event Dispatching for Notifications (#12) * remove phpunit & add pestphp * Drop support for Laravel 8 * update composer scripts & code quality tools * refactoring * migrate to pestphp * Achieved 100% code coverage * Temporarily revert changes that should be done in another PR * remove namespace * add Pest v1 support for Laravel 9 * formatting * Remove parallel flag for Pest v1 https://github.com/mertasan/onesignal/actions/runs/10187251895/job/28180865729#step:6:33 The Parallel plugin has been moved to the main repo in Pest v2. * Add missing directories to phpunit.xml * add Events * Apply events * Add tests for Events --- phpunit.xml | 34 +++---- .../OneSignalNotificationErrorsOccurred.php | 25 +++++ src/Events/OneSignalNotificationNotSent.php | 24 +++++ src/Events/OneSignalNotificationSending.php | 24 +++++ src/Events/OneSignalNotificationSent.php | 25 +++++ src/OneSignalChannel.php | 18 +++- tests/Feature/ChannelEventsTest.php | 97 +++++++++++++++++++ 7 files changed, 223 insertions(+), 24 deletions(-) create mode 100644 src/Events/OneSignalNotificationErrorsOccurred.php create mode 100644 src/Events/OneSignalNotificationNotSent.php create mode 100644 src/Events/OneSignalNotificationSending.php create mode 100644 src/Events/OneSignalNotificationSent.php create mode 100644 tests/Feature/ChannelEventsTest.php diff --git a/phpunit.xml b/phpunit.xml index 0610882..66cfe7c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,23 +1,17 @@ - - - - ./src - - + + + + tests/Unit + + + tests/Feature + + + + + ./src + + - - - tests - - diff --git a/src/Events/OneSignalNotificationErrorsOccurred.php b/src/Events/OneSignalNotificationErrorsOccurred.php new file mode 100644 index 0000000..d83b276 --- /dev/null +++ b/src/Events/OneSignalNotificationErrorsOccurred.php @@ -0,0 +1,25 @@ +routeNotificationFor('OneSignal', $notification)) { - return null; + OneSignalNotificationNotSent::dispatch($notifiable, $notification); + + return; } + OneSignalNotificationSending::dispatch($notifiable, $notification); + $result = Http::timeout($this->timeout) ->asJson()->acceptJson() ->post(self::ENDPOINT, [ @@ -58,6 +66,8 @@ public function send(mixed $notifiable, Notification $notification): ?object ]); + OneSignalNotificationSent::dispatch($notifiable, $notification, $result->json()); + if ($requestException = $result->toException()) { throw $requestException; } @@ -65,9 +75,9 @@ public function send(mixed $notifiable, Notification $notification): ?object $errors = $result->json('errors'); if (! empty($errors)) { + OneSignalNotificationErrorsOccurred::dispatch($notifiable, $notification, $errors); + throw CouldNotSendNotification::withErrors($result->body()); } - - return $result; } } diff --git a/tests/Feature/ChannelEventsTest.php b/tests/Feature/ChannelEventsTest.php new file mode 100644 index 0000000..9c309c7 --- /dev/null +++ b/tests/Feature/ChannelEventsTest.php @@ -0,0 +1,97 @@ + Http::response(), + ]); + + (new WrongNotifiable)->notify(new TestNotificationByText); + + Http::assertNothingSent(); + + Event::assertDispatched(OneSignalNotificationNotSent::class); +}); + +test('notification sent', function () { + Event::fake(); + + Http::fake([ + 'api/v1/notifications' => Http::response([ + 'id' => '931082f5-e442-42b1-a951-19e7e45dee39', + 'recipients' => 1, + 'external_id' => null, + ]), + ]); + + (new Notifiable)->notify(new TestNotification); + + Http::assertSent(function (Request $request) { + return $request->url() === OneSignalChannel::ENDPOINT && + $request['app_id'] === $this->appId && + $request['include_player_ids'] === ['player_id'] && + $request['headings'] === ['en' => 'Subject'] && + $request['contents'] === ['en' => 'Body'] && + $request['data'] === null; + }); + + Event::assertNotDispatched(OneSignalNotificationNotSent::class); + + Event::assertDispatched(OneSignalNotificationSending::class, static function ($event) { + return $event->notification instanceof TestNotification; + }); + + Event::assertDispatched(OneSignalNotificationSent::class, static function ($event) { + return $event->response['id'] === '931082f5-e442-42b1-a951-19e7e45dee39'; + }); + + Event::assertNotDispatched(OneSignalNotificationErrorsOccurred::class); +}); + +test('notification errors occurred', function () { + Event::fake(); + + Http::fake([ + 'api/v1/notifications' => Http::response([ + 'id' => '', + 'recipients' => 0, + 'errors' => [ + 'All included players are not subscribed', + ], + ]), + ]); + + try { + (new Notifiable)->notify(new TestNotification); + } catch (CouldNotSendNotification $e) { + expect($e->getMessage()) + ->toContain('{"id":"","recipients":0,"errors":["All included players are not subscribed"]}'); + } + + Event::assertNotDispatched(OneSignalNotificationNotSent::class); + + Event::assertDispatched(OneSignalNotificationSending::class, static function ($event) { + return $event->notification instanceof TestNotification; + }); + + Event::assertDispatched(OneSignalNotificationSent::class); + + Event::assertDispatched(OneSignalNotificationErrorsOccurred::class); +});