Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding EmailComponent::_getSocket() so EmailComponent + smtp is easie…

…r to test.

Fixing issue where hosts with portnames could cause smtp emails to fail.
Added tests, fixed an existing test to not depend on a local mailserver.
Fixes #1433
  • Loading branch information...
commit 8754d11aed8c5b88fb94dcd50db765cb4c0c46b5 1 parent f45f2e4
Mark Story markstory authored
16 cake/libs/controller/components/email.php
View
@@ -837,6 +837,18 @@ function _mail() {
return @mail($to, $this->_encode($this->subject), $message, $header, $this->additionalParams);
}
+
+/**
+ * Helper method to get socket, overridden in tests
+ *
+ * @param array $config Config data for the socket.
+ * @return void
+ * @access protected
+ */
+ function _getSocket($config) {
+ $this->__smtpConnection =& new CakeSocket($config);
+ }
+
/**
* Sends out email via SMTP
*
@@ -853,7 +865,7 @@ function _smtp() {
'timeout' => 30
);
$this->smtpOptions = array_merge($defaults, $this->smtpOptions);
- $this->__smtpConnection =& new CakeSocket($this->smtpOptions);
+ $this->_getSocket($this->smtpOptions);
if (!$this->__smtpConnection->connect()) {
$this->smtpError = $this->__smtpConnection->lastError();
@@ -867,7 +879,7 @@ function _smtp() {
if (isset($this->smtpOptions['client'])) {
$host = $this->smtpOptions['client'];
} elseif (!empty($httpHost)) {
- $host = $httpHost;
+ list($host) = explode(':', $httpHost);
} else {
$host = 'localhost';
}
95 cake/tests/cases/libs/controller/components/email.test.php
View
@@ -20,6 +20,9 @@
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
App::import('Component', 'Email');
+App::import('Core', 'CakeSocket');
+
+Mock::generate('CakeSocket', 'MockEmailSocket');
/**
* EmailTestComponent class
@@ -29,6 +32,7 @@
*/
class EmailTestComponent extends EmailComponent {
+ var $smtpSend = '';
/**
* smtpSend method override for testing
*
@@ -40,6 +44,19 @@ function smtpSend($data, $code = '250') {
}
/**
+ * undocumented function
+ *
+ * @return void
+ */
+ function _smtpSend($data, $code = '250') {
+ if ($this->_debug) {
+ $this->smtpSend .= $data . "\n";
+ return true;
+ }
+ return parent::_smtpSend($data, $code);
+ }
+
+/**
* Convenience setter method for testing.
*
* @access public
@@ -50,6 +67,18 @@ function setConnectionSocket(&$socket) {
}
/**
+ * Allows mocks to be used with tests.
+ *
+ * @param array $config
+ * @return void
+ */
+ function _getSocket($config) {
+ if (empty($this->__smtpConnection)) {
+ parent::_getSocket($config);
+ }
+ }
+
+/**
* Convenience getter method for testing.
*
* @access public
@@ -408,46 +437,60 @@ function testSmtpEhlo() {
* @return void
*/
function testSmtpSendMultipleTo() {
- if ($this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
- return;
- }
$this->Controller->EmailTest->reset();
$this->Controller->EmailTest->to = array('postmaster@localhost', 'root@localhost');
$this->Controller->EmailTest->from = 'noreply@example.com';
$this->Controller->EmailTest->subject = 'Cake SMTP multiple To test';
$this->Controller->EmailTest->replyTo = 'noreply@example.com';
$this->Controller->EmailTest->template = null;
-
+ $this->Controller->EmailTest->_debug = true;
+ $this->Controller->EmailTest->sendAs = 'text';
$this->Controller->EmailTest->delivery = 'smtp';
+
+ $socket = new MockEmailSocket();
+ $socket->setReturnValue('connect', true);
+ $this->Controller->EmailTest->setConnectionSocket($socket);
+
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
- $this->Controller->EmailTest->_debug = true;
- $this->Controller->EmailTest->sendAs = 'text';
- $expect = <<<TEMPDOC
-<pre>Host: localhost
-Port: 25
-Timeout: 30
-To: postmaster@localhost, root@localhost
-From: noreply@example.com
-Subject: Cake SMTP multiple To test
-Header:
+ $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend);
+ $this->assertPattern('/MAIL FROM: <noreply@example\.com>\n/', $this->Controller->EmailTest->smtpSend);
+ $this->assertPattern('/RCPT TO: <postmaster@localhost>\n/', $this->Controller->EmailTest->smtpSend);
+ $this->assertPattern('/RCPT TO: <root@localhost>\n/', $this->Controller->EmailTest->smtpSend);
+ $this->assertPattern(
+ '/To: postmaster@localhost, root@localhost[\n\r]/',
+ $this->Controller->EmailTest->smtpSend
+ );
+ }
-To: postmaster@localhost, root@localhost
-From: noreply@example.com
-Reply-To: noreply@example.com
-Subject: Cake SMTP multiple To test
-X-Mailer: CakePHP Email Component
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 7bitParameters:
+/**
+ * test sending smtp from a host using a port.
+ *
+ * @return void
+ */
+ function testSmtpSendHostWithPort() {
+ $bkp = env('HTTP_HOST');
+ $_SERVER['HTTP_HOST'] = 'localhost:8080';
-Message:
+ $this->Controller->EmailTest->reset();
+ $this->Controller->EmailTest->to = array('root@localhost');
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake SMTP host test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'smtp';
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->Controller->EmailTest->_debug = true;
-This is the body of the message
+ $socket = new MockEmailSocket();
+ $socket->setReturnValue('connect', true);
-</pre>
-TEMPDOC;
+ $this->Controller->EmailTest->setConnectionSocket($socket);
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
- $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect));
+
+ $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend);
+
+ $_SERVER['HTTP_HOST'] = $bkp;
}
/**
Please sign in to comment.
Something went wrong with that request. Please try again.