From ddda68e5e248bf49446c9e9427f63adf9d329c90 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Mon, 15 Jul 2024 18:31:42 -0400 Subject: [PATCH] Add `assertSentTo` shorthand (#52083) * Add `assertSentTo` shorthand * Add multiple example to test * Overload existing method * Add negative assertions --- .../Support/Testing/Fakes/MailFake.php | 65 +++++++++-- tests/Support/SupportTestingMailFakeTest.php | 104 ++++++++++++++++++ 2 files changed, 161 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Support/Testing/Fakes/MailFake.php b/src/Illuminate/Support/Testing/Fakes/MailFake.php index 326066114cfa..a077e2c346ef 100644 --- a/src/Illuminate/Support/Testing/Fakes/MailFake.php +++ b/src/Illuminate/Support/Testing/Fakes/MailFake.php @@ -9,6 +9,7 @@ use Illuminate\Contracts\Mail\MailQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\MailManager; +use Illuminate\Support\Arr; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\ReflectsClosures; use PHPUnit\Framework\Assert as PHPUnit; @@ -60,7 +61,7 @@ public function __construct(MailManager $manager) * Assert if a mailable was sent based on a truth-test callback. * * @param string|\Closure $mailable - * @param callable|int|null $callback + * @param callable|int|string|array|null $callback * @return void */ public function assertSent($mailable, $callback = null) @@ -71,15 +72,24 @@ public function assertSent($mailable, $callback = null) return $this->assertSentTimes($mailable, $callback); } - $message = "The expected [{$mailable}] mailable was not sent."; + $suggestion = count($this->queuedMailables) ? ' Did you mean to use assertQueued() instead?' : ''; - if (count($this->queuedMailables) > 0) { - $message .= ' Did you mean to use assertQueued() instead?'; + if (is_array($callback) || is_string($callback)) { + foreach (Arr::wrap($callback) as $address) { + $callback = fn ($mail) => $mail->hasTo($address); + + PHPUnit::assertTrue( + $this->sent($mailable, $callback)->count() > 0, + "The expected [{$mailable}] mailable was not sent to address [{$address}].".$suggestion + ); + } + + return; } PHPUnit::assertTrue( $this->sent($mailable, $callback)->count() > 0, - $message + "The expected [{$mailable}] mailable was not sent.".$suggestion ); } @@ -117,11 +127,24 @@ public function assertNotOutgoing($mailable, $callback = null) * Determine if a mailable was not sent based on a truth-test callback. * * @param string|\Closure $mailable - * @param callable|null $callback + * @param callable|string|array|null $callback * @return void */ public function assertNotSent($mailable, $callback = null) { + if (is_string($callback) || is_array($callback)) { + foreach (Arr::wrap($callback) as $address) { + $callback = fn ($mail) => $mail->hasTo($address); + + PHPUnit::assertCount( + 0, $this->sent($mailable, $callback), + "The unexpected [{$mailable}] mailable was sent to address [{$address}]." + ); + } + + return; + } + [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback); PHPUnit::assertCount( @@ -159,7 +182,7 @@ public function assertNothingSent() * Assert if a mailable was queued based on a truth-test callback. * * @param string|\Closure $mailable - * @param callable|int|null $callback + * @param callable|int|string|array|null $callback * @return void */ public function assertQueued($mailable, $callback = null) @@ -170,6 +193,19 @@ public function assertQueued($mailable, $callback = null) return $this->assertQueuedTimes($mailable, $callback); } + if (is_string($callback) || is_array($callback)) { + foreach (Arr::wrap($callback) as $address) { + $callback = fn ($mail) => $mail->hasTo($address); + + PHPUnit::assertTrue( + $this->queued($mailable, $callback)->count() > 0, + "The expected [{$mailable}] mailable was not queued to address [{$address}]." + ); + } + + return; + } + PHPUnit::assertTrue( $this->queued($mailable, $callback)->count() > 0, "The expected [{$mailable}] mailable was not queued." @@ -197,11 +233,24 @@ protected function assertQueuedTimes($mailable, $times = 1) * Determine if a mailable was not queued based on a truth-test callback. * * @param string|\Closure $mailable - * @param callable|null $callback + * @param callable|string|array|null $callback * @return void */ public function assertNotQueued($mailable, $callback = null) { + if (is_string($callback) || is_array($callback)) { + foreach (Arr::wrap($callback) as $address) { + $callback = fn ($mail) => $mail->hasTo($address); + + PHPUnit::assertCount( + 0, $this->queued($mailable, $callback), + "The unexpected [{$mailable}] mailable was queued to address [{$address}]." + ); + } + + return; + } + [$mailable, $callback] = $this->prepareMailableAndCallback($mailable, $callback); PHPUnit::assertCount( diff --git a/tests/Support/SupportTestingMailFakeTest.php b/tests/Support/SupportTestingMailFakeTest.php index 640661cd130e..07189bb92efc 100644 --- a/tests/Support/SupportTestingMailFakeTest.php +++ b/tests/Support/SupportTestingMailFakeTest.php @@ -50,6 +50,34 @@ public function testAssertSent() $this->fake->assertSent(MailableStub::class); } + public function testAssertSentTo() + { + try { + $this->fake->assertSent(MailableStub::class, 'taylor@laravel.com'); + $this->fail(); + } catch (ExpectationFailedException $e) { + $this->assertStringContainsString('The expected [Illuminate\Tests\Support\MailableStub] mailable was not sent to address [taylor@laravel.com].', $e->getMessage()); + } + + $this->fake->to('taylor@laravel.com')->send($this->mailable); + + $this->fake->assertSent(MailableStub::class, 'taylor@laravel.com'); + } + + public function testAssertSentToMultiple() + { + $this->fake->to('dries@laravel.com')->send($this->mailable); + $this->fake->to('taylor@laravel.com')->send($this->mailable); + + $this->fake->to(['nuno@laravel.com', 'jess@laravel.com'])->send($this->mailable); + + $this->fake->assertSent(MailableStub::class, 3); + $this->fake->assertSent( + MailableStub::class, + ['taylor@laravel.com', 'dries@laravel.com', 'nuno@laravel.com', 'jess@laravel.com'] + ); + } + public function testAssertSentWhenRecipientHasPreferredLocale() { $user = new LocalizedRecipientStub; @@ -118,6 +146,30 @@ public function testAssertNotSentWithClosure() $this->fake->assertNotSent($callback); } + public function testAssertNotSentWithString() + { + $this->fake->assertNotSent(MailableStub::class, 'taylor@laravel.com'); + + $this->fake->to('taylor@laravel.com')->send($this->mailable); + + $this->expectException(ExpectationFailedException::class); + $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was sent to address [taylor@laravel.com].'); + + $this->fake->assertNotSent(MailableStub::class, 'taylor@laravel.com'); + } + + public function testAssertNotSentWithArray() + { + $this->fake->assertNotSent(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']); + + $this->fake->to('dries@laravel.com')->send($this->mailable); + + $this->expectException(ExpectationFailedException::class); + $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was sent to address [dries@laravel.com].'); + + $this->fake->assertNotSent(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']); + } + public function testAssertSentTimes() { $this->fake->to('taylor@laravel.com')->send($this->mailable); @@ -162,6 +214,34 @@ public function testAssertQueued() $this->fake->assertQueued(MailableStub::class); } + public function testAssertQueuedTo() + { + try { + $this->fake->assertQueued(MailableStub::class, 'taylor@laravel.com'); + $this->fail(); + } catch (ExpectationFailedException $e) { + $this->assertStringContainsString('The expected [Illuminate\Tests\Support\MailableStub] mailable was not queued to address [taylor@laravel.com].', $e->getMessage()); + } + + $this->fake->to('taylor@laravel.com')->queue($this->mailable); + + $this->fake->assertQueued(MailableStub::class, 'taylor@laravel.com'); + } + + public function testAssertQueuedToMultiple() + { + $this->fake->to('dries@laravel.com')->queue($this->mailable); + $this->fake->to('taylor@laravel.com')->queue($this->mailable); + + $this->fake->to(['nuno@laravel.com', 'jess@laravel.com'])->queue($this->mailable); + + $this->fake->assertQueued(MailableStub::class, 3); + $this->fake->assertQueued( + MailableStub::class, + ['taylor@laravel.com', 'dries@laravel.com', 'nuno@laravel.com', 'jess@laravel.com'] + ); + } + public function testAssertQueuedTimes() { $this->fake->to('taylor@laravel.com')->queue($this->mailable); @@ -177,6 +257,30 @@ public function testAssertQueuedTimes() $this->fake->assertQueued(MailableStub::class, 2); } + public function testAssertNotQueuedWithString() + { + $this->fake->assertNotQueued(MailableStub::class, 'taylor@laravel.com'); + + $this->fake->to('taylor@laravel.com')->queue($this->mailable); + + $this->expectException(ExpectationFailedException::class); + $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was queued to address [taylor@laravel.com].'); + + $this->fake->assertNotQueued(MailableStub::class, 'taylor@laravel.com'); + } + + public function testAssertNotQueuedWithArray() + { + $this->fake->assertNotQueued(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']); + + $this->fake->to('dries@laravel.com')->queue($this->mailable); + + $this->expectException(ExpectationFailedException::class); + $this->expectExceptionMessage('The unexpected ['.MailableStub::class.'] mailable was queued to address [dries@laravel.com].'); + + $this->fake->assertNotQueued(MailableStub::class, ['taylor@laravel.com', 'dries@laravel.com']); + } + public function testAssertQueuedCount() { $this->fake->to('taylor@laravel.com')->queue($this->mailable);