Find this useful? Enter your email to receive occasional updates for securing PHP code.

Signing you up...

Thank you for signing up!

PHP Decode

<?php declare(strict_types=1); /** * CakePHP(tm) : Rapid Development Framework (https://..

Decoded Output download

<?php
declare(strict_types=1);

/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE
 * Redistributions of files must retain the above copyright notice
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         4.0.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Cake\Test\TestCase\Mailer;

use Cake\Core\Configure;
use Cake\Mailer\Message;
use Cake\Mailer\Transport\DebugTransport;
use Cake\TestSuite\TestCase;
use InvalidArgumentException;
use Laminas\Diactoros\UploadedFile;
use ReflectionClass;
use TestApp\Mailer\TestMessage;
use function Cake\Core\env;

/**
 * MessageTest class
 */
class MessageTest extends TestCase
{
    /**
     * @var \Cake\Mailer\Message
     */
    protected $message;

    public function setUp(): void
    {
        parent::setUp();

        $this->message = new TestMessage();
    }

    /**
     * testWrap method
     */
    public function testWrap(): void
    {
        $renderer = new TestMessage();

        $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci,',
            'non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan amet.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis',
            'orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan',
            'amet.',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula pellentesque accumsan amet.<hr></p>';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac',
            'turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula',
            'pellentesque accumsan amet.<hr></p>',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac <a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac',
            '<a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh',
            'nisi, vehicula pellentesque accumsan amet.',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum <a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">ok</a>';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum',
            '<a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">',
            'ok</a>',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite ok.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum',
            'withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite',
            'ok.',
            '',
        ];
        $this->assertSame($expected, $result);

