mail = $this->_mail; $this->subject = $this->_mail->getSubject(); $this->from = $this->_mail->getFrom(); $this->returnPath = $this->_mail->getReturnPath(); $this->called = true; } } /** * Mock mail transport class for testing Sendmail transport * * @category Zend * @package Zend_Mail * @subpackage UnitTests * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_Mail_Transport_Sendmail_Mock extends Zend_Mail_Transport_Sendmail { /** * @var Zend_Mail */ public $mail = null; public $from = null; public $subject = null; public $called = false; public function _sendMail() { $this->mail = $this->_mail; $this->from = $this->_mail->getFrom(); $this->subject = $this->_mail->getSubject(); $this->called = true; } } /** * @category Zend * @package Zend_Mail * @subpackage UnitTests * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_MailTest extends PHPUnit_Framework_TestCase { /** * Test case for a simple email text message with * multiple recipients. * */ public function testOnlyText() { $mail = new Zend_Mail(); $res = $mail->setBodyText('This is a test.'); $mail->setFrom('testmail@example.com', 'test Mail User'); $mail->setSubject('My Subject'); $mail->addTo('recipient1@example.com'); $mail->addTo('recipient2@example.com'); $mail->addBcc('recipient1_bcc@example.com'); $mail->addBcc('recipient2_bcc@example.com'); $mail->addCc('recipient1_cc@example.com', 'Example no. 1 for cc'); $mail->addCc('recipient2_cc@example.com', 'Example no. 2 for cc'); $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); $this->assertTrue($mock->called); $this->assertEquals('My Subject', $mock->subject); $this->assertEquals('testmail@example.com', $mock->from); $this->assertContains('recipient1@example.com', $mock->recipients); $this->assertContains('recipient2@example.com', $mock->recipients); $this->assertContains('recipient1_bcc@example.com', $mock->recipients); $this->assertContains('recipient2_bcc@example.com', $mock->recipients); $this->assertContains('recipient1_cc@example.com', $mock->recipients); $this->assertContains('recipient2_cc@example.com', $mock->recipients); $this->assertContains('This is a test.', $mock->body); $this->assertContains('Content-Transfer-Encoding: quoted-printable', $mock->header); $this->assertContains('Content-Type: text/plain', $mock->header); $this->assertContains('From: "test Mail User" ', $mock->header); $this->assertContains('Subject: My Subject', $mock->header); $this->assertContains('To: ', $mock->header); $this->assertContains('Cc: "Example no. 1 for cc" ', $mock->header); } /** * Check if Header Fields are encoded correctly and if * header injection is prevented. */ public function testHeaderEncoding() { $mail = new Zend_Mail(); $mail->setBodyText('My Nice Test Text'); // try header injection: $mail->addTo("testmail@example.com\nCc:foobar@example.com"); $mail->addHeader('X-MyTest', "Test\nCc:foobar2@example.com", true); // try special Chars in Header Fields: $mail->setFrom('mymail@example.com', '�������'); $mail->addTo('testmail2@example.com', '�������'); $mail->addCc('testmail3@example.com', '�������'); $mail->setSubject('�������'); $mail->addHeader('X-MyTest', 'Test-�������', true); $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); $this->assertTrue($mock->called); $this->assertContains('From: =?iso-8859-1?Q?"=E4=FC=F6=DF=C4=D6=DC"?=', $mock->header); $this->assertNotContains("\nCc:foobar@example.com", $mock->header); $this->assertContains('=?iso-8859-1?Q?=E4=FC=F6=DF=C4=D6=DC?=" ', $mock->header); $this->assertContains('Cc: "=?iso-8859-1?Q?=E4=FC=F6=DF=C4=D6=DC?=" ', $mock->header); $this->assertContains('Subject: =?iso-8859-1?Q?=E4=FC=F6=DF=C4=D6=DC?=', $mock->header); $this->assertContains('X-MyTest:', $mock->header); $this->assertNotContains("\nCc:foobar2@example.com", $mock->header); $this->assertContains('=?iso-8859-1?Q?Test-=E4=FC=F6=DF=C4=D6=DC?=', $mock->header); } /** * Check if Header Fields are stripped accordingly in sendmail transport; * also check for header injection * @todo Determine why this fails in Windows (testmail3@example.com example) */ public function testHeaderEncoding2() { throw new PHPUnit_Framework_IncompleteTestError('still working on cross-platform tests'); $mail = new Zend_Mail(); $mail->setBodyText('My Nice Test Text'); // try header injection: $mail->addTo("testmail@example.com\nCc:foobar@example.com"); $mail->addHeader('X-MyTest', "Test\nCc:foobar2@example.com", true); // try special Chars in Header Fields: $mail->setFrom('mymail@example.com', '�������'); $mail->addTo('testmail2@example.com', '�������'); $mail->addCc('testmail3@example.com', '�������'); $mail->setSubject('�������'); $mail->addHeader('X-MyTest', 'Test-�������', true); $mock = new Zend_Mail_Transport_Sendmail_Mock(); $mail->send($mock); $this->assertTrue($mock->called); $this->assertContains('From: =?iso-8859-1?Q?"=E4=FC=F6=DF=C4=D6=DC"?=', $mock->header); $this->assertNotContains("\nCc:foobar@example.com", $mock->header); $this->assertContains('Cc: "=?iso-8859-1?Q?=E4=FC=F6=DF=C4=D6=DC?=" ', $mock->header); $this->assertContains('X-MyTest:', $mock->header); $this->assertNotContains("\nCc:foobar2@example.com", $mock->header); $this->assertContains('=?iso-8859-1?Q?Test-=E4=FC=F6=DF=C4=D6=DC?=', $mock->header); $this->assertNotContains('Subject: ', $mock->header); $this->assertContains('=?iso-8859-1?Q?=E4=FC=F6=DF=C4=D6=DC?=', $mock->subject); $this->assertContains('"=?iso-8859-1?Q?=E4=FC=F6=DF=C4=D6=DC?=" ', $mock->recipients, $mock->recipients); } /** * Check if Mails with HTML and Text Body are generated correctly. * */ public function testMultipartAlternative() { $mail = new Zend_Mail(); $mail->setBodyText('My Nice Test Text'); $mail->setBodyHtml('My Nice Test Text'); $mail->addTo('testmail@example.com', 'Test Recipient'); $mail->setFrom('mymail@example.com', 'Test Sender'); $mail->setSubject('Test: Alternate Mail with Zend_Mail'); $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); // check headers $this->assertTrue($mock->called); $this->assertContains('multipart/alternative', $mock->header); $boundary = $mock->boundary; $this->assertContains('boundary="' . $boundary . '"', $mock->header); $this->assertContains('MIME-Version: 1.0', $mock->header); // check body // search for first boundary $p1 = strpos($mock->body, "--$boundary\n"); $this->assertNotNull($p1, $boundary . ': ' . $mock->body); // cut out first (Text) part $start1 = $p1 + 3 + strlen($boundary); $p2 = strpos($mock->body, "--$boundary\n", $start1); $this->assertNotNull($p2); $partBody1 = substr($mock->body, $start1, ($p2 - $start1)); $this->assertContains('Content-Type: text/plain', $partBody1); $this->assertContains('My Nice Test Text', $partBody1); // check second (HTML) part // search for end boundary $start2 = $p2 + 3 + strlen($boundary); $p3 = strpos($mock->body, "--$boundary--"); $this->assertNotNull($p3); $partBody2 = substr($mock->body, $start2, ($p3 - $start2)); $this->assertContains('Content-Type: text/html', $partBody2); $this->assertContains('My Nice Test Text', $partBody2); } /** * check if attachment handling works * */ public function testAttachment() { $mail = new Zend_Mail(); $mail->setBodyText('My Nice Test Text'); $mail->addTo('testmail@example.com', 'Test Recipient'); $mail->setFrom('mymail@example.com', 'Test Sender'); $mail->setSubject('Test: Attachment Test with Zend_Mail'); $at = $mail->createAttachment('abcdefghijklmnopqrstuvexyz'); $at->type = 'image/gif'; $at->id = 12; $at->filename = 'test.gif'; $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); // now check what was generated by Zend_Mail. // first the mail headers: $this->assertContains('Content-Type: multipart/mixed', $mock->header, $mock->header); $boundary = $mock->boundary; $this->assertContains('boundary="' . $boundary . '"', $mock->header); $this->assertContains('MIME-Version: 1.0', $mock->header); // check body // search for first boundary $p1 = strpos($mock->body, "--$boundary\n"); $this->assertNotNull($p1); // cut out first (Text) part $start1 = $p1 + 3 + strlen($boundary); $p2 = strpos($mock->body, "--$boundary\n", $start1); $this->assertNotNull($p2); $partBody1 = substr($mock->body, $start1, ($p2 - $start1)); $this->assertContains('Content-Type: text/plain', $partBody1); $this->assertContains('My Nice Test Text', $partBody1); // check second (HTML) part // search for end boundary $start2 = $p2 + 3 + strlen($boundary); $p3 = strpos($mock->body, "--$boundary--"); $this->assertNotNull($p3); $partBody2 = substr($mock->body, $start2, ($p3 - $start2)); $this->assertContains('Content-Type: image/gif', $partBody2); $this->assertContains('Content-Transfer-Encoding: base64', $partBody2); $this->assertContains('Content-ID: <12>', $partBody2); } /** * Check if Mails with HTML and Text Body are generated correctly. * */ public function testMultipartAlternativePlusAttachment() { $mail = new Zend_Mail(); $mail->setBodyText('My Nice Test Text'); $mail->setBodyHtml('My Nice Test Text'); $mail->addTo('testmail@example.com', 'Test Recipient'); $mail->setFrom('mymail@example.com', 'Test Sender'); $mail->setSubject('Test: Alternate Mail with Zend_Mail'); $at = $mail->createAttachment('abcdefghijklmnopqrstuvexyz'); $at->type = 'image/gif'; $at->id = 12; $at->filename = 'test.gif'; $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); // check headers $this->assertTrue($mock->called); $this->assertContains('multipart/mixed', $mock->header); $boundary = $mock->boundary; $this->assertContains('boundary="' . $boundary . '"', $mock->header); $this->assertContains('MIME-Version: 1.0', $mock->header); // check body // search for first boundary $p1 = strpos($mock->body, "--$boundary\n"); $this->assertNotNull($p1); // cut out first (multipart/alternative) part $start1 = $p1 + 3 + strlen($boundary); $p2 = strpos($mock->body, "--$boundary\n", $start1); $this->assertNotNull($p2); $partBody1 = substr($mock->body, $start1, ($p2 - $start1)); $this->assertContains('Content-Type: multipart/alternative', $partBody1); $this->assertContains('Content-Type: text/plain', $partBody1); $this->assertContains('Content-Type: text/html', $partBody1); $this->assertContains('My Nice Test Text', $partBody1); $this->assertContains('My Nice Test Text', $partBody1); // check second (image) part // search for end boundary $start2 = $p2 + 3 + strlen($boundary); $p3 = strpos($mock->body, "--$boundary--"); $this->assertNotNull($p3); $partBody2 = substr($mock->body, $start2, ($p3 - $start2)); $this->assertContains('Content-Type: image/gif', $partBody2); $this->assertContains('Content-Transfer-Encoding: base64', $partBody2); $this->assertContains('Content-ID: <12>', $partBody2); } public function testReturnPath() { $mail = new Zend_Mail(); $res = $mail->setBodyText('This is a test.'); $mail->setFrom('testmail@example.com', 'test Mail User'); $mail->setSubject('My Subject'); $mail->addTo('recipient1@example.com'); $mail->addTo('recipient2@example.com'); $mail->addBcc('recipient1_bcc@example.com'); $mail->addBcc('recipient2_bcc@example.com'); $mail->addCc('recipient1_cc@example.com', 'Example no. 1 for cc'); $mail->addCc('recipient2_cc@example.com', 'Example no. 2 for cc'); // First example: from and return-path should be equal $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); $this->assertTrue($mock->called); $this->assertEquals($mail->getFrom(), $mock->returnPath); // Second example: from and return-path should not be equal $mail->setReturnPath('sender2@example.com'); $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); $this->assertTrue($mock->called); $this->assertNotEquals($mail->getFrom(), $mock->returnPath); $this->assertEquals($mail->getReturnPath(), $mock->returnPath); $this->assertNotEquals($mock->returnPath, $mock->from); } public function testNoBody() { $mail = new Zend_Mail(); $mail->setFrom('testmail@example.com', 'test Mail User'); $mail->setSubject('My Subject'); $mail->addTo('recipient1@example.com'); // First example: from and return-path should be equal $mock = new Zend_Mail_Transport_Mock(); try { $mail->send($mock); $this->assertTrue($mock->called); } catch (Exception $e) { // success $this->assertContains('No body specified', $e->getMessage()); } } /** * Helper method for {@link testZf928ToAndBccHeadersShouldNotMix()}; extracts individual header lines * * @param Zend_Mail_Transport_Abstract $mock * @param string $type * @return string */ protected function _getHeader(Zend_Mail_Transport_Abstract $mock, $type = 'To') { $headers = str_replace("\r\n", "\n", $mock->header); $headers = explode("\n", $mock->header); $return = ''; foreach ($headers as $header) { if (!empty($return)) { // Check for header continuation if (!preg_match('/^[a-z-]+:/i', $header)) { $return .= "\r\n" . $header; continue; } else { break; } } if (preg_match('/^' . $type . ': /', $header)) { $return = $header; } } return $return; } public function testZf928ToAndBccHeadersShouldNotMix() { $mail = new Zend_Mail(); $mail->setSubject('my subject'); $mail->setBodyText('my body'); $mail->setFrom('info@onlime.ch'); $mail->addTo('to.address@email.com'); $mail->addBcc('first.bcc@email.com'); $mail->addBcc('second.bcc@email.com'); // test with generic transport $mock = new Zend_Mail_Transport_Mock(); $mail->send($mock); $to = $this->_getHeader($mock); $bcc = $this->_getHeader($mock, 'Bcc'); $this->assertContains('to.address@email.com', $to, $to); $this->assertNotContains('second.bcc@email.com', $to, $bcc); // test with sendmail-like transport $mock = new Zend_Mail_Transport_Sendmail_Mock(); $mail->send($mock); $to = $this->_getHeader($mock); $bcc = $this->_getHeader($mock, 'Bcc'); // Remove the following line due to fixes by Simon // $this->assertNotContains('to.address@email.com', $to, $mock->header); $this->assertNotContains('second.bcc@email.com', $to, $bcc); } public function testZf927BlankLinesShouldPersist() { $mail = new Zend_Mail(); $mail->setSubject('my subject'); $mail->setBodyText("my body\r\n\r\n...after two newlines"); $mail->setFrom('test@email.com'); $mail->addTo('test@email.com'); // test with generic transport $mock = new Zend_Mail_Transport_Sendmail_Mock(); $mail->send($mock); $body = quoted_printable_decode($mock->body); $this->assertContains("\r\n\r\n...after", $body, $body); } public function testGetJustBodyText() { $text = "my body\r\n\r\n...after two newlines"; $mail = new Zend_Mail(); $mail->setBodyText($text); $this->assertContains('my body', $mail->getBodyText(true)); $this->assertContains('after two newlines', $mail->getBodyText(true)); } public function testGetJustBodyHtml() { $text = "

Some body text

"; $mail = new Zend_Mail(); $mail->setBodyHtml($text); $this->assertContains('Some body text', $mail->getBodyHtml(true)); } public function testTypeAccessor() { $mail = new Zend_Mail(); $this->assertNull($mail->getType()); $mail->setType(Zend_Mime::MULTIPART_ALTERNATIVE); $this->assertEquals(Zend_Mime::MULTIPART_ALTERNATIVE, $mail->getType()); $mail->setType(Zend_Mime::MULTIPART_RELATED); $this->assertEquals(Zend_Mime::MULTIPART_RELATED, $mail->getType()); try { $mail->setType('text/plain'); $this->fail('Invalid Zend_Mime type should throw an exception'); } catch (Exception $e) { } } }