-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Run ./tests/MessageRendering/run-tests.sh to run all tests in that directory, which are supposed to check the rendering of concrete messages. The messages are served by a dovecot container from the Maildir in `tests/MessageRendering/src/maildir` and identified by their `Message-Id`.
- Loading branch information
Showing
13 changed files
with
490 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
src/maildir/subscriptions | ||
src/maildir/dovecot-uidvalidity | ||
src/maildir/dovecot.*.log | ||
src/maildir/dovecot.*.cache | ||
src/maildir/dovecot.list.index | ||
src/maildir/dovecot-uid* | ||
src/maildir/.Drafts | ||
src/maildir/.Junk | ||
src/maildir/.Sent | ||
src/maildir/.Trash | ||
.phpunit.result.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
|
||
namespace Tests\MessageRendering; | ||
|
||
/** | ||
* Test class to test simple messages. | ||
*/ | ||
class BasicMessagesTest extends MessageRenderingTestCase | ||
{ | ||
/** | ||
* Test that two text mime-parts with disposition "attachment" are shown as | ||
* attachments. | ||
*/ | ||
public function test_list_00() | ||
{ | ||
$domxpath = $this->run_and_get_html_output_domxpath('[email protected]'); | ||
$this->assertSame('Lines', $this->getScrubbedSubject($domxpath)); | ||
|
||
$this->assertStringStartsWith('Plain text message body.', $this->getBody($domxpath)); | ||
|
||
$attchElems = $domxpath->query('//span[@class="attachment-name"]'); | ||
$this->assertCount(2, $attchElems, 'Attachments'); | ||
$this->assertStringStartsWith('lines.txt', $attchElems[0]->textContent); | ||
$this->assertStringStartsWith('lines_lf.txt', $attchElems[1]->textContent); | ||
} | ||
|
||
/** | ||
* Test that one inline image is not shown as attachment. | ||
*/ | ||
public function test_list_01() | ||
{ | ||
$domxpath = $this->run_and_get_html_output_domxpath('[email protected]'); | ||
|
||
$this->assertSame('Test HTML with local and remote image', $this->getScrubbedSubject($domxpath)); | ||
|
||
$this->assertSame("Attached image: \nRemote image:", $this->getBody($domxpath)); | ||
|
||
$attchNames = $domxpath->query('//span[@class="attachment-name"]'); | ||
$this->assertCount(0, $attchNames, 'Attachments'); | ||
} | ||
|
||
/** | ||
* Test that text parts are shown and also listed as attachments, and that | ||
* filenames are properly listed. | ||
*/ | ||
public function test_filename() | ||
{ | ||
$domxpath = $this->run_and_get_html_output_domxpath('[email protected]'); | ||
|
||
$this->assertSame('Attachment filename encoding', $this->getScrubbedSubject($domxpath)); | ||
|
||
$msgParts = $domxpath->query('//div[@class="message-part"]'); | ||
$this->assertCount(3, $msgParts, 'Message text parts'); | ||
|
||
$this->assertSame("foo\nbar\ngna", $msgParts[0]->textContent); | ||
$this->assertSame('潦੯慢ੲ湧', $msgParts[1]->textContent); | ||
$this->assertSame("foo\nbar\ngna", $msgParts[2]->textContent); | ||
|
||
$attchNames = $domxpath->query('//span[@class="attachment-name"]'); | ||
$this->assertCount(6, $attchNames, 'Attachments'); | ||
|
||
$this->assertSame('A011.txt', $attchNames[0]->textContent); | ||
$this->assertSame('A012.txt', $attchNames[1]->textContent); | ||
$this->assertSame('A014.txt', $attchNames[2]->textContent); | ||
$this->assertSame('żółć.png', $attchNames[3]->textContent); | ||
$this->assertSame('żółć.png', $attchNames[4]->textContent); | ||
$this->assertSame('very very very very long very very very very long ćććććć very very very long name.txt', $attchNames[5]->textContent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<?php | ||
|
||
namespace Tests\MessageRendering; | ||
|
||
use Masterminds\HTML5; | ||
|
||
/** | ||
* Class to base actual test classes on, which test specific message rendering. | ||
*/ | ||
class MessageRenderingTestCase extends \ActionTestCase | ||
{ | ||
/** | ||
* Get the body from the document, trimmed from surrounding whitespace. | ||
*/ | ||
protected function getBody(\DOMXPath $domxpath): string | ||
{ | ||
$bodyElem = $domxpath->query('//div[@id="messagebody"]'); | ||
$this->assertCount(1, $bodyElem, 'Message body'); | ||
return trim($bodyElem[0]->textContent); | ||
} | ||
|
||
/** | ||
* Get the subject from the document, stripped by the prefix "Subject: ", | ||
* the suffix "Open in new window", and trimmed from surrounding whitespace. | ||
*/ | ||
protected function getScrubbedSubject(\DOMXPath $domxpath): string | ||
{ | ||
$subjectElem = $domxpath->query('//h2[@class="subject"][1]'); | ||
$subject = preg_replace('/^\s*Subject:\s*(.*)\s*Open in new window$/', '$1', trim($subjectElem[0]->textContent)); | ||
return trim($subject); | ||
} | ||
|
||
/** | ||
* Execute run() to render the message with the given $msg_id. | ||
* | ||
* This is useful to check how rcmail_action_mail_show() renders messages. | ||
* It requires a running dovecot to fetch the messages from. Messages need | ||
* to be placed as individual files in | ||
* `tests/src/emails/test@example/Mail/cur/`. | ||
*/ | ||
protected function run_and_get_html_output_domxpath(string $msg_id): \DOMXPath | ||
{ | ||
$rcmail = \rcmail::get_instance(); | ||
// We need to overwrite the storage object, else storage_init() just | ||
// returns the cached one (which might be a StorageMock instance). | ||
$mock_storage = $rcmail->storage = null; | ||
$rcmail->storage_init(); | ||
// Login our test user so we can fetch messages from the imap server. | ||
$rcmail->login('test', 'pass', 'tls://localhost'); | ||
$storage = $rcmail->get_storage(); | ||
$storage->set_options(['all_headers' => true]); | ||
// We need to set the folder, else no message can be fetched. | ||
$storage->set_folder('INBOX'); | ||
$output = $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', 'preview'); | ||
// TODO: Why do we need to set the skin manually? | ||
$output->set_skin('elastic'); | ||
|
||
$action = new \rcmail_action_mail_show(); | ||
$this->assertTrue($action->checks()); | ||
|
||
$messages_list = $storage->list_messages(); | ||
|
||
// Find the UID of the wanted message. | ||
$message_uid = null; | ||
foreach ($messages_list as $message_headers) { | ||
if ($message_headers->get('message-id') === "<{$msg_id}>") { | ||
$message_uid = $message_headers->uid; | ||
break; | ||
} | ||
} | ||
if ($message_uid === null) { | ||
throw new \Exception("No message found in messages list with Message-Id '{$msg_id}'"); | ||
} | ||
|
||
// Prepare and trigger the rendering. | ||
$_GET = ['_uid' => $message_uid]; | ||
$html = ''; | ||
try { | ||
$action->run(); | ||
} catch (\ExitException $e) { | ||
throw $e; | ||
} catch (\Exception $e) { | ||
$this->assertSame('simulatedExit', $e->getMessage()); | ||
$html = $output->getOutput(); | ||
} | ||
|
||
// Reset the storage to the mocked one most other tests expect. | ||
$rcmail->storage = $mock_storage; | ||
|
||
// disabled_html_ns=true is a workaround for the performance issue | ||
// https://github.com/Masterminds/html5-php/issues/181 | ||
$html5 = new HTML5(['disable_html_ns' => true]); | ||
return new \DOMXPath($html5->loadHTML($html)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace Tests\MessageRendering; | ||
|
||
/** | ||
* Test class to test "interesting" messages. | ||
*/ | ||
class SingleImageNoTextTest extends MessageRenderingTestCase | ||
{ | ||
/** | ||
* Test that of a multipart/mixed message which contains only one | ||
* image, that image is shown. | ||
*/ | ||
public function test_show_multipart_mixed_single_image_too() | ||
{ | ||
$this->markTestSkipped('TBD: test for fixing GH issue 9443'); // @phpstan-ignore-line | ||
|
||
$domxpath = $this->run_and_get_html_output_domxpath('[email protected]'); | ||
|
||
$this->assertSame('Not OK', $this->getScrubbedSubject($domxpath)); | ||
|
||
$attchNames = $domxpath->query('//span[@class="attachment-name"]'); | ||
$this->assertCount(1, $attchNames, 'Attachments'); | ||
$this->assertStringStartsWith('Resized_20240427_200026(1).jpeg', $attchNames[0]->textContent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
/* | ||
+-----------------------------------------------------------------------+ | ||
| This file is part of the Roundcube Webmail client | | ||
| | | ||
| Copyright (C) The Roundcube Dev Team | | ||
| | | ||
| Licensed under the GNU General Public License version 3 or | | ||
| any later version with exceptions for skins & plugins. | | ||
| See the README file for a full license statement. | | ||
| | | ||
| PURPOSE: | | ||
| Environment initialization script for unit tests | | ||
+-----------------------------------------------------------------------+ | ||
| Author: Thomas Bruederli <[email protected]> | | ||
| Author: Aleksander Machniak <[email protected]> | | ||
+-----------------------------------------------------------------------+ | ||
*/ | ||
|
||
error_reporting(\E_ALL); | ||
|
||
if (\PHP_SAPI != 'cli') { | ||
exit('Not in shell mode (php-cli)'); | ||
} | ||
|
||
if (!defined('INSTALL_PATH')) { | ||
define('INSTALL_PATH', realpath(__DIR__ . '/../../') . '/'); | ||
} | ||
|
||
define('ROUNDCUBE_TEST_MODE', true); | ||
define('ROUNDCUBE_TEST_SESSION', microtime(true)); | ||
define('TESTS_DIR', __DIR__ . '/'); | ||
|
||
if (@is_dir(TESTS_DIR . 'config')) { | ||
define('RCUBE_CONFIG_DIR', TESTS_DIR . 'config'); | ||
} | ||
|
||
// Some tests depend on the way phpunit is executed | ||
$_SERVER['SCRIPT_NAME'] = 'vendor/bin/phpunit'; | ||
|
||
require_once INSTALL_PATH . 'program/include/iniset.php'; | ||
|
||
rcmail::get_instance(0, 'test')->config->set('devel_mode', false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mail_location = maildir:~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?xml version="1.0"?> | ||
<phpunit | ||
bootstrap="bootstrap.php" | ||
colors="true" | ||
> | ||
<extensions> | ||
<extension class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/> | ||
</extensions> | ||
<testsuites> | ||
<testsuite name="tests"> | ||
<directory>.</directory> | ||
</testsuite> | ||
</testsuites> | ||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#!/bin/bash | ||
|
||
testsdir=$(realpath $(dirname $0)) | ||
cont_name="roundcubetest-dovecot" | ||
|
||
docker run -it --rm -d --name "$cont_name" \ | ||
-p 143:143 \ | ||
-v "$testsdir/src/maildir:/srv/mail/test" \ | ||
-v "$testsdir/dovecot-maildir.conf:/etc/dovecot/conf.d/dovecot-maildir.conf" \ | ||
docker.io/dovecot/dovecot:latest >/dev/null || exit 1 | ||
|
||
"$testsdir/../../vendor/bin/phpunit" -c "$testsdir/phpunit.xml" --fail-on-warning --fail-on-risky | ||
|
||
docker stop "$cont_name" >/dev/null |
34 changes: 34 additions & 0 deletions
34
tests/MessageRendering/src/maildir/cur/attachment-gh9443.eml:2,S
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
Message-Id: <[email protected]> | ||
Date:Mon, 06 May 2024 15:24:47 +0200 | ||
From: <[email protected]> | ||
To: [email protected] | ||
Subject: Not OK | ||
Mime-Version:1.0 | ||
Content-Type:multipart/mixed;boundary="--------------------------------------------=_NextPart_0_24856" | ||
|
||
this is a multi-part message in MIME format. | ||
|
||
----------------------------------------------=_NextPart_0_24856 | ||
Content-Type:image/jpeg; name="Resized_20240427_200026(1).jpeg" | ||
Content-Transfer-Encoding:base64 | ||
Content-Location:Resized_20240427_200026(1).jpeg | ||
Content-ID:<Resized_20240427_200026(1)> | ||
|
||
iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADMElEQVR4nOzVwQnAIBQFQYXff81R | ||
UkQCOyDj1YOPnbXWPmeTRef+/3O/OyBjzh3CD95BfqICMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0C | ||
MK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMK0CMO0TAAD//2An | ||
hf4QtqobAAAAAElFTkSuQmCC | ||
|
||
----------------------------------------------=_NextPart_0_24856-- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
From: "Thomas B." <[email protected]> | ||
To: Tom Tester <[email protected]> | ||
Subject: Attachment filename encoding | ||
MIME-Version: 1.0 | ||
Content-Type: multipart/mixed; boundary=1234; | ||
Date: Fri, 23 May 2014 19:44:50 +0200 | ||
Message-ID: <[email protected]> | ||
|
||
--1234 | ||
Content-Transfer-Encoding: base64 | ||
Content-Type: text/plain; name=A011.txt | ||
|
||
Zm9vDQpiYXINCmduYQ== | ||
--1234 | ||
Content-Transfer-Encoding: base64 | ||
Content-Type: text/plain; charset=UTF-16LE; name=A012.txt | ||
|
||
Zm9vCmJhcgpnbmE= | ||
--1234 | ||
Content-Transfer-Encoding: base64 | ||
Content-Type: text/plain; name=A013.txt | ||
Content-Disposition: attachment; filename=A014.txt | ||
|
||
Zm9vDQpiYXINCmduYQ== | ||
--1234 | ||
Content-Transfer-Encoding: base64 | ||
Content-Type: image/png; charset=UTF-16LE; | ||
name="=?UTF-8?Q?=C5=BC=C3=B3=C5=82=C4=87=2Epng?=" | ||
|
||
Zm9vCmJhcgpnbmE= | ||
--1234 | ||
Content-Transfer-Encoding: base64 | ||
Content-Type: image/png; charset=UTF-16LE; name=A016.txt | ||
Content-Disposition: attachment; | ||
filename*=UTF-8''%C5%BC%C3%B3%C5%82%C4%87.png | ||
|
||
Zm9vCmJhcgpnbmE= | ||
--1234 | ||
Content-Transfer-Encoding: base64 | ||
Content-Type: text/plain; charset=iso-8859-1; | ||
name="=?UTF-8?Q?very_very_very_very_long_very_very_very_very_long_=C4=87?= | ||
=?UTF-8?Q?=C4=87=C4=87=C4=87=C4=87=C4=87_very_very_very_long_name=2Etxt?= | ||
=?UTF-8?Q??=" | ||
|
||
Zm9vCmJhcgpnbmE= | ||
--1234-- |
Oops, something went wrong.