MDL-45374 messages: get_messages ws unit tests
authorJuan Leyva <juanleyvadelgado@gmail.com>
Tue, 6 May 2014 16:01:41 +0000 (18:01 +0200)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Fri, 3 Oct 2014 14:37:13 +0000 (16:37 +0200)
lib/db/services.php
message/externallib.php
message/tests/externallib_test.php

index 941a2a7..6db105f 100644 (file)
@@ -762,12 +762,12 @@ $functions = array(
     ),
 
     'core_message_get_messages' => array(
-        'classname'   => 'core_message_external',
-        'methodname'  => 'get_messages',
-        'classpath'   => 'message/externallib.php',
-        'description' => 'Retrieve a message list (conversations, notifications or boths)',
-        'type'        => 'read',
-        'capabilities'=> '',
+        'classname'     => 'core_message_external',
+        'methodname'    => 'get_messages',
+        'classpath'     => 'message/externallib.php',
+        'description'   => 'Retrieve a list of messages send or received by a user (conversations, notifications or both)',
+        'type'          => 'read',
+        'capabilities'  => '',
     ),
 
     // === notes related functions ===
index 6406ba8..488dcc8 100644 (file)
@@ -578,13 +578,16 @@ class core_message_external extends external_api {
     public static function get_messages_parameters() {
         return new external_function_parameters(
             array(
-                'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user'),
+                'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
+                'useridfrom' => new external_value(PARAM_INT,
+                            'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
+                            VALUE_DEFAULT, 0),
                 'type' => new external_value(PARAM_ALPHA,
-                            'type of message to return, expected values are: notifications, conversations, both'),
-                'read' => new external_value(PARAM_BOOL, 'true for retreiving read messages, false for unread'),
-                'useridfrom' => new external_value(PARAM_INT, 'user id who send the message, 0 for any user', VALUE_DEFAULT, 0),
+                            'type of message to return, expected values are: notifications, conversations and both',
+                            VALUE_DEFAULT, 'both'),
+                'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
                 'newestfirst' => new external_value(PARAM_BOOL,
-                            'true order by newest first, false for oldest first', VALUE_DEFAULT, true),
+                            'true for ordering by newest first, false for oldest first', VALUE_DEFAULT, true),
                 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
                 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)            )
         );
