Differences Between: [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 mod_data; 18 19 use context_module; 20 use rating_manager; 21 use stdClass; 22 23 /** 24 * Template tests class for mod_data. 25 * 26 * @package mod_data 27 * @category test 28 * @copyright 2022 Ferran Recio <ferran@moodle.com> 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 * @coversDefaultClass \mod_data\template 31 */ 32 class template_test extends \advanced_testcase { 33 /** 34 * Setup to ensure that fixtures are loaded. 35 */ 36 public static function setupBeforeClass(): void { 37 global $CFG; 38 require_once($CFG->dirroot . '/rating/lib.php'); 39 } 40 41 /** 42 * Test for static create methods. 43 * 44 * @covers ::parse_entries 45 * @dataProvider parse_entries_provider 46 * @param string $templatecontent the template string 47 * @param string $expected expected output 48 * @param string $rolename the user rolename 49 * @param bool $enableexport is portfolio export is enabled 50 * @param bool $approved if the entry is approved 51 * @param bool $enablecomments is comments are enabled 52 * @param bool $enableratings if ratings are enabled 53 * @param array $options extra parser options 54 * @param bool $otherauthor if the entry is from another user 55 */ 56 public function test_parse_entries( 57 string $templatecontent, 58 string $expected, 59 string $rolename = 'editingteacher', 60 bool $enableexport = false, 61 bool $approved = true, 62 bool $enablecomments = false, 63 bool $enableratings = false, 64 array $options = [], 65 bool $otherauthor = false 66 ) { 67 global $DB, $PAGE; 68 // Comments, tags, approval, user role. 69 $this->resetAfterTest(); 70 71 $params = ['approval' => true]; 72 73 // Enable comments. 74 if ($enablecomments) { 75 set_config('usecomments', 1); 76 $params['comments'] = true; 77 $PAGE->reset_theme_and_output(); 78 $PAGE->set_url('/mod/data/view.php'); 79 } 80 81 $course = $this->getDataGenerator()->create_course(); 82 $params['course'] = $course; 83 $activity = $this->getDataGenerator()->create_module('data', $params); 84 $cm = get_coursemodule_from_id('data', $activity->cmid, 0, false, MUST_EXIST); 85 $context = context_module::instance($cm->id); 86 87 $user = $this->getDataGenerator()->create_user(); 88 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); 89 $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleids[$rolename]); 90 $author = $user; 91 92 if ($otherauthor) { 93 $user2 = $this->getDataGenerator()->create_user(); 94 $this->getDataGenerator()->enrol_user($user2->id, $course->id, $roleids[$rolename]); 95 $author = $user2; 96 } 97 98 // Generate an entry. 99 $generator = $this->getDataGenerator()->get_plugin_generator('mod_data'); 100 $fieldrecord = (object)['name' => 'myfield', 'type' => 'text']; 101 $field = $generator->create_field($fieldrecord, $activity); 102 $otherfieldrecord = (object)['name' => 'otherfield', 'type' => 'text']; 103 $otherfield = $generator->create_field($otherfieldrecord, $activity); 104 105 $this->setUser($user); 106 107 $entryid = $generator->create_entry( 108 $activity, 109 [ 110 $field->field->id => 'Example entry', 111 $otherfield->field->id => 'Another example', 112 ], 113 0, 114 ['Cats', 'Dogs'], 115 ['approved' => $approved] 116 ); 117 118 if ($enableexport) { 119 $this->enable_portfolio($user); 120 } 121 122 $manager = manager::create_from_instance($activity); 123 124 $entry = (object)[ 125 'id' => $entryid, 126 'approved' => $approved, 127 'timecreated' => 1657618639, 128 'timemodified' => 1657618650, 129 'userid' => $author->id, 130 'groupid' => 0, 131 'dataid' => $activity->id, 132 'picture' => 0, 133 'firstname' => $author->firstname, 134 'lastname' => $author->lastname, 135 'firstnamephonetic' => $author->firstnamephonetic, 136 'lastnamephonetic' => $author->lastnamephonetic, 137 'middlename' => $author->middlename, 138 'alternatename' => $author->alternatename, 139 'imagealt' => 'PIXEXAMPLE', 140 'email' => $author->email, 141 ]; 142 $entries = [$entry]; 143 144 if ($enableratings) { 145 $entries = $this->enable_ratings($context, $activity, $entries, $user); 146 } 147 148 // Some cooked variables for the regular expression. 149 $replace = [ 150 '{authorfullname}' => fullname($author), 151 '{timeadded}' => userdate($entry->timecreated, get_string('strftimedatemonthabbr', 'langconfig')), 152 '{timemodified}' => userdate($entry->timemodified, get_string('strftimedatemonthabbr', 'langconfig')), 153 '{fieldid}' => $field->field->id, 154 '{fieldname}' => $field->field->name, 155 '{fielddescription}' => $field->field->description, 156 '{entryid}' => $entry->id, 157 '{cmid}' => $cm->id, 158 '{courseid}' => $course->id, 159 '{authorid}' => $author->id 160 ]; 161 162 $parser = new template($manager, $templatecontent, $options); 163 $result = $parser->parse_entries($entries); 164 165 // We don't want line breaks for the validations. 166 $result = str_replace("\n", '', $result); 167 $regexp = str_replace(array_keys($replace), array_values($replace), $expected); 168 $this->assertMatchesRegularExpression($regexp, $result); 169 } 170 171 /** 172 * Data provider for test_parse_entries(). 173 * 174 * @return array of scenarios 175 */ 176 public function parse_entries_provider(): array { 177 return [ 178 // Teacher scenarios. 179 'Teacher id tag' => [ 180 'templatecontent' => 'Some ##id## tag', 181 'expected' => '|Some {entryid} tag|', 182 'rolename' => 'editingteacher', 183 ], 184 'Teacher delete tag' => [ 185 'templatecontent' => 'Some ##delete## tag', 186 'expected' => '|Some .*delete.*{entryid}.*sesskey.*Delete.* tag|', 187 'rolename' => 'editingteacher', 188 ], 189 'Teacher edit tag' => [ 190 'templatecontent' => 'Some ##edit## tag', 191 'expected' => '|Some .*edit.*{entryid}.*sesskey.*Edit.* tag|', 192 'rolename' => 'editingteacher', 193 ], 194 'Teacher more tag' => [ 195 'templatecontent' => 'Some ##more## tag', 196 'expected' => '|Some .*more.*{cmid}.*rid.*{entryid}.*More.* tag|', 197 'rolename' => 'editingteacher', 198 'enableexport' => false, 199 'approved' => true, 200 'enablecomments' => false, 201 'enableratings' => false, 202 'options' => ['showmore' => true], 203 ], 204 'Teacher more tag with showmore set to false' => [ 205 'templatecontent' => 'Some ##more## tag', 206 'expected' => '|Some tag|', 207 'rolename' => 'editingteacher', 208 'enableexport' => false, 209 'approved' => true, 210 'enablecomments' => false, 211 'enableratings' => false, 212 'options' => ['showmore' => false], 213 ], 214 'Teacher moreurl tag' => [ 215 'templatecontent' => 'Some ##moreurl## tag', 216 'expected' => '|Some .*/mod/data/view.*{cmid}.*rid.*{entryid}.* tag|', 217 'rolename' => 'editingteacher', 218 'enableexport' => false, 219 'approved' => true, 220 'enablecomments' => false, 221 'enableratings' => false, 222 'options' => ['showmore' => true], 223 ], 224 'Teacher moreurl tag with showmore set to false' => [ 225 'templatecontent' => 'Some ##moreurl## tag', 226 'expected' => '|Some .*/mod/data/view.*{cmid}.*rid.*{entryid}.* tag|', 227 'rolename' => 'editingteacher', 228 'enableexport' => false, 229 'approved' => true, 230 'enablecomments' => false, 231 'enableratings' => false, 232 'options' => ['showmore' => false], 233 ], 234 'Teacher delcheck tag' => [ 235 'templatecontent' => 'Some ##delcheck## tag', 236 'expected' => '|Some .*input.*checkbox.*value.*{entryid}.* tag|', 237 'rolename' => 'editingteacher', 238 ], 239 'Teacher user tag' => [ 240 'templatecontent' => 'Some ##user## tag', 241 'expected' => '|Some .*user/view.*{authorid}.*course.*{courseid}.*{authorfullname}.* tag|', 242 'rolename' => 'editingteacher', 243 ], 244 'Teacher userpicture tag' => [ 245 'templatecontent' => 'Some ##userpicture## tag', 246 'expected' => '|Some .*user/view.*{authorid}.*course.*{courseid}.* tag|', 247 'rolename' => 'editingteacher', 248 ], 249 'Teacher export tag' => [ 250 'templatecontent' => 'Some ##export## tag', 251 'expected' => '|Some .*portfolio/add.* tag|', 252 'rolename' => 'editingteacher', 253 'enableexport' => true, 254 ], 255 'Teacher export tag not configured' => [ 256 'templatecontent' => 'Some ##export## tag', 257 'expected' => '|Some tag|', 258 'rolename' => 'editingteacher', 259 'enableexport' => false, 260 ], 261 'Teacher timeadded tag' => [ 262 'templatecontent' => 'Some ##timeadded## tag', 263 'expected' => '|Some <span.*>{timeadded}</span> tag|', 264 'rolename' => 'editingteacher', 265 ], 266 'Teacher timemodified tag' => [ 267 'templatecontent' => 'Some ##timemodified## tag', 268 'expected' => '|Some <span.*>{timemodified}</span> tag|', 269 'rolename' => 'editingteacher', 270 ], 271 'Teacher approve tag approved entry' => [ 272 'templatecontent' => 'Some ##approve## tag', 273 'expected' => '|Some tag|', 274 'rolename' => 'editingteacher', 275 'enableexport' => false, 276 'approved' => true, 277 ], 278 'Teacher approve tag disapproved entry' => [ 279 'templatecontent' => 'Some ##approve## tag', 280 'expected' => '|Some .*approve.*{entryid}.*sesskey.*Approve.* tag|', 281 'rolename' => 'editingteacher', 282 'enableexport' => false, 283 'approved' => false, 284 ], 285 'Teacher disapprove tag approved entry' => [ 286 'templatecontent' => 'Some ##disapprove## tag', 287 'expected' => '|Some .*disapprove.*{entryid}.*sesskey.*Undo approval.* tag|', 288 'rolename' => 'editingteacher', 289 'enableexport' => false, 290 'approved' => true, 291 ], 292 'Teacher disapprove tag disapproved entry' => [ 293 'templatecontent' => 'Some ##disapprove## tag', 294 'expected' => '|Some tag|', 295 'rolename' => 'editingteacher', 296 'enableexport' => false, 297 'approved' => false, 298 ], 299 'Teacher approvalstatus tag approved entry' => [ 300 'templatecontent' => 'Some ##approvalstatus## tag', 301 'expected' => '|Some tag|', // We do not display the approval status anymore. 302 'rolename' => 'editingteacher', 303 'enableexport' => false, 304 'approved' => true, 305 ], 306 'Teacher approvalstatus tag disapproved entry' => [ 307 'templatecontent' => 'Some ##approvalstatus## tag', 308 'expected' => '|Some .*Pending approval.* tag|', 309 'rolename' => 'editingteacher', 310 'enableexport' => false, 311 'approved' => false, 312 ], 313 'Teacher approvalstatusclass tag approved entry' => [ 314 'templatecontent' => 'Some ##approvalstatusclass## tag', 315 'expected' => '|Some approved tag|', 316 'rolename' => 'editingteacher', 317 'enableexport' => false, 318 'approved' => true, 319 ], 320 'Teacher approvalstatusclass tag disapproved entry' => [ 321 'templatecontent' => 'Some ##approvalstatusclass## tag', 322 'expected' => '|Some notapproved tag|', 323 'rolename' => 'editingteacher', 324 'enableexport' => false, 325 'approved' => false, 326 ], 327 'Teacher tags tag' => [ 328 'templatecontent' => 'Some ##tags## tag', 329 'expected' => '|Some .*Cats.* tag|', 330 'rolename' => 'editingteacher', 331 ], 332 'Teacher field name tag' => [ 333 'templatecontent' => 'Some [[myfield]] tag', 334 'expected' => '|Some .*Example entry.* tag|', 335 'rolename' => 'editingteacher', 336 ], 337 'Teacher field#id tag' => [ 338 'templatecontent' => 'Some [[myfield#id]] tag', 339 'expected' => '|Some {fieldid} tag|', 340 'rolename' => 'editingteacher', 341 ], 342 'Teacher field#name tag' => [ 343 'templatecontent' => 'Some [[myfield#name]] tag', 344 'expected' => '|Some {fieldname} tag|', 345 'rolename' => 'editingteacher', 346 ], 347 'Teacher field#description tag' => [ 348 'templatecontent' => 'Some [[myfield#description]] tag', 349 'expected' => '|Some {fielddescription} tag|', 350 'rolename' => 'editingteacher', 351 ], 352 'Teacher comments name tag with comments enabled' => [ 353 'templatecontent' => 'Some ##comments## tag', 354 'expected' => '|Some .*Comments.* tag|', 355 'rolename' => 'editingteacher', 356 'enableexport' => false, 357 'approved' => true, 358 'enablecomments' => true, 359 ], 360 'Teacher comments name tag with comments disabled' => [ 361 'templatecontent' => 'Some ##comments## tag', 362 'expected' => '|Some tag|', 363 'rolename' => 'editingteacher', 364 'enableexport' => false, 365 'approved' => true, 366 'enablecomments' => false, 367 ], 368 'Teacher comment forced with comments enables' => [ 369 'templatecontent' => 'No tags', 370 'expected' => '|No tags.*Comments.*|', 371 'rolename' => 'editingteacher', 372 'enableexport' => false, 373 'approved' => true, 374 'enablecomments' => true, 375 'enableratings' => false, 376 'options' => ['comments' => true], 377 ], 378 'Teacher comment forced without comments enables' => [ 379 'templatecontent' => 'No tags', 380 'expected' => '|^No tags$|', 381 'rolename' => 'editingteacher', 382 'enableexport' => false, 383 'approved' => true, 384 'enablecomments' => false, 385 'enableratings' => false, 386 'options' => ['comments' => true], 387 ], 388 'Teacher adding ratings without ratings configured' => [ 389 'templatecontent' => 'No tags', 390 'expected' => '|^No tags$|', 391 'rolename' => 'editingteacher', 392 'enableexport' => false, 393 'approved' => true, 394 'enablecomments' => false, 395 'enableratings' => false, 396 'options' => ['ratings' => true], 397 ], 398 'Teacher adding ratings with ratings configured' => [ 399 'templatecontent' => 'No tags', 400 'expected' => '|^No tags.*Average of ratings|', 401 'rolename' => 'editingteacher', 402 'enableexport' => false, 403 'approved' => true, 404 'enablecomments' => false, 405 'enableratings' => true, 406 'options' => ['ratings' => true], 407 ], 408 'Teacher actionsmenu tag with default options' => [ 409 'templatecontent' => 'Some ##actionsmenu## tag', 410 'expected' => '|Some .*edit.*{entryid}.*sesskey.*Edit.* .*delete.*{entryid}.*sesskey.*Delete.* tag|', 411 'rolename' => 'editingteacher', 412 ], 413 'Teacher actionsmenu tag with default options (check Show more is not there)' => [ 414 'templatecontent' => 'Some ##actionsmenu## tag', 415 'expected' => '|^Some((?!Show more).)*tag$|', 416 'rolename' => 'editingteacher', 417 ], 418 'Teacher actionsmenu tag with show more enabled' => [ 419 'templatecontent' => 'Some ##actionsmenu## tag', 420 'expected' => '|Some .*view.*{cmid}.*rid.*{entryid}.*Show more.* .*Edit.* .*Delete.* tag|', 421 'rolename' => 'editingteacher', 422 'enableexport' => false, 423 'approved' => false, 424 'enablecomments' => false, 425 'enableratings' => false, 426 'options' => ['showmore' => true], 427 ], 428 'Teacher actionsmenu tag with export enabled' => [ 429 'templatecontent' => 'Some ##actionsmenu## tag', 430 'expected' => '|Some .*Edit.* .*Delete.* .*portfolio/add.* tag|', 431 'rolename' => 'editingteacher', 432 'enableexport' => true, 433 ], 434 'Teacher actionsmenu tag with approved enabled' => [ 435 'templatecontent' => 'Some ##actionsmenu## tag', 436 'expected' => '|Some .*Edit.* .*Delete.* .*disapprove.*{entryid}.*sesskey.*Undo approval.* tag|', 437 'rolename' => 'editingteacher', 438 'enableexport' => false, 439 'approved' => true, 440 ], 441 'Teacher actionsmenu tag with export, approved and showmore enabled' => [ 442 'templatecontent' => 'Some ##actionsmenu## tag', 443 'expected' => '|Some .*Show more.* .*Edit.* .*Delete.* .*Undo approval.* .*Export to portfolio.* tag|', 444 'rolename' => 'editingteacher', 445 'enableexport' => true, 446 'approved' => true, 447 'enablecomments' => false, 448 'enableratings' => false, 449 'options' => ['showmore' => true], 450 ], 451 'Teacher otherfields tag' => [ 452 'templatecontent' => 'Some ##otherfields## tag', 453 'expected' => '|Some .*{fieldname}.*Example entry.*otherfield.*Another example.* tag|', 454 'rolename' => 'editingteacher', 455 ], 456 'Teacher otherfields tag with some field in the template' => [ 457 'templatecontent' => 'Some [[myfield]] and ##otherfields## tag', 458 'expected' => '|Some .*Example entry.* and .*otherfield.*Another example.* tag|', 459 'rolename' => 'editingteacher', 460 ], 461 // Student scenarios. 462 'Student id tag' => [ 463 'templatecontent' => 'Some ##id## tag', 464 'expected' => '|Some {entryid} tag|', 465 'rolename' => 'student', 466 ], 467 'Student delete tag' => [ 468 'templatecontent' => 'Some ##delete## tag', 469 'expected' => '|Some .*delete.*{entryid}.*sesskey.*Delete.* tag|', 470 'rolename' => 'student', 471 ], 472 'Student delete tag on other author entry' => [ 473 'templatecontent' => 'Some ##delete## tag', 474 'expected' => '|Some tag|', 475 'rolename' => 'student', 476 'enableexport' => false, 477 'approved' => true, 478 'enablecomments' => false, 479 'enableratings' => false, 480 'options' => [], 481 'otherauthor' => true, 482 ], 483 'Student edit tag' => [ 484 'templatecontent' => 'Some ##edit## tag', 485 'expected' => '|Some .*edit.*{entryid}.*sesskey.*Edit.* tag|', 486 'rolename' => 'student', 487 ], 488 'Student edit tag on other author entry' => [ 489 'templatecontent' => 'Some ##edit## tag', 490 'expected' => '|Some tag|', 491 'rolename' => 'student', 492 'enableexport' => false, 493 'approved' => true, 494 'enablecomments' => false, 495 'enableratings' => false, 496 'options' => [], 497 'otherauthor' => true, 498 ], 499 'Student more tag' => [ 500 'templatecontent' => 'Some ##more## tag', 501 'expected' => '|Some .*more.*{cmid}.*rid.*{entryid}.*More.* tag|', 502 'rolename' => 'student', 503 'enableexport' => false, 504 'approved' => true, 505 'enablecomments' => false, 506 'enableratings' => false, 507 'options' => ['showmore' => true], 508 ], 509 'Student more tag with showmore set to false' => [ 510 'templatecontent' => 'Some ##more## tag', 511 'expected' => '|Some tag|', 512 'rolename' => 'student', 513 'enableexport' => false, 514 'approved' => true, 515 'enablecomments' => false, 516 'enableratings' => false, 517 'options' => ['showmore' => false], 518 ], 519 'Student moreurl tag' => [ 520 'templatecontent' => 'Some ##moreurl## tag', 521 'expected' => '|Some .*/mod/data/view.*{cmid}.*rid.*{entryid}.* tag|', 522 'rolename' => 'student', 523 'enableexport' => false, 524 'approved' => true, 525 'enablecomments' => false, 526 'enableratings' => false, 527 'options' => ['showmore' => true], 528 ], 529 'Student moreurl tag with showmore set to false' => [ 530 'templatecontent' => 'Some ##moreurl## tag', 531 'expected' => '|Some .*/mod/data/view.*{cmid}.*rid.*{entryid}.* tag|', 532 'rolename' => 'student', 533 'enableexport' => false, 534 'approved' => true, 535 'enablecomments' => false, 536 'enableratings' => false, 537 'options' => ['showmore' => false], 538 ], 539 'Student delcheck tag' => [ 540 'templatecontent' => 'Some ##delcheck## tag', 541 'expected' => '|Some tag|', 542 'rolename' => 'student', 543 ], 544 'Student user tag' => [ 545 'templatecontent' => 'Some ##user## tag', 546 'expected' => '|Some .*user/view.*{authorid}.*course.*{courseid}.*{authorfullname}.* tag|', 547 'rolename' => 'student', 548 ], 549 'Student userpicture tag' => [ 550 'templatecontent' => 'Some ##userpicture## tag', 551 'expected' => '|Some .*user/view.*{authorid}.*course.*{courseid}.* tag|', 552 'rolename' => 'student', 553 ], 554 'Student export tag' => [ 555 'templatecontent' => 'Some ##export## tag', 556 'expected' => '|Some .*portfolio/add.* tag|', 557 'rolename' => 'student', 558 'enableexport' => true, 559 ], 560 'Student export tag not configured' => [ 561 'templatecontent' => 'Some ##export## tag', 562 'expected' => '|Some tag|', 563 'rolename' => 'student', 564 'enableexport' => false, 565 ], 566 'Student export tag on other user entry' => [ 567 'templatecontent' => 'Some ##export## tag', 568 'expected' => '|Some tag|', 569 'rolename' => 'student', 570 'enableexport' => false, 571 'approved' => true, 572 'enablecomments' => false, 573 'enableratings' => false, 574 'options' => [], 575 'otherauthor' => true, 576 ], 577 'Student timeadded tag' => [ 578 'templatecontent' => 'Some ##timeadded## tag', 579 'expected' => '|Some <span.*>{timeadded}</span> tag|', 580 'rolename' => 'student', 581 ], 582 'Student timemodified tag' => [ 583 'templatecontent' => 'Some ##timemodified## tag', 584 'expected' => '|Some <span.*>{timemodified}</span> tag|', 585 'rolename' => 'student', 586 ], 587 'Student approve tag approved entry' => [ 588 'templatecontent' => 'Some ##approve## tag', 589 'expected' => '|Some tag|', 590 'rolename' => 'student', 591 'enableexport' => false, 592 'approved' => true, 593 ], 594 'Student approve tag disapproved entry' => [ 595 'templatecontent' => 'Some ##approve## tag', 596 'expected' => '|Some tag|', 597 'rolename' => 'student', 598 'enableexport' => false, 599 'approved' => false, 600 ], 601 'Student disapprove tag approved entry' => [ 602 'templatecontent' => 'Some ##disapprove## tag', 603 'expected' => '|Some tag|', 604 'rolename' => 'student', 605 'enableexport' => false, 606 'approved' => true, 607 ], 608 'Student disapprove tag disapproved entry' => [ 609 'templatecontent' => 'Some ##disapprove## tag', 610 'expected' => '|Some tag|', 611 'rolename' => 'student', 612 'enableexport' => false, 613 'approved' => false, 614 ], 615 'Student approvalstatus tag approved entry' => [ 616 'templatecontent' => 'Some ##approvalstatus## tag', 617 'expected' => '|Some tag|', 618 'rolename' => 'student', 619 'enableexport' => false, 620 'approved' => true, 621 ], 622 'Student approvalstatus tag disapproved entry' => [ 623 'templatecontent' => 'Some ##approvalstatus## tag', 624 'expected' => '|Some .*Pending approval.* tag|', 625 'rolename' => 'student', 626 'enableexport' => false, 627 'approved' => false, 628 ], 629 'Student approvalstatusclass tag approved entry' => [ 630 'templatecontent' => 'Some ##approvalstatusclass## tag', 631 'expected' => '|Some approved tag|', 632 'rolename' => 'student', 633 'enableexport' => false, 634 'approved' => true, 635 ], 636 'Student approvalstatusclass tag disapproved entry' => [ 637 'templatecontent' => 'Some ##approvalstatusclass## tag', 638 'expected' => '|Some notapproved tag|', 639 'rolename' => 'student', 640 'enableexport' => false, 641 'approved' => false, 642 ], 643 'Student tags tag' => [ 644 'templatecontent' => 'Some ##tags## tag', 645 'expected' => '|Some .*Cats.* tag|', 646 'rolename' => 'student', 647 ], 648 'Student field name tag' => [ 649 'templatecontent' => 'Some [[myfield]] tag', 650 'expected' => '|Some .*Example entry.* tag|', 651 'rolename' => 'student', 652 ], 653 'Student field#id name tag' => [ 654 'templatecontent' => 'Some [[myfield#id]] tag', 655 'expected' => '|Some {fieldid} tag|', 656 'rolename' => 'student', 657 ], 658 'Student field#name tag' => [ 659 'templatecontent' => 'Some [[myfield#name]] tag', 660 'expected' => '|Some {fieldname} tag|', 661 'rolename' => 'student', 662 ], 663 'Student field#description tag' => [ 664 'templatecontent' => 'Some [[myfield#description]] tag', 665 'expected' => '|Some {fielddescription} tag|', 666 'rolename' => 'student', 667 ], 668 'Student comments name tag with comments enabled' => [ 669 'templatecontent' => 'Some ##comments## tag', 670 'expected' => '|Some .*Comments.* tag|', 671 'rolename' => 'student', 672 'enableexport' => false, 673 'approved' => true, 674 'enablecomments' => true, 675 ], 676 'Student comments name tag with comments disabled' => [ 677 'templatecontent' => 'Some ##comments## tag', 678 'expected' => '|Some tag|', 679 'rolename' => 'student', 680 'enableexport' => false, 681 'approved' => true, 682 'enablecomments' => false, 683 ], 684 'Student comment forced with comments enables' => [ 685 'templatecontent' => 'No tags', 686 'expected' => '|No tags.*Comments.*|', 687 'rolename' => 'student', 688 'enableexport' => false, 689 'approved' => true, 690 'enablecomments' => true, 691 'enableratings' => false, 692 'options' => ['comments' => true] 693 ], 694 'Student comment forced without comments enables' => [ 695 'templatecontent' => 'No tags', 696 'expected' => '|^No tags$|', 697 'rolename' => 'student', 698 'enableexport' => false, 699 'approved' => true, 700 'enablecomments' => false, 701 'enableratings' => false, 702 'options' => ['comments' => true] 703 ], 704 'Student adding ratings without ratings configured' => [ 705 'templatecontent' => 'No tags', 706 'expected' => '|^No tags$|', 707 'rolename' => 'student', 708 'enableexport' => false, 709 'approved' => true, 710 'enablecomments' => false, 711 'enableratings' => false, 712 'options' => ['ratings' => true] 713 ], 714 'Student adding ratings with ratings configured' => [ 715 'templatecontent' => 'No tags', 716 'expected' => '|^No tags$|', 717 'rolename' => 'student', 718 'enableexport' => false, 719 'approved' => true, 720 'enablecomments' => false, 721 'enableratings' => true, 722 'options' => ['ratings' => true] 723 ], 724 'Student actionsmenu tag with default options' => [ 725 'templatecontent' => 'Some ##actionsmenu## tag', 726 'expected' => '|Some .*edit.*{entryid}.*sesskey.*Edit.* .*delete.*{entryid}.*sesskey.*Delete.* tag|', 727 'rolename' => 'student', 728 ], 729 'Student actionsmenu tag with default options (check Show more is not there)' => [ 730 'templatecontent' => 'Some ##actionsmenu## tag', 731 'expected' => '|^Some((?!Show more).)*tag$|', 732 'rolename' => 'student', 733 ], 734 'Student actionsmenu tag with show more enabled' => [ 735 'templatecontent' => 'Some ##actionsmenu## tag', 736 'expected' => '|Some .*view.*{cmid}.*rid.*{entryid}.*Show more.* .*Edit.* .*Delete.* tag|', 737 'rolename' => 'student', 738 'enableexport' => false, 739 'approved' => false, 740 'enablecomments' => false, 741 'enableratings' => false, 742 'options' => ['showmore' => true], 743 ], 744 'Student actionsmenu tag with export enabled' => [ 745 'templatecontent' => 'Some ##actionsmenu## tag', 746 'expected' => '|Some .*Edit.* .*Delete.* .*portfolio/add.* tag|', 747 'rolename' => 'student', 748 'enableexport' => true, 749 ], 750 'Student actionsmenu tag with approved enabled' => [ 751 'templatecontent' => 'Some ##actionsmenu## tag', 752 'expected' => '|^Some((?!Approve).)*tag$|', 753 'rolename' => 'student', 754 'enableexport' => false, 755 'approved' => true, 756 ], 757 'Student actionsmenu tag with export, approved and showmore enabled' => [ 758 'templatecontent' => 'Some ##actionsmenu## tag', 759 'expected' => '|Some .*Show more.* .*Edit.* .*Delete.* .*Export to portfolio.* tag|', 760 'rolename' => 'student', 761 'enableexport' => true, 762 'approved' => true, 763 'enablecomments' => false, 764 'enableratings' => false, 765 'options' => ['showmore' => true], 766 ], 767 'Student otherfields tag' => [ 768 'templatecontent' => 'Some ##otherfields## tag', 769 'expected' => '|Some .*{fieldname}.*Example entry.*otherfield.*Another example.* tag|', 770 'rolename' => 'student', 771 ], 772 'Student otherfields tag with some field in the template' => [ 773 'templatecontent' => 'Some [[myfield]] and ##otherfields## tag', 774 'expected' => '|Some .*Example entry.* and .*otherfield.*Another example.* tag|', 775 'rolename' => 'student', 776 ], 777 ]; 778 } 779 780 /** 781 * Create all the necessary data to enable portfolio export in mod_data 782 * 783 * @param stdClass $user the current user record. 784 */ 785 protected function enable_portfolio(stdClass $user) { 786 global $DB; 787 set_config('enableportfolios', 1); 788 789 $plugin = 'download'; 790 $name = 'Download'; 791 792 $portfolioinstance = (object) [ 793 'plugin' => $plugin, 794 'name' => $name, 795 'visible' => 1 796 ]; 797 $portfolioinstance->id = $DB->insert_record('portfolio_instance', $portfolioinstance); 798 $userinstance = (object) [ 799 'instance' => $portfolioinstance->id, 800 'userid' => $user->id, 801 'name' => 'visible', 802 'value' => 1 803 ]; 804 $DB->insert_record('portfolio_instance_user', $userinstance); 805 806 $DB->insert_record('portfolio_log', [ 807 'portfolio' => $portfolioinstance->id, 808 'userid' => $user->id, 809 'caller_class' => 'data_portfolio_caller', 810 'caller_component' => 'mod_data', 811 'time' => time(), 812 ]); 813 } 814 815 /** 816 * Enable the ratings on the database entries. 817 * 818 * @param context_module $context the activity context 819 * @param stdClass $activity the activity record 820 * @param array $entries database entries 821 * @param stdClass $user the current user record 822 * @return stdClass the entries with the rating attribute 823 */ 824 protected function enable_ratings(context_module $context, stdClass $activity, array $entries, stdClass $user) { 825 global $CFG; 826 $ratingoptions = (object)[ 827 'context' => $context, 828 'component' => 'mod_data', 829 'ratingarea' => 'entry', 830 'items' => $entries, 831 'aggregate' => RATING_AGGREGATE_AVERAGE, 832 'scaleid' => $activity->scale, 833 'userid' => $user->id, 834 'returnurl' => $CFG->wwwroot . '/mod/data/view.php', 835 'assesstimestart' => $activity->assesstimestart, 836 'assesstimefinish' => $activity->assesstimefinish, 837 ]; 838 $rm = new rating_manager(); 839 return $rm->get_ratings($ratingoptions); 840 } 841 842 /** 843 * Test parse add entry template parsing. 844 * 845 * @covers ::parse_add_entry 846 * @dataProvider parse_add_entry_provider 847 * @param string $templatecontent the template string 848 * @param string $expected expected output 849 * @param bool $newentry if it is a new entry or editing and existing one 850 */ 851 public function test_parse_add_entry( 852 string $templatecontent, 853 string $expected, 854 bool $newentry = false 855 ) { 856 global $DB, $PAGE; 857 // Comments, tags, approval, user role. 858 $this->resetAfterTest(); 859 860 $params = ['approval' => true]; 861 862 $course = $this->getDataGenerator()->create_course(); 863 $params['course'] = $course; 864 $activity = $this->getDataGenerator()->create_module('data', $params); 865 $author = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); 866 867 // Generate an entry. 868 $generator = $this->getDataGenerator()->get_plugin_generator('mod_data'); 869 $fieldrecord = (object)[ 870 'name' => 'myfield', 871 'type' => 'text', 872 'description' => 'This is a field' 873 ]; 874 $field = $generator->create_field($fieldrecord, $activity); 875 $otherfieldrecord = (object)['name' => 'otherfield', 'type' => 'text']; 876 $otherfield = $generator->create_field($otherfieldrecord, $activity); 877 878 if ($newentry) { 879 $entryid = null; 880 $entry = null; 881 } else { 882 $entryid = $generator->create_entry( 883 $activity, 884 [ 885 $field->field->id => 'Example entry', 886 $otherfield->field->id => 'Another example', 887 ], 888 0, 889 ['Cats', 'Dogs'] 890 ); 891 $entry = (object)[ 892 'd' => $activity->id, 893 'rid' => $entryid, 894 "field_{$field->field->id}" => "New value", 895 "field_{$otherfield->field->id}" => "Altered value", 896 ]; 897 } 898 899 $manager = manager::create_from_instance($activity); 900 901 // Some cooked variables for the regular expression. 902 $replace = [ 903 '{fieldid}' => $field->field->id, 904 '{fieldname}' => $field->field->name, 905 '{fielddescription}' => $field->field->description, 906 '{otherid}' => $otherfield->field->id, 907 ]; 908 909 $processdata = (object)[ 910 'generalnotifications' => ['GENERAL'], 911 'fieldnotifications' => [ 912 $field->field->name => ['FIELD'], 913 $otherfield->field->name => ['OTHERFIELD'], 914 ], 915 ]; 916 917 $parser = new template($manager, $templatecontent); 918 $result = $parser->parse_add_entry($processdata, $entryid, $entry); 919 920 // We don't want line breaks for the validations. 921 $result = str_replace("\n", '', $result); 922 $regexp = str_replace(array_keys($replace), array_values($replace), $expected); 923 $this->assertMatchesRegularExpression($regexp, $result); 924 } 925 926 /** 927 * Data provider for test_parse_add_entry(). 928 * 929 * @return array of scenarios 930 */ 931 public function parse_add_entry_provider(): array { 932 return [ 933 // Editing an entry. 934 'Teacher editing entry tags tag' => [ 935 'templatecontent' => 'Some ##tags## tag', 936 'expected' => '|GENERAL.*Some .*select .*tags.*Cats.* tag|', 937 'newentry' => false, 938 ], 939 'Teacher editing entry field name tag' => [ 940 'templatecontent' => 'Some [[myfield]] tag', 941 'expected' => '|GENERAL.*Some .*FIELD.*field_{fieldid}.*input.*New value.* tag|', 942 'newentry' => false, 943 ], 944 'Teacher editing entry field#id tag' => [ 945 'templatecontent' => 'Some [[myfield#id]] tag', 946 'expected' => '|GENERAL.*Some field_{fieldid} tag|', 947 'newentry' => false, 948 ], 949 'Teacher editing field#name tag' => [ 950 'templatecontent' => 'Some [[myfield#name]] tag', 951 'expected' => '|GENERAL.*Some {fieldname} tag|', 952 'newentry' => false, 953 ], 954 'Teacher editing field#description tag' => [ 955 'templatecontent' => 'Some [[myfield#description]] tag', 956 'expected' => '|GENERAL.*Some {fielddescription} tag|', 957 'newentry' => false, 958 ], 959 'Teacher editing entry field otherfields tag' => [ 960 'templatecontent' => 'Some [[myfield]] and ##otherfields## tag', 961 'expected' => '|GENERAL.*Some .*FIELD.*field_{fieldid}.*input.*New value.* ' 962 . 'and .*OTHERFIELD.*field_{otherid}.*input.*Altered value.* tag|', 963 'newentry' => false, 964 ], 965 // New entry. 966 'Teacher new entry tags tag' => [ 967 'templatecontent' => 'Some ##tags## tag', 968 'expected' => '|GENERAL.*Some .*select .*tags\[\].* tag|', 969 'newentry' => true, 970 ], 971 'Teacher new entry field name tag' => [ 972 'templatecontent' => 'Some [[myfield]] tag', 973 'expected' => '|GENERAL.*Some .*FIELD.*field_{fieldid}.*input.*value="".* tag|', 974 'newentry' => true, 975 ], 976 'Teacher new entry field#id name tag' => [ 977 'templatecontent' => 'Some [[myfield#id]] tag', 978 'expected' => '|GENERAL.*Some field_{fieldid} tag|', 979 'newentry' => true, 980 ], 981 'Teacher new entry field#name tag' => [ 982 'templatecontent' => 'Some [[myfield#name]] tag', 983 'expected' => '|GENERAL.*Some {fieldname} tag|', 984 'newentry' => false, 985 ], 986 'Teacher new entry field#description tag' => [ 987 'templatecontent' => 'Some [[myfield#description]] tag', 988 'expected' => '|GENERAL.*Some {fielddescription} tag|', 989 'newentry' => false, 990 ], 991 'Teacher new entry field otherfields tag' => [ 992 'templatecontent' => 'Some [[myfield]] and ##otherfields## tag', 993 'expected' => '|GENERAL.*Some .*FIELD.*field_{fieldid}.*input.*New value.* ' 994 . '.* and .*OTHERFIELD.*field_{otherid}.*input.*Altered value.* |', 995 'newentry' => false, 996 ], 997 ]; 998 } 999 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body