/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/MailFake.php

https://gitlab.com/jjpa2018/dashboard · PHP · 433 lines · 197 code · 58 blank · 178 comment · 9 complexity · ba383ed33f6c17c73aa78affd47e7b83 MD5 · raw file

  1. <?php
  2. namespace Illuminate\Support\Testing\Fakes;
  3. use Closure;
  4. use Illuminate\Contracts\Mail\Factory;
  5. use Illuminate\Contracts\Mail\Mailable;
  6. use Illuminate\Contracts\Mail\Mailer;
  7. use Illuminate\Contracts\Mail\MailQueue;
  8. use Illuminate\Contracts\Queue\ShouldQueue;
  9. use Illuminate\Support\Traits\ReflectsClosures;
  10. use PHPUnit\Framework\Assert as PHPUnit;
  11. class MailFake implements Factory, Mailer, MailQueue
  12. {
  13. use ReflectsClosures;
  14. /**
  15. * The mailer currently being used to send a message.
  16. *
  17. * @var string
  18. */
  19. protected $currentMailer;
  20. /**
  21. * All of the mailables that have been sent.
  22. *
  23. * @var array
  24. */
  25. protected $mailables = [];
  26. /**
  27. * All of the mailables that have been queued.
  28. *
  29. * @var array
  30. */
  31. protected $queuedMailables = [];
  32. /**
  33. * Assert if a mailable was sent based on a truth-test callback.
  34. *
  35. * @param string|\Closure $mailable
  36. * @param callable|int|null $callback
  37. * @return void
  38. */
  39. public function assertSent($mailable, $callback = null)
  40. {
  41. [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
  42. if (is_numeric($callback)) {
  43. return $this->assertSentTimes($mailable, $callback);
  44. }
  45. $message = "The expected [{$mailable}] mailable was not sent.";
  46. if (count($this->queuedMailables) > 0) {
  47. $message .= ' Did you mean to use assertQueued() instead?';
  48. }
  49. PHPUnit::assertTrue(
  50. $this->sent($mailable, $callback)->count() > 0,
  51. $message
  52. );
  53. }
  54. /**
  55. * Assert if a mailable was sent a number of times.
  56. *
  57. * @param string $mailable
  58. * @param int $times
  59. * @return void
  60. */
  61. protected function assertSentTimes($mailable, $times = 1)
  62. {
  63. $count = $this->sent($mailable)->count();
  64. PHPUnit::assertSame(
  65. $times, $count,
  66. "The expected [{$mailable}] mailable was sent {$count} times instead of {$times} times."
  67. );
  68. }
  69. /**
  70. * Determine if a mailable was not sent or queued to be sent based on a truth-test callback.
  71. *
  72. * @param string|\Closure $mailable
  73. * @param callable|null $callback
  74. * @return void
  75. */
  76. public function assertNotOutgoing($mailable, $callback = null)
  77. {
  78. $this->assertNotSent($mailable, $callback);
  79. $this->assertNotQueued($mailable, $callback);
  80. }
  81. /**
  82. * Determine if a mailable was not sent based on a truth-test callback.
  83. *
  84. * @param string|\Closure $mailable
  85. * @param callable|null $callback
  86. * @return void
  87. */
  88. public function assertNotSent($mailable, $callback = null)
  89. {
  90. [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
  91. PHPUnit::assertCount(
  92. 0, $this->sent($mailable, $callback),
  93. "The unexpected [{$mailable}] mailable was sent."
  94. );
  95. }
  96. /**
  97. * Assert that no mailables were sent or queued to be sent.
  98. *
  99. * @return void
  100. */
  101. public function assertNothingOutgoing()
  102. {
  103. $this->assertNothingSent();
  104. $this->assertNothingQueued();
  105. }
  106. /**
  107. * Assert that no mailables were sent.
  108. *
  109. * @return void
  110. */
  111. public function assertNothingSent()
  112. {
  113. $mailableNames = collect($this->mailables)->map(function ($mailable) {
  114. return get_class($mailable);
  115. })->join(', ');
  116. PHPUnit::assertEmpty($this->mailables, 'The following mailables were sent unexpectedly: '.$mailableNames);
  117. }
  118. /**
  119. * Assert if a mailable was queued based on a truth-test callback.
  120. *
  121. * @param string|\Closure $mailable
  122. * @param callable|int|null $callback
  123. * @return void
  124. */
  125. public function assertQueued($mailable, $callback = null)
  126. {
  127. [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
  128. if (is_numeric($callback)) {
  129. return $this->assertQueuedTimes($mailable, $callback);
  130. }
  131. PHPUnit::assertTrue(
  132. $this->queued($mailable, $callback)->count() > 0,
  133. "The expected [{$mailable}] mailable was not queued."
  134. );
  135. }
  136. /**
  137. * Assert if a mailable was queued a number of times.
  138. *
  139. * @param string $mailable
  140. * @param int $times
  141. * @return void
  142. */
  143. protected function assertQueuedTimes($mailable, $times = 1)
  144. {
  145. $count = $this->queued($mailable)->count();
  146. PHPUnit::assertSame(
  147. $times, $count,
  148. "The expected [{$mailable}] mailable was queued {$count} times instead of {$times} times."
  149. );
  150. }
  151. /**
  152. * Determine if a mailable was not queued based on a truth-test callback.
  153. *
  154. * @param string|\Closure $mailable
  155. * @param callable|null $callback
  156. * @return void
  157. */
  158. public function assertNotQueued($mailable, $callback = null)
  159. {
  160. [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
  161. PHPUnit::assertCount(
  162. 0, $this->queued($mailable, $callback),
  163. "The unexpected [{$mailable}] mailable was queued."
  164. );
  165. }
  166. /**
  167. * Assert that no mailables were queued.
  168. *
  169. * @return void
  170. */
  171. public function assertNothingQueued()
  172. {
  173. $mailableNames = collect($this->queuedMailables)->map(function ($mailable) {
  174. return get_class($mailable);
  175. })->join(', ');
  176. PHPUnit::assertEmpty($this->queuedMailables, 'The following mailables were queued unexpectedly: '.$mailableNames);
  177. }
  178. /**
  179. * Get all of the mailables matching a truth-test callback.
  180. *
  181. * @param string|\Closure $mailable
  182. * @param callable|null $callback
  183. * @return \Illuminate\Support\Collection
  184. */
  185. public function sent($mailable, $callback = null)
  186. {
  187. [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
  188. if (! $this->hasSent($mailable)) {
  189. return collect();
  190. }
  191. $callback = $callback ?: function () {
  192. return true;
  193. };
  194. return $this->mailablesOf($mailable)->filter(function ($mailable) use ($callback) {
  195. return $callback($mailable);
  196. });
  197. }
  198. /**
  199. * Determine if the given mailable has been sent.
  200. *
  201. * @param string $mailable
  202. * @return bool
  203. */
  204. public function hasSent($mailable)
  205. {
  206. return $this->mailablesOf($mailable)->count() > 0;
  207. }
  208. /**
  209. * Get all of the queued mailables matching a truth-test callback.
  210. *
  211. * @param string|\Closure $mailable
  212. * @param callable|null $callback
  213. * @return \Illuminate\Support\Collection
  214. */
  215. public function queued($mailable, $callback = null)
  216. {
  217. [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
  218. if (! $this->hasQueued($mailable)) {
  219. return collect();
  220. }
  221. $callback = $callback ?: function () {
  222. return true;
  223. };
  224. return $this->queuedMailablesOf($mailable)->filter(function ($mailable) use ($callback) {
  225. return $callback($mailable);
  226. });
  227. }
  228. /**
  229. * Determine if the given mailable has been queued.
  230. *
  231. * @param string $mailable
  232. * @return bool
  233. */
  234. public function hasQueued($mailable)
  235. {
  236. return $this->queuedMailablesOf($mailable)->count() > 0;
  237. }
  238. /**
  239. * Get all of the mailed mailables for a given type.
  240. *
  241. * @param string $type
  242. * @return \Illuminate\Support\Collection
  243. */
  244. protected function mailablesOf($type)
  245. {
  246. return collect($this->mailables)->filter(function ($mailable) use ($type) {
  247. return $mailable instanceof $type;
  248. });
  249. }
  250. /**
  251. * Get all of the mailed mailables for a given type.
  252. *
  253. * @param string $type
  254. * @return \Illuminate\Support\Collection
  255. */
  256. protected function queuedMailablesOf($type)
  257. {
  258. return collect($this->queuedMailables)->filter(function ($mailable) use ($type) {
  259. return $mailable instanceof $type;
  260. });
  261. }
  262. /**
  263. * Get a mailer instance by name.
  264. *
  265. * @param string|null $name
  266. * @return \Illuminate\Contracts\Mail\Mailer
  267. */
  268. public function mailer($name = null)
  269. {
  270. $this->currentMailer = $name;
  271. return $this;
  272. }
  273. /**
  274. * Begin the process of mailing a mailable class instance.
  275. *
  276. * @param mixed $users
  277. * @return \Illuminate\Mail\PendingMail
  278. */
  279. public function to($users)
  280. {
  281. return (new PendingMailFake($this))->to($users);
  282. }
  283. /**
  284. * Begin the process of mailing a mailable class instance.
  285. *
  286. * @param mixed $users
  287. * @return \Illuminate\Mail\PendingMail
  288. */
  289. public function bcc($users)
  290. {
  291. return (new PendingMailFake($this))->bcc($users);
  292. }
  293. /**
  294. * Send a new message with only a raw text part.
  295. *
  296. * @param string $text
  297. * @param \Closure|string $callback
  298. * @return void
  299. */
  300. public function raw($text, $callback)
  301. {
  302. //
  303. }
  304. /**
  305. * Send a new message using a view.
  306. *
  307. * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
  308. * @param array $data
  309. * @param \Closure|string|null $callback
  310. * @return void
  311. */
  312. public function send($view, array $data = [], $callback = null)
  313. {
  314. if (! $view instanceof Mailable) {
  315. return;
  316. }
  317. $view->mailer($this->currentMailer);
  318. $this->currentMailer = null;
  319. if ($view instanceof ShouldQueue) {
  320. return $this->queue($view, $data);
  321. }
  322. $this->mailables[] = $view;
  323. }
  324. /**
  325. * Queue a new e-mail message for sending.
  326. *
  327. * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
  328. * @param string|null $queue
  329. * @return mixed
  330. */
  331. public function queue($view, $queue = null)
  332. {
  333. if (! $view instanceof Mailable) {
  334. return;
  335. }
  336. $view->mailer($this->currentMailer);
  337. $this->currentMailer = null;
  338. $this->queuedMailables[] = $view;
  339. }
  340. /**
  341. * Queue a new e-mail message for sending after (n) seconds.
  342. *
  343. * @param \DateTimeInterface|\DateInterval|int $delay
  344. * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
  345. * @param string|null $queue
  346. * @return mixed
  347. */
  348. public function later($delay, $view, $queue = null)
  349. {
  350. $this->queue($view, $queue);
  351. }
  352. /**
  353. * Get the array of failed recipients.
  354. *
  355. * @return array
  356. */
  357. public function failures()
  358. {
  359. return [];
  360. }
  361. /**
  362. * Infer mailable class using reflection if a typehinted closure is passed to assertion.
  363. *
  364. * @param string|\Closure $mailable
  365. * @param callable|null $callback
  366. * @return array
  367. */
  368. protected function prepareMailableAndCallback($mailable, $callback)
  369. {
  370. if ($mailable instanceof Closure) {
  371. return [$this->firstClosureParameterType($mailable), $mailable];
  372. }
  373. return [$mailable, $callback];
  374. }
  375. }