        /** @see https://github.com/cakephp/cakephp/issues/14459 */
        $line = 'some text <b>with html</b>';
        $trailing = str_repeat('X', Message::LINE_LENGTH_MUST - strlen($line));
        $result = $renderer->doWrap($line . $trailing, Message::LINE_LENGTH_MUST);
        $expected = [
            'some text <b>with',
            'html</b>' . $trailing,
            '',
        ];
        $this->assertSame($expected, $result);
    }

    /**
     * testWrapLongLine()
     */
    public function testWrapLongLine(): void
    {
        $transort = new DebugTransport();

        $message = '<a href="http://cakephp.org">' . str_repeat('x', Message::LINE_LENGTH_MUST) . '</a>';

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setBodyText($message);

        $result = $transort->send($this->message);

        $expected = "<a\r\n" . 'href="http://cakephp.org">' . str_repeat('x', Message::LINE_LENGTH_MUST - 26) . "\r\n" .
            str_repeat('x', 26) . "\r\n</a>\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);

        $str1 = 'a ';
        $str2 = ' b';
        $length = strlen($str1) + strlen($str2);
        $message = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length - 1) . $str2;

        $this->message->setBodyText($message);

        $result = $transort->send($this->message);
        $expected = "{$message}\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);

        $message = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length) . $str2;

        $this->message->setBodyText($message);

        $result = $transort->send($this->message);
        $expected = "{$message}\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);

        $message = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length + 1) . $str2;

        $this->message->setBodyText($message);

        $result = $transort->send($this->message);
        $expected = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length + 1) . sprintf("\r\n%s\r\n\r\n", trim($str2));
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);
    }

    /**
     * testWrapWithTagsAcrossLines()
     */
    public function testWrapWithTagsAcrossLines(): void
    {
        $str = <<<HTML
<table>
<th align="right" valign="top"
        style="font-weight: bold">The tag is across multiple lines</th>
</table>
HTML;
        $message = $str . str_repeat('x', Message::LINE_LENGTH_MUST + 1);

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setBodyText($message);

        $result = (new DebugTransport())->send($this->message);

        $message = str_replace("\r\n", "\n", substr($message, 0, -9));
        $message = str_replace("\n", "\r\n", $message);
        $expected = "{$message}\r\nxxxxxxxxx\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);
    }

    /**
     * CakeEmailTest::testWrapIncludeLessThanSign()
     */
    public function testWrapIncludeLessThanSign(): void
    {
        $str = 'foo<bar';
        $length = strlen($str);
        $message = $str . str_repeat('x', Message::LINE_LENGTH_MUST - $length + 1);

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setBodyText($message);

        $result = (new DebugTransport())->send($this->message);
        $message = substr($message, 0, -1);
        $expected = "{$message}\r\nx\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);
    }

    /**
     * CakeEmailTest::testWrapForJapaneseEncoding()
     */
    public function testWrapForJapaneseEncoding(): void
    {
        $this->skipIf(!function_exists('mb_convert_encoding'));

        $message = mb_convert_encoding('', 'iso-2022-jp', 'UTF-8');

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setCharset('iso-2022-jp');
        $this->message->setHeaderCharset('iso-2022-jp');
        $this->message->setBodyText($message);

        $result = (new DebugTransport())->send($this->message);
        $expected = "{$message}\r\n\r\n";
        $this->assertSame($expected, $result['message']);
    }

    /**
     * testHeaders method
     */
    public function testHeaders(): void
    {
        $this->message->setMessageId(false);
        $this->message->setHeaders(['X-Something' => 'nice']);
        $expected = [
            'X-Something' => 'nice',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders());

        $this->message->addHeaders(['X-Something' => 'very nice', 'X-Other' => 'cool']);
        $expected = [
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders());

        $this->message->setFrom('[email protected]');
        $this->assertSame($expected, $this->message->getHeaders());

        $expected = [
            'From' => '[email protected]',
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders(['from' => true]));

        $this->message->setFrom('[email protected]', 'CakePHP');
        $expected['From'] = 'CakePHP <[email protected]>';
        $this->assertSame($expected, $this->message->getHeaders(['from' => true]));

        $this->message->setTo(['[email protected]', '[email protected]' => 'CakePHP']);
        $expected = [
            'From' => 'CakePHP <[email protected]>',
            'To' => '[email protected], CakePHP <[email protected]>',
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders(['from' => true, 'to' => true]));

        $this->message->setCharset('ISO-2022-JP');
        $expected = [
            'From' => 'CakePHP <[email protected]>',
            'To' => '[email protected], CakePHP <[email protected]>',
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=ISO-2022-JP',
            'Content-Transfer-Encoding' => '7bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders(['from' => true, 'to' => true]));

        $result = $this->message->setHeaders([]);
        $this->assertInstanceOf(Message::class, $result);

        $this->message->setHeaders(['o:tag' => ['foo']]);
        $this->message->addHeaders(['o:tag' => ['bar']]);
        $result = $this->message->getHeaders();
        $this->assertEquals(['foo', 'bar'], $result['o:tag']);
    }

    /**
     * testHeadersString method
     */
    public function testHeadersString(): void
    {
        $this->message->setMessageId(false);
        $this->message->setHeaders(['X-Something' => 'nice']);
        $expected = [
            'X-Something: nice',
            'Date: ' . date(DATE_RFC2822),
            'MIME-Version: 1.0',
            'Content-Type: text/plain; charset=UTF-8',
            'Content-Transfer-Encoding: 8bit',
        ];
        $this->assertSame(implode("\r\n", $expected), $this->message->getHeadersString());
    }

    /**
     * testFrom method
     */
    public function testFrom(): void
    {
        $this->assertSame([], $this->message->getFrom());

        $this->message->setFrom('[email protected]');
        $expected = ['[email protected]' => '[email protected]'];
        $this->assertSame($expected, $this->message->getFrom());

        $this->message->setFrom(['[email protected]']);
        $this->assertSame($expected, $this->message->getFrom());

        $this->message->setFrom('[email protected]', 'CakePHP');
        $expected = ['[email protected]' => 'CakePHP'];
        $this->assertSame($expected, $this->message->getFrom());

        $result = $this->message->setFrom(['[email protected]' => 'CakePHP']);
        $this->assertSame($expected, $this->message->getFrom());
        $this->assertSame($this->message, $result);

        $this->expectException(InvalidArgumentException::class);
        $this->message->setFrom(['[email protected]' => 'CakePHP', '[email protected]' => 'From can only be one address']);
    }

    /**
     * Test that from addresses using colons work.
     */
    public function testFromWithColonsAndQuotes(): void
    {
        $address = [
            '[email protected]' => '70:20:00 " Forum',
        ];
        $this->message->setFrom($address);
        $this->assertEquals($address, $this->message->getFrom());

        $result = $this->message->getHeadersString(['from']);
        $this->assertStringContainsString('From: "70:20:00 \" Forum" <[email protected]>', $result);
    }

    /**
     * testSender method
     */
    public function testSender(): void
    {
        $this->message->reset();
        $this->assertSame([], $this->message->getSender());

        $this->message->setSender('[email protected]', 'Name');
        $expected = ['[email protected]' => 'Name'];
        $this->assertSame($expected, $this->message->getSender());

        $headers = $this->message->getHeaders(['from' => true, 'sender' => true]);
        $this->assertSame('', $headers['From']);
        $this->assertSame('Name <[email protected]>', $headers['Sender']);

        $this->message->setFrom('[email protected]', 'CakePHP');
        $headers = $this->message->getHeaders(['from' => true, 'sender' => true]);
        $this->assertSame('CakePHP <[email protected]>', $headers['From']);
        $this->assertSame('', $headers['Sender']);
    }

    /**
     * testTo method
     */
    public function testTo(): void
    {
        $this->assertSame([], $this->message->getTo());

        $result = $this->message->setTo('[email protected]');
        $expected = ['[email protected]' => '[email protected]'];
        $this->assertSame($expected, $this->message->getTo());
        $this->assertSame($this->message, $result);

        $this->message->setTo('[email protected]', 'CakePHP');
        $expected = ['[email protected]' => 'CakePHP'];
        $this->assertSame($expected, $this->message->getTo());

        $list = [
            'root@localhost' => 'root',
            '[email protected]' => 'Bjorn',
            '[email protected]' => 'Cake PHP',
            '[email protected]' => 'Cake Groups',
            '[email protected]',
        ];
        $this->message->setTo($list);
        $expected = [
            'root@localhost' => 'root',
            '[email protected]' => 'Bjorn',
            '[email protected]' => 'Cake PHP',
            '[email protected]' => 'Cake Groups',
            '[email protected]' => '[email protected]',
        ];
        $this->assertSame($expected, $this->message->getTo());

        $this->message->addTo('[email protected]');
        $this->message->addTo('[email protected]', 'Mark Story');
        $this->message->addTo('[email protected]');
        $result = $this->message->addTo(['[email protected]' => 'PhpNut', '[email protected]']);
        $expected = [
            'root@localhost' => 'root',
            '[email protected]' => 'Bjorn',
            '[email protected]' => 'Cake PHP',
            '[email protected]' => 'Cake Groups',
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
            '[email protected]' => 'Mark Story',
            '[email protected]' => '[email protected]',
            '[email protected]' => 'PhpNut',
            '[email protected]' => '[email protected]',
        ];
        $this->assertSame($expected, $this->message->getTo());
        $this->assertSame($this->message, $result);
    }

    /**
     * test to address with _ in domain name
     */
    public function testToUnderscoreDomain(): void
    {
        $result = $this->message->setTo('cake@cake_php.org');
        $expected = ['cake@cake_php.org' => 'cake@cake_php.org'];
        $this->assertSame($expected, $this->message->getTo());
        $this->assertSame($this->message, $result);
    }

    /**
     * Data provider function for testBuildInvalidData
     *
     * @return array
     */
    public static function invalidEmails(): array
    {
        return [
            [''],
            ['string'],
            ['<tag>'],
            [['[email protected]', '1.0', '', 'string']],
        ];
    }

    /**
     * testBuildInvalidData
     *
     * @dataProvider invalidEmails
     * @param array|string $value
     */
    public function testInvalidEmail($value): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->message->setTo($value);
    }

    /**
     * testBuildInvalidData
     *
     * @dataProvider invalidEmails
     * @param array|string $value
     */
    public function testInvalidEmailAdd($value): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->message->addTo($value);
    }

    /**
     * test emailPattern method
     */
    public function testEmailPattern(): void
    {
        $regex = '/.+@.+\..+/i';
        $this->assertSame($regex, $this->message->setEmailPattern($regex)->getEmailPattern());
    }

    /**
     * Tests that it is possible to set email regex configuration to a CakeEmail object
     */
    public function testConfigEmailPattern(): void
    {
        $regex = '/.+@.+\..+/i';
        $email = new Message(['emailPattern' => $regex]);
        $this->assertSame($regex, $email->getEmailPattern());
    }

    /**
     * Tests that it is possible set custom email validation
     */
    public function testCustomEmailValidation(): void
    {
        $regex = '/^[\.a-z0-9!#$%&\'*+\/=?^_`{|}~-]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]{2,6}$/i';

        $this->message->setEmailPattern($regex)->setTo('[email protected]');
        $this->assertSame([
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());

        $this->message->addTo('[email protected]');
        $this->assertSame([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());

        $this->message->reset();
        $emails = [
            '[email protected]',
            '[email protected]',
        ];
        $additionalEmails = [
            '[email protected]',
            '[email protected]',
        ];
        $this->message->setEmailPattern($regex)->setTo($emails);
        $this->assertSame([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());

        $this->message->addTo($additionalEmails);
        $this->assertSame([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());
    }

    /**
     * Tests that it is possible to unset the email pattern and make use of filter_var() instead.
     */
    public function testUnsetEmailPattern(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage('Invalid email set for `to`. You passed `[email protected]`.');
        $email = new Message();
        $this->assertSame(Message::EMAIL_PATTERN, $email->getEmailPattern());

        $email->setEmailPattern(null);
        $this->assertNull($email->getEmailPattern());

        $email->setTo('[email protected]');
        $email->setTo('[email protected]');
    }

    /**
     * Tests that passing an empty string throws an InvalidArgumentException.
     */
    public function testEmptyTo(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage('The email set for `to` is empty.');
        $email = new Message();
        $email->setTo('');
    }

    /**
     * testFormatAddress method
     */
    public function testFormatAddress(): void
    {
        $result = $this->message->fmtAddress(['[email protected]' => '[email protected]']);
        $expected = ['[email protected]'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ]);
        $expected = ['[email protected]', '[email protected]'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress([
            '[email protected]' => 'CakePHP',
            '[email protected]' => 'Cake',
        ]);
        $expected = ['CakePHP <[email protected]>', 'Cake <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Last, First']);
        $expected = ['"Last, First" <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => '"Last" First']);
        $expected = ['"\"Last\" First" <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Last First']);
        $expected = ['Last First <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Test']);
        $expected = ['=?UTF-8?B?w4TDlsOcVGVzdA==?= <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Test']);
        $expected = ['=?UTF-8?B?5pel5pys6KqeVGVzdA==?= <[email protected]>'];
        $this->assertSame($expected, $result);
    }

    /**
     * testFormatAddressJapanese
     */
    public function testFormatAddressJapanese(): void
    {
        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->fmtAddress(['[email protected]' => 'Test']);
        $expected = ['=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCVGVzdA==?= <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => '']);
        $expected = ["\"=?ISO-2022-JP?B?GyRCPHc4Qkw1PHc4Qkw1OF45ZSROOyQkakBaJGwzJDo9TXg/ZTV7GyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCJE4/ZTlUS3YxQE1oS3ZJd01oS3Y/KSQmPzIkaz1oJEs9OyRgGyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCPWgkZCRWJGk+Lk8pJE5pLjQ7O1IlUSUkJV0lUSUkJV0lUSUkGyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCJV0kTiU3JWUhPCVqJXMlLCVzJTclZSE8JWolcyUsJXMkTiUwGyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCITwlaiVzJUAlJCUwITwlaiVzJUAlJCROJV0lcyVdJTMlVCE8GyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJE4lXSVzJV0lMyVKITwkTkQ5NVdMPyRORDk9dRsoQg==?=" <[email protected]>'];
        $this->assertSame($expected, $result);
    }

    /**
     * testAddresses method
     */
    public function testAddresses(): void
    {
        $this->message->reset();
        $this->message->setFrom('[email protected]', 'CakePHP');
        $this->message->setReplyTo('[email protected]', 'ReplyTo CakePHP');
        $this->message->setReadReceipt('[email protected]', 'ReadReceipt CakePHP');
        $this->message->setReturnPath('[email protected]', 'ReturnPath CakePHP');
        $this->message->setTo('[email protected]', 'To, CakePHP');
        $this->message->setCc('[email protected]', 'Cc CakePHP');
        $this->message->setBcc('[email protected]', 'Bcc CakePHP');
        $this->message->addTo('[email protected]', 'To2 CakePHP');
        $this->message->addCc('[email protected]', 'Cc2 CakePHP');
        $this->message->addBcc('[email protected]', 'Bcc2 CakePHP');
        $this->message->addReplyTo('[email protected]', 'ReplyTo2 CakePHP');

        $this->assertSame($this->message->getFrom(), ['[email protected]' => 'CakePHP']);
        $this->assertSame($this->message->getReplyTo(), ['[email protected]' => 'ReplyTo CakePHP', '[email protected]' => 'ReplyTo2 CakePHP']);
        $this->assertSame($this->message->getReadReceipt(), ['[email protected]' => 'ReadReceipt CakePHP']);
        $this->assertSame($this->message->getReturnPath(), ['[email protected]' => 'ReturnPath CakePHP']);
        $this->assertSame($this->message->getTo(), ['[email protected]' => 'To, CakePHP', '[email protected]' => 'To2 CakePHP']);
        $this->assertSame($this->message->getCc(), ['[email protected]' => 'Cc CakePHP', '[email protected]' => 'Cc2 CakePHP']);
        $this->assertSame($this->message->getBcc(), ['[email protected]' => 'Bcc CakePHP', '[email protected]' => 'Bcc2 CakePHP']);

        $headers = $this->message->getHeaders(array_fill_keys(['from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'], true));
        $this->assertSame($headers['From'], 'CakePHP <[email protected]>');
        $this->assertSame($headers['Reply-To'], 'ReplyTo CakePHP <[email protected]>, ReplyTo2 CakePHP <[email protected]>');
        $this->assertSame($headers['Disposition-Notification-To'], 'ReadReceipt CakePHP <[email protected]>');
        $this->assertSame($headers['Return-Path'], 'ReturnPath CakePHP <[email protected]>');
        $this->assertSame($headers['To'], '"To, CakePHP" <[email protected]>, To2 CakePHP <[email protected]>');
        $this->assertSame($headers['Cc'], 'Cc CakePHP <[email protected]>, Cc2 CakePHP <[email protected]>');
        $this->assertSame($headers['Bcc'], 'Bcc CakePHP <[email protected]>, Bcc2 CakePHP <[email protected]>');

        $this->message->setReplyTo(['[email protected]' => 'ReplyTo CakePHP', '[email protected]' => 'ReplyTo2 CakePHP']);
        $this->assertSame($this->message->getReplyTo(), ['[email protected]' => 'ReplyTo CakePHP', '[email protected]' => 'ReplyTo2 CakePHP']);
        $headers = $this->message->getHeaders(array_fill_keys(['replyTo'], true));
        $this->assertSame($headers['Reply-To'], 'ReplyTo CakePHP <[email protected]>, ReplyTo2 CakePHP <[email protected]>');
    }

    /**
     * test reset addresses method
     */
    public function testResetAddresses(): void
    {
        $this->message->reset();
        $this->message
            ->setFrom('[email protected]', 'CakePHP')
            ->setReplyTo('[email protected]', 'ReplyTo CakePHP')
            ->setReadReceipt('[email protected]', 'ReadReceipt CakePHP')
            ->setReturnPath('[email protected]', 'ReturnPath CakePHP')
            ->setTo('[email protected]', 'To, CakePHP')
            ->setCc('[email protected]', 'Cc CakePHP')
            ->setBcc('[email protected]', 'Bcc CakePHP');

        $this->assertNotEmpty($this->message->getFrom());
        $this->assertNotEmpty($this->message->getReplyTo());
        $this->assertNotEmpty($this->message->getReadReceipt());
        $this->assertNotEmpty($this->message->getReturnPath());
        $this->assertNotEmpty($this->message->getTo());
        $this->assertNotEmpty($this->message->getCc());
        $this->assertNotEmpty($this->message->getBcc());

        $this->message
            ->setFrom([])
            ->setReplyTo([])
            ->setReadReceipt([])
            ->setReturnPath([])
            ->setTo([])
            ->setCc([])
            ->setBcc([]);

        $this->assertEmpty($this->message->getFrom());
        $this->assertEmpty($this->message->getReplyTo());
        $this->assertEmpty($this->message->getReadReceipt());
        $this->assertEmpty($this->message->getReturnPath());
        $this->assertEmpty($this->message->getTo());
        $this->assertEmpty($this->message->getCc());
        $this->assertEmpty($this->message->getBcc());
    }

    /**
     * testMessageId method
     */
    public function testMessageId(): void
    {
        $this->message->setMessageId(true);
        $result = $this->message->getHeaders();
        $this->assertArrayHasKey('Message-ID', $result);

        $this->message->setMessageId(false);
        $result = $this->message->getHeaders();
        $this->assertArrayNotHasKey('Message-ID', $result);

        $result = $this->message->setMessageId('<my-email@localhost>');
        $this->assertSame($this->message, $result);
        $result = $this->message->getHeaders();
        $this->assertSame('<my-email@localhost>', $result['Message-ID']);

        $result = $this->message->getMessageId();
        $this->assertSame('<my-email@localhost>', $result);
    }

    public function testAutoMessageIdIsIdempotent(): void
    {
        $headers = $this->message->getHeaders();
        $this->assertArrayHasKey('Message-ID', $headers);

        $regeneratedHeaders = $this->message->getHeaders();
        $this->assertSame($headers['Message-ID'], $regeneratedHeaders['Message-ID']);
    }

    public function testPriority(): void
    {
        $this->message->setPriority(4);

        $this->assertSame(4, $this->message->getPriority());

        $result = $this->message->getHeaders();
        $this->assertArrayHasKey('X-Priority', $result);
    }

    /**
     * testMessageIdInvalid method
     */
    public function testMessageIdInvalid(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->message->setMessageId('my-email@localhost');
    }

    /**
     * testDomain method
     */
    public function testDomain(): void
    {
        $result = $this->message->getDomain();
        $expected = env('HTTP_HOST') ? env('HTTP_HOST') : php_uname('n');
        $this->assertSame($expected, $result);

        $this->message->setDomain('example.org');
        $result = $this->message->getDomain();
        $expected = 'example.org';
        $this->assertSame($expected, $result);
    }

    /**
     * testMessageIdWithDomain method
     */
    public function testMessageIdWithDomain(): void
    {
        $this->message->setDomain('example.org');
        $result = $this->message->getHeaders();
        $expected = '@example.org>';
        $this->assertTextContains($expected, $result['Message-ID']);

        $_SERVER['HTTP_HOST'] = 'example.org';
        $result = $this->message->getHeaders();
        $this->assertTextContains('example.org', $result['Message-ID']);

        $_SERVER['HTTP_HOST'] = 'example.org:81';
        $result = $this->message->getHeaders();
        $this->assertTextNotContains(':81', $result['Message-ID']);
    }

    /**
     * testSubject method
     */
    public function testSubject(): void
    {
        $this->message->setSubject('You have a new message.');
        $this->assertSame('You have a new message.', $this->message->getSubject());

        $this->message->setSubject('You have a new message, I think.');
        $this->assertSame($this->message->getSubject(), 'You have a new message, I think.');
        $this->message->setSubject('1');
        $this->assertSame('1', $this->message->getSubject());

        $input = '     ';
        $this->message->setSubject($input);
        $expected = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?=';
        $this->assertSame($expected, $this->message->getSubject());
        $this->assertSame($input, $this->message->getOriginalSubject());
    }

    /**
     * testSubjectJapanese
     */
    public function testSubjectJapanese(): void
    {
        mb_internal_encoding('UTF-8');

        $this->message->setHeaderCharset('ISO-2022-JP');
        $this->message->setSubject('Subject');
        $expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsJE4bKEJTdWJqZWN0GyRCJEskYkJQMX4kOSRrJGgbKEI=?=';
        $this->assertSame($expected, $this->message->getSubject());

        $this->message->setSubject('Subjectfolding');
        $expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
            " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=';
        $this->assertSame($expected, $this->message->getSubject());
    }

    /**
     * testAttachments method
     */
    public function testSetAttachments(): void
    {
        $uploadedFile = new UploadedFile(
            __FILE__,
            filesize(__FILE__),
            UPLOAD_ERR_OK,
            'MessageTest.php',
            'text/x-php'
        );

        $this->message->setAttachments([
            CAKE . 'Mailer' . DS . 'Message.php',
            $uploadedFile,
        ]);
        $expected = [
            'Message.php' => [
                'file' => CAKE . 'Mailer' . DS . 'Message.php',
                'mimetype' => 'text/x-php',
            ],
            'MessageTest.php' => [
                'file' => $uploadedFile,
                'mimetype' => 'text/x-php',
            ],
        ];
        $this->assertSame($expected, $this->message->getAttachments());

        $this->message->setAttachments([]);
        $this->assertSame([], $this->message->getAttachments());

        $this->message->setAttachments([
            ['file' => __FILE__, 'mimetype' => 'text/plain'],
        ]);
        $this->message->addAttachments([CORE_PATH . 'config' . DS . 'bootstrap.php']);
        $this->message->addAttachments([CORE_PATH . 'config' . DS . 'bootstrap.php']);
        $this->message->addAttachments([
            'other.txt' => CORE_PATH . 'config' . DS . 'bootstrap.php',
            'license' => CORE_PATH . 'LICENSE',
        ]);
        $expected = [
            'MessageTest.php' => ['file' => __FILE__, 'mimetype' => 'text/plain'],
            'bootstrap.php' => ['file' => CORE_PATH . 'config' . DS . 'bootstrap.php', 'mimetype' => 'text/x-php'],
            'other.txt' => ['file' => CORE_PATH . 'config' . DS . 'bootstrap.php', 'mimetype' => 'text/x-php'],
            'license' => ['file' => CORE_PATH . 'LICENSE', 'mimetype' => 'text/plain'],
        ];
        $this->assertSame($expected, $this->message->getAttachments());
        $this->expectException(InvalidArgumentException::class);
        $this->message->setAttachments([['nofile' => __FILE__, 'mimetype' => 'text/plain']]);
    }

    /**
     * Test send() with no template and data string attachment and no mimetype
     */
    public function testSetAttachmentDataNoMimetype(): void
    {
        $this->message->setAttachments(['cake.icon.gif' => [
            'data' => 'test',
        ]]);
        $expected = [
            'cake.icon.gif' => [
                'data' => base64_encode('test') . "\r\n",
                'mimetype' => 'application/octet-stream',
            ],
        ];
        $this->assertSame($expected, $this->message->getAttachments());
    }

    public function testSetAttachmentInvalidFile(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage(
            'File must be a filepath or UploadedFileInterface instance. Found `boolean` instead.'
        );

        $this->message->setAttachments(['cake.icon.gif' => [
            'file' => true,
        ]]);
    }

    /**
     * testReset method
     */
    public function testReset(): void
    {
        $this->message->setTo('[email protected]');
        $this->message->setEmailPattern('/.+@.+\..+/i');
        $this->assertSame(['[email protected]' => '[email protected]'], $this->message->getTo());

        $this->message->reset();
        $this->assertSame([], $this->message->getTo());
        $this->assertSame(Message::EMAIL_PATTERN, $this->message->getEmailPattern());
    }

    /**
     * testReset with charset
     */
    public function testResetWithCharset(): void
    {
        $this->message->setCharset('ISO-2022-JP');
        $this->message->reset();

        $this->assertSame('utf-8', $this->message->getCharset());
        $this->assertSame('utf-8', $this->message->getHeaderCharset());
    }

    /**
     * testEmailFormat method
     */
    public function testEmailFormat(): void
    {
        $result = $this->message->getEmailFormat();
        $this->assertSame('text', $result);

        $result = $this->message->setEmailFormat('html');
        $this->assertInstanceOf(Message::class, $result);

        $result = $this->message->getEmailFormat();
        $this->assertSame('html', $result);

        $this->expectException(InvalidArgumentException::class);
        $this->message->setEmailFormat('invalid');
    }

    /**
     * Tests that it is possible to add charset configuration to a CakeEmail object
     */
    public function testConfigCharset(): void
    {
        $email = new Message();
        $this->assertEquals(Configure::read('App.encoding'), $email->getCharset());
        $this->assertEquals(Configure::read('App.encoding'), $email->getHeaderCharset());

        $email = new Message(['charset' => 'iso-2022-jp', 'headerCharset' => 'iso-2022-jp-ms']);
        $this->assertSame('iso-2022-jp', $email->getCharset());
        $this->assertSame('iso-2022-jp-ms', $email->getHeaderCharset());

        $email = new Message(['charset' => 'iso-2022-jp']);
        $this->assertSame('iso-2022-jp', $email->getCharset());
        $this->assertSame('iso-2022-jp', $email->getHeaderCharset());

        $email = new Message(['headerCharset' => 'iso-2022-jp-ms']);
        $this->assertEquals(Configure::read('App.encoding'), $email->getCharset());
        $this->assertSame('iso-2022-jp-ms', $email->getHeaderCharset());
    }

    public function testGetBody(): void
    {
        $message = new Message();

        $uploadedFile = new UploadedFile(
            __FILE__,
            filesize(__FILE__),
            UPLOAD_ERR_OK,
            'MessageTest.php',
            'text/x-php'
        );
        $chunks = base64_encode(file_get_contents(__FILE__));

        $result = $message->setAttachments([$uploadedFile])
            ->setBodyText('Attached an uploaded file')
            ->getBody();
        $result = implode("\r\n", $result);
        $this->assertStringContainsString($chunks[0], $result);
    }

    /**
     * Tests that the body is encoded using the configured charset (Japanese standard encoding)
     */
    public function testBodyEncodingIso2022Jp(): void
    {
        $message = new Message([
            'charset' => 'iso-2022-jp',
            'headerCharset' => 'iso-2022-jp',
            'transport' => 'debug',
        ]);
        $message->setSubject('');

        $headers = $message->getHeaders(['subject']);
        $expected = '?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=';
        $this->assertStringContainsString($expected, $headers['Subject']);

        $message->setBodyHtml(' ');

        $result = $message->getHeadersString();
        $this->assertTextContains('Content-Type: text/plain; charset=ISO-2022-JP', $result);
        $this->assertTextNotContains('Content-Type: text/plain; charset=ISO-2022-JP-MS', $result); // not charset=iso-2022-jp-ms

        $result = implode('', $message->getBody());
        $this->assertTextNotContains(mb_convert_encoding(' ', 'ISO-2022-JP-MS'), $result);
    }

    /**
     * Tests that the body is encoded using the configured charset (Japanese irregular encoding, but sometime use this)
     */
    public function testBodyEncodingIso2022JpMs(): void
    {
        $message = new Message([
            'charset' => 'iso-2022-jp-ms',
            'headerCharset' => 'iso-2022-jp-ms',
            'transport' => 'debug',
        ]);
        $message->setSubject('');
        $headers = $message->getHeaders(['subject']);
        $expected = '?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=';
        $this->assertStringContainsString($expected, $headers['Subject']);

        $result = $message->setBodyText(' ');

        $result = $message->getHeadersString();
        $this->assertTextContains('Content-Type: text/plain; charset=ISO-2022-JP', $result);
        $this->assertTextNotContains('Content-Type: text/plain; charset=iso-2022-jp-ms', $result); // not charset=iso-2022-jp-ms

        $result = implode('', $message->getBody());
        $this->assertStringContainsString(mb_convert_encoding(' ', 'ISO-2022-JP-MS'), $result);
    }

    /**
     * Tests that the body is encoded using the configured charset
     */
    public function testEncodingMixed(): void
    {
        $message = new Message([
            'headerCharset' => 'iso-2022-jp-ms',
            'charset' => 'iso-2022-jp',
        ]);

        $message->setBodyText('');

        $result = $message->getHeadersString();
        $this->assertStringContainsString('Content-Type: text/plain; charset=ISO-2022-JP', $result);

        $result = implode('', $message->getBody());
        $this->assertStringContainsString(mb_convert_encoding('', 'ISO-2022-JP'), $result);
    }

    /**
     * Test CakeMessage::_encode function
     */
    public function testEncode(): void
    {
        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->encode('');
        $expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=';
        $this->assertSame($expected, $result);

        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->encode('Subjectfolding');
        $expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
            " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=';
        $this->assertSame($expected, $result);
    }

    /**
     * Test CakeMessage::_decode function
     */
    public function testDecode(): void
    {
        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->decode('=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=');
        $expected = '';
        $this->assertSame($expected, $result);

        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->decode("=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
            " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=');
        $expected = 'Subjectfolding';
        $this->assertSame($expected, $result);
    }

    /**
     * Tests charset setter/getter
     */
    public function testCharset(): void
    {
        $this->message->setCharset('UTF-8');
        $this->assertSame($this->message->getCharset(), 'UTF-8');

        $this->message->setCharset('ISO-2022-JP');
        $this->assertSame($this->message->getCharset(), 'ISO-2022-JP');

        $charset = $this->message->setCharset('Shift_JIS');
        $this->assertSame('Shift_JIS', $charset->getCharset());
    }

    /**
     * Tests headerCharset setter/getter
     */
    public function testHeaderCharset(): void
    {
        $this->message->setHeaderCharset('UTF-8');
        $this->assertSame($this->message->getHeaderCharset(), 'UTF-8');

        $this->message->setHeaderCharset('ISO-2022-JP');
        $this->assertSame($this->message->getHeaderCharset(), 'ISO-2022-JP');

        $charset = $this->message->setHeaderCharset('Shift_JIS');
        $this->assertSame('Shift_JIS', $charset->getHeaderCharset());
    }

    /**
     * Test transferEncoding
     */
    public function testTransferEncoding(): void
    {
        // Test new transfer encoding
        $expected = 'quoted-printable';
        $this->message->setTransferEncoding($expected);
        $this->assertSame($expected, $this->message->getTransferEncoding());
        $this->assertSame($expected, $this->message->getContentTransferEncoding());

        // Test default charset/encoding : utf8/8bit
        $expected = '8bit';
        $this->message->reset();
        $this->assertNull($this->message->getTransferEncoding());
        $this->assertSame($expected, $this->message->getContentTransferEncoding());

        //Test wrong encoding
        $this->expectException(InvalidArgumentException::class);
        $this->message->setTransferEncoding('invalid');
    }

    /**
     * Tests for compatible check.
     *          charset property and       charset() method.
     *    headerCharset property and headerCharset() method.
     */
    public function testCharsetsCompatible(): void
    {
        $checkHeaders = [
            'from' => true,
            'to' => true,
            'cc' => true,
            'subject' => true,
        ];

        // Header Charset : null (used by default UTF-8)
        //   Body Charset : ISO-2022-JP
        $oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', null);
        $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);

        $newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', null);
        $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);

        $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
        $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
        $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
        $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);

        // Header Charset : UTF-8
        //   Boby Charset : ISO-2022-JP
        $oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', 'utf-8');
        $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);

        $newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', 'utf-8');
        $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);

        $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
        $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
        $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
        $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);

        // Header Charset : ISO-2022-JP
        //   Boby Charset : UTF-8
        $oldStyleEmail = $this->_getEmailByOldStyleCharset('utf-8', 'iso-2022-jp');
        $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);

        $newStyleEmail = $this->_getEmailByNewStyleCharset('utf-8', 'iso-2022-jp');
        $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);

        $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
        $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
        $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
        $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
    }

    /**
     * @param mixed $charset
     * @param mixed $headerCharset
     */
    protected function _getEmailByOldStyleCharset($charset, $headerCharset): Message
    {
        $message = new Message(['transport' => 'debug']);

        if ($charset) {
            $message->setCharset($charset);
        }
        if ($headerCharset) {
            $message->setHeaderCharset($headerCharset);
        }

        $message->setFrom('[email protected]', '');
        $message->setTo('[email protected]', '');
        $message->setCc('[email protected]', '');
        $message->setSubject('');
        $message->setBodyText('');

        return $message;
    }

    /**
     * @param mixed $charset
     * @param mixed $headerCharset
     */
    protected function _getEmailByNewStyleCharset($charset, $headerCharset): Message
    {
        $message = new Message();

        if ($charset) {
            $message->setCharset($charset);
        }
        if ($headerCharset) {
            $message->setHeaderCharset($headerCharset);
        }

        $message->setFrom('[email protected]', '');
        $message->setTo('[email protected]', '');
        $message->setCc('[email protected]', '');
        $message->setSubject('');
        $message->setBodyText('');

        return $message;
    }

    /**
     * @param string $message
     */
    protected function assertLineLengths($message): void
    {
        $lines = explode("\r\n", $message);
        foreach ($lines as $line) {
            $this->assertTrue(
                strlen($line) <= Message::LINE_LENGTH_MUST,
                'Line length exceeds the max. limit of Message::LINE_LENGTH_MUST'
            );
        }
    }

    public function testSerialization(): void
    {
        $message = new Message();
        $reflection = new ReflectionClass($message);
        $property = $reflection->getProperty('serializableProperties');
        $property->setAccessible(true);
        $serializableProperties = $property->getValue($message);

        $message
            ->setSubject('I haz Cake')
            ->setEmailFormat(Message::MESSAGE_BOTH)
            ->setBody([
                Message::MESSAGE_TEXT => 'text message',
                Message::MESSAGE_HTML => '<strong>html message</strong>',
            ]);

        $string = serialize($message);
        $this->assertStringContainsString('text message', $string);

        $this->assertIsArray($serializableProperties);
        $this->assertContains('subject', $serializableProperties);
        $this->assertContains('emailFormat', $serializableProperties);
        $this->assertContains('textMessage', $serializableProperties);
        $this->assertContains('htmlMessage', $serializableProperties);

        /** @var \Cake\Mailer\Message $message */
        $message = unserialize($string);
        $this->assertSame('I haz Cake', $message->getSubject());
        $body = $message->getBodyString();
        $this->assertStringContainsString('text message', $body);
        $this->assertStringContainsString('<strong>html message</strong>', $body);
    }
}
 ?>