@@ -592,17 +595,17 @@ class core_message_external extends external_api {
 
     /**
      * Get messages function implementation.
-     * @param  int      $useridto       the user id who received the messages
-     * @param  string   $type           type of message tu return, notifications, conversations or both
+     * @param  int      $useridto       the user id who received the message
+     * @param  int      $useridfrom     the user id who send the message. -10 or -20 for no-reply or support user
+     * @param  string   $type           type of message tu return, expected values: notifications, conversations and both
      * @param  bool     $read           true for retreiving read messages, false for unread
-     * @param  int      $useridfrom     user id from for filtering
-     * @param  bool     $newestfirst    true order by newest first, false for oldest first
+     * @param  bool     $newestfirst    true for ordering by newest first, false for oldest first
      * @param  int      $limitfrom      limit from
      * @param  int      $limitnum       limit num
      * @return external_description
      * @since  2.7
      */
-    public static function get_messages($useridto, $type, $read, $useridfrom = 0,
+    public static function get_messages($useridto, $useridfrom = 0, $type = 'both' , $read = true,
                                         $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
         global $CFG, $DB, $USER;
         require_once($CFG->dirroot . "/message/lib.php");
@@ -611,9 +614,9 @@ class core_message_external extends external_api {
 
         $params = array(
             'useridto' => $useridto,
+            'useridfrom' => $useridfrom,
             'type' => $type,
             'read' => $read,
-            'useridfrom' => $useridfrom,
             'newestfirst' => $newestfirst,
             'limitfrom' => $limitfrom,
             'limitnum' => $limitnum
@@ -625,9 +628,9 @@ class core_message_external extends external_api {
         self::validate_context($context);
 
         $useridto = $params['useridto'];
+        $useridfrom = $params['useridfrom'];
         $type = $params['type'];
         $read = $params['read'];
-        $useridfrom = $params['useridfrom'];
         $newestfirst = $params['newestfirst'];
         $limitfrom = $params['limitfrom'];
         $limitnum = $params['limitnum'];
@@ -641,7 +644,6 @@ class core_message_external extends external_api {
         // Check if private messaging between users is allowed.
         if (empty($CFG->messaging)) {
             // If we are retreiving only conversations, and messaging is disabled, throw an exception.
-            // DOUBT -- check user is admin?
             if ($type == "conversations") {
                 throw new moodle_exception('disabled', 'message');
             }
@@ -657,7 +659,11 @@ class core_message_external extends external_api {
         }
 
         if (!empty($useridto)) {
-            $userto = $DB->get_record('user', array('id' => $useridto), '*', MUST_EXIST);
+            if (core_user::is_real_user($useridto)) {
+                $userto = core_user::get_user($useridto, '*', MUST_EXIST);
+            } else {
+                throw new moodle_exception('invaliduser');
+            }
         }
 
         if (!empty($useridfrom)) {
@@ -671,25 +677,23 @@ class core_message_external extends external_api {
             throw new moodle_exception('accessdenied', 'admin');
         }
 
-        if ($useridto == $useridfrom) {
-            throw new moodle_exception('invaliduserid');
-        }
-
         // Get messages.
         $messagetable = $read ? '{message_read}' : '{message}';
         $usersql = "";
+        $joinsql = "";
         $params = array('deleted' => 0);
 
         // Empty useridto means that we are going to retrieve messages send by the useridfrom to any user.
         if (empty($useridto)) {
-            $userfields = get_all_user_name_fields(true, 'u', 'userto', 'userto');
-            $joinuserfield = "mr.useridto";
-            $usersql = "mr.useridfrom = :useridfrom";
+            $userfields = get_all_user_name_fields(true, 'u', '', 'userto');
+            $joinsql = "JOIN {user} u ON u.id = mr.useridto";
+            $usersql = "mr.useridfrom = :useridfrom AND u.deleted = :deleted";
             $params['useridfrom'] = $useridfrom;
         } else {
-            $userfields = get_all_user_name_fields(true, 'u', 'userfrom', 'userfrom');
-            $joinuserfield = "mr.useridfrom";
-            $usersql = "mr.useridto = :useridto";
+            $userfields = get_all_user_name_fields(true, 'u', '', 'userfrom');
+            // Left join because useridfrom may be -10 or -20 (no-reply and support users).
+            $joinsql = "LEFT JOIN {user} u ON u.id = mr.useridfrom";
+            $usersql = "mr.useridto = :useridto AND (u.deleted IS NULL OR u.deleted = :deleted)";
             $params['useridto'] = $useridto;
             if (!empty($useridfrom)) {
                 $usersql .= " AND mr.useridfrom = :useridfrom";
@@ -701,7 +705,7 @@ class core_message_external extends external_api {
         $typesql = "";
         if ($type != 'both') {
             $typesql = "AND mr.notification = :notification";
-            $params['notification'] = ($type == 'notification') ? 1 : 0;
+            $params['notification'] = ($type == 'notifications') ? 1 : 0;
         }
 
         // Finally the sort direction.
@@ -709,8 +713,8 @@ class core_message_external extends external_api {
 
         $sql = "SELECT mr.*, $userfields
                   FROM $messagetable mr
-                       JOIN {user} u ON u.id = $joinuserfield
-                 WHERE  $usersql AND u.deleted = :deleted
+                     $joinsql
+                 WHERE  $usersql
                         $typesql
                  ORDER BY mr.timecreated $orderdirection";
 
@@ -737,9 +741,15 @@ class core_message_external extends external_api {
 
                 // We need to get the user from the query.
                 if (empty($userfromfullname)) {
-                    $user = new stdclass();
-                    $user = username_load_fields_from_object($user, $message, 'userfrom');
-                    $message->userfromfullname = fullname($user, $canviewfullname);
+                    // Check for non-reply and support users.
+                    if (core_user::is_real_user($message->useridfrom)) {
+                        $user = new stdclass();
+                        $user = username_load_fields_from_object($user, $message, 'userfrom');
+                        $message->userfromfullname = fullname($user, $canviewfullname);
+                    } else {
+                        $user = core_user::get_user($message->useridfrom);
+                        $message->userfromfullname = fullname($user, $canviewfullname);
+                    }
                 } else {
                     $message->userfromfullname = $userfromfullname;
                 }
@@ -757,7 +767,6 @@ class core_message_external extends external_api {
                     $message->timeread = 0;
                 }
 
-                // DOUBT, getting crazy with formats...
                 $message->text = message_format_message_text($message);
 
                 $messages[$mid] = (array) $message;
@@ -775,7 +784,7 @@ class core_message_external extends external_api {
     /**
      * Get messages return description.
      *
-     * @return external_description
+     * @return external_single_structure
      * @since 2.7
      */
     public static function get_messages_returns() {
index cddd3e3..2f0f385 100644 (file)
@@ -32,6 +32,15 @@ require_once($CFG->dirroot . '/message/externallib.php');
 
 class core_message_externallib_testcase extends externallib_advanced_testcase {
 
+    /**
+     * Tests set up
+     */
+    protected function setUp() {
+        global $CFG;
+
+        require_once($CFG->dirroot . '/message/lib.php');
+    }
+
     /**
      * Send a fake message.
      *
@@ -381,4 +390,192 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
         $this->setExpectedException('moodle_exception');
         $results = core_message_external::search_contacts('');
     }
+
+    /**
+     * Test get_messages.
+     */
+    public function test_get_messages() {
+        global $CFG;
+        $this->resetAfterTest(true);
+
+        $this->preventResetByRollback();
+        // This mark the messages as read!.
+        $sink = $this->redirectMessages();
+
+        $user1 = self::getDataGenerator()->create_user();
+        $user2 = self::getDataGenerator()->create_user();
+        $user3 = self::getDataGenerator()->create_user();
+
+        $course = self::getDataGenerator()->create_course();
+
+        // Send a message from one user to another.
+        message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
+        message_post_message($user1, $user3, 'some random text 2', FORMAT_MOODLE);
+        message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
+        message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
+        message_post_message($user3, $user1, 'some random text 5', FORMAT_MOODLE);
+
+        $this->setUser($user1);
+        // Get read conversations from user1 to user2.
+        $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(1, $messages['messages']);
+
+        // Get unread conversations from user1 to user2.
+        $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', false, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(0, $messages['messages']);
+
+        // Get read messages send from user1.
+        $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(2, $messages['messages']);
+
+        $this->setUser($user2);
+        // Get read conversations from any user to user2.
+        $messages = core_message_external::get_messages($user2->id, 0, 'conversations', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(2, $messages['messages']);
+
+        $this->setUser($user3);
+        // Get read notifications received by user3.
+        $messages = core_message_external::get_messages($user3->id, 0, 'notifications', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(0, $messages['messages']);
+
+        // Now, create some notifications...
+        // We are creating fake notifications but based on real ones.
+
+        // This ones ommits notification = 1.
+        $eventdata = new stdClass();
+        $eventdata->modulename        = 'moodle';
+        $eventdata->component         = 'enrol_paypal';
+        $eventdata->name              = 'paypal_enrolment';
+        $eventdata->userfrom          = get_admin();
+        $eventdata->userto            = $user1;
+        $eventdata->subject           = "Moodle: PayPal payment";
+        $eventdata->fullmessage       = "Your PayPal payment is pending.";
+        $eventdata->fullmessageformat = FORMAT_PLAIN;
+        $eventdata->fullmessagehtml   = '';
+        $eventdata->smallmessage      = '';
+        message_send($eventdata);
+
+        $message = new stdClass();
+        $message->notification      = 1;
+        $message->component         = 'enrol_manual';
+        $message->name              = 'expiry_notification';
+        $message->userfrom          = $user2;
+        $message->userto            = $user1;
+        $message->subject           = 'Enrolment expired';
+        $message->fullmessage       = 'Enrolment expired blah blah blah';
+        $message->fullmessageformat = FORMAT_MARKDOWN;
+        $message->fullmessagehtml   = markdown_to_html($message->fullmessage);
+        $message->smallmessage      = $message->subject;
+        $message->contexturlname    = $course->fullname;
+        $message->contexturl        = (string)new moodle_url('/course/view.php', array('id' => $course->id));
+        message_send($message);
+
+        $userfrom = core_user::get_noreply_user();
+        $userfrom->maildisplay = true;
+        $eventdata = new stdClass();
+        $eventdata->component         = 'moodle';
+        $eventdata->name              = 'badgecreatornotice';
+        $eventdata->userfrom          = $userfrom;
+        $eventdata->userto            = $user1;
+        $eventdata->notification      = 1;
+        $eventdata->subject           = 'New badge';
+        $eventdata->fullmessage       = format_text_email($eventdata->subject, FORMAT_HTML);
+        $eventdata->fullmessageformat = FORMAT_PLAIN;
+        $eventdata->fullmessagehtml   = $eventdata->subject;
+        $eventdata->smallmessage      = $eventdata->subject;
+        message_send($eventdata);
+
+        $eventdata = new stdClass();
+        $eventdata->name             = 'submission';
+        $eventdata->component        = 'mod_feedback';
+        $eventdata->userfrom         = $user1;
+        $eventdata->userto           = $user2;
+        $eventdata->subject          = 'Feedback submitted';
+        $eventdata->fullmessage      = 'Feedback submitted from an user';
+        $eventdata->fullmessageformat = FORMAT_PLAIN;
+        $eventdata->fullmessagehtml  = '<strong>Feedback submitted</strong>';
+        $eventdata->smallmessage     = '';
+        message_send($eventdata);
+
+        $this->setUser($user1);
+        // Get read notifications from any user to user1.
+        $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(3, $messages['messages']);
+
+        // Get one read notifications from any user to user1.
+        $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 1);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(1, $messages['messages']);
+
+        // Get unread notifications from any user to user1.
+        $messages = core_message_external::get_messages($user1->id, 0, 'notifications', false, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(0, $messages['messages']);
+
+        // Get read both type of messages from any user to user1.
+        $messages = core_message_external::get_messages($user1->id, 0, 'both', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(4, $messages['messages']);
+
+        // Get read notifications from no-reply-user to user1.
+        $messages = core_message_external::get_messages($user1->id, $userfrom->id, 'notifications', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(1, $messages['messages']);
+
+        // Get notifications send by user1 to any user.
+        $messages = core_message_external::get_messages(0, $user1->id, 'notifications', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(1, $messages['messages']);
+
+        // Test warnings.
+        $CFG->messaging = 0;
+
+        $messages = core_message_external::get_messages(0, $user1->id, 'both', true, true, 0, 0);
+        $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
+        $this->assertCount(1, $messages['warnings']);
+
+        // Test exceptions.
+
+        // Messaging disabled.
+        try {
+            $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
+            $this->fail('Exception expected due messaging disabled.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('disabled', $e->errorcode);
+        }
+
+        $CFG->messaging = 1;
+
+        // Invalid users.
+        try {
+            $messages = core_message_external::get_messages(0, 0, 'conversations', true, true, 0, 0);
+            $this->fail('Exception expected due invalid users.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('accessdenied', $e->errorcode);
+        }
+
+        // Invalid user ids.
+        try {
+            $messages = core_message_external::get_messages(2500, 0, 'conversations', true, true, 0, 0);
+            $this->fail('Exception expected due invalid users.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('invaliduser', $e->errorcode);
+        }
+
+        // Invalid users (permissions).
+        $this->setUser($user2);
+        try {
+            $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
+            $this->fail('Exception expected due invalid user.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('accessdenied', $e->errorcode);
+        }
+
+    }
 }