EmailLibTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. <?php
  2. App::uses('MyCakeTestCase', 'Tools.TestSuite');
  3. App::uses('EmailLib', 'Tools.Lib');
  4. if (!Configure::read('Config.adminEmail')) {
  5. Configure::write('Config.adminEmail', 'example@gmx.de');
  6. }
  7. class EmailLibTest extends MyCakeTestCase {
  8. public $Email;
  9. public $sendEmails = false;
  10. public function setUp() {
  11. parent::setUp();
  12. //$this->skipIf(!file_exists(APP . 'Config' . DS . 'email.php'), 'no email.php');
  13. Configure::write('Email.live', false);
  14. $this->Email = new TestEmailLib();
  15. }
  16. /**
  17. * EmailLibTest::testObject()
  18. *
  19. * @return void
  20. */
  21. public function testObject() {
  22. $this->assertTrue(is_object($this->Email));
  23. $this->assertInstanceOf('EmailLib', $this->Email);
  24. }
  25. /**
  26. * EmailLibTest::testSendDefault()
  27. *
  28. * @return void
  29. */
  30. public function testSendDefault() {
  31. // start
  32. $this->Email->transport('debug');
  33. $this->Email->to(Configure::read('Config.adminEmail'), Configure::read('Config.adminEmailname'));
  34. $this->Email->subject('Test Subject');
  35. $res = $this->Email->send('xyz xyz');
  36. // end
  37. if ($error = $this->Email->getError()) {
  38. $this->out($error);
  39. }
  40. $this->assertEquals('', $this->Email->getError());
  41. $this->assertTrue($res);
  42. $this->Email->reset();
  43. // start
  44. $this->Email->transport('debug');
  45. $this->Email->to(Configure::read('Config.adminEmail'), Configure::read('Config.adminEmailname'));
  46. $this->Email->subject('Test Subject 2');
  47. $this->Email->template('default', 'default');
  48. $this->Email->viewVars(['x' => 'y', 'xx' => 'yy', 'text' => '']);
  49. $this->Email->addAttachments([CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'edit.gif']);
  50. $this->Email->addAttachments(['http://www.spiegel.de/static/sys/v10/icons/home_v2.png']);
  51. $res = $this->Email->send('xyz');
  52. $debug = $this->Email->getDebug();
  53. $this->assertTextContains('Content-Disposition: attachment; filename="edit.gif"', $debug['message']);
  54. $this->assertTextContains('Content-Disposition: attachment; filename="home_v2.png"', $debug['message']);
  55. if ($error = $this->Email->getError()) {
  56. $this->out($error);
  57. }
  58. $this->assertEquals('', $this->Email->getError());
  59. $this->assertTrue($res);
  60. }
  61. /**
  62. * EmailLibTest::testSendFast()
  63. *
  64. * @return void
  65. */
  66. public function testSendFast() {
  67. $this->skipIf(php_sapi_name() === 'cli');
  68. //$this->Email->reset();
  69. //$this->Email->from(Configure::read('Config.adminEmail'), Configure::read('Config.adminEmailname'));
  70. $res = EmailLib::systemEmail('system-mail test', 'some fast email to admin test');
  71. //debug($res);
  72. $this->assertTrue($res);
  73. }
  74. /**
  75. * EmailLibTest::testXMailer()
  76. *
  77. * @return void
  78. */
  79. public function testXMailer() {
  80. $this->Email = new TestEmailLib();
  81. $this->Email->from('cake@cakephp.org');
  82. $this->Email->to('cake@cakephp.org');
  83. $this->Email->subject('My title');
  84. $this->Email->emailFormat('both');
  85. $this->Email->transport('debug');
  86. $result = $this->Email->send();
  87. $this->assertTrue($result);
  88. $result = $this->Email->getDebug();
  89. $this->assertTextContains('X-Mailer: CakePHP Email', $result['headers']);
  90. Configure::write('Config.xMailer', 'Tools Plugin');
  91. $this->Email = new TestEmailLib();
  92. $this->Email->from('cake@cakephp.org');
  93. $this->Email->to('cake@cakephp.org');
  94. $this->Email->subject('My title');
  95. $this->Email->emailFormat('both');
  96. $this->Email->transport('debug');
  97. $result = $this->Email->send();
  98. $this->assertTrue($result);
  99. $result = $this->Email->getDebug();
  100. $this->assertTextNotContains('X-Mailer: CakePHP Email', $result['headers']);
  101. $this->assertTextContains('X-Mailer: Tools Plugin', $result['headers']);
  102. }
  103. public function _testSendWithInlineAttachments() {
  104. $this->Email = new TestEmailLib();
  105. $this->Email->transport('debug');
  106. $this->Email->from('cake@cakephp.org');
  107. $this->Email->to('cake@cakephp.org');
  108. $this->Email->subject('My title');
  109. $this->Email->emailFormat('both');
  110. $result = $this->Email->send();
  111. //debug($result);
  112. $boundary = $this->Email->getBoundary();
  113. /*
  114. $this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
  115. $expected = "--$boundary\r\n" .
  116. "Content-Type: multipart/related; boundary=\"rel-$boundary\"\r\n" .
  117. "\r\n" .
  118. "--rel-$boundary\r\n" .
  119. "Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
  120. "\r\n" .
  121. "--alt-$boundary\r\n" .
  122. "Content-Type: text/plain; charset=UTF-8\r\n" .
  123. "Content-Transfer-Encoding: 8bit\r\n" .
  124. "\r\n" .
  125. "Hello" .
  126. "\r\n" .
  127. "\r\n" .
  128. "\r\n" .
  129. "--alt-$boundary\r\n" .
  130. "Content-Type: text/html; charset=UTF-8\r\n" .
  131. "Content-Transfer-Encoding: 8bit\r\n" .
  132. "\r\n" .
  133. "Hello" .
  134. "\r\n" .
  135. "\r\n" .
  136. "\r\n" .
  137. "--alt-{$boundary}--\r\n" .
  138. "\r\n" .
  139. "--rel-$boundary\r\n" .
  140. "Content-Type: application/octet-stream\r\n" .
  141. "Content-Transfer-Encoding: base64\r\n" .
  142. "Content-ID: <abc123>\r\n" .
  143. "Content-Disposition: inline; filename=\"cake.png\"\r\n\r\n";
  144. $this->assertContains($expected, $result['message']);
  145. $this->assertContains('--rel-' . $boundary . '--', $result['message']);
  146. $this->assertContains('--' . $boundary . '--', $result['message']);
  147. */
  148. //debug($boundary);
  149. die();
  150. }
  151. /**
  152. * EmailLibTest::testAddAttachment()
  153. *
  154. * @return void
  155. */
  156. public function testAddAttachment() {
  157. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  158. $this->assertTrue(file_exists($file));
  159. $this->Email->addAttachment($file);
  160. $res = $this->Email->getProtected('attachments');
  161. $expected = [
  162. 'hotel.png' => [
  163. 'file' => $file,
  164. 'mimetype' => 'image/png',
  165. ]
  166. ];
  167. $this->assertEquals($expected, $res);
  168. $this->Email->addAttachment($file, 'my_image.jpg');
  169. $res = $this->Email->getProtected('attachments');
  170. $expected = [
  171. 'file' => $file,
  172. 'mimetype' => 'image/jpeg',
  173. ];
  174. $this->assertEquals($expected, $res['my_image.jpg']);
  175. }
  176. /**
  177. * EmailLibTest::testAddAttachment()
  178. *
  179. * @return void
  180. */
  181. public function testAddAttachmentSend() {
  182. $this->skipIf(!$this->sendEmails);
  183. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  184. $this->assertTrue(file_exists($file));
  185. Configure::write('debug', 0);
  186. $this->Email->to(Configure::read('Config.adminEmail'));
  187. $this->Email->addAttachment($file);
  188. $res = $this->Email->send('test_default', 'default');
  189. if ($error = $this->Email->getError()) {
  190. $this->out($error);
  191. }
  192. $this->assertEquals('', $this->Email->getError());
  193. $this->assertTrue($res);
  194. $this->Email->reset();
  195. $this->Email->to(Configure::read('Config.adminEmail'));
  196. $this->Email->addAttachment($file, 'x.jpg');
  197. $res = $this->Email->send('test_custom_filename');
  198. Configure::write('debug', 2);
  199. $this->assertEquals('', $this->Email->getError());
  200. $this->assertTrue($res);
  201. }
  202. /**
  203. * EmailLibTest::testAddBlobAttachment()
  204. *
  205. * @return void
  206. */
  207. public function testAddBlobAttachment() {
  208. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  209. $content = file_get_contents($file);
  210. $this->Email->addBlobAttachment($content, 'hotel.png');
  211. $res = $this->Email->getProtected('attachments');
  212. $expected = [
  213. 'hotel.png' => [
  214. 'content' => $content,
  215. 'mimetype' => 'image/png',
  216. ]
  217. ];
  218. $this->assertEquals($expected, $res);
  219. $this->Email->addBlobAttachment($content, 'hotel.gif', 'image/jpeg');
  220. $res = $this->Email->getProtected('attachments');
  221. $expected = [
  222. 'content' => $content,
  223. 'mimetype' => 'image/jpeg',
  224. ];
  225. $this->assertEquals($expected, $res['hotel.gif']);#
  226. $this->assertSame(2, count($res));
  227. }
  228. /**
  229. * EmailLibTest::testAddEmbeddedAttachment()
  230. *
  231. * @return void
  232. */
  233. public function testAddEmbeddedAttachment() {
  234. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  235. $this->assertTrue(file_exists($file));
  236. $this->Email = new TestEmailLib();
  237. $this->Email->emailFormat('both');
  238. $cid = $this->Email->addEmbeddedAttachment($file);
  239. $cid2 = $this->Email->addEmbeddedAttachment($file);
  240. $this->assertSame($cid, $cid2);
  241. $this->assertContains('@' . env('HTTP_HOST'), $cid);
  242. $res = $this->Email->getProtected('attachments');
  243. $this->assertSame(1, count($res));
  244. $image = array_shift($res);
  245. $expected = [
  246. 'file' => $file,
  247. 'mimetype' => 'image/png',
  248. 'contentId' => $cid
  249. ];
  250. $this->assertSame($expected, $image);
  251. }
  252. /**
  253. * Html email
  254. *
  255. * @return void
  256. */
  257. public function testAddEmbeddedAttachmentSend() {
  258. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  259. Configure::write('debug', 0);
  260. $this->Email = new TestEmailLib();
  261. $this->Email->emailFormat('both');
  262. $this->Email->to(Configure::read('Config.adminEmail'));
  263. $cid = $this->Email->addEmbeddedAttachment($file);
  264. $cid2 = $this->Email->addEmbeddedAttachment($file);
  265. $this->assertContains('@' . env('HTTP_HOST'), $cid);
  266. $html = '<head>
  267. <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  268. <meta name="author" content="ohyeah" />
  269. <title>Untitled 6</title>
  270. </head>
  271. <body>
  272. test_embedded_default äöü <img src="cid:' . $cid . '" /> end
  273. another image <img src="cid:' . $cid2 . '" /> end
  274. html-part
  275. </body>
  276. </html>';
  277. $text = trim(strip_tags($html));
  278. $this->Email->viewVars(compact('text', 'html'));
  279. if (!$this->sendEmails) {
  280. Configure::write('debug', 2);
  281. }
  282. $this->skipIf(!$this->sendEmails);
  283. $res = $this->Email->send();
  284. Configure::write('debug', 2);
  285. if ($error = $this->Email->getError()) {
  286. $this->out($error);
  287. }
  288. $this->assertEquals('', $this->Email->getError());
  289. $this->assertTrue($res);
  290. }
  291. /**
  292. * EmailLibTest::testAddEmbeddedBlobAttachment()
  293. *
  294. * @return void
  295. */
  296. public function testAddEmbeddedBlobAttachment() {
  297. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  298. $this->assertTrue(file_exists($file));
  299. $this->Email = new TestEmailLib();
  300. $this->Email->emailFormat('both');
  301. $cid = $this->Email->addEmbeddedBlobAttachment(file_get_contents($file), 'my_hotel.png');
  302. $this->assertContains('@' . env('HTTP_HOST'), $cid);
  303. $cid2 = $this->Email->addEmbeddedBlobAttachment(file_get_contents($file), 'my_hotel.png');
  304. $this->assertSame($cid2, $cid);
  305. $res = $this->Email->getProtected('attachments');
  306. $this->assertSame(1, count($res));
  307. $cid3 = $this->Email->addEmbeddedBlobAttachment(file_get_contents($file) . 'xxx', 'my_hotel.png');
  308. $this->assertNotSame($cid3, $cid);
  309. $res = $this->Email->getProtected('attachments');
  310. $this->assertSame(2, count($res));
  311. $options = [
  312. 'contentDisposition' => true,
  313. ];
  314. $cid = 'abcdef';
  315. $this->Email->addEmbeddedBlobAttachment(file_get_contents($file), 'my_other_hotel.png', 'image/jpeg', $cid, $options);
  316. $res = $this->Email->getProtected('attachments');
  317. $keys = array_keys($res);
  318. $expected = [
  319. 'contentDisposition' => true,
  320. 'content' => file_get_contents($file),
  321. 'mimetype' => 'image/jpeg',
  322. 'contentId' => $cid,
  323. ];
  324. $this->assertTrue($res[$keys[count($keys) - 1]]['contentDisposition']);
  325. }
  326. /**
  327. * EmailLibTest::testValidates()
  328. *
  329. * @return void
  330. */
  331. public function testValidates() {
  332. $this->Email = new TestEmailLib();
  333. $this->Email->transport('debug');
  334. $res = $this->Email->validates();
  335. $this->assertFalse($res);
  336. $this->Email->subject('foo');
  337. $res = $this->Email->validates();
  338. $this->assertFalse($res);
  339. $this->Email->to('some@web.de');
  340. $res = $this->Email->validates();
  341. $this->assertTrue($res);
  342. $res = $this->Email->send();
  343. $this->assertTrue($res);
  344. }
  345. /**
  346. * Html email
  347. *
  348. * @return void
  349. */
  350. public function testAddEmbeddedBlobAttachmentSend() {
  351. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  352. Configure::write('debug', 0);
  353. $this->Email = new TestEmailLib();
  354. $this->Email->emailFormat('both');
  355. $this->Email->to(Configure::read('Config.adminEmail'));
  356. $cid = $this->Email->addEmbeddedBlobAttachment(file_get_contents($file), 'my_hotel.png', 'image/png');
  357. $this->assertContains('@' . env('HTTP_HOST'), $cid);
  358. $html = '<head>
  359. <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  360. <meta name="author" content="ohyeah" />
  361. <title>Untitled 6</title>
  362. </head>
  363. <body>
  364. test_embedded_blob_default äöü <img src="cid:' . $cid . '" /> end
  365. html-part
  366. </body>
  367. </html>';
  368. $text = trim(strip_tags($html));
  369. $this->Email->viewVars(compact('text', 'html'));
  370. if (!$this->sendEmails) {
  371. Configure::write('debug', 2);
  372. }
  373. $this->skipIf(!$this->sendEmails);
  374. $res = $this->Email->send();
  375. Configure::write('debug', 2);
  376. if ($error = $this->Email->getError()) {
  377. $this->out($error);
  378. }
  379. $this->assertEquals('', $this->Email->getError());
  380. $this->assertTrue($res);
  381. }
  382. public function _testComplexeHtmlWithEmbeddedImages() {
  383. $file = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'img' . DS . 'hotel.png';
  384. $this->assertTrue(file_exists($file));
  385. //TODO
  386. }
  387. public function testWrapLongEmailContent() {
  388. $this->Email = new TestEmailLib();
  389. $html = <<<HTML
  390. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  391. <html><head></head><body style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 16px; text-align: left; vertical-align: top; margin: 0;">
  392. sjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsfsjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsfsjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsfsjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsf
  393. </body></html>
  394. HTML;
  395. //$html = str_replace(array("\r\n", "\n", "\r"), "", $html);
  396. $is = $this->Email->wrap($html);
  397. foreach ($is as $line => $content) {
  398. $this->assertTrue(strlen($content) <= EmailLib::LINE_LENGTH_MUST);
  399. }
  400. $this->debug($is);
  401. $this->assertTrue(count($is) >= 5);
  402. }
  403. public function testWrapCustomized() {
  404. $this->Email = new TestEmailLib();
  405. $html = <<<HTML
  406. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  407. <html><head></head><body style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 16px; text-align: left; vertical-align: top; margin: 0;">
  408. sjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsfsjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsfsjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsfsjdf ojdshfdsf odsfh dsfhodsf hodshfhdsjdshfjdshfjdshfj dsjfh jdsfh ojds hfposjdf pohpojds fojds hfojds fpojds foijds fpodsij fojdsnhfojdshf dsufhpodsufds fuds foudshf ouds hfoudshf udsofhuds hfouds hfouds hfoudshf udsh fouhds fluds hflsdu hflsud hfuldsuhf dsf
  409. </body></html>
  410. HTML;
  411. //$html = str_replace(array("\r\n", "\n", "\r"), "", $html);
  412. $this->Email->wrapLength(100);
  413. $is = $this->Email->wrap($html);
  414. foreach ($is as $line => $content) {
  415. $this->assertTrue(strlen($content) <= EmailLib::LINE_LENGTH_MUST);
  416. }
  417. $this->debug($is);
  418. $this->assertTrue(count($is) >= 16);
  419. }
  420. }
  421. /**
  422. * Help to test EmailLib
  423. *
  424. */
  425. class TestEmailLib extends EmailLib {
  426. /**
  427. * Wrap to protected method
  428. *
  429. */
  430. public function formatAddress($address) {
  431. return parent::_formatAddress($address);
  432. }
  433. /**
  434. * Wrap to protected method
  435. *
  436. */
  437. public function wrap($text) {
  438. return parent::_wrap($text);
  439. }
  440. /**
  441. * Get the boundary attribute
  442. *
  443. * @return string
  444. */
  445. public function getBoundary() {
  446. return $this->_boundary;
  447. }
  448. public function getProtected($attribute) {
  449. $attribute = '_' . $attribute;
  450. return $this->$attribute;
  451. }
  452. /**
  453. * Encode to protected method
  454. *
  455. */
  456. public function encode($text) {
  457. return $this->_encode($text);
  458. }
  459. }