Did this file decode correctly?

Original Code

<?php
declare(strict_types=1);

/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE
 * Redistributions of files must retain the above copyright notice
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         4.0.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Cake\Test\TestCase\Mailer;

use Cake\Core\Configure;
use Cake\Mailer\Message;
use Cake\Mailer\Transport\DebugTransport;
use Cake\TestSuite\TestCase;
use InvalidArgumentException;
use Laminas\Diactoros\UploadedFile;
use ReflectionClass;
use TestApp\Mailer\TestMessage;
use function Cake\Core\env;

/**
 * MessageTest class
 */
class MessageTest extends TestCase
{
    /**
     * @var \Cake\Mailer\Message
     */
    protected $message;

    public function setUp(): void
    {
        parent::setUp();

        $this->message = new TestMessage();
    }

    /**
     * testWrap method
     */
    public function testWrap(): void
    {
        $renderer = new TestMessage();

        $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci,',
            'non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan amet.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis',
            'orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan',
            'amet.',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula pellentesque accumsan amet.<hr></p>';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac',
            'turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula',
            'pellentesque accumsan amet.<hr></p>',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac <a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac',
            '<a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh',
            'nisi, vehicula pellentesque accumsan amet.',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum <a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">ok</a>';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum',
            '<a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">',
            'ok</a>',
            '',
        ];
        $this->assertSame($expected, $result);

