MDL-41196 Unit Tests: Add a phpmailer message sink
authorAndrew Nicols <andrew@nicols.co.uk>
Wed, 14 Aug 2013 15:40:16 +0000 (16:40 +0100)
committerAndrew Nicols <andrew@nicols.co.uk>
Thu, 15 Aug 2013 12:58:51 +0000 (13:58 +0100)
lib/phpmailer/moodle_phpmailer.php
lib/phpunit/classes/advanced_testcase.php
lib/phpunit/classes/phpmailer_sink.php [new file with mode: 0644]
lib/phpunit/classes/util.php
lib/phpunit/lib.php

index cf2563a..c7ce0da 100644 (file)
@@ -125,4 +125,19 @@ class moodle_phpmailer extends PHPMailer {
         fclose($fp);
         return $out;
     }
+
+    protected function PostSend() {
+        // Now ask phpunit if it wants to catch this message.
+        if (phpunit_util::is_redirecting_messages()) {
+            $mail = new stdClass();
+            $mail->header = $this->MIMEHeader;
+            $mail->body = $this->MIMEBody;
+            $mail->subject = $this->Subject;
+            $mail->from = $this->From;
+            phpunit_util::phpmailer_sent($mail);
+            return true;
+        } else {
+            return parent::PostSend();
+        }
+    }
 }
index 0a4848d..602962b 100644 (file)
@@ -352,6 +352,19 @@ abstract class advanced_testcase extends PHPUnit_Framework_TestCase {
         return phpunit_util::start_message_redirection();
     }
 
+    /**
+     * Starts email redirection.
+     *
+     * You can verify if email were sent or not by inspecting the email
+     * array in the returned phpmailer sink instance. The redirection
+     * can be stopped by calling $sink->close();
+     *
+     * @return phpunit_message_sink
+     */
+    public function redirectEmails() {
+        return phpunit_util::start_phpmailer_redirection();
+    }
+
     /**
      * Starts event redirection.
      *
diff --git a/lib/phpunit/classes/phpmailer_sink.php b/lib/phpunit/classes/phpmailer_sink.php
new file mode 100644 (file)
index 0000000..bb00478
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * phpmailer message sink.
+ *
+ * @package    core
+ * @category   phpunit
+ * @copyright  2013 Andrew Nicols
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+/**
+ * phpmailer message sink.
+ *
+ * @package    core
+ * @category   phpunit
+ * @copyright  2013 Andrew Nicols
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class phpunit_phpmailer_sink {
+    /**
+     * @var array of records which would have been sent by phpmailer.
+     */
+    protected $messages = array();
+
+    /**
+     * Stop message redirection.
+     *
+     * Use if you do not want message redirected any more.
+     */
+    public function close() {
+        phpunit_util::stop_phpmailer_redirection();
+    }
+
+    /**
+     * To be called from phpunit_util only!
+     *
+     * @param stdClass $message record from message_read table
+     */
+    public function add_message($message) {
+        /* Number messages from 0. */
+        $this->messages[] = $message;
+    }
+
+    /**
+     * Returns all redirected messages.
+     *
+     * The instances are records form the message_read table.
+     * The array indexes are numbered from 0 and the order is matching
+     * the creation of events.
+     *
+     * @return array
+     */
+    public function get_messages() {
+        return $this->messages;
+    }
+
+    /**
+     * Return number of messages redirected to this sink.
+     * @return int
+     */
+    public function count() {
+        return count($this->messages);
+    }
+
+    /**
+     * Removes all previously stored messages.
+     */
+    public function clear() {
+        $this->messages = array();
+    }
+}
index 552e78a..0b08ebb 100644 (file)
@@ -43,6 +43,9 @@ class phpunit_util extends testing_util {
     /** @var phpunit_message_sink alternative target for moodle messaging */
     protected static $messagesink = null;
 
+    /** @var phpunit_phpmailer_sink alternative target for phpmailer messaging */
+    protected static $phpmailersink = null;
+
     /** @var phpunit_message_sink alternative target for moodle messaging */
     protected static $eventsink = null;
 
@@ -98,6 +101,9 @@ class phpunit_util extends testing_util {
         // Stop any message redirection.
         phpunit_util::stop_message_redirection();
 
+        // Stop any message redirection.
+        phpunit_util::stop_phpmailer_redirection();
+
         // Stop any message redirection.
         phpunit_util::stop_event_redirection();
 
@@ -668,6 +674,55 @@ class phpunit_util extends testing_util {
         }
     }
 
+    /**
+     * Start phpmailer redirection.
+     *
+     * Note: Do not call directly from tests,
+     *       use $sink = $this->redirectEmails() instead.
+     *
+     * @return phpunit_phpmailer_sink
+     */
+    public static function start_phpmailer_redirection() {
+        if (self::$phpmailersink) {
+            self::stop_phpmailer_redirection();
+        }
+        self::$phpmailersink = new phpunit_phpmailer_sink();
+        return self::$phpmailersink;
+    }
+
+    /**
+     * End phpmailer redirection.
+     *
+     * Note: Do not call directly from tests,
+     *       use $sink->close() instead.
+     */
+    public static function stop_phpmailer_redirection() {
+        self::$phpmailersink = null;
+    }
+
+    /**
+     * Are messages for phpmailer redirected to some sink?
+     *
+     * Note: to be called from moodle_phpmailer.php only!
+     *
+     * @return bool
+     */
+    public static function is_redirecting_phpmailer() {
+        return !empty(self::$phpmailersink);
+    }
+
+    /**
+     * To be called from messagelib.php only!
+     *
+     * @param stdClass $message record from message_read table
+     * @return bool true means send message, false means message "sent" to sink.
+     */
+    public static function phpmailer_sent($message) {
+        if (self::$phpmailersink) {
+            self::$phpmailersink->add_message($message);
+        }
+    }
+
     /**
      * Start event redirection.
      *
index 9f08760..86f8e41 100644 (file)
@@ -32,6 +32,7 @@ require_once(__DIR__.'/classes/util.php');
 require_once(__DIR__.'/classes/event_mock.php');
 require_once(__DIR__.'/classes/event_sink.php');
 require_once(__DIR__.'/classes/message_sink.php');
+require_once(__DIR__.'/classes/phpmailer_sink.php');
 require_once(__DIR__.'/classes/basic_testcase.php');
 require_once(__DIR__.'/classes/database_driver_testcase.php');
 require_once(__DIR__.'/classes/arraydataset.php');