mirror of
https://github.com/roundcube/roundcubemail.git
synced 2026-02-19 17:11:20 +01:00
Test message rendering (#9460)
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
services:
|
||||
mailhost:
|
||||
image: docker.io/greenmail/standalone
|
||||
environment:
|
||||
GREENMAIL_OPTS: '-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.preload.dir=/emails'
|
||||
volumes:
|
||||
- "../tests/MessageRendering/data/greenmail:/emails"
|
||||
browserhost:
|
||||
image: docker.io/selenium/standalone-chromium
|
||||
ports:
|
||||
@@ -40,6 +44,17 @@ services:
|
||||
command:
|
||||
- .ci/run_tests.sh
|
||||
|
||||
test_message_rendering:
|
||||
depends_on:
|
||||
- mailhost
|
||||
image: ghcr.io/roundcube/roundcubemail-testrunner:php8.3
|
||||
environment:
|
||||
RC_CONFIG_IMAP_HOST: 'tls://mailhost:3143'
|
||||
volumes:
|
||||
- '..:/app'
|
||||
command:
|
||||
- .ci/run_test_message_rendering.sh
|
||||
|
||||
codespell:
|
||||
image: ghcr.io/roundcube/roundcubemail-testrunner:php8.3
|
||||
volumes:
|
||||
|
||||
11
.ci/run_test_message_rendering.sh
Executable file
11
.ci/run_test_message_rendering.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
if ! test -f config/config-test.inc.php; then
|
||||
cp -v .ci/config-test.inc.php config/config-test.inc.php
|
||||
fi
|
||||
|
||||
# Install dependencies, prefer highest.
|
||||
composer update --prefer-dist --no-interaction --no-progress
|
||||
|
||||
# Execute tests.
|
||||
vendor/bin/phpunit -c ./tests/MessageRendering/phpunit.xml --fail-on-warning --fail-on-risky
|
||||
37
.github/workflows/message_rendering.yml
vendored
Normal file
37
.github/workflows/message_rendering.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Message Rendering
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
message_rendering:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
name: Linux / PHP 8.3
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Run via docker compose because we can't run greenmail in a server here
|
||||
# (it requires the testing emails to be present when starting but
|
||||
# services are started before the repo is cloned). And instead of
|
||||
# re-building what our compose-file contains we can just use it.
|
||||
- name: Run tests via docker compose
|
||||
run: docker compose -f .ci/compose.yaml run test_message_rendering
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@master
|
||||
if: failure()
|
||||
with:
|
||||
name: Logs
|
||||
path: logs/errors.log
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -34,3 +34,6 @@ skins/elastic/styles/_variables.less
|
||||
.vscode
|
||||
.DS_Store
|
||||
.idea
|
||||
|
||||
# Ignore files used for local overriding.
|
||||
/tests/MessageRendering/.env
|
||||
|
||||
@@ -172,7 +172,7 @@ class rcmail_action_mail_show extends rcmail_action_mail_index
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
$rcmail->output->sendExit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
11
tests/MessageRendering/.gitignore
vendored
Normal file
11
tests/MessageRendering/.gitignore
vendored
Normal file
@@ -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
|
||||
69
tests/MessageRendering/BasicMessagesTest.php
Normal file
69
tests/MessageRendering/BasicMessagesTest.php
Normal file
@@ -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 testList00()
|
||||
{
|
||||
$domxpath = $this->runAndGetHtmlOutputDomxpath('99839b8ec12482419372f1edafa9de75@woodcrest.local');
|
||||
$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 testList01()
|
||||
{
|
||||
$domxpath = $this->runAndGetHtmlOutputDomxpath('3ef8a0120cd7dc2fd776468c8515e29a@domain.tld');
|
||||
|
||||
$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 testFilename()
|
||||
{
|
||||
$domxpath = $this->runAndGetHtmlOutputDomxpath('de75@tester.local');
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
95
tests/MessageRendering/MessageRenderingTestCase.php
Normal file
95
tests/MessageRendering/MessageRenderingTestCase.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\MessageRendering;
|
||||
|
||||
use Masterminds\HTML5;
|
||||
use Roundcube\Tests\ActionTestCase;
|
||||
use Roundcube\Tests\ExitException;
|
||||
|
||||
/**
|
||||
* 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 $msgId.
|
||||
*
|
||||
* 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 runAndGetHtmlOutputDomxpath(string $msgId): \DOMXPath
|
||||
{
|
||||
$imap_host = getenv('RC_CONFIG_IMAP_HOST') ?: 'tls://localhost:143';
|
||||
$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).
|
||||
$mockStorage = $rcmail->storage = null;
|
||||
$rcmail->storage_init();
|
||||
// Login our test user so we can fetch messages from the imap server.
|
||||
$rcmail->login('test-message-rendering@localhost', 'pass', $imap_host);
|
||||
$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());
|
||||
|
||||
$messagesList = $storage->list_messages();
|
||||
|
||||
// Find the UID of the wanted message.
|
||||
$messageUid = null;
|
||||
foreach ($messagesList as $messageHeaders) {
|
||||
if ($messageHeaders->get('message-id') === "<{$msgId}>") {
|
||||
$messageUid = $messageHeaders->uid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($messageUid === null) {
|
||||
throw new \Exception("No message found in messages list with Message-Id '{$msgId}'");
|
||||
}
|
||||
|
||||
// Prepare and trigger the rendering.
|
||||
$_GET = ['_uid' => $messageUid];
|
||||
$html = '';
|
||||
try {
|
||||
$action->run();
|
||||
} catch (ExitException $e) {
|
||||
$html = $output->getOutput();
|
||||
}
|
||||
|
||||
// Reset the storage to the mocked one most other tests expect.
|
||||
$rcmail->storage = $mockStorage;
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
29
tests/MessageRendering/SingleImageNoTextTest.php
Normal file
29
tests/MessageRendering/SingleImageNoTextTest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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 testShowMultipartMixedSingleImageToo()
|
||||
{
|
||||
$this->markTestSkipped('TBD: test for fixing GH issue 9443');
|
||||
// This next comment line prevents phpstan from reporting this as
|
||||
// unreachable code (technically it is right, but that's on purpose
|
||||
// here...).
|
||||
// @phpstan-ignore-next-line
|
||||
$domxpath = $this->runAndGetHtmlOutputDomxpath('XXXXXXXXXXXXX@mx01.lytzenitmail.dk');
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
||||
44
tests/MessageRendering/bootstrap.php
Normal file
44
tests/MessageRendering/bootstrap.php
Normal file
@@ -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 <roundcube@gmail.com> |
|
||||
| Author: Aleksander Machniak <alec@alec.pl> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
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);
|
||||
@@ -0,0 +1,34 @@
|
||||
Message-Id: <XXXXXXXXXXXXX@mx01.lytzenitmail.dk>
|
||||
Date:Mon, 06 May 2024 15:24:47 +0200
|
||||
From: <+45XXXXXXXX@telenor.dk>
|
||||
To: XXXXXX@jubii.dk
|
||||
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--
|
||||
@@ -0,0 +1,46 @@
|
||||
From: "Thomas B." <thomas@roundcube.net>
|
||||
To: Tom Tester <tb@tester.local>
|
||||
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: <de75@tester.local>
|
||||
|
||||
--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--
|
||||
@@ -0,0 +1,46 @@
|
||||
Return-Path: <thomas@roundcube.net>
|
||||
X-Original-To: tb@tester.local
|
||||
From: "Thomas B." <thomas@roundcube.net>
|
||||
To: Tom Tester <tb@tester.local>
|
||||
Subject: Lines
|
||||
Cc: test1@domain.tld, test2@domain.tld, test3@domain.tld, test4@domain.tld,
|
||||
test5@domain.tld, test6@domain.tld, test7@domain.tld, test8@domain.tld,
|
||||
test9@domain.tld, test10@domain.tld, test11@domain.tld, test12@domain.tld
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed;
|
||||
boundary="=_8853bfb47b7da1852ac882e69cc724f3"
|
||||
Date: Fri, 23 May 2014 19:44:50 +0200
|
||||
Reply-To: hello@roundcube.net
|
||||
Mail-Reply-To: hello@roundcube.net
|
||||
Message-ID: <99839b8ec12482419372f1edafa9de75@woodcrest.local>
|
||||
X-Sender: thomas@roundcube.net
|
||||
|
||||
--=_8853bfb47b7da1852ac882e69cc724f3
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Content-Type: text/plain; charset=UTF-8;
|
||||
format=flowed
|
||||
|
||||
Plain text message body.
|
||||
|
||||
--
|
||||
Developer of Free Software
|
||||
Sent with Roundcube Webmail - roundcube.net
|
||||
--=_8853bfb47b7da1852ac882e69cc724f3
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Type: text/plain;
|
||||
name=lines.txt
|
||||
Content-Disposition: attachment;
|
||||
filename=lines.txt;
|
||||
size=13
|
||||
|
||||
Zm9vDQpiYXINCmduYQ==
|
||||
--=_8853bfb47b7da1852ac882e69cc724f3
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Type: text/plain;
|
||||
name=lines_lf.txt
|
||||
Content-Disposition: attachment;
|
||||
filename=lines_lf.txt;
|
||||
size=11
|
||||
|
||||
Zm9vCmJhcgpnbmE=
|
||||
--=_8853bfb47b7da1852ac882e69cc724f3--
|
||||
@@ -0,0 +1,89 @@
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="=_08f545e592541b77db5fd93e3267655b"
|
||||
Date: Sat, 11 Jan 2020 19:31:21 +0100
|
||||
From: test-from@domain.tld
|
||||
To: test-to@domain.tld
|
||||
Subject: Test HTML with local and remote image
|
||||
Message-ID: <3ef8a0120cd7dc2fd776468c8515e29a@domain.tld>
|
||||
|
||||
--=_08f545e592541b77db5fd93e3267655b
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Content-Type: text/plain; charset=US-ASCII;
|
||||
format=flowed
|
||||
|
||||
Attached image:
|
||||
|
||||
Remote image:
|
||||
--=_08f545e592541b77db5fd93e3267655b
|
||||
Content-Type: multipart/related;
|
||||
boundary="=_48ae8051b8f2cc74607d3ed75f3568af"
|
||||
|
||||
--=_48ae8051b8f2cc74607d3ed75f3568af
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=
|
||||
=3DUTF-8" /></head><body style=3D'font-size: 10pt; font-family: Verdana,Gen=
|
||||
eva,sans-serif'>
|
||||
<p id=3D"attached">Attached image: <img src=3D"cid:15787674815e1a1479c8db24=
|
||||
52476888@alec.pl" alt=3D"" /></p>
|
||||
<p id=3D"remote">Remote image: <img src=3D"https://roundcube.net/images/rou=
|
||||
ndcube_logo_icon.svg" width=3D"16" /></p>
|
||||
<p><br /></p>
|
||||
|
||||
</body></html>
|
||||
|
||||
--=_48ae8051b8f2cc74607d3ed75f3568af
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <15787674815e1a1479c8db2452476888@alec.pl>
|
||||
Content-Type: image/x-icon;
|
||||
name=favicon.ico
|
||||
Content-Disposition: inline;
|
||||
filename=favicon.ico;
|
||||
size=2294
|
||||
|
||||
AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAAABACAAaAQAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA
|
||||
AAAEAADDDgAAww4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRPQABUT0ADT0xAQW9hP8DkrDjA
|
||||
/8E3Qf++NwP/vjcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVE9AAFRPQABUT0AiVE9AilNOQOhp
|
||||
XD//6rE4//+/N+j/vjeK/743Iv++NwD/vjcAAAAAAAAAAABUT0AAVE9AAFRPQBJUT0BrVE9A11RP
|
||||
QP5TTkD/aVw//+qxOP//vzf//743/v++N9f/vjdr/743Ev++NwD/vjcAVE9ACFRPQExUT0C/VE9A
|
||||
+1RPQP9UT0D/U05A/2hcPv/qsDj//783//++N///vjf//743+/++N7//vjdM/743CFRPQKxUT0Dx
|
||||
VE9A/1RPQP9UT0D/VE9A/1FNPv9sYUb/7LRA//++Nf//vjf//743//++N///vjf//7438f++N6xU
|
||||
T0D/VE9A/1RPQP9UT0D/U04//1VRQv91cmf/uriz/+vZs//4yWb//r45//++Nf//vjf//743//++
|
||||
N///vjf/VE9A/1RPQP9UT0D/U04//2hkWP+cmpT/0NDP/+bn5//l5uj/5+Pb/+/Vn//7xVX//742
|
||||
//++N///vjf//743/1RPQP9UT0D/V1JD/4mGfv++vbv/0NDQ/+Hh4f/l5eX/5eXl/+Xl5v/l5uf/
|
||||
6ODQ//PPhP/+vzv//743//++N/9UT0D/Uk0+/29rYP/FxcT/zc3N/9PT0//k5OT/5eXl/+Xl5f/l
|
||||
5eX/5eXl/+Xl5//n49z/+cdf//++Nf//vjf/VE9Ay1JNPvqJh37/zc3N/8zMzP/X19f/5eXl/+Xl
|
||||
5f/l5eX/5eXl/+Xl5f/l5eX/5eXn//PPhf//vTT6/743y1RPQBZRSzxum5mT4M3Nzf/MzMz/2NjY
|
||||
/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5//v1Z/g/70ybv++NxZUT0AA////AMbGxXTMzMz/
|
||||
zMzM/9bW1v/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5uPdddb9/wD/vjcAAAAAAMzMzADM
|
||||
zMw2zMzM7MzMzP/T09P/5OTk/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl7OXl5Tfl5eUAAAAAAAAA
|
||||
AADMzMwAzMzMBczMzJXMzMz/zs7O/+Dg4P/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5Zbk5OQF5OTk
|
||||
AAAAAAAAAAAAzMzMAMzMzADMzMwYzMzMp8zMzPvW1tb/5OTk/+Xl5f/l5eX/5eXl++Xl5anl5eUZ
|
||||
5eXlAOHh4QAAAAAAAAAAAAAAAADMzMwAzMzMAMzMzBLMzMx1zc3N1Nzc3Prl5eX65eXl1uXl5Xfl
|
||||
5eUT5eXlAOLi4gAAAAAAAAAAAPgfAADwDwAAwAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAwAMAAMADAADAAwAA4AcAAPAPAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4A
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFRPQABUT0ADT0xAQW9hP8DkrDjA/8E3Qf++NwP/vjcA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVE9AAFRPQABUT0AiVE9AilNOQOhpXD//6rE4//+/N+j/
|
||||
vjeK/743Iv++NwD/vjcAAAAAAAAAAABUT0AAVE9AAFRPQBJUT0BrVE9A11RPQP5TTkD/aVw//+qx
|
||||
OP//vzf//743/v++N9f/vjdr/743Ev++NwD/vjcAVE9ACFRPQExUT0C/VE9A+1RPQP9UT0D/U05A
|
||||
/2hcPv/qsDj//783//++N///vjf//743+/++N7//vjdM/743CFRPQKxUT0DxVE9A/1RPQP9UT0D/
|
||||
VE9A/1FNPv9sYUb/7LRA//++Nf//vjf//743//++N///vjf//7438f++N6xUT0D/VE9A/1RPQP9U
|
||||
T0D/U04//1VRQv91cmf/uriz/+vZs//4yWb//r45//++Nf//vjf//743//++N///vjf/VE9A/1RP
|
||||
QP9UT0D/U04//2hkWP+cmpT/0NDP/+bn5//l5uj/5+Pb/+/Vn//7xVX//742//++N///vjf//743
|
||||
/1RPQP9UT0D/V1JD/4mGfv++vbv/0NDQ/+Hh4f/l5eX/5eXl/+Xl5v/l5uf/6ODQ//PPhP/+vzv/
|
||||
/743//++N/9UT0D/Uk0+/29rYP/FxcT/zc3N/9PT0//k5OT/5eXl/+Xl5f/l5eX/5eXl/+Xl5//n
|
||||
49z/+cdf//++Nf//vjf/VE9Ay1JNPvqJh37/zc3N/8zMzP/X19f/5eXl/+Xl5f/l5eX/5eXl/+Xl
|
||||
5f/l5eX/5eXn//PPhf//vTT6/743y1RPQBZRSzxum5mT4M3Nzf/MzMz/2NjY/+Xl5f/l5eX/5eXl
|
||||
/+Xl5f/l5eX/5eXl/+Xl5//v1Z/g/70ybv++NxZUT0AA////AMbGxXTMzMz/zMzM/9bW1v/l5eX/
|
||||
5eXl/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5uPdddb9/wD/vjcAAAAAAMzMzADMzMw2zMzM7MzMzP/T
|
||||
09P/5OTk/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl7OXl5Tfl5eUAAAAAAAAAAADMzMwAzMzMBczM
|
||||
zJXMzMz/zs7O/+Dg4P/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5Zbk5OQF5OTkAAAAAAAAAAAAzMzM
|
||||
AMzMzADMzMwYzMzMp8zMzPvW1tb/5OTk/+Xl5f/l5eX/5eXl++Xl5anl5eUZ5eXlAOHh4QAAAAAA
|
||||
AAAAAAAAAADMzMwAzMzMAMzMzBLMzMx1zc3N1Nzc3Prl5eX65eXl1uXl5Xfl5eUT5eXlAOLi4gAA
|
||||
AAAAAAAAAPgfAADwDwAAwAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAMAAMAD
|
||||
AADAAwAA4AcAAPAPAAA=
|
||||
--=_48ae8051b8f2cc74607d3ed75f3568af--
|
||||
|
||||
--=_08f545e592541b77db5fd93e3267655b--
|
||||
14
tests/MessageRendering/phpunit.xml
Normal file
14
tests/MessageRendering/phpunit.xml
Normal file
@@ -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>
|
||||
18
tests/MessageRendering/run-tests.sh
Executable file
18
tests/MessageRendering/run-tests.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
testsdir=$(realpath $(dirname $0))
|
||||
cont_name="roundcubetest-dovecot"
|
||||
|
||||
ROUNDCUBE_TEST_IMAP_SERVER_IMAGE="docker.io/dovecot/dovecot:latest"
|
||||
|
||||
test -f "$testsdir/.env" && source "$testsdir/.env"
|
||||
|
||||
docker run -it --rm -d --name "$cont_name" \
|
||||
-p 143:143 \
|
||||
-v "$testsdir/data/maildir:/srv/mail/test" \
|
||||
-v "$testsdir/dovecot-maildir.conf:/etc/dovecot/conf.d/dovecot-maildir.conf" \
|
||||
"$ROUNDCUBE_TEST_IMAP_SERVER_IMAGE" >/dev/null || exit 1
|
||||
|
||||
"$testsdir/../../vendor/bin/phpunit" -c "$testsdir/phpunit.xml" --fail-on-warning --fail-on-risky
|
||||
|
||||
docker stop "$cont_name" >/dev/null
|
||||
@@ -85,7 +85,7 @@ class OutputHtmlMock extends \rcmail_output_html
|
||||
$this->header($header);
|
||||
}
|
||||
|
||||
$this->output = $body;
|
||||
$this->output .= $body;
|
||||
|
||||
throw new ExitException('Output sent', self::E_EXIT);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<testsuite name="tests">
|
||||
<directory>.</directory>
|
||||
<exclude>Browser</exclude>
|
||||
<exclude>MessageRendering</exclude>
|
||||
</testsuite>
|
||||
<testsuite name="plugins">
|
||||
<directory>../plugins/acl/tests</directory>
|
||||
|
||||
Reference in New Issue
Block a user