Skip to content

Commit 50a9486

Browse files
macbookandrewtimacdonaldtaylorotwell
authored
[9.x] Add ability to determine if attachments exist (#43967)
* add ability to determine if attachments exist * add tests for asserting file attachment * add tests for asserting data attachment * add tests for asserting storage attachment * add from storage tests * code style * add assertions * test assertion methods * code style * formatting Co-authored-by: Tim MacDonald <[email protected]> Co-authored-by: Taylor Otwell <[email protected]>
1 parent 71034a4 commit 50a9486

File tree

3 files changed

+451
-0
lines changed

3 files changed

+451
-0
lines changed

src/Illuminate/Mail/Mailable.php

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,39 @@ public function attachMany($files)
909909
return $this;
910910
}
911911

912+
/**
913+
* Determine if the mailable has the given attachment.
914+
*
915+
* @param string|\Illuminate\Contracts\Mail\Attachable|\Illuminate\Mail\Attachment $file
916+
* @param array $options
917+
* @return bool
918+
*/
919+
public function hasAttachment($file, array $options = [])
920+
{
921+
if ($file instanceof Attachable) {
922+
$file = $file->toMailAttachment();
923+
}
924+
925+
if ($file instanceof Attachment) {
926+
$parts = $file->attachWith(
927+
fn ($path) => [$path, ['as' => $file->as, 'mime' => $file->mime]],
928+
fn ($data) => $this->hasAttachedData($data(), $file->as, ['mime' => $file->mime])
929+
);
930+
931+
if ($parts === true) {
932+
return true;
933+
}
934+
935+
[$file, $options] = $parts === false
936+
? [null, []]
937+
: $parts;
938+
}
939+
940+
return collect($this->attachments)->contains(
941+
fn ($attachment) => $attachment['file'] === $file && array_filter($attachment['options']) === array_filter($options)
942+
);
943+
}
944+
912945
/**
913946
* Attach a file to the message from storage.
914947
*
@@ -945,6 +978,38 @@ public function attachFromStorageDisk($disk, $path, $name = null, array $options
945978
return $this;
946979
}
947980

981+
/**
982+
* Determine if the mailable has the given attachment from storage.
983+
*
984+
* @param string $path
985+
* @param string|null $name
986+
* @param array $options
987+
* @return bool
988+
*/
989+
public function hasAttachmentFromStorage($path, $name = null, array $options = [])
990+
{
991+
return $this->hasAttachmentFromStorageDisk(null, $path, $name, $options);
992+
}
993+
994+
/**
995+
* Determine if the mailable has the given attachment from a specific storage disk.
996+
*
997+
* @param string $disk
998+
* @param string $path
999+
* @param string|null $name
1000+
* @param array $options
1001+
* @return bool
1002+
*/
1003+
public function hasAttachmentFromStorageDisk($disk, $path, $name = null, array $options = [])
1004+
{
1005+
return collect($this->diskAttachments)->contains(
1006+
fn ($attachment) => $attachment['disk'] === $disk
1007+
&& $attachment['path'] === $path
1008+
&& $attachment['name'] === ($name ?? basename($path))
1009+
&& $attachment['options'] === $options
1010+
);
1011+
}
1012+
9481013
/**
9491014
* Attach in-memory data as an attachment.
9501015
*
@@ -964,6 +1029,23 @@ public function attachData($data, $name, array $options = [])
9641029
return $this;
9651030
}
9661031

1032+
/**
1033+
* Determine if the mailable has the given data as an attachment.
1034+
*
1035+
* @param string $data
1036+
* @param string $name
1037+
* @param array $options
1038+
* @return bool
1039+
*/
1040+
public function hasAttachedData($data, $name, array $options = [])
1041+
{
1042+
return collect($this->rawAttachments)->contains(
1043+
fn ($attachment) => $attachment['data'] === $data
1044+
&& $attachment['name'] === $name
1045+
&& array_filter($attachment['options']) === array_filter($options)
1046+
);
1047+
}
1048+
9671049
/**
9681050
* Add a tag header to the message when supported by the underlying transport.
9691051
*
@@ -1093,6 +1175,86 @@ public function assertSeeInOrderInText($strings)
10931175
return $this;
10941176
}
10951177

1178+
/**
1179+
* Assert the mailable has the given attachment.
1180+
*
1181+
* @param string|\Illuminate\Contracts\Mail\Attachable|\Illuminate\Mail\Attachment $file
1182+
* @param array $options
1183+
* @return $this
1184+
*/
1185+
public function assertHasAttachment($file, array $options = [])
1186+
{
1187+
$this->renderForAssertions();
1188+
1189+
PHPUnit::assertTrue(
1190+
$this->hasAttachment($file, $options),
1191+
'Did not find the expected attachment.'
1192+
);
1193+
1194+
return $this;
1195+
}
1196+
1197+
/**
1198+
* Assert the mailable has the given data as an attachment.
1199+
*
1200+
* @param string $data
1201+
* @param string $name
1202+
* @param array $options
1203+
* @return $this
1204+
*/
1205+
public function assertHasAttachedData($data, $name, array $options = [])
1206+
{
1207+
$this->renderForAssertions();
1208+
1209+
PHPUnit::assertTrue(
1210+
$this->hasAttachedData($data, $name, $options),
1211+
'Did not find the expected attachment.'
1212+
);
1213+
1214+
return $this;
1215+
}
1216+
1217+
/**
1218+
* Assert the mailable has the given attachment from storage.
1219+
*
1220+
* @param string $path
1221+
* @param string|null $name
1222+
* @param array $options
1223+
* @return $this
1224+
*/
1225+
public function assertHasAttachmentFromStorage($path, $name = null, array $options = [])
1226+
{
1227+
$this->renderForAssertions();
1228+
1229+
PHPUnit::assertTrue(
1230+
$this->hasAttachmentFromStorage($path, $name, $options),
1231+
'Did not find the expected attachment.'
1232+
);
1233+
1234+
return $this;
1235+
}
1236+
1237+
/**
1238+
* Assert the mailable has the given attachment from a specific storage disk.
1239+
*
1240+
* @param string $disk
1241+
* @param string $path
1242+
* @param string|null $name
1243+
* @param array $options
1244+
* @return $this
1245+
*/
1246+
public function assertHasAttachmentFromStorageDisk($disk, $path, $name = null, array $options = [])
1247+
{
1248+
$this->renderForAssertions();
1249+
1250+
PHPUnit::assertTrue(
1251+
$this->hasAttachmentFromStorageDisk($disk, $path, $name, $options),
1252+
'Did not find the expected attachment.'
1253+
);
1254+
1255+
return $this;
1256+
}
1257+
10961258
/**
10971259
* Render the HTML and plain-text version of the mailable into views for assertions.
10981260
*

tests/Integration/Mail/AttachingFromStorageTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Illuminate\Tests\Integration\Mail;
44

55
use Illuminate\Mail\Attachment;
6+
use Illuminate\Mail\Mailable;
67
use Illuminate\Notifications\Messages\MailMessage;
78
use Illuminate\Support\Facades\Storage;
89
use Orchestra\Testbench\TestCase;
@@ -65,4 +66,13 @@ public function testItCanChainAttachWithMailMessage()
6566

6667
$this->assertSame($message, $result);
6768
}
69+
70+
public function testItCanCheckForStorageBasedAttachments()
71+
{
72+
Storage::disk()->put('/dir/foo.png', 'expected body contents');
73+
$mailable = new Mailable();
74+
$mailable->attach(Attachment::fromStorage('/dir/foo.png'));
75+
76+
$this->assertTrue($mailable->hasAttachment(Attachment::fromStorage('/dir/foo.png')));
77+
}
6878
}

0 commit comments

Comments
 (0)