diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 12a8537..ad50a8a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: true matrix: - php: [8.2, 8.1, 8.0] + php: [8.3, 8.2, 8.1] laravel: ['8.*', '9.*', '10.*', '11.*'] include: - laravel: 10.* @@ -25,16 +25,8 @@ jobs: - laravel: 11.* testbench: 9.* exclude: - - laravel: 10.* - php: 8.0 - - laravel: 10.* - php: 7.4 - - laravel: 9.* - php: 7.4 - laravel: 11.* php: 8.1 - - laravel: 11.* - php: 8.0 steps: - name: Checkout code diff --git a/.gitignore b/.gitignore index 3f0a634..74b638a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /vendor build +.phpunit.result.cache composer.phar composer.lock diff --git a/composer.json b/composer.json index 3be3655..6e60f0e 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "guzzlehttp/guzzle": "^7.0.1", "illuminate/notifications": "^8.0 || ^9.0 || ^10.0 || ^11.0", "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0" diff --git a/src/Exceptions/CouldNotSendNotification.php b/src/Exceptions/CouldNotSendNotification.php index 93ba3bd..8fbca37 100644 --- a/src/Exceptions/CouldNotSendNotification.php +++ b/src/Exceptions/CouldNotSendNotification.php @@ -3,15 +3,16 @@ namespace NotificationChannels\Pushover\Exceptions; use Exception; +use Illuminate\Notifications\AnonymousNotifiable; use Psr\Http\Message\ResponseInterface; class CouldNotSendNotification extends Exception { - public static function serviceRespondedWithAnError(ResponseInterface $response, $notifiable) + public static function serviceRespondedWithAnError(ResponseInterface $response, $notifiable): static { $statusCode = $response->getStatusCode(); - $result = json_decode($response->getBody()); + $result = json_decode($response->getBody()->getContents()); $exceptionMessage = sprintf( "Pushover responded with an error (%s) for notifiable '%s' with id '%s'", @@ -30,8 +31,12 @@ public static function serviceRespondedWithAnError(ResponseInterface $response, return new static($exceptionMessage, $statusCode); } - public static function pushoverKeyHasWrongLength($notifiable) + public static function pushoverKeyHasWrongLength($notifiable): static { + if ($notifiable instanceof AnonymousNotifiable) { + return new static('Pushover key has wrong length. It needs to be 30 characters long.'); + } + $exceptionMessage = sprintf( "Pushover key has wrong length for notifiable '%s' with id '%s'. It needs to be 30 characters long.", get_class($notifiable), diff --git a/src/Exceptions/ServiceCommunicationError.php b/src/Exceptions/ServiceCommunicationError.php index 0e33c22..59ec424 100644 --- a/src/Exceptions/ServiceCommunicationError.php +++ b/src/Exceptions/ServiceCommunicationError.php @@ -6,7 +6,7 @@ class ServiceCommunicationError extends Exception { - public static function communicationFailed(Exception $exception) + public static function communicationFailed(Exception $exception): static { return new static("The communication with Pushover failed because `{$exception->getCode()} - {$exception->getMessage()}`"); } diff --git a/src/Pushover.php b/src/Pushover.php index 50a1b18..4afca02 100644 --- a/src/Pushover.php +++ b/src/Pushover.php @@ -4,9 +4,11 @@ use Exception; use GuzzleHttp\Client as HttpClient; +use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\RequestException; use NotificationChannels\Pushover\Exceptions\CouldNotSendNotification; use NotificationChannels\Pushover\Exceptions\ServiceCommunicationError; +use Psr\Http\Message\ResponseInterface; class Pushover { @@ -22,27 +24,27 @@ class Pushover * * @var string */ - protected $pushoverApiUrl = 'https://api.pushover.net/1/messages.json'; + protected string $pushoverApiUrl = 'https://api.pushover.net/1/messages.json'; /** * The HTTP client instance. * - * @var \GuzzleHttp\Client + * @var HttpClient */ - protected $http; + protected HttpClient $http; /** * Pushover App Token. * * @var string */ - protected $token; + protected string $token; /** - * @param HttpClient $http - * @param string $token + * @param HttpClient $http + * @param string $token */ - public function __construct(HttpClient $http, $token) + public function __construct(HttpClient $http, string $token) { $this->http = $http; @@ -54,13 +56,15 @@ public function __construct(HttpClient $http, $token) * * @link https://pushover.net/api * - * @param array $params + * @param array $params * @param mixed $notifiable - * @return \Psr\Http\Message\ResponseInterface + * @return ResponseInterface * * @throws CouldNotSendNotification + * @throws ServiceCommunicationError + * @throws GuzzleException */ - public function send($params, $notifiable) + public function send(array $params, mixed $notifiable): ResponseInterface { try { $multipart = []; @@ -68,7 +72,7 @@ public function send($params, $notifiable) foreach ($this->paramsWithToken($params) as $name => $contents) { if ($name !== 'image') { $multipart[] = [ - 'name' => $name, + 'name' => $name, 'contents' => $contents, ]; } else { @@ -80,6 +84,7 @@ public function send($params, $notifiable) } } + //dd($multipart); return $this->http->post( $this->pushoverApiUrl, [ @@ -101,10 +106,10 @@ public function send($params, $notifiable) /** * Merge token into parameters array, unless it has been set on the PushoverReceiver. * - * @param array $params + * @param array $params * @return array */ - protected function paramsWithToken($params) + protected function paramsWithToken(array $params): array { return array_merge([ 'token' => $this->token, @@ -119,9 +124,14 @@ protected function paramsWithToken($params) * * @param $file * @return array|null + * @throws GuzzleException */ private function getImageData($file): ?array { + if (empty($file)) { + return null; + } + try { // check if $file is not too big if (is_file($file) && is_readable($file)) { @@ -141,7 +151,7 @@ private function getImageData($file): ?array } // some servers may not return the "Content-Length" header - $fileSizeChecked = (bool) $contentLength; + $fileSizeChecked = (bool)$contentLength; } // check if $file is an image @@ -153,7 +163,7 @@ private function getImageData($file): ?array $contents = file_get_contents($file); // if not checked before, finally check the file size after reading it - if (! $fileSizeChecked && strlen($contents) > self::IMAGE_SIZE_LIMIT) { + if (!$fileSizeChecked && strlen($contents) > self::IMAGE_SIZE_LIMIT) { return null; } } catch (Exception $exception) { @@ -162,10 +172,10 @@ private function getImageData($file): ?array return [ // name of the field holding the image must be 'attachment' (https://pushover.net/api#attachments) - 'name' => 'attachment', + 'name' => 'attachment', 'contents' => $contents, 'filename' => basename($file), - 'headers' => [ + 'headers' => [ 'Content-Type' => $contentType, ], ]; diff --git a/src/PushoverChannel.php b/src/PushoverChannel.php index d3359dc..e346556 100644 --- a/src/PushoverChannel.php +++ b/src/PushoverChannel.php @@ -2,6 +2,7 @@ namespace NotificationChannels\Pushover; +use GuzzleHttp\Exception\GuzzleException; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Notifications\Events\NotificationFailed; use Illuminate\Notifications\Notification; @@ -10,16 +11,15 @@ class PushoverChannel { - /** @var Pushover */ - protected $pushover; + protected Pushover $pushover; - /** @var Dispatcher */ - protected $events; + protected Dispatcher $events; /** * Create a new Pushover channel instance. * - * @param Pushover $pushover + * @param Pushover $pushover + * @param Dispatcher $events */ public function __construct(Pushover $pushover, Dispatcher $events) { @@ -30,12 +30,13 @@ public function __construct(Pushover $pushover, Dispatcher $events) /** * Send the given notification. * - * @param mixed $notifiable - * @param \Illuminate\Notifications\Notification $notification + * @param mixed $notifiable + * @param Notification $notification * - * @throws \NotificationChannels\Pushover\Exceptions\CouldNotSendNotification + * @throws CouldNotSendNotification + * @throws GuzzleException */ - public function send($notifiable, Notification $notification) + public function send(mixed $notifiable, Notification $notification): void { if (! $pushoverReceiver = $notifiable->routeNotificationFor('pushover')) { return; @@ -63,7 +64,7 @@ public function send($notifiable, Notification $notification) } } - protected function fireFailedEvent($notifiable, $notification, $message) + protected function fireFailedEvent($notifiable, $notification, $message): void { $this->events->dispatch( new NotificationFailed($notifiable, $notification, 'pushover', [$message]) diff --git a/src/PushoverMessage.php b/src/PushoverMessage.php index 4ff3065..eaae8d1 100644 --- a/src/PushoverMessage.php +++ b/src/PushoverMessage.php @@ -12,111 +12,109 @@ class PushoverMessage * * @var string */ - public $content; + public string $content; /** * The format of the message. * - * Either "plain", "html" or "monospace". - * - * @var string + * @var int */ - public $format = self::FORMAT_PLAIN; + public int $format = self::FORMAT_PLAIN; /** * The (optional) title of the message. * * @var string */ - public $title; + public string $title; /** * The (optional) timestamp of the message. * * @var int */ - public $timestamp; + public int $timestamp; /** * The (optional) priority of the message. * * @var int */ - public $priority; + public int $priority; /** * The (optional) timeout between retries when sending a message * with an emergency priority. The timeout is in seconds. * - * @var int + * @var int|null */ - public $retry; + public int|null $retry; /** * The (optional) expire time of a message with an emergency priority. * The expire time is in seconds. * - * @var int + * @var int|null */ - public $expire; + public int|null $expire; /** * The (optional) supplementary url of the message. * * @var string */ - public $url; + public string $url; /** * The (optional) supplementary url title of the message. * * @var string */ - public $urlTitle; + public string $urlTitle; /** * The (optional) sound of the message. * * @var string */ - public $sound; + public string $sound; /** * The (optional) image to be attached to the message. * * @var string */ - public $image; + public string $image = ''; /** * Message formats. */ - const FORMAT_PLAIN = 0; - const FORMAT_HTML = 1; - const FORMAT_MONOSPACE = 2; + public const FORMAT_PLAIN = 0; + public const FORMAT_HTML = 1; + public const FORMAT_MONOSPACE = 2; /** * Message priorities. */ - const LOWEST_PRIORITY = -2; - const LOW_PRIORITY = -1; - const NORMAL_PRIORITY = 0; - const HIGH_PRIORITY = 1; - const EMERGENCY_PRIORITY = 2; + public const LOWEST_PRIORITY = -2; + public const LOW_PRIORITY = -1; + public const NORMAL_PRIORITY = 0; + public const HIGH_PRIORITY = 1; + public const EMERGENCY_PRIORITY = 2; /** - * @param string $content + * @param string $content * @return static */ - public static function create($content = '') + public static function create(string $content = ''): static { return new static($content); } /** - * @param string $content + * @param string $content */ - public function __construct($content = '') + public function __construct(string $content = '') { $this->content = $content; } @@ -124,10 +122,10 @@ public function __construct($content = '') /** * Set the content of the Pushover message. * - * @param string $content + * @param string $content * @return $this */ - public function content($content) + public function content(string $content): static { $this->content = $content; @@ -139,7 +137,7 @@ public function content($content) * * @return $this */ - public function plain() + public function plain(): static { $this->format = static::FORMAT_PLAIN; @@ -151,7 +149,7 @@ public function plain() * * @return $this */ - public function html() + public function html(): static { $this->format = static::FORMAT_HTML; @@ -163,7 +161,7 @@ public function html() * * @return $this */ - public function monospace() + public function monospace(): static { $this->format = self::FORMAT_MONOSPACE; @@ -173,10 +171,10 @@ public function monospace() /** * Set the title of the Pushover message. * - * @param string $title + * @param string $title * @return $this */ - public function title($title) + public function title(string $title): static { $this->title = $title; @@ -186,13 +184,13 @@ public function title($title) /** * Set the time of the Pushover message. * - * @param Carbon|int $time + * @param int|Carbon $time * @return $this */ - public function time($time) + public function time(int|Carbon $time): static { if ($time instanceof Carbon) { - $time = $time->timestamp; + $time = (int)$time->timestamp; } $this->timestamp = $time; @@ -203,11 +201,11 @@ public function time($time) /** * Set a supplementary url for the Pushover message. * - * @param string $url - * @param string $title + * @param string $url + * @param string $title * @return $this */ - public function url($url, $title = null) + public function url(string $url, string $title = ''): static { $this->url = $url; $this->urlTitle = $title; @@ -218,10 +216,10 @@ public function url($url, $title = null) /** * Set the sound of the Pushover message. * - * @param string $sound + * @param string $sound * @return $this */ - public function sound($sound) + public function sound(string $sound): static { $this->sound = $sound; @@ -231,10 +229,10 @@ public function sound($sound) /** * Set the image for attaching to the Pushover message. Either full or relative server path or a URL. * - * @param string $image + * @param string $image * @return $this */ - public function image($image) + public function image(string $image): static { $this->image = $image; @@ -245,12 +243,13 @@ public function image($image) * Set the priority of the Pushover message. * Retry and expire are mandatory when setting the priority to emergency. * - * @param int $priority - * @param int $retryTimeout - * @param int $expireAfter + * @param int $priority + * @param int|null $retryTimeout + * @param int|null $expireAfter * @return $this + * @throws EmergencyNotificationRequiresRetryAndExpire */ - public function priority($priority, $retryTimeout = null, $expireAfter = null) + public function priority(int $priority, int|null $retryTimeout = null, int|null $expireAfter = null): static { $this->noEmergencyWithoutRetryOrExpire($priority, $retryTimeout, $expireAfter); @@ -265,8 +264,9 @@ public function priority($priority, $retryTimeout = null, $expireAfter = null) * Set the priority of the Pushover message to the lowest priority. * * @return $this + * @throws EmergencyNotificationRequiresRetryAndExpire */ - public function lowestPriority() + public function lowestPriority(): static { return $this->priority(self::LOWEST_PRIORITY); } @@ -275,8 +275,9 @@ public function lowestPriority() * Set the priority of the Pushover message to low. * * @return $this + * @throws EmergencyNotificationRequiresRetryAndExpire */ - public function lowPriority() + public function lowPriority(): static { return $this->priority(self::LOW_PRIORITY); } @@ -285,8 +286,9 @@ public function lowPriority() * Set the priority of the Pushover message to normal. * * @return $this + * @throws EmergencyNotificationRequiresRetryAndExpire */ - public function normalPriority() + public function normalPriority(): static { return $this->priority(self::NORMAL_PRIORITY); } @@ -295,8 +297,9 @@ public function normalPriority() * Set the priority of the Pushover message to high. * * @return $this + * @throws EmergencyNotificationRequiresRetryAndExpire */ - public function highPriority() + public function highPriority(): static { return $this->priority(self::HIGH_PRIORITY); } @@ -305,11 +308,12 @@ public function highPriority() * Set the priority of the Pushover message to emergency. * Retry and expire are mandatory when setting the priority to emergency. * - * @param int $retryTimeout - * @param int $expireAfter + * @param int $retryTimeout + * @param int $expireAfter * @return $this + * @throws EmergencyNotificationRequiresRetryAndExpire */ - public function emergencyPriority($retryTimeout, $expireAfter) + public function emergencyPriority(int $retryTimeout, int $expireAfter): static { return $this->priority(self::EMERGENCY_PRIORITY, $retryTimeout, $expireAfter); } @@ -319,7 +323,7 @@ public function emergencyPriority($retryTimeout, $expireAfter) * * @return array */ - public function toArray() + public function toArray(): array { return [ 'message' => $this->content, @@ -340,15 +344,15 @@ public function toArray() /** * Ensure an emergency message has an retry and expiry time. * - * @param int $priority - * @param int $retry - * @param int $expire + * @param int $priority + * @param int|null $retry + * @param int|null $expire * * @throws EmergencyNotificationRequiresRetryAndExpire */ - protected function noEmergencyWithoutRetryOrExpire($priority, $retry, $expire) + protected function noEmergencyWithoutRetryOrExpire(int $priority, int|null $retry, int|null $expire): void { - if ($priority == self::EMERGENCY_PRIORITY && (! isset($retry) || ! isset($expire))) { + if ($priority === self::EMERGENCY_PRIORITY && ($retry === null || $expire === null)) { throw new EmergencyNotificationRequiresRetryAndExpire(); } } diff --git a/src/PushoverReceiver.php b/src/PushoverReceiver.php index f228a41..83472f8 100644 --- a/src/PushoverReceiver.php +++ b/src/PushoverReceiver.php @@ -4,16 +4,16 @@ class PushoverReceiver { - protected $key; - protected $token; - protected $devices = []; + protected string $key; + protected string|null $token = null; + protected array $devices = []; /** * PushoverReceiver constructor. * - * @param $key User or group key. + * @param string $key User or group key. */ - protected function __construct($key) + protected function __construct(string $key) { $this->key = $key; } @@ -21,10 +21,10 @@ protected function __construct($key) /** * Create new Pushover receiver with an user key. * - * @param $userKey Pushover user key. + * @param string $userKey Pushover user key. * @return PushoverReceiver */ - public static function withUserKey($userKey) + public static function withUserKey(string $userKey): PushoverReceiver { return new static($userKey); } @@ -32,10 +32,10 @@ public static function withUserKey($userKey) /** * Create new Pushover receiver with a group key. * - * @param $groupKey Pushover group key. + * @param string $groupKey Pushover group key. * @return PushoverReceiver */ - public static function withGroupKey($groupKey) + public static function withGroupKey(string $groupKey): PushoverReceiver { // This has exactly the same behaviour as an user key, so we // will use the same factory method as for the user key. @@ -45,18 +45,17 @@ public static function withGroupKey($groupKey) /** * Send the message to a specific device. * - * @param array|string $device + * @param array|string $device * @return PushoverReceiver */ - public function toDevice($device) + public function toDevice(array|string $device): static { if (is_array($device)) { $this->devices = array_merge($device, $this->devices); - return $this; } - $this->devices[] = $device; + $this->devices[] = $device; return $this; } @@ -66,7 +65,7 @@ public function toDevice($device) * @param $token * @return PushoverReceiver */ - public function withApplicationToken($token) + public function withApplicationToken($token): static { $this->token = $token; @@ -78,7 +77,7 @@ public function withApplicationToken($token) * * @return array */ - public function toArray() + public function toArray(): array { return array_merge([ 'user' => $this->key, diff --git a/src/PushoverServiceProvider.php b/src/PushoverServiceProvider.php index 4757648..1d83106 100644 --- a/src/PushoverServiceProvider.php +++ b/src/PushoverServiceProvider.php @@ -10,7 +10,7 @@ class PushoverServiceProvider extends ServiceProvider /** * Bootstrap the application services. */ - public function boot() + public function boot(): void { $this->app->when(PushoverChannel::class) ->needs(Pushover::class) @@ -18,11 +18,4 @@ public function boot() return new Pushover(new HttpClient(), config('services.pushover.token')); }); } - - /** - * Register the application services. - */ - public function register() - { - } } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 9416812..1183677 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -34,7 +34,7 @@ public function setUp(): void } /** @test */ - public function it_can_send_a_pushover_notification_with_a_global_token() + public function it_can_send_a_pushover_notification_with_a_global_token(): void { $message = (new PushoverMessage('Message text')) ->title('Message title') @@ -45,19 +45,19 @@ public function it_can_send_a_pushover_notification_with_a_global_token() $this->requestWillBeSentToPushoverWith([ 'token' => 'global-application-token', - 'user' => 'pushover-key', - 'device' => 'iphone,desktop', 'message' => 'Message text', 'title' => 'Message title', - 'priority' => 2, - 'retry' => 60, - 'expire' => 600, 'timestamp' => 123456789, - 'sound' => 'boing', + 'priority' => 2, 'url' => 'http://example.com', 'url_title' => 'Example Website', + 'sound' => 'boing', + 'retry' => 60, + 'expire' => 600, 'html' => false, 'monospace' => false, + 'user' => 'pushover-key-30characters-long', + 'device' => 'iphone,desktop', ]); $pushover = new Pushover($this->guzzleClient, 'global-application-token'); @@ -70,7 +70,7 @@ public function it_can_send_a_pushover_notification_with_a_global_token() } /** @test */ - public function it_can_send_a_pushover_notification_with_an_overridden_token() + public function it_can_send_a_pushover_notification_with_an_overridden_token(): void { $message = (new PushoverMessage('Message text')) ->html() @@ -82,19 +82,19 @@ public function it_can_send_a_pushover_notification_with_an_overridden_token() $this->requestWillBeSentToPushoverWith([ 'token' => 'overridden-application-token', - 'user' => 'pushover-key', - 'device' => 'iphone,desktop', 'message' => 'Message text', 'title' => 'Message title', - 'priority' => 2, - 'retry' => 60, - 'expire' => 600, 'timestamp' => 123456789, - 'sound' => 'boing', + 'priority' => 2, 'url' => 'http://example.com', 'url_title' => 'Example Website', + 'sound' => 'boing', + 'retry' => 60, + 'expire' => 600, 'html' => true, 'monospace' => false, + 'user' => 'pushover-key-30characters-long', + 'device' => 'iphone,desktop', ]); $pushover = new Pushover($this->guzzleClient, 'global-application-token'); @@ -106,19 +106,25 @@ public function it_can_send_a_pushover_notification_with_an_overridden_token() $channel->send(new NotifiableWithPushoverReceiverWithToken(), $this->notification); } - protected function requestWillBeSentToPushoverWith($params) + protected function requestWillBeSentToPushoverWith($params): void { + $multipartData = array_map( + fn($key, $value) => ['name' => $key, 'contents' => $value], + array_keys($params), + array_values($params) + ); + $this->guzzleClient->shouldReceive('post') ->with('https://api.pushover.net/1/messages.json', [ - 'form_params' => $params, + 'multipart' => $multipartData, ]) ->once(); } - protected function ignoreEvents() + protected function ignoreEvents(): void { $dispatcher = Mockery::mock('Illuminate\Contracts\Events\Dispatcher'); - $dispatcher->shouldReceive('fire'); + $dispatcher->shouldReceive('dispatch'); app()->instance('events', $dispatcher); } } diff --git a/tests/Notifiable.php b/tests/Notifiable.php index f4e19dc..c5ce36a 100644 --- a/tests/Notifiable.php +++ b/tests/Notifiable.php @@ -6,6 +6,11 @@ class Notifiable { public function routeNotificationFor($channel) { - return 'pushover-key'; + return 'pushover-key-30characters-long'; + } + + public function getKey() + { + return '1'; } } diff --git a/tests/NotifiableWithPushoverReceiver.php b/tests/NotifiableWithPushoverReceiver.php index 072f2e7..d3beff6 100644 --- a/tests/NotifiableWithPushoverReceiver.php +++ b/tests/NotifiableWithPushoverReceiver.php @@ -8,7 +8,7 @@ class NotifiableWithPushoverReceiver extends Notifiable { public function routeNotificationFor($channel) { - return PushoverReceiver::withUserKey('pushover-key') + return PushoverReceiver::withUserKey('pushover-key-30characters-long') ->toDevice('iphone') ->toDevice('desktop'); } diff --git a/tests/NotifiableWithPushoverReceiverWithToken.php b/tests/NotifiableWithPushoverReceiverWithToken.php index bcff167..f956f35 100644 --- a/tests/NotifiableWithPushoverReceiverWithToken.php +++ b/tests/NotifiableWithPushoverReceiverWithToken.php @@ -8,7 +8,7 @@ class NotifiableWithPushoverReceiverWithToken extends Notifiable { public function routeNotificationFor($channel) { - return PushoverReceiver::withUserKey('pushover-key') + return PushoverReceiver::withUserKey('pushover-key-30characters-long') ->withApplicationToken('overridden-application-token') ->toDevice('iphone') ->toDevice('desktop'); diff --git a/tests/PushoverChannelTest.php b/tests/PushoverChannelTest.php index 6f7397f..41e8374 100644 --- a/tests/PushoverChannelTest.php +++ b/tests/PushoverChannelTest.php @@ -43,56 +43,60 @@ public function setUp(): void } /** @test */ - public function it_can_send_a_message_to_pushover() + public function it_can_send_a_message_to_pushover(): void { $notifiable = new Notifiable; $this->notification->shouldReceive('toPushover') ->with($notifiable) ->andReturn($this->message); + $this->pushover->shouldReceive('send') ->with(Mockery::subset([ - 'user' => 'pushover-key', + 'user' => 'pushover-key-30characters-long', 'device' => '', - ])) + ]), $notifiable) ->once(); $this->channel->send($notifiable, $this->notification); } /** @test */ - public function it_can_send_a_message_to_pushover_using_a_pushover_receiver() + public function it_can_send_a_message_to_pushover_using_a_pushover_receiver(): void { $notifiable = new NotifiableWithPushoverReceiver; $this->notification->shouldReceive('toPushover') ->with($notifiable) ->andReturn($this->message); + $this->pushover->shouldReceive('send') ->with(Mockery::subset([ - 'user' => 'pushover-key', + 'user' => 'pushover-key-30characters-long', 'device' => 'iphone,desktop', - ])) + ]), $notifiable) ->once(); $this->channel->send($notifiable, $this->notification); } /** @test */ - public function it_fires_a_notification_failed_event_when_the_communication_with_pushover_failed() + public function it_fires_a_notification_failed_event_when_the_communication_with_pushover_failed(): void { $this->notification->shouldReceive('toPushover')->andReturn($this->message); $this->pushover->shouldReceive('send')->andThrow( ServiceCommunicationError::communicationFailed(new Exception()) ); - $this->events->shouldReceive('fire')->with(Mockery::type(NotificationFailed::class)); + $this->events->shouldReceive('dispatch')->with(Mockery::type(NotificationFailed::class)); $this->channel->send(new Notifiable, $this->notification); + + $this->expectNotToPerformAssertions(); } /** @test */ - public function it_does_not_send_a_message_when_notifiable_does_not_have_route_notificaton_for_pushover() + public function it_does_not_send_a_message_when_notifiable_does_not_have_route_notificaton_for_pushover(): void { $this->notification->shouldReceive('toPushover')->never(); diff --git a/tests/PushoverMessageTest.php b/tests/PushoverMessageTest.php index a2c371e..1440806 100644 --- a/tests/PushoverMessageTest.php +++ b/tests/PushoverMessageTest.php @@ -19,7 +19,7 @@ public function setUp(): void } /** @test */ - public function it_can_accept_a_message_when_constructing_a_message() + public function it_can_accept_a_message_when_constructing_a_message(): void { $message = new PushoverMessage('message text'); @@ -27,7 +27,7 @@ public function it_can_accept_a_message_when_constructing_a_message() } /** @test */ - public function it_can_create_a_message() + public function it_can_create_a_message(): void { $message = PushoverMessage::create(); @@ -35,7 +35,7 @@ public function it_can_create_a_message() } /** @test */ - public function it_can_accept_a_message_when_creating_a_message() + public function it_can_accept_a_message_when_creating_a_message(): void { $message = PushoverMessage::create('message text'); @@ -43,7 +43,7 @@ public function it_can_accept_a_message_when_creating_a_message() } /** @test */ - public function it_can_set_content() + public function it_can_set_content(): void { $this->message->content('message text'); @@ -51,7 +51,7 @@ public function it_can_set_content() } /** @test */ - public function it_can_set_the_message_format_to_plain() + public function it_can_set_the_message_format_to_plain(): void { $this->message->plain(); @@ -59,7 +59,7 @@ public function it_can_set_the_message_format_to_plain() } /** @test */ - public function it_can_set_the_message_format_to_html() + public function it_can_set_the_message_format_to_html(): void { $this->message->html(); @@ -67,7 +67,7 @@ public function it_can_set_the_message_format_to_html() } /** @test */ - public function it_can_set_the_message_format_to_monospace() + public function it_can_set_the_message_format_to_monospace(): void { $this->message->monospace(); @@ -75,7 +75,7 @@ public function it_can_set_the_message_format_to_monospace() } /** @test */ - public function it_can_set_a_title() + public function it_can_set_a_title(): void { $this->message->title('message title'); @@ -83,7 +83,7 @@ public function it_can_set_a_title() } /** @test */ - public function it_can_set_a_time() + public function it_can_set_a_time(): void { $this->message->time(123456789); @@ -91,7 +91,7 @@ public function it_can_set_a_time() } /** @test */ - public function it_can_set_a_time_from_a_carbon_object() + public function it_can_set_a_time_from_a_carbon_object(): void { $carbon = Carbon::now(); @@ -101,7 +101,7 @@ public function it_can_set_a_time_from_a_carbon_object() } /** @test */ - public function it_can_set_an_url() + public function it_can_set_an_url(): void { $this->message->url('http://example.com'); @@ -109,7 +109,7 @@ public function it_can_set_an_url() } /** @test */ - public function it_can_set_an_url_with_a_title() + public function it_can_set_an_url_with_a_title(): void { $this->message->url('http://example.com', 'Go to example website'); @@ -118,7 +118,7 @@ public function it_can_set_an_url_with_a_title() } /** @test */ - public function it_can_set_a_sound() + public function it_can_set_a_sound(): void { $this->message->sound('boing'); @@ -126,7 +126,7 @@ public function it_can_set_a_sound() } /** @test */ - public function it_can_set_a_priority() + public function it_can_set_a_priority(): void { $this->message->priority(PushoverMessage::NORMAL_PRIORITY); @@ -134,7 +134,7 @@ public function it_can_set_a_priority() } /** @test */ - public function it_can_set_a_priority_with_retry_and_expire() + public function it_can_set_a_priority_with_retry_and_expire(): void { $this->message->priority(PushoverMessage::EMERGENCY_PRIORITY, 60, 600); @@ -144,7 +144,7 @@ public function it_can_set_a_priority_with_retry_and_expire() } /** @test */ - public function it_cannot_set_priority_to_emergency_when_not_providing_a_retry_and_expiry_time() + public function it_cannot_set_priority_to_emergency_when_not_providing_a_retry_and_expiry_time(): void { $this->expectException(EmergencyNotificationRequiresRetryAndExpire::class); @@ -152,7 +152,7 @@ public function it_cannot_set_priority_to_emergency_when_not_providing_a_retry_a } /** @test */ - public function it_can_set_the_priority_to_the_lowest() + public function it_can_set_the_priority_to_the_lowest(): void { $this->message->lowestPriority(); @@ -160,7 +160,7 @@ public function it_can_set_the_priority_to_the_lowest() } /** @test */ - public function it_can_set_the_priority_to_low() + public function it_can_set_the_priority_to_low(): void { $this->message->lowPriority(); @@ -168,7 +168,7 @@ public function it_can_set_the_priority_to_low() } /** @test */ - public function it_can_set_the_priority_to_normal() + public function it_can_set_the_priority_to_normal(): void { $this->message->normalPriority(); @@ -176,7 +176,7 @@ public function it_can_set_the_priority_to_normal() } /** @test */ - public function it_can_set_the_priority_to_high() + public function it_can_set_the_priority_to_high(): void { $this->message->highPriority(); @@ -184,7 +184,7 @@ public function it_can_set_the_priority_to_high() } /** @test */ - public function it_can_set_the_priority_to_emergency() + public function it_can_set_the_priority_to_emergency(): void { $this->message->emergencyPriority(60, 600); diff --git a/tests/PushoverServiceProviderTest.php b/tests/PushoverServiceProviderTest.php index b692201..000676f 100644 --- a/tests/PushoverServiceProviderTest.php +++ b/tests/PushoverServiceProviderTest.php @@ -3,6 +3,7 @@ namespace NotificationChannels\Pushover\Test; use Illuminate\Contracts\Foundation\Application; +use Illuminate\Support\Facades\Config; use Mockery; use NotificationChannels\Pushover\Pushover; use NotificationChannels\Pushover\PushoverChannel; @@ -28,8 +29,10 @@ public function setUp(): void } /** @test */ - public function it_gives_an_instantiated_pushover_object_when_the_channel_asks_for_it() + public function it_gives_an_instantiated_pushover_object_when_the_channel_asks_for_it(): void { + Config::shouldReceive('get')->with('services.pushover.token', null)->once()->andReturn('test-token'); + $this->app->shouldReceive('when')->with(PushoverChannel::class)->once()->andReturn($this->app); $this->app->shouldReceive('needs')->with(Pushover::class)->once()->andReturn($this->app); $this->app->shouldReceive('give')->with(Mockery::on(function ($pushover) { diff --git a/tests/PushoverTest.php b/tests/PushoverTest.php index d51b8b9..1e546f4 100644 --- a/tests/PushoverTest.php +++ b/tests/PushoverTest.php @@ -24,85 +24,91 @@ public function setUp(): void parent::setUp(); $this->guzzleClient = Mockery::mock(HttpClient::class); - $this->pushover = new Pushover($this->guzzleClient, 'application-token'); + $this->pushover = new Pushover($this->guzzleClient, 'new-application-token-12345678'); } /** @test */ - public function it_can_send_a_request_to_pushover() + public function it_can_send_a_request_to_pushover(): void { $this->guzzleClient->shouldReceive('post') ->with('https://api.pushover.net/1/messages.json', [ - 'form_params' => [ - 'token' => 'application-token', + 'multipart' => [ + ['name' => 'token', 'contents' => 'new-application-token-12345678'], ], ]); - $this->pushover->send([]); + $this->pushover->send([], new Notifiable()); + + $this->expectNotToPerformAssertions(); } /** @test */ - public function it_can_send_a_request_with_an_overridden_token() + public function it_can_send_a_request_with_an_overridden_token(): void { $this->guzzleClient->shouldReceive('post') ->with('https://api.pushover.net/1/messages.json', [ - 'form_params' => [ - 'token' => 'dynamic-application-token', + 'multipart' => [ + ['name' => 'token', 'contents' => 'dynamic-application-token-1234'], ], ]); - $this->pushover->send(['token' => 'dynamic-application-token']); + $this->pushover->send(['token' => 'dynamic-application-token-1234'], new Notifiable()); + + $this->expectNotToPerformAssertions(); } /** @test */ - public function it_can_accept_parameters_for_a_send_request() + public function it_can_accept_parameters_for_a_send_request(): void { $this->guzzleClient->shouldReceive('post') ->with('https://api.pushover.net/1/messages.json', [ - 'form_params' => [ - 'token' => 'application-token', - 'content' => 'content of message', + 'multipart' => [ + ['name' => 'token', 'contents' => 'new-application-token-12345678'], + ['name' => 'content', 'contents' => 'content of message'], ], ]); $this->pushover->send([ 'content' => 'content of message', - ]); + ], new Notifiable()); + + $this->expectNotToPerformAssertions(); } /** @test */ - public function it_throws_an_exception_when_pushover_returns_an_error_with_invalid_json() + public function it_throws_an_exception_when_pushover_returns_an_error_with_invalid_json(): void { $this->expectException(CouldNotSendNotification::class); - $this->expectExceptionMessage('Pushover responded with an error (400).'); + $this->expectExceptionMessage('Pushover responded with an error (400)'); $guzzleRequest = Mockery::mock(\Psr\Http\Message\RequestInterface::class); $guzzleResponse = Mockery::mock(\Psr\Http\Message\ResponseInterface::class); $guzzleResponse->shouldReceive('getStatusCode')->andReturn(400); - $guzzleResponse->shouldReceive('getBody')->andReturn(''); + $guzzleResponse->shouldReceive('getBody->getContents'); $this->guzzleClient->shouldReceive('post')->andThrow(new RequestException('message', $guzzleRequest, $guzzleResponse)); - $this->pushover->send([]); + $this->pushover->send([], new Notifiable()); } /** @test */ - public function it_throws_an_exception_when_pushover_returns_an_error_with_valid_json() + public function it_throws_an_exception_when_pushover_returns_an_error_with_valid_json(): void { $this->expectException(CouldNotSendNotification::class); - $this->expectExceptionMessage('Pushover responded with an error (400): error_message_1, error_message_2'); + $this->expectExceptionMessage("Pushover responded with an error (400) for notifiable 'NotificationChannels\Pushover\Test\Notifiable' with id '1': error_message_1, error_message_2"); $guzzleRequest = Mockery::mock(\Psr\Http\Message\RequestInterface::class); $guzzleResponse = Mockery::mock(\Psr\Http\Message\ResponseInterface::class); $guzzleResponse->shouldReceive('getStatusCode')->andReturn(400); - $guzzleResponse->shouldReceive('getBody')->andReturn('{"errors": ["error_message_1", "error_message_2"]}'); + $guzzleResponse->shouldReceive('getBody->getContents')->andReturn('{"errors": ["error_message_1", "error_message_2"]}'); $this->guzzleClient->shouldReceive('post')->andThrow(new RequestException('message', $guzzleRequest, $guzzleResponse)); - $this->pushover->send([]); + $this->pushover->send([], new Notifiable()); } /** @test */ - public function it_throws_an_exception_when_pushover_returns_nothing() + public function it_throws_an_exception_when_pushover_returns_nothing(): void { $this->expectException(ServiceCommunicationError::class); $this->expectExceptionMessage('The communication with Pushover failed because'); @@ -111,17 +117,17 @@ public function it_throws_an_exception_when_pushover_returns_nothing() $this->guzzleClient->shouldReceive('post')->andThrow(new RequestException('message', $guzzleRequest, null)); - $this->pushover->send([]); + $this->pushover->send([], new Notifiable()); } /** @test */ - public function it_throws_an_exception_when_an_unknown_communication_error_occurred() + public function it_throws_an_exception_when_an_unknown_communication_error_occurred(): void { $this->expectException(ServiceCommunicationError::class); $this->expectExceptionMessage('The communication with Pushover failed'); $this->guzzleClient->shouldReceive('post')->andThrow(new Exception); - $this->pushover->send([]); + $this->pushover->send([], new Notifiable()); } }