123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- <?php
- namespace Illuminate\Support\Testing\Fakes;
- use Closure;
- use Illuminate\Contracts\Mail\Factory;
- use Illuminate\Contracts\Mail\Mailable;
- use Illuminate\Contracts\Mail\Mailer;
- use Illuminate\Contracts\Mail\MailQueue;
- use Illuminate\Contracts\Queue\ShouldQueue;
- use Illuminate\Mail\MailManager;
- use Illuminate\Support\Traits\ForwardsCalls;
- use Illuminate\Support\Traits\ReflectsClosures;
- use PHPUnit\Framework\Assert as PHPUnit;
- class MailFake implements Factory, Fake, Mailer, MailQueue
- {
- use ForwardsCalls, ReflectsClosures;
- /**
- * The mailer instance.
- *
- * @var MailManager
- */
- public $manager;
- /**
- * The mailer currently being used to send a message.
- *
- * @var string
- */
- protected $currentMailer;
- /**
- * All of the mailables that have been sent.
- *
- * @var array
- */
- protected $mailables = [];
- /**
- * All of the mailables that have been queued.
- *
- * @var array
- */
- protected $queuedMailables = [];
- /**
- * Create a new mail fake.
- *
- * @param MailManager $manager
- * @return void
- */
- public function __construct(MailManager $manager)
- {
- $this->manager = $manager;
- }
- /**
- * Assert if a mailable was sent based on a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|int|null $callback
- * @return void
- */
- public function assertSent($mailable, $callback = null)
- {
- [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
- if (is_numeric($callback)) {
- return $this->assertSentTimes($mailable, $callback);
- }
- $message = "The expected [{$mailable}] mailable was not sent.";
- if (count($this->queuedMailables) > 0) {
- $message .= ' Did you mean to use assertQueued() instead?';
- }
- PHPUnit::assertTrue(
- $this->sent($mailable, $callback)->count() > 0,
- $message
- );
- }
- /**
- * Assert if a mailable was sent a number of times.
- *
- * @param string $mailable
- * @param int $times
- * @return void
- */
- protected function assertSentTimes($mailable, $times = 1)
- {
- $count = $this->sent($mailable)->count();
- PHPUnit::assertSame(
- $times, $count,
- "The expected [{$mailable}] mailable was sent {$count} times instead of {$times} times."
- );
- }
- /**
- * Determine if a mailable was not sent or queued to be sent based on a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|null $callback
- * @return void
- */
- public function assertNotOutgoing($mailable, $callback = null)
- {
- $this->assertNotSent($mailable, $callback);
- $this->assertNotQueued($mailable, $callback);
- }
- /**
- * Determine if a mailable was not sent based on a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|null $callback
- * @return void
- */
- public function assertNotSent($mailable, $callback = null)
- {
- [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
- PHPUnit::assertCount(
- 0, $this->sent($mailable, $callback),
- "The unexpected [{$mailable}] mailable was sent."
- );
- }
- /**
- * Assert that no mailables were sent or queued to be sent.
- *
- * @return void
- */
- public function assertNothingOutgoing()
- {
- $this->assertNothingSent();
- $this->assertNothingQueued();
- }
- /**
- * Assert that no mailables were sent.
- *
- * @return void
- */
- public function assertNothingSent()
- {
- $mailableNames = collect($this->mailables)->map(
- fn ($mailable) => get_class($mailable)
- )->join(', ');
- PHPUnit::assertEmpty($this->mailables, 'The following mailables were sent unexpectedly: '.$mailableNames);
- }
- /**
- * Assert if a mailable was queued based on a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|int|null $callback
- * @return void
- */
- public function assertQueued($mailable, $callback = null)
- {
- [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
- if (is_numeric($callback)) {
- return $this->assertQueuedTimes($mailable, $callback);
- }
- PHPUnit::assertTrue(
- $this->queued($mailable, $callback)->count() > 0,
- "The expected [{$mailable}] mailable was not queued."
- );
- }
- /**
- * Assert if a mailable was queued a number of times.
- *
- * @param string $mailable
- * @param int $times
- * @return void
- */
- protected function assertQueuedTimes($mailable, $times = 1)
- {
- $count = $this->queued($mailable)->count();
- PHPUnit::assertSame(
- $times, $count,
- "The expected [{$mailable}] mailable was queued {$count} times instead of {$times} times."
- );
- }
- /**
- * Determine if a mailable was not queued based on a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|null $callback
- * @return void
- */
- public function assertNotQueued($mailable, $callback = null)
- {
- [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
- PHPUnit::assertCount(
- 0, $this->queued($mailable, $callback),
- "The unexpected [{$mailable}] mailable was queued."
- );
- }
- /**
- * Assert that no mailables were queued.
- *
- * @return void
- */
- public function assertNothingQueued()
- {
- $mailableNames = collect($this->queuedMailables)->map(
- fn ($mailable) => get_class($mailable)
- )->join(', ');
- PHPUnit::assertEmpty($this->queuedMailables, 'The following mailables were queued unexpectedly: '.$mailableNames);
- }
- /**
- * Assert the total number of mailables that were sent.
- *
- * @param int $count
- * @return void
- */
- public function assertSentCount($count)
- {
- $total = collect($this->mailables)->count();
- PHPUnit::assertSame(
- $count, $total,
- "The total number of mailables sent was {$total} instead of {$count}."
- );
- }
- /**
- * Assert the total number of mailables that were queued.
- *
- * @param int $count
- * @return void
- */
- public function assertQueuedCount($count)
- {
- $total = collect($this->queuedMailables)->count();
- PHPUnit::assertSame(
- $count, $total,
- "The total number of mailables queued was {$total} instead of {$count}."
- );
- }
- /**
- * Assert the total number of mailables that were sent or queued.
- *
- * @param int $count
- * @return void
- */
- public function assertOutgoingCount($count)
- {
- $total = collect($this->mailables)
- ->concat($this->queuedMailables)
- ->count();
- PHPUnit::assertSame(
- $count, $total,
- "The total number of outgoing mailables was {$total} instead of {$count}."
- );
- }
- /**
- * Get all of the mailables matching a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|null $callback
- * @return \Illuminate\Support\Collection
- */
- public function sent($mailable, $callback = null)
- {
- [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
- if (! $this->hasSent($mailable)) {
- return collect();
- }
- $callback = $callback ?: fn () => true;
- return $this->mailablesOf($mailable)->filter(fn ($mailable) => $callback($mailable));
- }
- /**
- * Determine if the given mailable has been sent.
- *
- * @param string $mailable
- * @return bool
- */
- public function hasSent($mailable)
- {
- return $this->mailablesOf($mailable)->count() > 0;
- }
- /**
- * Get all of the queued mailables matching a truth-test callback.
- *
- * @param string|\Closure $mailable
- * @param callable|null $callback
- * @return \Illuminate\Support\Collection
- */
- public function queued($mailable, $callback = null)
- {
- [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback);
- if (! $this->hasQueued($mailable)) {
- return collect();
- }
- $callback = $callback ?: fn () => true;
- return $this->queuedMailablesOf($mailable)->filter(fn ($mailable) => $callback($mailable));
- }
- /**
- * Determine if the given mailable has been queued.
- *
- * @param string $mailable
- * @return bool
- */
- public function hasQueued($mailable)
- {
- return $this->queuedMailablesOf($mailable)->count() > 0;
- }
- /**
- * Get all of the mailed mailables for a given type.
- *
- * @param string $type
- * @return \Illuminate\Support\Collection
- */
- protected function mailablesOf($type)
- {
- return collect($this->mailables)->filter(fn ($mailable) => $mailable instanceof $type);
- }
- /**
- * Get all of the mailed mailables for a given type.
- *
- * @param string $type
- * @return \Illuminate\Support\Collection
- */
- protected function queuedMailablesOf($type)
- {
- return collect($this->queuedMailables)->filter(fn ($mailable) => $mailable instanceof $type);
- }
- /**
- * Get a mailer instance by name.
- *
- * @param string|null $name
- * @return \Illuminate\Contracts\Mail\Mailer
- */
- public function mailer($name = null)
- {
- $this->currentMailer = $name;
- return $this;
- }
- /**
- * Begin the process of mailing a mailable class instance.
- *
- * @param mixed $users
- * @return \Illuminate\Mail\PendingMail
- */
- public function to($users)
- {
- return (new PendingMailFake($this))->to($users);
- }
- /**
- * Begin the process of mailing a mailable class instance.
- *
- * @param mixed $users
- * @return \Illuminate\Mail\PendingMail
- */
- public function cc($users)
- {
- return (new PendingMailFake($this))->cc($users);
- }
- /**
- * Begin the process of mailing a mailable class instance.
- *
- * @param mixed $users
- * @return \Illuminate\Mail\PendingMail
- */
- public function bcc($users)
- {
- return (new PendingMailFake($this))->bcc($users);
- }
- /**
- * Send a new message with only a raw text part.
- *
- * @param string $text
- * @param \Closure|string $callback
- * @return void
- */
- public function raw($text, $callback)
- {
- //
- }
- /**
- * Send a new message using a view.
- *
- * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
- * @param array $data
- * @param \Closure|string|null $callback
- * @return void
- */
- public function send($view, array $data = [], $callback = null)
- {
- if (! $view instanceof Mailable) {
- return;
- }
- $view->mailer($this->currentMailer);
- if ($view instanceof ShouldQueue) {
- return $this->queue($view, $data);
- }
- $this->currentMailer = null;
- $this->mailables[] = $view;
- }
- /**
- * Queue a new e-mail message for sending.
- *
- * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
- * @param string|null $queue
- * @return mixed
- */
- public function queue($view, $queue = null)
- {
- if (! $view instanceof Mailable) {
- return;
- }
- $view->mailer($this->currentMailer);
- $this->currentMailer = null;
- $this->queuedMailables[] = $view;
- }
- /**
- * Queue a new e-mail message for sending after (n) seconds.
- *
- * @param \DateTimeInterface|\DateInterval|int $delay
- * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
- * @param string|null $queue
- * @return mixed
- */
- public function later($delay, $view, $queue = null)
- {
- $this->queue($view, $queue);
- }
- /**
- * Infer mailable class using reflection if a typehinted closure is passed to assertion.
- *
- * @param string|\Closure $mailable
- * @param callable|null $callback
- * @return array
- */
- protected function prepareMailableAndCallback($mailable, $callback)
- {
- if ($mailable instanceof Closure) {
- return [$this->firstClosureParameterType($mailable), $mailable];
- }
- return [$mailable, $callback];
- }
- /**
- * Forget all of the resolved mailer instances.
- *
- * @return $this
- */
- public function forgetMailers()
- {
- $this->currentMailer = null;
- return $this;
- }
- /**
- * Handle dynamic method calls to the mailer.
- *
- * @param string $method
- * @param array $parameters
- * @return mixed
- */
- public function __call($method, $parameters)
- {
- return $this->forwardCallTo($this->manager, $method, $parameters);
- }
- }
|