SmtpTransportTest.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  12. * @since 2.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Network\Email;
  16. use Cake\Network\Email\Email;
  17. use Cake\Network\Email\SmtpTransport;
  18. use Cake\Network\Socket;
  19. use Cake\TestSuite\TestCase;
  20. /**
  21. * Help to test SmtpTransport
  22. *
  23. */
  24. class SmtpTestTransport extends SmtpTransport {
  25. /**
  26. * Helper to change the socket
  27. *
  28. * @param Socket $socket
  29. * @return void
  30. */
  31. public function setSocket(Socket $socket) {
  32. $this->_socket = $socket;
  33. }
  34. /**
  35. * Helper to change the Email
  36. *
  37. * @param object $cakeEmail
  38. * @return void
  39. */
  40. public function setEmail($cakeEmail) {
  41. $this->_cakeEmail = $cakeEmail;
  42. }
  43. /**
  44. * Disabled the socket change
  45. *
  46. * @return void
  47. */
  48. protected function _generateSocket() {
  49. }
  50. /**
  51. * Magic function to call protected methods
  52. *
  53. * @param string $method
  54. * @param string $args
  55. * @return mixed
  56. */
  57. public function __call($method, $args) {
  58. $method = '_' . $method;
  59. return call_user_func_array(array($this, $method), $args);
  60. }
  61. }
  62. /**
  63. * Test case
  64. *
  65. */
  66. class SmtpTransportTest extends TestCase {
  67. /**
  68. * Setup
  69. *
  70. * @return void
  71. */
  72. public function setUp() {
  73. parent::setUp();
  74. $this->socket = $this->getMock(
  75. 'Cake\Network\Socket',
  76. array('read', 'write', 'connect', 'disconnect', 'enableCrypto')
  77. );
  78. $this->SmtpTransport = new SmtpTestTransport();
  79. $this->SmtpTransport->setSocket($this->socket);
  80. $this->SmtpTransport->config(array('client' => 'localhost'));
  81. }
  82. /**
  83. * testConnectEhlo method
  84. *
  85. * @return void
  86. */
  87. public function testConnectEhlo() {
  88. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  89. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  90. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  91. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  92. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  93. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  94. $this->SmtpTransport->connect();
  95. }
  96. /**
  97. * testConnectEhloTls method
  98. *
  99. * @return void
  100. */
  101. public function testConnectEhloTls() {
  102. $this->SmtpTransport->config(array('tls' => true));
  103. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  104. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  105. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  106. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  107. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  108. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  109. $this->socket->expects($this->at(5))->method('write')->with("STARTTLS\r\n");
  110. $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  111. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("220 Server ready\r\n"));
  112. $this->socket->expects($this->at(8))->method('enableCrypto')->with('tls')->will($this->returnValue(true));
  113. $this->socket->expects($this->at(9))->method('write')->with("EHLO localhost\r\n");
  114. $this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
  115. $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  116. $this->SmtpTransport->connect();
  117. }
  118. /**
  119. * testConnectEhloTlsOnNonTlsServer method
  120. *
  121. * @expectedException Cake\Network\Exception\SocketException
  122. * @expectedExceptionMessage SMTP server did not accept the connection or trying to connect to non TLS SMTP server using TLS.
  123. * @return void
  124. */
  125. public function testConnectEhloTlsOnNonTlsServer() {
  126. $this->SmtpTransport->config(array('tls' => true));
  127. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  128. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  129. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  130. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  131. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  132. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  133. $this->socket->expects($this->at(5))->method('write')->with("STARTTLS\r\n");
  134. $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  135. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
  136. $this->SmtpTransport->connect();
  137. }
  138. /**
  139. * testConnectEhloNoTlsOnRequiredTlsServer method
  140. *
  141. * @expectedException Cake\Network\Exception\SocketException
  142. * @expectedExceptionMessage SMTP authentication method not allowed, check if SMTP server requires TLS.
  143. * @return void
  144. */
  145. public function testConnectEhloNoTlsOnRequiredTlsServer() {
  146. $this->SmtpTransport->config(array('tls' => false, 'username' => 'user', 'password' => 'pass'));
  147. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  148. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  149. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  150. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  151. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  152. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  153. $this->socket->expects($this->at(5))->method('write')->with("AUTH LOGIN\r\n");
  154. $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  155. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("504 5.7.4 Unrecognized authentication type\r\n"));
  156. $this->SmtpTransport->connect();
  157. }
  158. /**
  159. * testConnectHelo method
  160. *
  161. * @return void
  162. */
  163. public function testConnectHelo() {
  164. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  165. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  166. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  167. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  168. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  169. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
  170. $this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n");
  171. $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  172. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250 Accepted\r\n"));
  173. $this->SmtpTransport->connect();
  174. }
  175. /**
  176. * testConnectFail method
  177. *
  178. * @expectedException Cake\Network\Exception\SocketException
  179. * @expectedExceptionMessage SMTP server did not accept the connection.
  180. * @return void
  181. */
  182. public function testConnectFail() {
  183. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  184. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  185. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  186. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  187. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  188. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
  189. $this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n");
  190. $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
  191. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
  192. $this->SmtpTransport->connect();
  193. }
  194. /**
  195. * testAuth method
  196. *
  197. * @return void
  198. */
  199. public function testAuth() {
  200. $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
  201. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  202. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n"));
  203. $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n");
  204. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  205. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("334 Pass\r\n"));
  206. $this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n");
  207. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
  208. $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("235 OK\r\n"));
  209. $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
  210. $this->SmtpTransport->auth();
  211. }
  212. /**
  213. * testAuthNotRecognized method
  214. *
  215. * @expectedException \Cake\Network\Exception\SocketException
  216. * @expectedExceptionMessage AUTH command not recognized or not implemented, SMTP server may not require authentication.
  217. * @return void
  218. */
  219. public function testAuthNotRecognized() {
  220. $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
  221. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  222. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
  223. $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
  224. $this->SmtpTransport->auth();
  225. }
  226. /**
  227. * testAuthNotImplemented method
  228. *
  229. * @expectedException \Cake\Network\Exception\SocketException
  230. * @expectedExceptionMessage AUTH command not recognized or not implemented, SMTP server may not require authentication.
  231. * @return void
  232. */
  233. public function testAuthNotImplemented() {
  234. $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
  235. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  236. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("502 5.3.3 Command not implemented\r\n"));
  237. $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
  238. $this->SmtpTransport->auth();
  239. }
  240. /**
  241. * testAuthBadSequence method
  242. *
  243. * @expectedException \Cake\Network\Exception\SocketException
  244. * @expectedExceptionMessage SMTP Error: 503 5.5.1 Already authenticated
  245. * @return void
  246. */
  247. public function testAuthBadSequence() {
  248. $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
  249. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  250. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("503 5.5.1 Already authenticated\r\n"));
  251. $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
  252. $this->SmtpTransport->auth();
  253. }
  254. /**
  255. * testAuthBadUsername method
  256. *
  257. * @expectedException \Cake\Network\Exception\SocketException
  258. * @expectedExceptionMessage SMTP server did not accept the username.
  259. * @return void
  260. */
  261. public function testAuthBadUsername() {
  262. $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
  263. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  264. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n"));
  265. $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n");
  266. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  267. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n"));
  268. $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
  269. $this->SmtpTransport->auth();
  270. }
  271. /**
  272. * testAuthBadPassword method
  273. *
  274. * @expectedException \Cake\Network\Exception\SocketException
  275. * @expectedExceptionMessage SMTP server did not accept the password.
  276. * @return void
  277. */
  278. public function testAuthBadPassword() {
  279. $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
  280. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  281. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n"));
  282. $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n");
  283. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  284. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("334 Pass\r\n"));
  285. $this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n");
  286. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
  287. $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n"));
  288. $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
  289. $this->SmtpTransport->auth();
  290. }
  291. /**
  292. * testRcpt method
  293. *
  294. * @return void
  295. */
  296. public function testRcpt() {
  297. $email = new Email();
  298. $email->from('noreply@cakephp.org', 'CakePHP Test');
  299. $email->to('cake@cakephp.org', 'CakePHP');
  300. $email->bcc('phpnut@cakephp.org');
  301. $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
  302. $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
  303. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  304. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n"));
  305. $this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
  306. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  307. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
  308. $this->socket->expects($this->at(6))->method('write')->with("RCPT TO:<mark@cakephp.org>\r\n");
  309. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
  310. $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 OK\r\n"));
  311. $this->socket->expects($this->at(9))->method('write')->with("RCPT TO:<juan@cakephp.org>\r\n");
  312. $this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
  313. $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 OK\r\n"));
  314. $this->socket->expects($this->at(12))->method('write')->with("RCPT TO:<phpnut@cakephp.org>\r\n");
  315. $this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false));
  316. $this->socket->expects($this->at(14))->method('read')->will($this->returnValue("250 OK\r\n"));
  317. $this->SmtpTransport->setEmail($email);
  318. $this->SmtpTransport->sendRcpt();
  319. }
  320. /**
  321. * testRcptWithReturnPath method
  322. *
  323. * @return void
  324. */
  325. public function testRcptWithReturnPath() {
  326. $email = new Email();
  327. $email->from('noreply@cakephp.org', 'CakePHP Test');
  328. $email->to('cake@cakephp.org', 'CakePHP');
  329. $email->returnPath('pleasereply@cakephp.org', 'CakePHP Return');
  330. $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<pleasereply@cakephp.org>\r\n");
  331. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  332. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n"));
  333. $this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
  334. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  335. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
  336. $this->SmtpTransport->setEmail($email);
  337. $this->SmtpTransport->sendRcpt();
  338. }
  339. /**
  340. * testSendData method
  341. *
  342. * @return void
  343. */
  344. public function testSendData() {
  345. $email = $this->getMock('Cake\Network\Email\Email', array('message'));
  346. $email->from('noreply@cakephp.org', 'CakePHP Test');
  347. $email->returnPath('pleasereply@cakephp.org', 'CakePHP Return');
  348. $email->to('cake@cakephp.org', 'CakePHP');
  349. $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
  350. $email->bcc('phpnut@cakephp.org');
  351. $email->messageID('<4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>');
  352. $email->subject('Testing SMTP');
  353. $date = date(DATE_RFC2822);
  354. $email->setHeaders(array('X-Mailer' => Email::EMAIL_CLIENT, 'Date' => $date));
  355. $email->expects($this->once())
  356. ->method('message')
  357. ->will($this->returnValue(array('First Line', 'Second Line', '.Third Line', '')));
  358. $data = "From: CakePHP Test <noreply@cakephp.org>\r\n";
  359. $data .= "To: CakePHP <cake@cakephp.org>\r\n";
  360. $data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
  361. $data .= "X-Mailer: CakePHP Email\r\n";
  362. $data .= "Date: " . $date . "\r\n";
  363. $data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
  364. $data .= "Subject: Testing SMTP\r\n";
  365. $data .= "MIME-Version: 1.0\r\n";
  366. $data .= "Content-Type: text/plain; charset=UTF-8\r\n";
  367. $data .= "Content-Transfer-Encoding: 8bit\r\n";
  368. $data .= "\r\n";
  369. $data .= "First Line\r\n";
  370. $data .= "Second Line\r\n";
  371. $data .= "..Third Line\r\n"; // RFC5321 4.5.2.Transparency
  372. $data .= "\r\n";
  373. $data .= "\r\n\r\n.\r\n";
  374. $this->socket->expects($this->at(0))->method('write')->with("DATA\r\n");
  375. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  376. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("354 OK\r\n"));
  377. $this->socket->expects($this->at(3))->method('write')->with($data);
  378. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  379. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
  380. $this->SmtpTransport->setEmail($email);
  381. $this->SmtpTransport->sendData();
  382. }
  383. /**
  384. * testQuit method
  385. *
  386. * @return void
  387. */
  388. public function testQuit() {
  389. $this->socket->expects($this->at(0))->method('write')->with("QUIT\r\n");
  390. $this->socket->connected = true;
  391. $this->SmtpTransport->disconnect();
  392. }
  393. /**
  394. * testEmptyConfigArray method
  395. *
  396. * @return void
  397. */
  398. public function testEmptyConfigArray() {
  399. $this->SmtpTransport->config(array(
  400. 'client' => 'myhost.com',
  401. 'port' => 666
  402. ));
  403. $expected = $this->SmtpTransport->config();
  404. $this->assertEquals(666, $expected['port']);
  405. $this->SmtpTransport->config(array());
  406. $result = $this->SmtpTransport->config();
  407. $this->assertEquals($expected, $result);
  408. }
  409. /**
  410. * testGetLastResponse method
  411. *
  412. * @return void
  413. */
  414. public function testGetLastResponse() {
  415. $this->assertEmpty($this->SmtpTransport->getLastResponse());
  416. $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
  417. $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
  418. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  419. $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
  420. $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
  421. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250-PIPELINING\r\n"));
  422. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250-SIZE 102400000\r\n"));
  423. $this->socket->expects($this->at(6))->method('read')->will($this->returnValue("250-VRFY\r\n"));
  424. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250-ETRN\r\n"));
  425. $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250-STARTTLS\r\n"));
  426. $this->socket->expects($this->at(9))->method('read')->will($this->returnValue("250-AUTH PLAIN LOGIN\r\n"));
  427. $this->socket->expects($this->at(10))->method('read')->will($this->returnValue("250-AUTH=PLAIN LOGIN\r\n"));
  428. $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250-ENHANCEDSTATUSCODES\r\n"));
  429. $this->socket->expects($this->at(12))->method('read')->will($this->returnValue("250-8BITMIME\r\n"));
  430. $this->socket->expects($this->at(13))->method('read')->will($this->returnValue("250 DSN\r\n"));
  431. $this->SmtpTransport->connect();
  432. $expected = array(
  433. array('code' => '250', 'message' => 'PIPELINING'),
  434. array('code' => '250', 'message' => 'SIZE 102400000'),
  435. array('code' => '250', 'message' => 'VRFY'),
  436. array('code' => '250', 'message' => 'ETRN'),
  437. array('code' => '250', 'message' => 'STARTTLS'),
  438. array('code' => '250', 'message' => 'AUTH PLAIN LOGIN'),
  439. array('code' => '250', 'message' => 'AUTH=PLAIN LOGIN'),
  440. array('code' => '250', 'message' => 'ENHANCEDSTATUSCODES'),
  441. array('code' => '250', 'message' => '8BITMIME'),
  442. array('code' => '250', 'message' => 'DSN')
  443. );
  444. $result = $this->SmtpTransport->getLastResponse();
  445. $this->assertEquals($expected, $result);
  446. $email = new Email();
  447. $email->from('noreply@cakephp.org', 'CakePHP Test');
  448. $email->to('cake@cakephp.org', 'CakePHP');
  449. $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
  450. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  451. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n"));
  452. $this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
  453. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  454. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
  455. $this->SmtpTransport->setEmail($email);
  456. $this->SmtpTransport->sendRcpt();
  457. $expected = array(
  458. array('code' => '250', 'message' => 'OK'),
  459. );
  460. $result = $this->SmtpTransport->getLastResponse();
  461. $this->assertEquals($expected, $result);
  462. }
  463. /**
  464. * testBufferResponseLines method
  465. *
  466. * @return void
  467. */
  468. public function testBufferResponseLines() {
  469. $reponseLines = array(
  470. '123',
  471. "456\tFOO",
  472. 'FOOBAR',
  473. '250-PIPELINING',
  474. '250-ENHANCEDSTATUSCODES',
  475. '250-8BITMIME',
  476. '250 DSN',
  477. );
  478. $this->SmtpTransport->bufferResponseLines($reponseLines);
  479. $expected = array(
  480. array('code' => '123', 'message' => null),
  481. array('code' => '250', 'message' => 'PIPELINING'),
  482. array('code' => '250', 'message' => 'ENHANCEDSTATUSCODES'),
  483. array('code' => '250', 'message' => '8BITMIME'),
  484. array('code' => '250', 'message' => 'DSN')
  485. );
  486. $result = $this->SmtpTransport->getLastResponse();
  487. $this->assertEquals($expected, $result);
  488. }
  489. /**
  490. * testExplicitConnectAlreadyConnected method
  491. *
  492. * @return void
  493. */
  494. public function testExplicitConnectAlreadyConnected() {
  495. $this->socket->expects($this->never())->method('connect');
  496. $this->socket->connected = true;
  497. $this->SmtpTransport->connect();
  498. }
  499. /**
  500. * testConnected method
  501. *
  502. * @return void
  503. */
  504. public function testConnected() {
  505. $this->socket->connected = true;
  506. $this->assertTrue($this->SmtpTransport->connected());
  507. $this->socket->connected = false;
  508. $this->assertFalse($this->SmtpTransport->connected());
  509. }
  510. /**
  511. * testAutoDisconnect method
  512. *
  513. * @return void
  514. */
  515. public function testAutoDisconnect() {
  516. $this->socket->expects($this->at(0))->method('write')->with("QUIT\r\n");
  517. $this->socket->expects($this->at(1))->method('disconnect');
  518. $this->socket->connected = true;
  519. unset($this->SmtpTransport);
  520. }
  521. /**
  522. * testExplicitDisconnect method
  523. *
  524. * @return void
  525. */
  526. public function testExplicitDisconnect() {
  527. $this->socket->expects($this->at(0))->method('write')->with("QUIT\r\n");
  528. $this->socket->expects($this->at(1))->method('disconnect');
  529. $this->socket->connected = true;
  530. $this->SmtpTransport->disconnect();
  531. }
  532. /**
  533. * testExplicitDisconnectNotConnected method
  534. *
  535. * @return void
  536. */
  537. public function testExplicitDisconnectNotConnected() {
  538. $callback = function($arg) {
  539. $this->assertNotEquals("QUIT\r\n", $arg);
  540. };
  541. $this->socket->expects($this->any())->method('write')->will($this->returnCallback($callback));
  542. $this->socket->expects($this->never())->method('disconnect');
  543. $this->SmtpTransport->disconnect();
  544. }
  545. /**
  546. * testKeepAlive method
  547. *
  548. * @return void
  549. */
  550. public function testKeepAlive() {
  551. $this->SmtpTransport->config(array('keepAlive' => true));
  552. $email = $this->getMock('Cake\Network\Email\Email', array('message'));
  553. $email->from('noreply@cakephp.org', 'CakePHP Test');
  554. $email->to('cake@cakephp.org', 'CakePHP');
  555. $email->expects($this->exactly(2))->method('message')->will($this->returnValue(array('First Line')));
  556. $callback = function($arg) {
  557. $this->assertNotEquals("QUIT\r\n", $arg);
  558. };
  559. $this->socket->expects($this->any())->method('write')->will($this->returnCallback($callback));
  560. $this->socket->expects($this->never())->method('disconnect');
  561. $this->socket->expects($this->at(0))->method('connect')->will($this->returnValue(true));
  562. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  563. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  564. $this->socket->expects($this->at(3))->method('write')->with("EHLO localhost\r\n");
  565. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  566. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
  567. $this->socket->expects($this->at(6))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
  568. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
  569. $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 OK\r\n"));
  570. $this->socket->expects($this->at(9))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
  571. $this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
  572. $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 OK\r\n"));
  573. $this->socket->expects($this->at(12))->method('write')->with("DATA\r\n");
  574. $this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false));
  575. $this->socket->expects($this->at(14))->method('read')->will($this->returnValue("354 OK\r\n"));
  576. $this->socket->expects($this->at(15))->method('write')->with($this->stringContains('First Line'));
  577. $this->socket->expects($this->at(16))->method('read')->will($this->returnValue(false));
  578. $this->socket->expects($this->at(17))->method('read')->will($this->returnValue("250 OK\r\n"));
  579. $this->socket->expects($this->at(18))->method('write')->with("RSET\r\n");
  580. $this->socket->expects($this->at(19))->method('read')->will($this->returnValue(false));
  581. $this->socket->expects($this->at(20))->method('read')->will($this->returnValue("250 OK\r\n"));
  582. $this->socket->expects($this->at(21))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
  583. $this->socket->expects($this->at(22))->method('read')->will($this->returnValue(false));
  584. $this->socket->expects($this->at(23))->method('read')->will($this->returnValue("250 OK\r\n"));
  585. $this->socket->expects($this->at(24))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
  586. $this->socket->expects($this->at(25))->method('read')->will($this->returnValue(false));
  587. $this->socket->expects($this->at(26))->method('read')->will($this->returnValue("250 OK\r\n"));
  588. $this->socket->expects($this->at(27))->method('write')->with("DATA\r\n");
  589. $this->socket->expects($this->at(28))->method('read')->will($this->returnValue(false));
  590. $this->socket->expects($this->at(29))->method('read')->will($this->returnValue("354 OK\r\n"));
  591. $this->socket->expects($this->at(15))->method('write')->with($this->stringContains('First Line'));
  592. $this->socket->expects($this->at(31))->method('read')->will($this->returnValue(false));
  593. $this->socket->expects($this->at(32))->method('read')->will($this->returnValue("250 OK\r\n"));
  594. $this->SmtpTransport->send($email);
  595. $this->socket->connected = true;
  596. $this->SmtpTransport->send($email);
  597. }
  598. /**
  599. * testSendDefaults method
  600. *
  601. * @return void
  602. */
  603. public function testSendDefaults() {
  604. $email = $this->getMock('Cake\Network\Email\Email', array('message'));
  605. $email->from('noreply@cakephp.org', 'CakePHP Test');
  606. $email->to('cake@cakephp.org', 'CakePHP');
  607. $email->expects($this->once())->method('message')->will($this->returnValue(array('First Line')));
  608. $this->socket->expects($this->at(0))->method('connect')->will($this->returnValue(true));
  609. $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
  610. $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
  611. $this->socket->expects($this->at(3))->method('write')->with("EHLO localhost\r\n");
  612. $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
  613. $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
  614. $this->socket->expects($this->at(6))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
  615. $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
  616. $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 OK\r\n"));
  617. $this->socket->expects($this->at(9))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
  618. $this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
  619. $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 OK\r\n"));
  620. $this->socket->expects($this->at(12))->method('write')->with("DATA\r\n");
  621. $this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false));
  622. $this->socket->expects($this->at(14))->method('read')->will($this->returnValue("354 OK\r\n"));
  623. $this->socket->expects($this->at(15))->method('write')->with($this->stringContains('First Line'));
  624. $this->socket->expects($this->at(16))->method('read')->will($this->returnValue(false));
  625. $this->socket->expects($this->at(17))->method('read')->will($this->returnValue("250 OK\r\n"));
  626. $this->socket->expects($this->at(18))->method('write')->with("QUIT\r\n");
  627. $this->socket->expects($this->at(19))->method('disconnect');
  628. $this->SmtpTransport->send($email);
  629. }
  630. }