Skip to content

Commit b7c207f

Browse files
committed
Add tests
1 parent 2708386 commit b7c207f

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

tests/Unit/FileMessageTest.php

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,160 @@
198198
expect($attachments[0]->filename())->toBe('inline_image.png');
199199
});
200200

201+
test('it can extract attachments from forwarded messages', function () {
202+
// Create a forwarded message that contains an attachment
203+
$forwardedMessage = <<<'EOT'
204+
From: "Original Sender" <original@example.com>
205+
To: "Original Recipient" <original-recipient@example.com>
206+
Subject: Original Message with Attachment
207+
Date: Tue, 18 Feb 2025 10:00:00 -0500
208+
Message-ID: <original-message@example.com>
209+
MIME-Version: 1.0
210+
Content-Type: multipart/mixed; boundary="ORIGINAL_BOUNDARY"
211+
212+
--ORIGINAL_BOUNDARY
213+
Content-Type: text/plain; charset="UTF-8"
214+
215+
This is the original message with an attachment.
216+
217+
--ORIGINAL_BOUNDARY
218+
Content-Type: application/pdf; name="original-document.pdf"
219+
Content-Disposition: attachment; filename="original-document.pdf"
220+
Content-Transfer-Encoding: base64
221+
222+
JVBERi0xLjUKJeLjz9MKMyAwIG9iago8PC9MZW5ndGggNCAgIC9GaWx0ZXIvQXNjaWlIYXgg
223+
ICAgPj5zdHJlYW0Kc3R1ZmYKZW5kc3RyZWFtCmVuZG9iajAK
224+
--ORIGINAL_BOUNDARY--
225+
EOT;
226+
227+
// Create the main message that forwards the above message
228+
$contents = <<<EOT
229+
From: "Forwarder" <forwarder@example.com>
230+
To: "Final Recipient" <final@example.com>
231+
Subject: Fwd: Original Message with Attachment
232+
Date: Wed, 19 Feb 2025 12:34:56 -0500
233+
Message-ID: <forwarded-message@example.com>
234+
MIME-Version: 1.0
235+
Content-Type: multipart/mixed; boundary="FORWARD_BOUNDARY"
236+
237+
--FORWARD_BOUNDARY
238+
Content-Type: text/plain; charset="UTF-8"
239+
240+
Here is the forwarded message with its attachment.
241+
242+
--FORWARD_BOUNDARY
243+
Content-Type: message/rfc822; name="forwarded-message.eml"
244+
Content-Disposition: attachment; filename="forwarded-message.eml"
245+
246+
$forwardedMessage
247+
--FORWARD_BOUNDARY
248+
Content-Type: application/zip; name="additional-file.zip"
249+
Content-Disposition: attachment; filename="additional-file.zip"
250+
Content-Transfer-Encoding: base64
251+
252+
UEsDBAoAAAAAAKxVVVMAAAAAAAAAAAAAAAAJAAAAdGVzdC50eHRQSwECFAAKAAAAAACs
253+
VVVTAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAAAAAAAHRlc3QudHh0UEsFBgAAAAABAAEA
254+
NwAAAB8AAAAAAA==
255+
--FORWARD_BOUNDARY--
256+
EOT;
257+
258+
$message = new FileMessage($contents);
259+
260+
// Should find attachments from both the main message and the forwarded message
261+
$attachments = $message->attachments();
262+
263+
expect($attachments)->toHaveCount(2);
264+
265+
// First attachment should be from the forwarded message
266+
expect($attachments[0]->filename())->toBe('original-document.pdf');
267+
expect($attachments[0]->contentType())->toBe('application/pdf');
268+
269+
// Second attachment should be from the main message
270+
expect($attachments[1]->filename())->toBe('additional-file.zip');
271+
expect($attachments[1]->contentType())->toBe('application/zip');
272+
});
273+
274+
test('it can handle multiple levels of forwarded messages with attachments', function () {
275+
// Create the deepest nested message with an attachment
276+
$deepestMessage = <<<'EOT'
277+
From: "Deep Sender" <deep@example.com>
278+
To: "Deep Recipient" <deep-recipient@example.com>
279+
Subject: Deep Message
280+
MIME-Version: 1.0
281+
Content-Type: multipart/mixed; boundary="DEEP_BOUNDARY"
282+
283+
--DEEP_BOUNDARY
284+
Content-Type: text/plain; charset="UTF-8"
285+
286+
This is the deepest message.
287+
288+
--DEEP_BOUNDARY
289+
Content-Type: text/plain; name="deep-file.txt"
290+
Content-Disposition: attachment; filename="deep-file.txt"
291+
292+
Deep file content
293+
--DEEP_BOUNDARY--
294+
EOT;
295+
296+
// Create a middle forwarded message that forwards the deep message
297+
$middleMessage = <<<EOT
298+
From: "Middle Sender" <middle@example.com>
299+
To: "Middle Recipient" <middle-recipient@example.com>
300+
Subject: Fwd: Deep Message
301+
MIME-Version: 1.0
302+
Content-Type: multipart/mixed; boundary="MIDDLE_BOUNDARY"
303+
304+
--MIDDLE_BOUNDARY
305+
Content-Type: text/plain; charset="UTF-8"
306+
307+
Forwarding the deep message.
308+
309+
--MIDDLE_BOUNDARY
310+
Content-Type: message/rfc822
311+
312+
$deepestMessage
313+
--MIDDLE_BOUNDARY
314+
Content-Type: image/jpeg; name="middle-image.jpg"
315+
Content-Disposition: attachment; filename="middle-image.jpg"
316+
Content-Transfer-Encoding: base64
317+
318+
/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
319+
--MIDDLE_BOUNDARY--
320+
EOT;
321+
322+
// Create the top-level message
323+
$contents = <<<EOT
324+
From: "Top Sender" <top@example.com>
325+
To: "Top Recipient" <top-recipient@example.com>
326+
Subject: Fwd: Fwd: Deep Message
327+
MIME-Version: 1.0
328+
Content-Type: multipart/mixed; boundary="TOP_BOUNDARY"
329+
330+
--TOP_BOUNDARY
331+
Content-Type: text/plain; charset="UTF-8"
332+
333+
Multiple levels of forwarding.
334+
335+
--TOP_BOUNDARY
336+
Content-Type: message/rfc822
337+
338+
$middleMessage
339+
--TOP_BOUNDARY--
340+
EOT;
341+
342+
$message = new FileMessage($contents);
343+
344+
$attachments = $message->attachments();
345+
346+
// Should find attachments from all levels: deep-file.txt and middle-image.jpg
347+
expect($attachments)->toHaveCount(2);
348+
349+
// Verify we get attachments from nested messages
350+
$filenames = array_map(fn ($attachment) => $attachment->filename(), $attachments);
351+
expect($filenames)->toContain('deep-file.txt');
352+
expect($filenames)->toContain('middle-image.jpg');
353+
});
354+
201355
test('it can determine if two messages are the same', function () {
202356
$contents1 = <<<'EOT'
203357
From: "John Doe" <john@example.com>

0 commit comments

Comments
 (0)