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 |
Stats
MD5 | 5aec916bcbb98fb49ebeda0d1ee4836e |
Eval Count | 0 |
Decode Time | 87 ms |