See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
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_comment; 18 19 use comment_exception; 20 use core_comment_external; 21 use externallib_advanced_testcase; 22 23 defined('MOODLE_INTERNAL') || die(); 24 25 global $CFG; 26 27 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 28 29 /** 30 * External comment functions unit tests 31 * 32 * @package core_comment 33 * @category external 34 * @copyright 2015 Juan Leyva <juan@moodle.com> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 * @since Moodle 2.9 37 */ 38 class externallib_test extends externallib_advanced_testcase { 39 40 /** 41 * Tests set up 42 */ 43 protected function setUp(): void { 44 $this->resetAfterTest(); 45 } 46 47 /** 48 * Helper used to set up a course, with a module, a teacher and two students. 49 * 50 * @return array the array of records corresponding to the course, teacher, and students. 51 */ 52 protected function setup_course_and_users_basic() { 53 global $CFG, $DB; 54 55 require_once($CFG->dirroot . '/comment/lib.php'); 56 57 $CFG->usecomments = true; 58 59 $student1 = $this->getDataGenerator()->create_user(); 60 $student2 = $this->getDataGenerator()->create_user(); 61 $teacher1 = $this->getDataGenerator()->create_user(); 62 $course1 = $this->getDataGenerator()->create_course(array('enablecomment' => 1)); 63 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 64 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 65 $this->getDataGenerator()->enrol_user($student1->id, $course1->id, $studentrole->id); 66 $this->getDataGenerator()->enrol_user($student2->id, $course1->id, $studentrole->id); 67 $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, $teacherrole->id); 68 69 // Create a database module instance. 70 $record = new \stdClass(); 71 $record->course = $course1->id; 72 $record->name = "Mod data test"; 73 $record->intro = "Some intro of some sort"; 74 $record->comments = 1; 75 76 $module1 = $this->getDataGenerator()->create_module('data', $record); 77 $field = data_get_field_new('text', $module1); 78 79 $fielddetail = new \stdClass(); 80 $fielddetail->name = 'Name'; 81 $fielddetail->description = 'Some name'; 82 83 $field->define_field($fielddetail); 84 $field->insert_field(); 85 $recordid = data_add_record($module1); 86 87 $datacontent = array(); 88 $datacontent['fieldid'] = $field->field->id; 89 $datacontent['recordid'] = $recordid; 90 $datacontent['content'] = 'Asterix'; 91 $DB->insert_record('data_content', $datacontent); 92 93 return [$module1, $recordid, $teacher1, $student1, $student2]; 94 } 95 96 /** 97 * Test get_comments 98 */ 99 public function test_get_comments() { 100 global $CFG; 101 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 102 103 // Create some comments as student 1. 104 $this->setUser($student1); 105 $inputdata = [ 106 [ 107 'contextlevel' => 'module', 108 'instanceid' => $module1->cmid, 109 'component' => 'mod_data', 110 'content' => 'abc', 111 'itemid' => $recordid, 112 'area' => 'database_entry' 113 ], 114 [ 115 'contextlevel' => 'module', 116 'instanceid' => $module1->cmid, 117 'component' => 'mod_data', 118 'content' => 'def', 119 'itemid' => $recordid, 120 'area' => 'database_entry' 121 ] 122 ]; 123 $result = core_comment_external::add_comments($inputdata); 124 $result = \external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result); 125 $ids = array_column($result, 'id'); 126 127 // Verify we can get the comments. 128 $contextlevel = 'module'; 129 $instanceid = $module1->cmid; 130 $component = 'mod_data'; 131 $itemid = $recordid; 132 $area = 'database_entry'; 133 $page = 0; 134 $result = core_comment_external::get_comments($contextlevel, $instanceid, $component, $itemid, $area, $page); 135 $result = \external_api::clean_returnvalue(core_comment_external::get_comments_returns(), $result); 136 137 $this->assertCount(0, $result['warnings']); 138 $this->assertCount(2, $result['comments']); 139 $this->assertEquals(2, $result['count']); 140 $this->assertEquals(15, $result['perpage']); 141 $this->assertTrue($result['canpost']); 142 143 $this->assertEquals($student1->id, $result['comments'][0]['userid']); 144 $this->assertEquals($student1->id, $result['comments'][1]['userid']); 145 146 $this->assertEquals($ids[1], $result['comments'][0]['id']); // Default ordering newer first. 147 $this->assertEquals($ids[0], $result['comments'][1]['id']); 148 149 // Test sort direction and pagination. 150 $CFG->commentsperpage = 1; 151 $result = core_comment_external::get_comments($contextlevel, $instanceid, $component, $itemid, $area, $page, 'ASC'); 152 $result = \external_api::clean_returnvalue(core_comment_external::get_comments_returns(), $result); 153 154 $this->assertCount(0, $result['warnings']); 155 $this->assertCount(1, $result['comments']); // Only one per page. 156 $this->assertEquals(2, $result['count']); 157 $this->assertEquals($CFG->commentsperpage, $result['perpage']); 158 $this->assertEquals($ids[0], $result['comments'][0]['id']); // Comments order older first. 159 160 // Next page. 161 $result = core_comment_external::get_comments($contextlevel, $instanceid, $component, $itemid, $area, $page + 1, 'ASC'); 162 $result = \external_api::clean_returnvalue(core_comment_external::get_comments_returns(), $result); 163 164 $this->assertCount(0, $result['warnings']); 165 $this->assertCount(1, $result['comments']); 166 $this->assertEquals(2, $result['count']); 167 $this->assertEquals($CFG->commentsperpage, $result['perpage']); 168 $this->assertEquals($ids[1], $result['comments'][0]['id']); 169 } 170 171 /** 172 * Test add_comments not enabled site level 173 */ 174 public function test_add_comments_not_enabled_site_level() { 175 global $CFG; 176 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 177 178 // Try to add a comment, as student 1, when comments is disabled at site level. 179 $this->setUser($student1); 180 $CFG->usecomments = false; 181 182 $this->expectException(comment_exception::class); 183 core_comment_external::add_comments([ 184 [ 185 'contextlevel' => 'module', 186 'instanceid' => $module1->cmid, 187 'component' => 'mod_data', 188 'content' => 'abc', 189 'itemid' => $recordid, 190 'area' => 'database_entry' 191 ] 192 ]); 193 } 194 195 /** 196 * Test add_comments not enabled module level 197 */ 198 public function test_add_comments_not_enabled_module_level() { 199 global $DB; 200 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 201 202 // Disable comments for the module. 203 $DB->set_field('data', 'comments', 0, array('id' => $module1->id)); 204 205 // Verify we can't add a comment. 206 $this->setUser($student1); 207 $this->expectException(comment_exception::class); 208 core_comment_external::add_comments([ 209 [ 210 'contextlevel' => 'module', 211 'instanceid' => $module1->cmid, 212 'component' => 'mod_data', 213 'content' => 'abc', 214 'itemid' => $recordid, 215 'area' => 'database_entry' 216 ] 217 ]); 218 } 219 220 /** 221 * Test add_comments 222 */ 223 public function test_add_comments_single() { 224 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 225 226 // Add a comment as student 1. 227 $this->setUser($student1); 228 $result = core_comment_external::add_comments([ 229 [ 230 'contextlevel' => 'module', 231 'instanceid' => $module1->cmid, 232 'component' => 'mod_data', 233 'content' => 'abc', 234 'itemid' => $recordid, 235 'area' => 'database_entry' 236 ] 237 ]); 238 $result = \external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result); 239 240 // Verify the result contains 1 result having the correct structure. 241 $this->assertCount(1, $result); 242 243 $expectedkeys = [ 244 'id', 245 'content', 246 'format', 247 'timecreated', 248 'strftimeformat', 249 'profileurl', 250 'fullname', 251 'time', 252 'avatar', 253 'userid', 254 'delete', 255 ]; 256 foreach ($expectedkeys as $key) { 257 $this->assertArrayHasKey($key, $result[0]); 258 } 259 } 260 261 /** 262 * Test add_comments when one of the comments contains invalid data and cannot be created. 263 * 264 * This simply verifies that the entire operation fails. 265 */ 266 public function test_add_comments_multiple_contains_invalid() { 267 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 268 269 // Try to create some comments as student 1, but provide a bad area for the second comment. 270 $this->setUser($student1); 271 $this->expectException(comment_exception::class); 272 core_comment_external::add_comments([ 273 [ 274 'contextlevel' => 'module', 275 'instanceid' => $module1->cmid, 276 'component' => 'mod_data', 277 'content' => 'abc', 278 'itemid' => $recordid, 279 'area' => 'database_entry' 280 ], 281 [ 282 'contextlevel' => 'module', 283 'instanceid' => $module1->cmid, 284 'component' => 'mod_data', 285 'content' => 'def', 286 'itemid' => $recordid, 287 'area' => 'badarea' 288 ], 289 ]); 290 } 291 292 /** 293 * Test add_comments when one of the comments contains invalid data and cannot be created. 294 * 295 * This simply verifies that the entire operation fails. 296 */ 297 public function test_add_comments_multiple_all_valid() { 298 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 299 300 // Try to create some comments as student 1. 301 $this->setUser($student1); 302 $inputdata = [ 303 [ 304 'contextlevel' => 'module', 305 'instanceid' => $module1->cmid, 306 'component' => 'mod_data', 307 'content' => 'abc', 308 'itemid' => $recordid, 309 'area' => 'database_entry' 310 ], 311 [ 312 'contextlevel' => 'module', 313 'instanceid' => $module1->cmid, 314 'component' => 'mod_data', 315 'content' => 'def', 316 'itemid' => $recordid, 317 'area' => 'database_entry' 318 ] 319 ]; 320 $result = core_comment_external::add_comments($inputdata); 321 $result = \external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result); 322 323 // Two comments should have been created. 324 $this->assertCount(2, $result); 325 326 // The content for each comment should come back formatted. 327 foreach ($result as $index => $comment) { 328 $formatoptions = array('overflowdiv' => true, 'blanktarget' => true); 329 $expectedcontent = format_text($inputdata[$index]['content'], FORMAT_MOODLE, $formatoptions); 330 $this->assertEquals($expectedcontent, $comment['content']); 331 } 332 } 333 334 /** 335 * Test add_comments invalid area 336 */ 337 public function test_add_comments_invalid_area() { 338 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 339 340 // Try to create a comment with an invalid area, verifying failure. 341 $this->setUser($student1); 342 $comments = [ 343 [ 344 'contextlevel' => 'module', 345 'instanceid' => $module1->cmid, 346 'component' => 'mod_data', 347 'content' => 'abc', 348 'itemid' => $recordid, 349 'area' => 'spaghetti' 350 ] 351 ]; 352 $this->expectException(comment_exception::class); 353 core_comment_external::add_comments($comments); 354 } 355 356 /** 357 * Test delete_comment invalid comment. 358 */ 359 public function test_delete_comments_invalid_comment_id() { 360 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 361 $this->setUser($student1); 362 363 $this->expectException(comment_exception::class); 364 core_comment_external::delete_comments([-1, 0]); 365 } 366 367 /** 368 * Test delete_comment own user. 369 */ 370 public function test_delete_comments_own_user() { 371 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 372 373 // Create a few comments as student 1. 374 $this->setUser($student1); 375 $result = core_comment_external::add_comments([ 376 [ 377 'contextlevel' => 'module', 378 'instanceid' => $module1->cmid, 379 'component' => 'mod_data', 380 'content' => 'abc', 381 'itemid' => $recordid, 382 'area' => 'database_entry' 383 ], 384 [ 385 'contextlevel' => 'module', 386 'instanceid' => $module1->cmid, 387 'component' => 'mod_data', 388 'content' => 'def', 389 'itemid' => $recordid, 390 'area' => 'database_entry' 391 ] 392 ]); 393 $result = \external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result); 394 395 // Delete those comments we just created. 396 $result = core_comment_external::delete_comments([ 397 $result[0]['id'], 398 $result[1]['id'] 399 ]); 400 $result = \external_api::clean_returnvalue(core_comment_external::delete_comments_returns(), $result); 401 $this->assertEquals([], $result); 402 } 403 404 /** 405 * Test delete_comment other student. 406 */ 407 public function test_delete_comment_other_student() { 408 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 409 410 // Create a comment as the student. 411 $this->setUser($student1); 412 $result = core_comment_external::add_comments([ 413 [ 414 'contextlevel' => 'module', 415 'instanceid' => $module1->cmid, 416 'component' => 'mod_data', 417 'content' => 'abc', 418 'itemid' => $recordid, 419 'area' => 'database_entry' 420 ] 421 ]); 422 $result = \external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result); 423 424 // Now, as student 2, try to delete the comment made by student 1. Verify we can't. 425 $this->setUser($student2); 426 $this->expectException(comment_exception::class); 427 core_comment_external::delete_comments([$result[0]['id']]); 428 } 429 430 /** 431 * Test delete_comment as teacher. 432 */ 433 public function test_delete_comments_as_teacher() { 434 [$module1, $recordid, $teacher1, $student1, $student2] = $this->setup_course_and_users_basic(); 435 436 // Create a comment as the student. 437 $this->setUser($student1); 438 $result = core_comment_external::add_comments([ 439 [ 440 'contextlevel' => 'module', 441 'instanceid' => $module1->cmid, 442 'component' => 'mod_data', 443 'content' => 'abc', 444 'itemid' => $recordid, 445 'area' => 'database_entry' 446 ] 447 ]); 448 $result = \external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result); 449 450 // Verify teachers can delete the comment. 451 $this->setUser($teacher1); 452 $result = core_comment_external::delete_comments([$result[0]['id']]); 453 $result = \external_api::clean_returnvalue(core_comment_external::delete_comments_returns(), $result); 454 $this->assertEquals([], $result); 455 } 456 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body