NotificationFake.php 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. namespace Illuminate\Support\Testing\Fakes;
  3. use Illuminate\Support\Str;
  4. use Illuminate\Support\Collection;
  5. use PHPUnit\Framework\Assert as PHPUnit;
  6. use Illuminate\Contracts\Notifications\Factory as NotificationFactory;
  7. use Illuminate\Contracts\Notifications\Dispatcher as NotificationDispatcher;
  8. class NotificationFake implements NotificationFactory, NotificationDispatcher
  9. {
  10. /**
  11. * All of the notifications that have been sent.
  12. *
  13. * @var array
  14. */
  15. protected $notifications = [];
  16. /**
  17. * Assert if a notification was sent based on a truth-test callback.
  18. *
  19. * @param mixed $notifiable
  20. * @param string $notification
  21. * @param callable|null $callback
  22. * @return void
  23. */
  24. public function assertSentTo($notifiable, $notification, $callback = null)
  25. {
  26. if (is_array($notifiable) || $notifiable instanceof Collection) {
  27. foreach ($notifiable as $singleNotifiable) {
  28. $this->assertSentTo($singleNotifiable, $notification, $callback);
  29. }
  30. return;
  31. }
  32. if (is_numeric($callback)) {
  33. return $this->assertSentToTimes($notifiable, $notification, $callback);
  34. }
  35. PHPUnit::assertTrue(
  36. $this->sent($notifiable, $notification, $callback)->count() > 0,
  37. "The expected [{$notification}] notification was not sent."
  38. );
  39. }
  40. /**
  41. * Assert if a notification was sent a number of times.
  42. *
  43. * @param mixed $notifiable
  44. * @param string $notification
  45. * @param int $times
  46. * @return void
  47. */
  48. public function assertSentToTimes($notifiable, $notification, $times = 1)
  49. {
  50. PHPUnit::assertTrue(
  51. ($count = $this->sent($notifiable, $notification)->count()) === $times,
  52. "Expected [{$notification}] to be sent {$count} times, but was sent {$times} times."
  53. );
  54. }
  55. /**
  56. * Determine if a notification was sent based on a truth-test callback.
  57. *
  58. * @param mixed $notifiable
  59. * @param string $notification
  60. * @param callable|null $callback
  61. * @return void
  62. */
  63. public function assertNotSentTo($notifiable, $notification, $callback = null)
  64. {
  65. if (is_array($notifiable) || $notifiable instanceof Collection) {
  66. foreach ($notifiable as $singleNotifiable) {
  67. $this->assertNotSentTo($singleNotifiable, $notification, $callback);
  68. }
  69. return;
  70. }
  71. PHPUnit::assertTrue(
  72. $this->sent($notifiable, $notification, $callback)->count() === 0,
  73. "The unexpected [{$notification}] notification was sent."
  74. );
  75. }
  76. /**
  77. * Assert that no notifications were sent.
  78. *
  79. * @return void
  80. */
  81. public function assertNothingSent()
  82. {
  83. PHPUnit::assertEmpty($this->notifications, 'Notifications were sent unexpectedly.');
  84. }
  85. /**
  86. * Assert the total amount of times a notification was sent.
  87. *
  88. * @param int $expectedCount
  89. * @param string $notification
  90. * @return void
  91. */
  92. public function assertTimesSent($expectedCount, $notification)
  93. {
  94. $actualCount = collect($this->notifications)
  95. ->flatten(1)
  96. ->reduce(function ($count, $sent) use ($notification) {
  97. return $count + count($sent[$notification] ?? []);
  98. }, 0);
  99. PHPUnit::assertSame(
  100. $expectedCount, $actualCount,
  101. "Expected [{$notification}] to be sent {$expectedCount} times, but was sent {$actualCount} times."
  102. );
  103. }
  104. /**
  105. * Get all of the notifications matching a truth-test callback.
  106. *
  107. * @param mixed $notifiable
  108. * @param string $notification
  109. * @param callable|null $callback
  110. * @return \Illuminate\Support\Collection
  111. */
  112. public function sent($notifiable, $notification, $callback = null)
  113. {
  114. if (! $this->hasSent($notifiable, $notification)) {
  115. return collect();
  116. }
  117. $callback = $callback ?: function () {
  118. return true;
  119. };
  120. $notifications = collect($this->notificationsFor($notifiable, $notification));
  121. return $notifications->filter(function ($arguments) use ($callback) {
  122. return $callback(...array_values($arguments));
  123. })->pluck('notification');
  124. }
  125. /**
  126. * Determine if there are more notifications left to inspect.
  127. *
  128. * @param mixed $notifiable
  129. * @param string $notification
  130. * @return bool
  131. */
  132. public function hasSent($notifiable, $notification)
  133. {
  134. return ! empty($this->notificationsFor($notifiable, $notification));
  135. }
  136. /**
  137. * Get all of the notifications for a notifiable entity by type.
  138. *
  139. * @param mixed $notifiable
  140. * @param string $notification
  141. * @return array
  142. */
  143. protected function notificationsFor($notifiable, $notification)
  144. {
  145. if (isset($this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification])) {
  146. return $this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification];
  147. }
  148. return [];
  149. }
  150. /**
  151. * Send the given notification to the given notifiable entities.
  152. *
  153. * @param \Illuminate\Support\Collection|array|mixed $notifiables
  154. * @param mixed $notification
  155. * @return void
  156. */
  157. public function send($notifiables, $notification)
  158. {
  159. return $this->sendNow($notifiables, $notification);
  160. }
  161. /**
  162. * Send the given notification immediately.
  163. *
  164. * @param \Illuminate\Support\Collection|array|mixed $notifiables
  165. * @param mixed $notification
  166. * @return void
  167. */
  168. public function sendNow($notifiables, $notification)
  169. {
  170. if (! $notifiables instanceof Collection && ! is_array($notifiables)) {
  171. $notifiables = [$notifiables];
  172. }
  173. foreach ($notifiables as $notifiable) {
  174. if (! $notification->id) {
  175. $notification->id = Str::uuid()->toString();
  176. }
  177. $this->notifications[get_class($notifiable)][$notifiable->getKey()][get_class($notification)][] = [
  178. 'notification' => $notification,
  179. 'channels' => $notification->via($notifiable),
  180. 'notifiable' => $notifiable,
  181. ];
  182. }
  183. }
  184. /**
  185. * Get a channel instance by name.
  186. *
  187. * @param string|null $name
  188. * @return mixed
  189. */
  190. public function channel($name = null)
  191. {
  192. //
  193. }
  194. }