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