        $text = 'Lorem ipsum withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite ok.';
        $result = $renderer->doWrap($text, Message::LINE_LENGTH_SHOULD);
        $expected = [
            'Lorem ipsum',
            'withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite',
            'ok.',
            '',
        ];
        $this->assertSame($expected, $result);

        /** @see https://github.com/cakephp/cakephp/issues/14459 */
        $line = 'some text <b>with html</b>';
        $trailing = str_repeat('X', Message::LINE_LENGTH_MUST - strlen($line));
        $result = $renderer->doWrap($line . $trailing, Message::LINE_LENGTH_MUST);
        $expected = [
            'some text <b>with',
            'html</b>' . $trailing,
            '',
        ];
        $this->assertSame($expected, $result);
    }

    /**
     * testWrapLongLine()
     */
    public function testWrapLongLine(): void
    {
        $transort = new DebugTransport();

        $message = '<a href="http://cakephp.org">' . str_repeat('x', Message::LINE_LENGTH_MUST) . '</a>';

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setBodyText($message);

        $result = $transort->send($this->message);

        $expected = "<a\r\n" . 'href="http://cakephp.org">' . str_repeat('x', Message::LINE_LENGTH_MUST - 26) . "\r\n" .
            str_repeat('x', 26) . "\r\n</a>\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);

        $str1 = 'a ';
        $str2 = ' b';
        $length = strlen($str1) + strlen($str2);
        $message = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length - 1) . $str2;

        $this->message->setBodyText($message);

        $result = $transort->send($this->message);
        $expected = "{$message}\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);

        $message = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length) . $str2;

        $this->message->setBodyText($message);

        $result = $transort->send($this->message);
        $expected = "{$message}\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);

        $message = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length + 1) . $str2;

        $this->message->setBodyText($message);

        $result = $transort->send($this->message);
        $expected = $str1 . str_repeat('x', Message::LINE_LENGTH_MUST - $length + 1) . sprintf("\r\n%s\r\n\r\n", trim($str2));
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);
    }

    /**
     * testWrapWithTagsAcrossLines()
     */
    public function testWrapWithTagsAcrossLines(): void
    {
        $str = <<<HTML
<table>
<th align="right" valign="top"
        style="font-weight: bold">The tag is across multiple lines</th>
</table>
HTML;
        $message = $str . str_repeat('x', Message::LINE_LENGTH_MUST + 1);

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setBodyText($message);

        $result = (new DebugTransport())->send($this->message);

        $message = str_replace("\r\n", "\n", substr($message, 0, -9));
        $message = str_replace("\n", "\r\n", $message);
        $expected = "{$message}\r\nxxxxxxxxx\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);
    }

    /**
     * CakeEmailTest::testWrapIncludeLessThanSign()
     */
    public function testWrapIncludeLessThanSign(): void
    {
        $str = 'foo<bar';
        $length = strlen($str);
        $message = $str . str_repeat('x', Message::LINE_LENGTH_MUST - $length + 1);

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setBodyText($message);

        $result = (new DebugTransport())->send($this->message);
        $message = substr($message, 0, -1);
        $expected = "{$message}\r\nx\r\n\r\n";
        $this->assertSame($expected, $result['message']);
        $this->assertLineLengths($result['message']);
    }

    /**
     * CakeEmailTest::testWrapForJapaneseEncoding()
     */
    public function testWrapForJapaneseEncoding(): void
    {
        $this->skipIf(!function_exists('mb_convert_encoding'));

        $message = mb_convert_encoding('', 'iso-2022-jp', 'UTF-8');

        $this->message->setFrom('[email protected]');
        $this->message->setTo('[email protected]');
        $this->message->setSubject('Wordwrap Test');
        $this->message->setCharset('iso-2022-jp');
        $this->message->setHeaderCharset('iso-2022-jp');
        $this->message->setBodyText($message);

        $result = (new DebugTransport())->send($this->message);
        $expected = "{$message}\r\n\r\n";
        $this->assertSame($expected, $result['message']);
    }

    /**
     * testHeaders method
     */
    public function testHeaders(): void
    {
        $this->message->setMessageId(false);
        $this->message->setHeaders(['X-Something' => 'nice']);
        $expected = [
            'X-Something' => 'nice',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders());

        $this->message->addHeaders(['X-Something' => 'very nice', 'X-Other' => 'cool']);
        $expected = [
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders());

        $this->message->setFrom('[email protected]');
        $this->assertSame($expected, $this->message->getHeaders());

        $expected = [
            'From' => '[email protected]',
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders(['from' => true]));

        $this->message->setFrom('[email protected]', 'CakePHP');
        $expected['From'] = 'CakePHP <[email protected]>';
        $this->assertSame($expected, $this->message->getHeaders(['from' => true]));

        $this->message->setTo(['[email protected]', '[email protected]' => 'CakePHP']);
        $expected = [
            'From' => 'CakePHP <[email protected]>',
            'To' => '[email protected], CakePHP <[email protected]>',
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Transfer-Encoding' => '8bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders(['from' => true, 'to' => true]));

        $this->message->setCharset('ISO-2022-JP');
        $expected = [
            'From' => 'CakePHP <[email protected]>',
            'To' => '[email protected], CakePHP <[email protected]>',
            'X-Something' => 'very nice',
            'X-Other' => 'cool',
            'Date' => date(DATE_RFC2822),
            'MIME-Version' => '1.0',
            'Content-Type' => 'text/plain; charset=ISO-2022-JP',
            'Content-Transfer-Encoding' => '7bit',
        ];
        $this->assertSame($expected, $this->message->getHeaders(['from' => true, 'to' => true]));

        $result = $this->message->setHeaders([]);
        $this->assertInstanceOf(Message::class, $result);

        $this->message->setHeaders(['o:tag' => ['foo']]);
        $this->message->addHeaders(['o:tag' => ['bar']]);
        $result = $this->message->getHeaders();
        $this->assertEquals(['foo', 'bar'], $result['o:tag']);
    }

    /**
     * testHeadersString method
     */
    public function testHeadersString(): void
    {
        $this->message->setMessageId(false);
        $this->message->setHeaders(['X-Something' => 'nice']);
        $expected = [
            'X-Something: nice',
            'Date: ' . date(DATE_RFC2822),
            'MIME-Version: 1.0',
            'Content-Type: text/plain; charset=UTF-8',
            'Content-Transfer-Encoding: 8bit',
        ];
        $this->assertSame(implode("\r\n", $expected), $this->message->getHeadersString());
    }

    /**
     * testFrom method
     */
    public function testFrom(): void
    {
        $this->assertSame([], $this->message->getFrom());

        $this->message->setFrom('[email protected]');
        $expected = ['[email protected]' => '[email protected]'];
        $this->assertSame($expected, $this->message->getFrom());

        $this->message->setFrom(['[email protected]']);
        $this->assertSame($expected, $this->message->getFrom());

        $this->message->setFrom('[email protected]', 'CakePHP');
        $expected = ['[email protected]' => 'CakePHP'];
        $this->assertSame($expected, $this->message->getFrom());

        $result = $this->message->setFrom(['[email protected]' => 'CakePHP']);
        $this->assertSame($expected, $this->message->getFrom());
        $this->assertSame($this->message, $result);

        $this->expectException(InvalidArgumentException::class);
        $this->message->setFrom(['[email protected]' => 'CakePHP', '[email protected]' => 'From can only be one address']);
    }

    /**
     * Test that from addresses using colons work.
     */
    public function testFromWithColonsAndQuotes(): void
    {
        $address = [
            '[email protected]' => '70:20:00 " Forum',
        ];
        $this->message->setFrom($address);
        $this->assertEquals($address, $this->message->getFrom());

        $result = $this->message->getHeadersString(['from']);
        $this->assertStringContainsString('From: "70:20:00 \" Forum" <[email protected]>', $result);
    }

    /**
     * testSender method
     */
    public function testSender(): void
    {
        $this->message->reset();
        $this->assertSame([], $this->message->getSender());

        $this->message->setSender('[email protected]', 'Name');
        $expected = ['[email protected]' => 'Name'];
        $this->assertSame($expected, $this->message->getSender());

        $headers = $this->message->getHeaders(['from' => true, 'sender' => true]);
        $this->assertSame('', $headers['From']);
        $this->assertSame('Name <[email protected]>', $headers['Sender']);

        $this->message->setFrom('[email protected]', 'CakePHP');
        $headers = $this->message->getHeaders(['from' => true, 'sender' => true]);
        $this->assertSame('CakePHP <[email protected]>', $headers['From']);
        $this->assertSame('', $headers['Sender']);
    }

    /**
     * testTo method
     */
    public function testTo(): void
    {
        $this->assertSame([], $this->message->getTo());

        $result = $this->message->setTo('[email protected]');
        $expected = ['[email protected]' => '[email protected]'];
        $this->assertSame($expected, $this->message->getTo());
        $this->assertSame($this->message, $result);

        $this->message->setTo('[email protected]', 'CakePHP');
        $expected = ['[email protected]' => 'CakePHP'];
        $this->assertSame($expected, $this->message->getTo());

        $list = [
            'root@localhost' => 'root',
            '[email protected]' => 'Bjorn',
            '[email protected]' => 'Cake PHP',
            '[email protected]' => 'Cake Groups',
            '[email protected]',
        ];
        $this->message->setTo($list);
        $expected = [
            'root@localhost' => 'root',
            '[email protected]' => 'Bjorn',
            '[email protected]' => 'Cake PHP',
            '[email protected]' => 'Cake Groups',
            '[email protected]' => '[email protected]',
        ];
        $this->assertSame($expected, $this->message->getTo());

        $this->message->addTo('[email protected]');
        $this->message->addTo('[email protected]', 'Mark Story');
        $this->message->addTo('[email protected]');
        $result = $this->message->addTo(['[email protected]' => 'PhpNut', '[email protected]']);
        $expected = [
            'root@localhost' => 'root',
            '[email protected]' => 'Bjorn',
            '[email protected]' => 'Cake PHP',
            '[email protected]' => 'Cake Groups',
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
            '[email protected]' => 'Mark Story',
            '[email protected]' => '[email protected]',
            '[email protected]' => 'PhpNut',
            '[email protected]' => '[email protected]',
        ];
        $this->assertSame($expected, $this->message->getTo());
        $this->assertSame($this->message, $result);
    }

    /**
     * test to address with _ in domain name
     */
    public function testToUnderscoreDomain(): void
    {
        $result = $this->message->setTo('cake@cake_php.org');
        $expected = ['cake@cake_php.org' => 'cake@cake_php.org'];
        $this->assertSame($expected, $this->message->getTo());
        $this->assertSame($this->message, $result);
    }

    /**
     * Data provider function for testBuildInvalidData
     *
     * @return array
     */
    public static function invalidEmails(): array
    {
        return [
            [''],
            ['string'],
            ['<tag>'],
            [['[email protected]', '1.0', '', 'string']],
        ];
    }

    /**
     * testBuildInvalidData
     *
     * @dataProvider invalidEmails
     * @param array|string $value
     */
    public function testInvalidEmail($value): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->message->setTo($value);
    }

    /**
     * testBuildInvalidData
     *
     * @dataProvider invalidEmails
     * @param array|string $value
     */
    public function testInvalidEmailAdd($value): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->message->addTo($value);
    }

    /**
     * test emailPattern method
     */
    public function testEmailPattern(): void
    {
        $regex = '/.+@.+\..+/i';
        $this->assertSame($regex, $this->message->setEmailPattern($regex)->getEmailPattern());
    }

    /**
     * Tests that it is possible to set email regex configuration to a CakeEmail object
     */
    public function testConfigEmailPattern(): void
    {
        $regex = '/.+@.+\..+/i';
        $email = new Message(['emailPattern' => $regex]);
        $this->assertSame($regex, $email->getEmailPattern());
    }

    /**
     * Tests that it is possible set custom email validation
     */
    public function testCustomEmailValidation(): void
    {
        $regex = '/^[\.a-z0-9!#$%&\'*+\/=?^_`{|}~-]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]{2,6}$/i';

        $this->message->setEmailPattern($regex)->setTo('[email protected]');
        $this->assertSame([
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());

        $this->message->addTo('[email protected]');
        $this->assertSame([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());

        $this->message->reset();
        $emails = [
            '[email protected]',
            '[email protected]',
        ];
        $additionalEmails = [
            '[email protected]',
            '[email protected]',
        ];
        $this->message->setEmailPattern($regex)->setTo($emails);
        $this->assertSame([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());

        $this->message->addTo($additionalEmails);
        $this->assertSame([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ], $this->message->getTo());
    }

    /**
     * Tests that it is possible to unset the email pattern and make use of filter_var() instead.
     */
    public function testUnsetEmailPattern(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage('Invalid email set for `to`. You passed `[email protected]`.');
        $email = new Message();
        $this->assertSame(Message::EMAIL_PATTERN, $email->getEmailPattern());

        $email->setEmailPattern(null);
        $this->assertNull($email->getEmailPattern());

        $email->setTo('[email protected]');
        $email->setTo('[email protected]');
    }

    /**
     * Tests that passing an empty string throws an InvalidArgumentException.
     */
    public function testEmptyTo(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage('The email set for `to` is empty.');
        $email = new Message();
        $email->setTo('');
    }

    /**
     * testFormatAddress method
     */
    public function testFormatAddress(): void
    {
        $result = $this->message->fmtAddress(['[email protected]' => '[email protected]']);
        $expected = ['[email protected]'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress([
            '[email protected]' => '[email protected]',
            '[email protected]' => '[email protected]',
        ]);
        $expected = ['[email protected]', '[email protected]'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress([
            '[email protected]' => 'CakePHP',
            '[email protected]' => 'Cake',
        ]);
        $expected = ['CakePHP <[email protected]>', 'Cake <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Last, First']);
        $expected = ['"Last, First" <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => '"Last" First']);
        $expected = ['"\"Last\" First" <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Last First']);
        $expected = ['Last First <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Test']);
        $expected = ['=?UTF-8?B?w4TDlsOcVGVzdA==?= <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => 'Test']);
        $expected = ['=?UTF-8?B?5pel5pys6KqeVGVzdA==?= <[email protected]>'];
        $this->assertSame($expected, $result);
    }

    /**
     * testFormatAddressJapanese
     */
    public function testFormatAddressJapanese(): void
    {
        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->fmtAddress(['[email protected]' => 'Test']);
        $expected = ['=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCVGVzdA==?= <[email protected]>'];
        $this->assertSame($expected, $result);

        $result = $this->message->fmtAddress(['[email protected]' => '']);
        $expected = ["\"=?ISO-2022-JP?B?GyRCPHc4Qkw1PHc4Qkw1OF45ZSROOyQkakBaJGwzJDo9TXg/ZTV7GyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCJE4/ZTlUS3YxQE1oS3ZJd01oS3Y/KSQmPzIkaz1oJEs9OyRgGyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCPWgkZCRWJGk+Lk8pJE5pLjQ7O1IlUSUkJV0lUSUkJV0lUSUkGyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCJV0kTiU3JWUhPCVqJXMlLCVzJTclZSE8JWolcyUsJXMkTiUwGyhC?=\r\n" .
            " =?ISO-2022-JP?B?GyRCITwlaiVzJUAlJCUwITwlaiVzJUAlJCROJV0lcyVdJTMlVCE8GyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJE4lXSVzJV0lMyVKITwkTkQ5NVdMPyRORDk9dRsoQg==?=" <[email protected]>'];
        $this->assertSame($expected, $result);
    }

    /**
     * testAddresses method
     */
    public function testAddresses(): void
    {
        $this->message->reset();
        $this->message->setFrom('[email protected]', 'CakePHP');
        $this->message->setReplyTo('[email protected]', 'ReplyTo CakePHP');
        $this->message->setReadReceipt('[email protected]', 'ReadReceipt CakePHP');
        $this->message->setReturnPath('[email protected]', 'ReturnPath CakePHP');
        $this->message->setTo('[email protected]', 'To, CakePHP');
        $this->message->setCc('[email protected]', 'Cc CakePHP');
        $this->message->setBcc('[email protected]', 'Bcc CakePHP');
        $this->message->addTo('[email protected]', 'To2 CakePHP');
        $this->message->addCc('[email protected]', 'Cc2 CakePHP');
        $this->message->addBcc('[email protected]', 'Bcc2 CakePHP');
        $this->message->addReplyTo('[email protected]', 'ReplyTo2 CakePHP');

        $this->assertSame($this->message->getFrom(), ['[email protected]' => 'CakePHP']);
        $this->assertSame($this->message->getReplyTo(), ['[email protected]' => 'ReplyTo CakePHP', '[email protected]' => 'ReplyTo2 CakePHP']);
        $this->assertSame($this->message->getReadReceipt(), ['[email protected]' => 'ReadReceipt CakePHP']);
        $this->assertSame($this->message->getReturnPath(), ['[email protected]' => 'ReturnPath CakePHP']);
        $this->assertSame($this->message->getTo(), ['[email protected]' => 'To, CakePHP', '[email protected]' => 'To2 CakePHP']);
        $this->assertSame($this->message->getCc(), ['[email protected]' => 'Cc CakePHP', '[email protected]' => 'Cc2 CakePHP']);
        $this->assertSame($this->message->getBcc(), ['[email protected]' => 'Bcc CakePHP', '[email protected]' => 'Bcc2 CakePHP']);

        $headers = $this->message->getHeaders(array_fill_keys(['from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'], true));
        $this->assertSame($headers['From'], 'CakePHP <[email protected]>');
        $this->assertSame($headers['Reply-To'], 'ReplyTo CakePHP <[email protected]>, ReplyTo2 CakePHP <[email protected]>');
        $this->assertSame($headers['Disposition-Notification-To'], 'ReadReceipt CakePHP <[email protected]>');
        $this->assertSame($headers['Return-Path'], 'ReturnPath CakePHP <[email protected]>');
        $this->assertSame($headers['To'], '"To, CakePHP" <[email protected]>, To2 CakePHP <[email protected]>');
        $this->assertSame($headers['Cc'], 'Cc CakePHP <[email protected]>, Cc2 CakePHP <[email protected]>');
        $this->assertSame($headers['Bcc'], 'Bcc CakePHP <[email protected]>, Bcc2 CakePHP <[email protected]>');

        $this->message->setReplyTo(['[email protected]' => 'ReplyTo CakePHP', '[email protected]' => 'ReplyTo2 CakePHP']);
        $this->assertSame($this->message->getReplyTo(), ['[email protected]' => 'ReplyTo CakePHP', '[email protected]' => 'ReplyTo2 CakePHP']);
        $headers = $this->message->getHeaders(array_fill_keys(['replyTo'], true));
        $this->assertSame($headers['Reply-To'], 'ReplyTo CakePHP <[email protected]>, ReplyTo2 CakePHP <[email protected]>');
    }

    /**
     * test reset addresses method
     */
    public function testResetAddresses(): void
    {
        $this->message->reset();
        $this->message
            ->setFrom('[email protected]', 'CakePHP')
            ->setReplyTo('[email protected]', 'ReplyTo CakePHP')
            ->setReadReceipt('[email protected]', 'ReadReceipt CakePHP')
            ->setReturnPath('[email protected]', 'ReturnPath CakePHP')
            ->setTo('[email protected]', 'To, CakePHP')
            ->setCc('[email protected]', 'Cc CakePHP')
            ->setBcc('[email protected]', 'Bcc CakePHP');

        $this->assertNotEmpty($this->message->getFrom());
        $this->assertNotEmpty($this->message->getReplyTo());
        $this->assertNotEmpty($this->message->getReadReceipt());
        $this->assertNotEmpty($this->message->getReturnPath());
        $this->assertNotEmpty($this->message->getTo());
        $this->assertNotEmpty($this->message->getCc());
        $this->assertNotEmpty($this->message->getBcc());

        $this->message
            ->setFrom([])
            ->setReplyTo([])
            ->setReadReceipt([])
            ->setReturnPath([])
            ->setTo([])
            ->setCc([])
            ->setBcc([]);

        $this->assertEmpty($this->message->getFrom());
        $this->assertEmpty($this->message->getReplyTo());
        $this->assertEmpty($this->message->getReadReceipt());
        $this->assertEmpty($this->message->getReturnPath());
        $this->assertEmpty($this->message->getTo());
        $this->assertEmpty($this->message->getCc());
        $this->assertEmpty($this->message->getBcc());
    }

    /**
     * testMessageId method
     */
    public function testMessageId(): void
    {
        $this->message->setMessageId(true);
        $result = $this->message->getHeaders();
        $this->assertArrayHasKey('Message-ID', $result);

        $this->message->setMessageId(false);
        $result = $this->message->getHeaders();
        $this->assertArrayNotHasKey('Message-ID', $result);

        $result = $this->message->setMessageId('<my-email@localhost>');
        $this->assertSame($this->message, $result);
        $result = $this->message->getHeaders();
        $this->assertSame('<my-email@localhost>', $result['Message-ID']);

        $result = $this->message->getMessageId();
        $this->assertSame('<my-email@localhost>', $result);
    }

    public function testAutoMessageIdIsIdempotent(): void
    {
        $headers = $this->message->getHeaders();
        $this->assertArrayHasKey('Message-ID', $headers);

        $regeneratedHeaders = $this->message->getHeaders();
        $this->assertSame($headers['Message-ID'], $regeneratedHeaders['Message-ID']);
    }

    public function testPriority(): void
    {
        $this->message->setPriority(4);

        $this->assertSame(4, $this->message->getPriority());

        $result = $this->message->getHeaders();
        $this->assertArrayHasKey('X-Priority', $result);
    }

    /**
     * testMessageIdInvalid method
     */
    public function testMessageIdInvalid(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->message->setMessageId('my-email@localhost');
    }

    /**
     * testDomain method
     */
    public function testDomain(): void
    {
        $result = $this->message->getDomain();
        $expected = env('HTTP_HOST') ? env('HTTP_HOST') : php_uname('n');
        $this->assertSame($expected, $result);

        $this->message->setDomain('example.org');
        $result = $this->message->getDomain();
        $expected = 'example.org';
        $this->assertSame($expected, $result);
    }

    /**
     * testMessageIdWithDomain method
     */
    public function testMessageIdWithDomain(): void
    {
        $this->message->setDomain('example.org');
        $result = $this->message->getHeaders();
        $expected = '@example.org>';
        $this->assertTextContains($expected, $result['Message-ID']);

        $_SERVER['HTTP_HOST'] = 'example.org';
        $result = $this->message->getHeaders();
        $this->assertTextContains('example.org', $result['Message-ID']);

        $_SERVER['HTTP_HOST'] = 'example.org:81';
        $result = $this->message->getHeaders();
        $this->assertTextNotContains(':81', $result['Message-ID']);
    }

    /**
     * testSubject method
     */
    public function testSubject(): void
    {
        $this->message->setSubject('You have a new message.');
        $this->assertSame('You have a new message.', $this->message->getSubject());

        $this->message->setSubject('You have a new message, I think.');
        $this->assertSame($this->message->getSubject(), 'You have a new message, I think.');
        $this->message->setSubject('1');
        $this->assertSame('1', $this->message->getSubject());

        $input = '     ';
        $this->message->setSubject($input);
        $expected = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?=';
        $this->assertSame($expected, $this->message->getSubject());
        $this->assertSame($input, $this->message->getOriginalSubject());
    }

    /**
     * testSubjectJapanese
     */
    public function testSubjectJapanese(): void
    {
        mb_internal_encoding('UTF-8');

        $this->message->setHeaderCharset('ISO-2022-JP');
        $this->message->setSubject('Subject');
        $expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsJE4bKEJTdWJqZWN0GyRCJEskYkJQMX4kOSRrJGgbKEI=?=';
        $this->assertSame($expected, $this->message->getSubject());

        $this->message->setSubject('Subjectfolding');
        $expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
            " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=';
        $this->assertSame($expected, $this->message->getSubject());
    }

    /**
     * testAttachments method
     */
    public function testSetAttachments(): void
    {
        $uploadedFile = new UploadedFile(
            __FILE__,
            filesize(__FILE__),
            UPLOAD_ERR_OK,
            'MessageTest.php',
            'text/x-php'
        );

        $this->message->setAttachments([
            CAKE . 'Mailer' . DS . 'Message.php',
            $uploadedFile,
        ]);
        $expected = [
            'Message.php' => [
                'file' => CAKE . 'Mailer' . DS . 'Message.php',
                'mimetype' => 'text/x-php',
            ],
            'MessageTest.php' => [
                'file' => $uploadedFile,
                'mimetype' => 'text/x-php',
            ],
        ];
        $this->assertSame($expected, $this->message->getAttachments());

        $this->message->setAttachments([]);
        $this->assertSame([], $this->message->getAttachments());

        $this->message->setAttachments([
            ['file' => __FILE__, 'mimetype' => 'text/plain'],
        ]);
        $this->message->addAttachments([CORE_PATH . 'config' . DS . 'bootstrap.php']);
        $this->message->addAttachments([CORE_PATH . 'config' . DS . 'bootstrap.php']);
        $this->message->addAttachments([
            'other.txt' => CORE_PATH . 'config' . DS . 'bootstrap.php',
            'license' => CORE_PATH . 'LICENSE',
        ]);
        $expected = [
            'MessageTest.php' => ['file' => __FILE__, 'mimetype' => 'text/plain'],
            'bootstrap.php' => ['file' => CORE_PATH . 'config' . DS . 'bootstrap.php', 'mimetype' => 'text/x-php'],
            'other.txt' => ['file' => CORE_PATH . 'config' . DS . 'bootstrap.php', 'mimetype' => 'text/x-php'],
            'license' => ['file' => CORE_PATH . 'LICENSE', 'mimetype' => 'text/plain'],
        ];
        $this->assertSame($expected, $this->message->getAttachments());
        $this->expectException(InvalidArgumentException::class);
        $this->message->setAttachments([['nofile' => __FILE__, 'mimetype' => 'text/plain']]);
    }

    /**
     * Test send() with no template and data string attachment and no mimetype
     */
    public function testSetAttachmentDataNoMimetype(): void
    {
        $this->message->setAttachments(['cake.icon.gif' => [
            'data' => 'test',
        ]]);
        $expected = [
            'cake.icon.gif' => [
                'data' => base64_encode('test') . "\r\n",
                'mimetype' => 'application/octet-stream',
            ],
        ];
        $this->assertSame($expected, $this->message->getAttachments());
    }

    public function testSetAttachmentInvalidFile(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage(
            'File must be a filepath or UploadedFileInterface instance. Found `boolean` instead.'
        );

        $this->message->setAttachments(['cake.icon.gif' => [
            'file' => true,
        ]]);
    }

    /**
     * testReset method
     */
    public function testReset(): void
    {
        $this->message->setTo('[email protected]');
        $this->message->setEmailPattern('/.+@.+\..+/i');
        $this->assertSame(['[email protected]' => '[email protected]'], $this->message->getTo());

        $this->message->reset();
        $this->assertSame([], $this->message->getTo());
        $this->assertSame(Message::EMAIL_PATTERN, $this->message->getEmailPattern());
    }

    /**
     * testReset with charset
     */
    public function testResetWithCharset(): void
    {
        $this->message->setCharset('ISO-2022-JP');
        $this->message->reset();

        $this->assertSame('utf-8', $this->message->getCharset());
        $this->assertSame('utf-8', $this->message->getHeaderCharset());
    }

    /**
     * testEmailFormat method
     */
    public function testEmailFormat(): void
    {
        $result = $this->message->getEmailFormat();
        $this->assertSame('text', $result);

        $result = $this->message->setEmailFormat('html');
        $this->assertInstanceOf(Message::class, $result);

        $result = $this->message->getEmailFormat();
        $this->assertSame('html', $result);

        $this->expectException(InvalidArgumentException::class);
        $this->message->setEmailFormat('invalid');
    }

    /**
     * Tests that it is possible to add charset configuration to a CakeEmail object
     */
    public function testConfigCharset(): void
    {
        $email = new Message();
        $this->assertEquals(Configure::read('App.encoding'), $email->getCharset());
        $this->assertEquals(Configure::read('App.encoding'), $email->getHeaderCharset());

        $email = new Message(['charset' => 'iso-2022-jp', 'headerCharset' => 'iso-2022-jp-ms']);
        $this->assertSame('iso-2022-jp', $email->getCharset());
        $this->assertSame('iso-2022-jp-ms', $email->getHeaderCharset());

        $email = new Message(['charset' => 'iso-2022-jp']);
        $this->assertSame('iso-2022-jp', $email->getCharset());
        $this->assertSame('iso-2022-jp', $email->getHeaderCharset());

        $email = new Message(['headerCharset' => 'iso-2022-jp-ms']);
        $this->assertEquals(Configure::read('App.encoding'), $email->getCharset());
        $this->assertSame('iso-2022-jp-ms', $email->getHeaderCharset());
    }

    public function testGetBody(): void
    {
        $message = new Message();

        $uploadedFile = new UploadedFile(
            __FILE__,
            filesize(__FILE__),
            UPLOAD_ERR_OK,
            'MessageTest.php',
            'text/x-php'
        );
        $chunks = base64_encode(file_get_contents(__FILE__));

        $result = $message->setAttachments([$uploadedFile])
            ->setBodyText('Attached an uploaded file')
            ->getBody();
        $result = implode("\r\n", $result);
        $this->assertStringContainsString($chunks[0], $result);
    }

    /**
     * Tests that the body is encoded using the configured charset (Japanese standard encoding)
     */
    public function testBodyEncodingIso2022Jp(): void
    {
        $message = new Message([
            'charset' => 'iso-2022-jp',
            'headerCharset' => 'iso-2022-jp',
            'transport' => 'debug',
        ]);
        $message->setSubject('');

        $headers = $message->getHeaders(['subject']);
        $expected = '?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=';
        $this->assertStringContainsString($expected, $headers['Subject']);

        $message->setBodyHtml(' ');

        $result = $message->getHeadersString();
        $this->assertTextContains('Content-Type: text/plain; charset=ISO-2022-JP', $result);
        $this->assertTextNotContains('Content-Type: text/plain; charset=ISO-2022-JP-MS', $result); // not charset=iso-2022-jp-ms

        $result = implode('', $message->getBody());
        $this->assertTextNotContains(mb_convert_encoding(' ', 'ISO-2022-JP-MS'), $result);
    }

    /**
     * Tests that the body is encoded using the configured charset (Japanese irregular encoding, but sometime use this)
     */
    public function testBodyEncodingIso2022JpMs(): void
    {
        $message = new Message([
            'charset' => 'iso-2022-jp-ms',
            'headerCharset' => 'iso-2022-jp-ms',
            'transport' => 'debug',
        ]);
        $message->setSubject('');
        $headers = $message->getHeaders(['subject']);
        $expected = '?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=';
        $this->assertStringContainsString($expected, $headers['Subject']);

        $result = $message->setBodyText(' ');

        $result = $message->getHeadersString();
        $this->assertTextContains('Content-Type: text/plain; charset=ISO-2022-JP', $result);
        $this->assertTextNotContains('Content-Type: text/plain; charset=iso-2022-jp-ms', $result); // not charset=iso-2022-jp-ms

        $result = implode('', $message->getBody());
        $this->assertStringContainsString(mb_convert_encoding(' ', 'ISO-2022-JP-MS'), $result);
    }

    /**
     * Tests that the body is encoded using the configured charset
     */
    public function testEncodingMixed(): void
    {
        $message = new Message([
            'headerCharset' => 'iso-2022-jp-ms',
            'charset' => 'iso-2022-jp',
        ]);

        $message->setBodyText('');

        $result = $message->getHeadersString();
        $this->assertStringContainsString('Content-Type: text/plain; charset=ISO-2022-JP', $result);

        $result = implode('', $message->getBody());
        $this->assertStringContainsString(mb_convert_encoding('', 'ISO-2022-JP'), $result);
    }

    /**
     * Test CakeMessage::_encode function
     */
    public function testEncode(): void
    {
        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->encode('');
        $expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=';
        $this->assertSame($expected, $result);

        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->encode('Subjectfolding');
        $expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
            " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=';
        $this->assertSame($expected, $result);
    }

    /**
     * Test CakeMessage::_decode function
     */
    public function testDecode(): void
    {
        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->decode('=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=');
        $expected = '';
        $this->assertSame($expected, $result);

        $this->message->setHeaderCharset('ISO-2022-JP');
        $result = $this->message->decode("=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
            " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
            ' =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=');
        $expected = 'Subjectfolding';
        $this->assertSame($expected, $result);
    }

    /**
     * Tests charset setter/getter
     */
    public function testCharset(): void
    {
        $this->message->setCharset('UTF-8');
        $this->assertSame($this->message->getCharset(), 'UTF-8');

        $this->message->setCharset('ISO-2022-JP');
        $this->assertSame($this->message->getCharset(), 'ISO-2022-JP');

        $charset = $this->message->setCharset('Shift_JIS');
        $this->assertSame('Shift_JIS', $charset->getCharset());
    }

    /**
     * Tests headerCharset setter/getter
     */
    public function testHeaderCharset(): void
    {
        $this->message->setHeaderCharset('UTF-8');
        $this->assertSame($this->message->getHeaderCharset(), 'UTF-8');

        $this->message->setHeaderCharset('ISO-2022-JP');
        $this->assertSame($this->message->getHeaderCharset(), 'ISO-2022-JP');

        $charset = $this->message->setHeaderCharset('Shift_JIS');
        $this->assertSame('Shift_JIS', $charset->getHeaderCharset());
    }

    /**
     * Test transferEncoding
     */
    public function testTransferEncoding(): void
    {
        // Test new transfer encoding
        $expected = 'quoted-printable';
        $this->message->setTransferEncoding($expected);
        $this->assertSame($expected, $this->message->getTransferEncoding());
        $this->assertSame($expected, $this->message->getContentTransferEncoding());

        // Test default charset/encoding : utf8/8bit
        $expected = '8bit';
        $this->message->reset();
        $this->assertNull($this->message->getTransferEncoding());
        $this->assertSame($expected, $this->message->getContentTransferEncoding());

        //Test wrong encoding
        $this->expectException(InvalidArgumentException::class);
        $this->message->setTransferEncoding('invalid');
    }

    /**
     * Tests for compatible check.
     *          charset property and       charset() method.
     *    headerCharset property and headerCharset() method.
     */
    public function testCharsetsCompatible(): void
    {
        $checkHeaders = [
            'from' => true,
            'to' => true,
            'cc' => true,
            'subject' => true,
        ];

        // Header Charset : null (used by default UTF-8)
        //   Body Charset : ISO-2022-JP
        $oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', null);
        $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);

        $newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', null);
        $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);

        $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
        $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
        $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
        $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);

        // Header Charset : UTF-8
        //   Boby Charset : ISO-2022-JP
        $oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', 'utf-8');
        $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);

        $newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', 'utf-8');
        $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);

        $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
        $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
        $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
        $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);

        // Header Charset : ISO-2022-JP
        //   Boby Charset : UTF-8
        $oldStyleEmail = $this->_getEmailByOldStyleCharset('utf-8', 'iso-2022-jp');
        $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);

        $newStyleEmail = $this->_getEmailByNewStyleCharset('utf-8', 'iso-2022-jp');
        $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);

        $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
        $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
        $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
        $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
    }

    /**
     * @param mixed $charset
     * @param mixed $headerCharset
     */
    protected function _getEmailByOldStyleCharset($charset, $headerCharset): Message
    {
        $message = new Message(['transport' => 'debug']);

        if ($charset) {
            $message->setCharset($charset);
        }
        if ($headerCharset) {
            $message->setHeaderCharset($headerCharset);
        }

        $message->setFrom('[email protected]', '');
        $message->setTo('[email protected]', '');
        $message->setCc('[email protected]', '');
        $message->setSubject('');
        $message->setBodyText('');

        return $message;
    }

    /**
     * @param mixed $charset
     * @param mixed $headerCharset
     */
    protected function _getEmailByNewStyleCharset($charset, $headerCharset): Message
    {
        $message = new Message();

        if ($charset) {
            $message->setCharset($charset);
        }
        if ($headerCharset) {
            $message->setHeaderCharset($headerCharset);
        }

        $message->setFrom('[email protected]', '');
        $message->setTo('[email protected]', '');
        $message->setCc('[email protected]', '');
        $message->setSubject('');
        $message->setBodyText('');

        return $message;
    }

    /**
     * @param string $message
     */
    protected function assertLineLengths($message): void
    {
        $lines = explode("\r\n", $message);
        foreach ($lines as $line) {
            $this->assertTrue(
                strlen($line) <= Message::LINE_LENGTH_MUST,
                'Line length exceeds the max. limit of Message::LINE_LENGTH_MUST'
            );
        }
    }

    public function testSerialization(): void
    {
        $message = new Message();
        $reflection = new ReflectionClass($message);
        $property = $reflection->getProperty('serializableProperties');
        $property->setAccessible(true);
        $serializableProperties = $property->getValue($message);

        $message
            ->setSubject('I haz Cake')
            ->setEmailFormat(Message::MESSAGE_BOTH)
            ->setBody([
                Message::MESSAGE_TEXT => 'text message',
                Message::MESSAGE_HTML => '<strong>html message</strong>',
            ]);

        $string = serialize($message);
        $this->assertStringContainsString('text message', $string);

        $this->assertIsArray($serializableProperties);
        $this->assertContains('subject', $serializableProperties);
        $this->assertContains('emailFormat', $serializableProperties);
        $this->assertContains('textMessage', $serializableProperties);
        $this->assertContains('htmlMessage', $serializableProperties);

        /** @var \Cake\Mailer\Message $message */
        $message = unserialize($string);
        $this->assertSame('I haz Cake', $message->getSubject());
        $body = $message->getBodyString();
        $this->assertStringContainsString('text message', $body);
        $this->assertStringContainsString('<strong>html message</strong>', $body);
    }
}

Function Calls

None

Variables

None

Stats

MD5 5aec916bcbb98fb49ebeda0d1ee4836e
Eval Count 0
Decode Time 87 ms