See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core_message; 18 19 defined('MOODLE_INTERNAL') || die(); 20 21 global $CFG; 22 23 require_once($CFG->dirroot . '/message/tests/messagelib_test.php'); 24 25 /** 26 * Tests for the message helper class. 27 * 28 * @package core_message 29 * @category test 30 * @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com> 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 * @covers \core_message\helper 33 */ 34 class helper_test extends \advanced_testcase { 35 36 public function setUp(): void { 37 $this->resetAfterTest(true); 38 } 39 40 public function test_get_member_info_ordering() { 41 // Create a conversation with several users. 42 $user1 = self::getDataGenerator()->create_user(); 43 $user2 = self::getDataGenerator()->create_user(); 44 $user3 = self::getDataGenerator()->create_user(); 45 $user4 = self::getDataGenerator()->create_user(); 46 47 \core_message\api::create_conversation( 48 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 49 [ 50 $user1->id, 51 $user2->id, 52 $user3->id, 53 $user4->id, 54 ], 55 'Group conversation' 56 ); 57 58 // Verify that the member information comes back in the same order that we specified in the input array. 59 $memberinfo = \core_message\helper::get_member_info($user1->id, [$user3->id, $user4->id, $user2->id]); 60 $this->assertEquals($user3->id, array_shift($memberinfo)->id); 61 $this->assertEquals($user4->id, array_shift($memberinfo)->id); 62 $this->assertEquals($user2->id, array_shift($memberinfo)->id); 63 } 64 65 /** 66 * Test search_get_user_details returns the correct profile data when $CFG->messagingallusers is disabled. 67 */ 68 public function test_search_get_user_details_sitewide_disabled() { 69 global $DB; 70 set_config('messagingallusers', false); 71 72 // Two students sharing course 1, visible profile within course (no groups). 73 $user1 = $this->getDataGenerator()->create_user(); 74 $user2 = $this->getDataGenerator()->create_user(); 75 $course1 = $this->getDataGenerator()->create_course((object) ['groupmode' => 0]); 76 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 77 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 78 79 // A teacher in course 1. 80 $user3 = $this->getDataGenerator()->create_user(); 81 $this->getDataGenerator()->enrol_user($user3->id, $course1->id, 'editingteacher'); 82 83 // Two students sharing course 2, separate groups (profiles not visible to one another). 84 // Note: no groups are created here, but separate groups mode alone is enough to restrict profile access. 85 $user4 = $this->getDataGenerator()->create_user(); 86 $user5 = $this->getDataGenerator()->create_user(); 87 $course2 = $this->getDataGenerator()->create_course((object) ['groupmode' => 1]); 88 $this->getDataGenerator()->enrol_user($user4->id, $course2->id); 89 $this->getDataGenerator()->enrol_user($user5->id, $course2->id); 90 91 // A teacher in course 2. 92 $user6 = $this->getDataGenerator()->create_user(); 93 $this->getDataGenerator()->enrol_user($user6->id, $course2->id, 'editingteacher'); 94 95 // Teacher and course contact in course 3. 96 $user7 = $this->getDataGenerator()->create_user(); 97 $course3 = $this->getDataGenerator()->create_course(); 98 $this->getDataGenerator()->enrol_user($user7->id, $course3->id, 'editingteacher'); 99 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 100 101 // Make teachers course contacts. 102 set_config('coursecontact', $teacherrole->id); 103 104 // User 1 should be able to see users within their course, but not course contacts or students in other courses. 105 $this->setUser($user1); 106 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user2)); // Student in same course. 107 $this->assertEmpty(\core_message\helper::search_get_user_details($user4)); // Student in another course. 108 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user3)); // Teacher in same course. 109 $this->assertEmpty(\core_message\helper::search_get_user_details($user7)); // Teacher (course contact) in another course. 110 111 // User 3 should be able to see the teacher in their own course, but not other students in that course nor course contacts 112 // or students in other courses. 113 $this->setUser($user4); 114 $this->assertEmpty(\core_message\helper::search_get_user_details($user5)); // Student in same course. 115 $this->assertEmpty(\core_message\helper::search_get_user_details($user1)); // Student in another course. 116 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user6)); // Teacher in same course. 117 $this->assertEmpty(\core_message\helper::search_get_user_details($user7)); // Teacher (course contact) in another course. 118 } 119 120 /** 121 * Test search_get_user_details returns the correct profile data we limit the data we wish to be returned. 122 */ 123 public function test_search_get_user_details_limited_data() { 124 set_config('messagingallusers', false); 125 126 // Two students sharing course 1, visible profile within course (no groups). 127 $user1 = $this->getDataGenerator()->create_user(); 128 $user2 = $this->getDataGenerator()->create_user(); 129 $course1 = $this->getDataGenerator()->create_course((object) ['groupmode' => 0]); 130 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 131 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 132 133 // Calculate the minimum fields that can be returned. 134 $namefields = \core_user\fields::for_name()->get_required_fields(); 135 $fields = array_intersect($namefields, user_get_default_fields()); 136 137 $minimaluser = (object) [ 138 'id' => $user2->id, 139 'deleted' => $user2->deleted, 140 ]; 141 142 foreach ($namefields as $field) { 143 $minimaluser->$field = $user2->$field; 144 } 145 146 // Test that less data is returned using the filter. 147 $this->setUser($user1); 148 $fulldetails = helper::search_get_user_details($user2); 149 $limiteddetails = helper::search_get_user_details($minimaluser, $fields); 150 $fullcount = count($fulldetails); 151 $limitedcount = count($limiteddetails); 152 $this->assertLessThan($fullcount, $limitedcount); 153 $this->assertNotEquals($fulldetails, $limiteddetails); 154 } 155 156 /** 157 * Test search_get_user_details returns the correct profile data when $CFG->messagingallusers is enabled. 158 */ 159 public function test_search_get_user_details_sitewide_enabled() { 160 global $DB; 161 set_config('messagingallusers', true); 162 163 // Two students sharing course 1, visible profile within course (no groups). 164 $user1 = $this->getDataGenerator()->create_user(); 165 $user2 = $this->getDataGenerator()->create_user(); 166 $course1 = $this->getDataGenerator()->create_course((object) ['groupmode' => 0]); 167 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 168 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 169 170 // A teacher in course 1. 171 $user3 = $this->getDataGenerator()->create_user(); 172 $this->getDataGenerator()->enrol_user($user3->id, $course1->id, 'editingteacher'); 173 174 // Two students sharing course 2, separate groups (profiles not visible to one another). 175 // Note: no groups are created here, but separate groups mode alone is enough to restrict profile access. 176 $user4 = $this->getDataGenerator()->create_user(); 177 $user5 = $this->getDataGenerator()->create_user(); 178 $course2 = $this->getDataGenerator()->create_course((object) ['groupmode' => 1]); 179 $this->getDataGenerator()->enrol_user($user4->id, $course2->id); 180 $this->getDataGenerator()->enrol_user($user5->id, $course2->id); 181 182 // A teacher in course 2. 183 $user6 = $this->getDataGenerator()->create_user(); 184 $this->getDataGenerator()->enrol_user($user6->id, $course2->id, 'editingteacher'); 185 186 // Teacher and course contact in course 3. 187 $user7 = $this->getDataGenerator()->create_user(); 188 $course3 = $this->getDataGenerator()->create_course(); 189 $this->getDataGenerator()->enrol_user($user7->id, $course3->id, 'editingteacher'); 190 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 191 192 // Make teachers course contacts. 193 set_config('coursecontact', $teacherrole->id); 194 195 // User 1 should be able to see users within their course and course contacts, but not students in other courses. 196 $this->setUser($user1); 197 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user2)); // Student in same course. 198 $this->assertEmpty(\core_message\helper::search_get_user_details($user4)); // Student in another course. 199 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user3)); // Teacher in same course. 200 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user7)); // Teacher (course contact) in another course. 201 202 // User 3 should be able to see the teacher in their own course, but not other students in that course nor course contacts 203 // or students in other courses. 204 $this->setUser($user4); 205 $this->assertEmpty(\core_message\helper::search_get_user_details($user5)); // Student in same course. 206 $this->assertEmpty(\core_message\helper::search_get_user_details($user1)); // Student in another course. 207 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user6)); // Teacher in same course. 208 $this->assertNotEmpty(\core_message\helper::search_get_user_details($user7)); // Teacher (course contact) in another course. 209 } 210 211 /** 212 * Test prevent_unclosed_html_tags returns the correct html. 213 * 214 * @dataProvider prevent_unclosed_html_tags_data 215 * @param string $text text to preview unclosed html tags. 216 * @param string $goodhtml html good structured. 217 * @param bool $removebody true if we want to remove tag body. 218 */ 219 public function test_prevent_unclosed_html_tags(string $message, string $goodhtml, bool $removebody) { 220 $this->setAdminUser(); 221 222 $html = \core_message\helper::prevent_unclosed_html_tags($message, $removebody); 223 $this->assertSame($goodhtml, $html); 224 } 225 226 /** 227 * Data provider for the test_prevent_unclosed_html_tags_data tests. 228 * 229 * @return array 230 */ 231 public function prevent_unclosed_html_tags_data(): array { 232 return [ 233 'Prevent unclosed html elements' => [ 234 '<h1>Title</h1><p>Paragraph</p><b>Bold', '<h1>Title</h1><p>Paragraph</p><b>Bold</b>', true 235 ], 236 'Prevent unclosed html elements including comments' => [ 237 '<h1>Title</h1><p>Paragraph</p><!-- Comments //--><b>Bold', '<h1>Title</h1><p>Paragraph</p><!-- Comments //--><b>Bold</b>', true 238 ], 239 'Prevent unclosed comments' => ['<h1>Title</h1><p>Paragraph</p><!-- Comments', '<h1>Title</h1><p>Paragraph</p>', true 240 ], 241 'Prevent unclosed html elements without removing tag body' => [ 242 '<body><h2>Title 2</h2><p>Paragraph</p><b>Bold</body>', '<body><h2>Title 2</h2><p>Paragraph</p><b>Bold</b></body>', false 243 ], 244 'Empty html' => [ 245 '', '', false 246 ], 247 'Check encoding UTF-8 is working' => [ 248 '<body><h1>Title</h1><p>السلام عليكم</p></body>', '<body><h1>Title</h1><p>السلام عليكم</p></body>', false 249 ], 250 ]; 251 } 252 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body