Skip to content

Commit

Permalink
[6.x] Fix notifications database channel for anonymous notifiables (#…
Browse files Browse the repository at this point in the history
…33409)

* Prevent usage of database channel with anonymous notifiable

* Prevent sending for anonymous notifiables and database channel

* Update AnonymousNotifiable.php

* Update NotificationRoutesNotificationsTest.php

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
driesvints and taylorotwell authored Jul 2, 2020
1 parent c914a3e commit 1116adb
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/Illuminate/Notifications/AnonymousNotifiable.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Notifications;

use Illuminate\Contracts\Notifications\Dispatcher;
use InvalidArgumentException;

class AnonymousNotifiable
{
Expand All @@ -22,6 +23,10 @@ class AnonymousNotifiable
*/
public function route($channel, $route)
{
if ($channel === 'database') {
throw new InvalidArgumentException('The database channel does not support on-demand notifications.');
}

$this->routes[$channel] = $route;

return $this;
Expand Down
4 changes: 3 additions & 1 deletion src/Illuminate/Notifications/NotificationSender.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ public function sendNow($notifiables, $notification, array $channels = null)
$notificationId = Str::uuid()->toString();

foreach ((array) $viaChannels as $channel) {
$this->sendToNotifiable($notifiable, $notificationId, clone $original, $channel);
if (! ($notifiable instanceof AnonymousNotifiable && $channel === 'database')) {
$this->sendToNotifiable($notifiable, $notificationId, clone $original, $channel);
}
}
});
}
Expand Down
11 changes: 11 additions & 0 deletions tests/Notifications/NotificationRoutesNotificationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Illuminate\Container\Container;
use Illuminate\Contracts\Notifications\Dispatcher;
use Illuminate\Notifications\RoutesNotifications;
use Illuminate\Support\Facades\Notification;
use InvalidArgumentException;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use stdClass;
Expand Down Expand Up @@ -50,6 +52,15 @@ public function testNotificationOptionRouting()
$this->assertSame('bar', $instance->routeNotificationFor('foo'));
$this->assertSame('taylor@laravel.com', $instance->routeNotificationFor('mail'));
}

public function testOnDemandNotificationsCannotUseDatabaseChannel()
{
$this->expectExceptionObject(
new InvalidArgumentException('The database channel does not support on-demand notifications.')
);

Notification::route('database', 'foo');
}
}

class RoutesNotificationsTestInstance
Expand Down
59 changes: 59 additions & 0 deletions tests/Notifications/NotificationSenderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Notifications\ChannelManager;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
Expand Down Expand Up @@ -34,6 +35,32 @@ public function testItCanSendQueuedNotificationsWithAStringVia()

$sender->send($notifiable, new DummyQueuedNotificationWithStringVia());
}

public function testItCanSendNotificationsWithAnEmptyStringVia()
{
$notifiable = new AnonymousNotifiable;
$manager = m::mock(ChannelManager::class);
$bus = m::mock(BusDispatcher::class);
$bus->shouldNotReceive('dispatch');
$events = m::mock(EventDispatcher::class);

$sender = new NotificationSender($manager, $bus, $events);

$sender->sendNow($notifiable, new DummyNotificationWithEmptyStringVia());
}

public function testItCannotSendNotificationsViaDatabaseForAnonymousNotifiables()
{
$notifiable = new AnonymousNotifiable;
$manager = m::mock(ChannelManager::class);
$bus = m::mock(BusDispatcher::class);
$bus->shouldNotReceive('dispatch');
$events = m::mock(EventDispatcher::class);

$sender = new NotificationSender($manager, $bus, $events);

$sender->sendNow($notifiable, new DummyNotificationWithDatabaseVia());
}
}

class DummyQueuedNotificationWithStringVia extends Notification implements ShouldQueue
Expand All @@ -51,3 +78,35 @@ public function via($notifiable)
return 'mail';
}
}

class DummyNotificationWithEmptyStringVia extends Notification
{
use Queueable;

/**
* Get the notification channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return '';
}
}

class DummyNotificationWithDatabaseVia extends Notification
{
use Queueable;

/**
* Get the notification channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return 'database';
}
}

0 comments on commit 1116adb

Please sign in to comment.