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_favourites; 18 19 use core_favourites\local\repository\favourite_repository; 20 use core_favourites\local\entity\favourite; 21 22 /** 23 * Test class covering the favourite_repository. 24 * 25 * @package core_favourites 26 * @category test 27 * @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com> 28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 29 */ 30 class repository_test extends \advanced_testcase { 31 32 public function setUp(): void { 33 $this->resetAfterTest(); 34 } 35 36 // Basic setup stuff to be reused in most tests. 37 protected function setup_users_and_courses() { 38 $user1 = self::getDataGenerator()->create_user(); 39 $user1context = \context_user::instance($user1->id); 40 $user2 = self::getDataGenerator()->create_user(); 41 $user2context = \context_user::instance($user2->id); 42 $course1 = self::getDataGenerator()->create_course(); 43 $course2 = self::getDataGenerator()->create_course(); 44 $course1context = \context_course::instance($course1->id); 45 $course2context = \context_course::instance($course2->id); 46 return [$user1context, $user2context, $course1context, $course2context]; 47 } 48 49 /** 50 * Verify the basic create operation can create records, and is validated. 51 */ 52 public function test_add() { 53 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 54 55 // Create a favourites repository and favourite a course. 56 $favouritesrepo = new favourite_repository($user1context); 57 58 $favcourse = new favourite( 59 'core_course', 60 'course', 61 $course1context->instanceid, 62 $course1context->id, 63 $user1context->instanceid 64 ); 65 $timenow = time(); // Reference only, to check that the created item has a time equal to or greater than this. 66 $favourite = $favouritesrepo->add($favcourse); 67 68 // Verify we get the record back. 69 $this->assertInstanceOf(favourite::class, $favourite); 70 $this->assertObjectHasAttribute('id', $favourite); 71 $this->assertEquals('core_course', $favourite->component); 72 $this->assertEquals('course', $favourite->itemtype); 73 74 // Verify the returned object has additional properties, created as part of the add. 75 $this->assertObjectHasAttribute('ordering', $favourite); 76 $this->assertObjectHasAttribute('timecreated', $favourite); 77 $this->assertGreaterThanOrEqual($timenow, $favourite->timecreated); 78 79 // Try to save the same record again and confirm the store throws an exception. 80 $this->expectException('dml_write_exception'); 81 $favouritesrepo->add($favcourse); 82 } 83 84 /** 85 * Tests that malformed favourites cannot be saved. 86 */ 87 public function test_add_malformed_favourite() { 88 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 89 90 // Create a favourites repository and favourite a course. 91 $favouritesrepo = new favourite_repository($user1context); 92 93 $favcourse = new favourite( 94 'core_course', 95 'course', 96 $course1context->instanceid, 97 $course1context->id, 98 $user1context->instanceid 99 ); 100 $favcourse->something = 'something'; 101 102 $this->expectException('moodle_exception'); 103 $favouritesrepo->add($favcourse); 104 } 105 106 /** 107 * Tests that incomplete favourites cannot be saved. 108 */ 109 public function test_add_incomplete_favourite() { 110 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 111 112 // Create a favourites repository and try to favourite a course. 113 $favouritesrepo = new favourite_repository($user1context); 114 115 $favcourse = new favourite( 116 'core_course', 117 'course', 118 $course1context->instanceid, 119 $course1context->id, 120 $user1context->instanceid 121 ); 122 unset($favcourse->userid); 123 124 $this->expectException('moodle_exception'); 125 $favouritesrepo->add($favcourse); 126 } 127 128 public function test_add_all_basic() { 129 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 130 131 // Create a favourites repository and favourite several courses. 132 $favouritesrepo = new favourite_repository($user1context); 133 $favcourses = []; 134 135 $favcourses[] = new favourite( 136 'core_course', 137 'course', 138 $course1context->instanceid, 139 $course1context->id, 140 $user1context->instanceid 141 ); 142 $favcourses[] = new favourite( 143 'core_course', 144 'course', 145 $course2context->instanceid, 146 $course2context->id, 147 $user1context->instanceid 148 ); 149 150 $timenow = time(); // Reference only, to check that the created item has a time equal to or greater than this. 151 $favourites = $favouritesrepo->add_all($favcourses); 152 153 $this->assertIsArray($favourites); 154 $this->assertCount(2, $favourites); 155 foreach ($favourites as $favourite) { 156 // Verify we get the favourite back. 157 $this->assertInstanceOf(favourite::class, $favourite); 158 $this->assertEquals('core_course', $favourite->component); 159 $this->assertEquals('course', $favourite->itemtype); 160 161 // Verify the returned object has additional properties, created as part of the add. 162 $this->assertObjectHasAttribute('ordering', $favourite); 163 $this->assertObjectHasAttribute('timecreated', $favourite); 164 $this->assertGreaterThanOrEqual($timenow, $favourite->timecreated); 165 } 166 167 // Try to save the same record again and confirm the store throws an exception. 168 $this->expectException('dml_write_exception'); 169 $favouritesrepo->add_all($favcourses); 170 } 171 172 /** 173 * Tests reading from the repository by instance id. 174 */ 175 public function test_find() { 176 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 177 178 // Create a favourites repository and favourite a course. 179 $favouritesrepo = new favourite_repository($user1context); 180 $favourite = new favourite( 181 'core_course', 182 'course', 183 $course1context->instanceid, 184 $course1context->id, 185 $user1context->instanceid 186 ); 187 $favourite = $favouritesrepo->add($favourite); 188 189 // Now, from the repo, get the single favourite we just created, by id. 190 $userfavourite = $favouritesrepo->find($favourite->id); 191 $this->assertInstanceOf(favourite::class, $userfavourite); 192 $this->assertObjectHasAttribute('timecreated', $userfavourite); 193 194 // Try to get a favourite we know doesn't exist. 195 // We expect an exception in this case. 196 $this->expectException(\dml_exception::class); 197 $favouritesrepo->find(0); 198 } 199 200 /** 201 * Test verifying that find_all() returns all favourites, or an empty array. 202 */ 203 public function test_find_all() { 204 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 205 206 $favouritesrepo = new favourite_repository($user1context); 207 208 // Verify that only two self-conversations are found. 209 $this->assertCount(2, $favouritesrepo->find_all()); 210 211 // Save a favourite for 2 courses, in different areas. 212 $favourite = new favourite( 213 'core_course', 214 'course', 215 $course1context->instanceid, 216 $course1context->id, 217 $user1context->instanceid 218 ); 219 $favourite2 = new favourite( 220 'core_course', 221 'course', 222 $course2context->instanceid, 223 $course2context->id, 224 $user1context->instanceid 225 ); 226 $favouritesrepo->add($favourite); 227 $favouritesrepo->add($favourite2); 228 229 // Verify that find_all returns both of our favourites + two self-conversations. 230 $favourites = $favouritesrepo->find_all(); 231 $this->assertCount(4, $favourites); 232 foreach ($favourites as $fav) { 233 $this->assertInstanceOf(favourite::class, $fav); 234 $this->assertObjectHasAttribute('id', $fav); 235 $this->assertObjectHasAttribute('timecreated', $fav); 236 } 237 } 238 239 /** 240 * Testing the pagination of the find_all method. 241 */ 242 public function test_find_all_pagination() { 243 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 244 245 $favouritesrepo = new favourite_repository($user1context); 246 247 // Verify that for an empty repository, find_all with any combination of page options returns only self-conversations. 248 $this->assertCount(2, $favouritesrepo->find_all(0, 0)); 249 $this->assertCount(2, $favouritesrepo->find_all(0, 10)); 250 $this->assertCount(1, $favouritesrepo->find_all(1, 0)); 251 $this->assertCount(1, $favouritesrepo->find_all(1, 10)); 252 253 // Save 10 arbitrary favourites to the repo. 254 foreach (range(1, 10) as $i) { 255 $favourite = new favourite( 256 'core_course', 257 'course', 258 $i, 259 $course1context->id, 260 $user1context->instanceid 261 ); 262 $favouritesrepo->add($favourite); 263 } 264 265 // Verify we have 10 favourites + 2 self-conversations. 266 $this->assertEquals(12, $favouritesrepo->count()); 267 268 // Verify we can fetch the first page of 5 records+ 2 self-conversations. 269 $favourites = $favouritesrepo->find_all(0, 6); 270 $this->assertCount(6, $favourites); 271 272 // Verify we can fetch the second page. 273 $favourites = $favouritesrepo->find_all(6, 6); 274 $this->assertCount(6, $favourites); 275 276 // Verify the third page request ends with an empty array. 277 $favourites = $favouritesrepo->find_all(12, 6); 278 $this->assertCount(0, $favourites); 279 } 280 281 /** 282 * Test retrieval of a user's favourites for a given criteria, in this case, area. 283 */ 284 public function test_find_by() { 285 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 286 287 // Create a favourites repository and favourite a course. 288 $favouritesrepo = new favourite_repository($user1context); 289 $favourite = new favourite( 290 'core_course', 291 'course', 292 $course1context->instanceid, 293 $course1context->id, 294 $user1context->instanceid 295 ); 296 $favouritesrepo->add($favourite); 297 298 // Add another favourite. 299 $favourite = new favourite( 300 'core_course', 301 'course_item', 302 $course1context->instanceid, 303 $course1context->id, 304 $user1context->instanceid 305 ); 306 $favouritesrepo->add($favourite); 307 308 // From the repo, get the list of favourites for the 'core_course/course' area. 309 $userfavourites = $favouritesrepo->find_by(['component' => 'core_course', 'itemtype' => 'course']); 310 $this->assertIsArray($userfavourites); 311 $this->assertCount(1, $userfavourites); 312 313 // Try to get a list of favourites for a non-existent area. 314 $userfavourites = $favouritesrepo->find_by(['component' => 'core_cannibalism', 'itemtype' => 'course']); 315 $this->assertIsArray($userfavourites); 316 $this->assertCount(0, $userfavourites); 317 318 // From the repo, get the list of favourites for the 'core_course/course' area when passed as an array. 319 $userfavourites = $favouritesrepo->find_by(['component' => 'core_course', 'itemtype' => ['course']]); 320 $this->assertIsArray($userfavourites); 321 $this->assertCount(1, $userfavourites); 322 323 // From the repo, get the list of favourites for the 'core_course' area given multiple item_types. 324 $userfavourites = $favouritesrepo->find_by(['component' => 'core_course', 'itemtype' => ['course', 'course_item']]); 325 $this->assertIsArray($userfavourites); 326 $this->assertCount(2, $userfavourites); 327 } 328 329 /** 330 * Testing the pagination of the find_by method. 331 */ 332 public function test_find_by_pagination() { 333 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 334 335 $favouritesrepo = new favourite_repository($user1context); 336 337 // Verify that by default, find_all with any combination of page options returns only self-conversations. 338 $this->assertCount(2, $favouritesrepo->find_by([], 0, 0)); 339 $this->assertCount(2, $favouritesrepo->find_by([], 0, 10)); 340 $this->assertCount(1, $favouritesrepo->find_by([], 1, 0)); 341 $this->assertCount(1, $favouritesrepo->find_by([], 1, 10)); 342 343 // Save 10 arbitrary favourites to the repo. 344 foreach (range(1, 10) as $i) { 345 $favourite = new favourite( 346 'core_course', 347 'course', 348 $i, 349 $course1context->id, 350 $user1context->instanceid 351 ); 352 $favouritesrepo->add($favourite); 353 } 354 355 // Verify we have 10 favourites + 2 self-conversations. 356 $this->assertEquals(12, $favouritesrepo->count()); 357 358 // Verify a request for a page, when no criteria match, results in 2 self-conversations array. 359 $favourites = $favouritesrepo->find_by(['component' => 'core_message'], 0, 5); 360 $this->assertCount(2, $favourites); 361 362 // Verify we can fetch a the first page of 5 records. 363 $favourites = $favouritesrepo->find_by(['component' => 'core_course'], 0, 5); 364 $this->assertCount(5, $favourites); 365 366 // Verify we can fetch the second page. 367 $favourites = $favouritesrepo->find_by(['component' => 'core_course'], 5, 5); 368 $this->assertCount(5, $favourites); 369 370 // Verify the third page request ends with an empty array. 371 $favourites = $favouritesrepo->find_by(['component' => 'core_course'], 10, 5); 372 $this->assertCount(0, $favourites); 373 } 374 375 /** 376 * Test the count_by() method. 377 */ 378 public function test_count_by() { 379 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 380 381 // Create a favourites repository and add 2 favourites in different areas. 382 $favouritesrepo = new favourite_repository($user1context); 383 $favourite = new favourite( 384 'core_course', 385 'course', 386 $course1context->instanceid, 387 $course1context->id, 388 $user1context->instanceid 389 ); 390 $favourite2 = new favourite( 391 'core_course', 392 'anothertype', 393 $course2context->instanceid, 394 $course2context->id, 395 $user1context->instanceid 396 ); 397 $favouritesrepo->add($favourite); 398 $favouritesrepo->add($favourite2); 399 400 // Verify counts can be restricted by criteria. 401 $this->assertEquals(1, $favouritesrepo->count_by(['userid' => $user1context->instanceid, 'component' => 'core_course', 402 'itemtype' => 'course'])); 403 $this->assertEquals(1, $favouritesrepo->count_by(['userid' => $user1context->instanceid, 'component' => 'core_course', 404 'itemtype' => 'anothertype'])); 405 $this->assertEquals(0, $favouritesrepo->count_by(['userid' => $user1context->instanceid, 'component' => 'core_course', 406 'itemtype' => 'nonexistenttype'])); 407 } 408 409 /** 410 * Test the exists() function. 411 */ 412 public function test_exists() { 413 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 414 415 // Create a favourites repository and favourite a course. 416 $favouritesrepo = new favourite_repository($user1context); 417 $favourite = new favourite( 418 'core_course', 419 'course', 420 $course1context->instanceid, 421 $course1context->id, 422 $user1context->instanceid 423 ); 424 $createdfavourite = $favouritesrepo->add($favourite); 425 426 // Verify the existence of the favourite in the repo. 427 $this->assertTrue($favouritesrepo->exists($createdfavourite->id)); 428 429 // Verify exists returns false for non-existent favourite. 430 $this->assertFalse($favouritesrepo->exists(0)); 431 } 432 433 /** 434 * Test the exists_by() method. 435 */ 436 public function test_exists_by() { 437 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 438 439 // Create a favourites repository and favourite two courses, in different areas. 440 $favouritesrepo = new favourite_repository($user1context); 441 $favourite = new favourite( 442 'core_course', 443 'course', 444 $course1context->instanceid, 445 $course1context->id, 446 $user1context->instanceid 447 ); 448 $favourite2 = new favourite( 449 'core_course', 450 'anothertype', 451 $course2context->instanceid, 452 $course2context->id, 453 $user1context->instanceid 454 ); 455 $favourite1 = $favouritesrepo->add($favourite); 456 $favourite2 = $favouritesrepo->add($favourite2); 457 458 // Verify the existence of the favourites. 459 $this->assertTrue($favouritesrepo->exists_by( 460 [ 461 'userid' => $user1context->instanceid, 462 'component' => 'core_course', 463 'itemtype' => 'course', 464 'itemid' => $favourite1->itemid, 465 'contextid' => $favourite1->contextid 466 ] 467 )); 468 $this->assertTrue($favouritesrepo->exists_by( 469 [ 470 'userid' => $user1context->instanceid, 471 'component' => 'core_course', 472 'itemtype' => 'anothertype', 473 'itemid' => $favourite2->itemid, 474 'contextid' => $favourite2->contextid 475 ] 476 )); 477 478 // Verify that we can't find a favourite from one area, in another. 479 $this->assertFalse($favouritesrepo->exists_by( 480 [ 481 'userid' => $user1context->instanceid, 482 'component' => 'core_course', 483 'itemtype' => 'anothertype', 484 'itemid' => $favourite1->itemid, 485 'contextid' => $favourite1->contextid 486 ] 487 )); 488 } 489 490 /** 491 * Test the update() method, by simulating a user changing the ordering of a favourite. 492 */ 493 public function test_update() { 494 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 495 496 // Create a favourites repository and favourite a course. 497 $favouritesrepo = new favourite_repository($user1context); 498 $favourite = new favourite( 499 'core_course', 500 'course', 501 $course1context->instanceid, 502 $course1context->id, 503 $user1context->instanceid 504 ); 505 $favourite1 = $favouritesrepo->add($favourite); 506 $this->assertNull($favourite1->ordering); 507 508 // Verify we can update the ordering for 2 favourites. 509 $favourite1->ordering = 1; 510 $favourite1 = $favouritesrepo->update($favourite1); 511 $this->assertInstanceOf(favourite::class, $favourite1); 512 $this->assertEquals('1', $favourite1->ordering); 513 } 514 515 public function test_delete() { 516 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 517 518 // Create a favourites repository and favourite a course. 519 $favouritesrepo = new favourite_repository($user1context); 520 $favourite = new favourite( 521 'core_course', 522 'course', 523 $course1context->instanceid, 524 $course1context->id, 525 $user1context->instanceid 526 ); 527 $favourite = $favouritesrepo->add($favourite); 528 529 // Verify the existence of the favourite in the repo. 530 $this->assertTrue($favouritesrepo->exists($favourite->id)); 531 532 // Now, delete the favourite and confirm it's not retrievable. 533 $favouritesrepo->delete($favourite->id); 534 $this->assertFalse($favouritesrepo->exists($favourite->id)); 535 } 536 537 /** 538 * Test the delete_by() method. 539 */ 540 public function test_delete_by() { 541 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 542 543 // Create a favourites repository and favourite two courses, in different areas. 544 $favouritesrepo = new favourite_repository($user1context); 545 $favourite = new favourite( 546 'core_course', 547 'course', 548 $course1context->instanceid, 549 $course1context->id, 550 $user1context->instanceid 551 ); 552 $favourite2 = new favourite( 553 'core_course', 554 'anothertype', 555 $course1context->instanceid, 556 $course1context->id, 557 $user1context->instanceid 558 ); 559 $favourite1 = $favouritesrepo->add($favourite); 560 $favourite2 = $favouritesrepo->add($favourite2); 561 562 // Verify we have 2 items in the repo + 2 self-conversations. 563 $this->assertEquals(4, $favouritesrepo->count()); 564 565 // Try to delete by a non-existent area, and confirm it doesn't remove anything. 566 $favouritesrepo->delete_by( 567 [ 568 'userid' => $user1context->instanceid, 569 'component' => 'core_course', 570 'itemtype' => 'donaldduck' 571 ] 572 ); 573 $this->assertEquals(4, $favouritesrepo->count()); 574 575 // Try to delete by a non-existent area, and confirm it doesn't remove anything. 576 $favouritesrepo->delete_by( 577 [ 578 'userid' => $user1context->instanceid, 579 'component' => 'core_course', 580 'itemtype' => 'cat' 581 ] 582 ); 583 $this->assertEquals(4, $favouritesrepo->count()); 584 585 // Delete by area, and confirm we have one record left, from the 'core_course/anothertype' area. 586 $favouritesrepo->delete_by( 587 [ 588 'userid' => $user1context->instanceid, 589 'component' => 'core_course', 590 'itemtype' => 'course' 591 ] 592 ); 593 $this->assertEquals(3, $favouritesrepo->count()); 594 $this->assertFalse($favouritesrepo->exists($favourite1->id)); 595 $this->assertTrue($favouritesrepo->exists($favourite2->id)); 596 } 597 598 /** 599 * Test the find_favourite() method for an existing favourite. 600 */ 601 public function test_find_favourite_basic() { 602 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 603 604 // Create a favourites repository and favourite two courses, in different areas. 605 $favouritesrepo = new favourite_repository($user1context); 606 $favourite = new favourite( 607 'core_course', 608 'course', 609 $course1context->instanceid, 610 $course1context->id, 611 $user1context->instanceid 612 ); 613 $favourite2 = new favourite( 614 'core_course', 615 'anothertype', 616 $course1context->instanceid, 617 $course1context->id, 618 $user1context->instanceid 619 ); 620 $favourite1 = $favouritesrepo->add($favourite); 621 $favourite2 = $favouritesrepo->add($favourite2); 622 623 $fav = $favouritesrepo->find_favourite($user1context->instanceid, 'core_course', 'course', $course1context->instanceid, 624 $course1context->id); 625 $this->assertInstanceOf(\core_favourites\local\entity\favourite::class, $fav); 626 } 627 628 /** 629 * Test confirming the repository throws an exception in find_favourite if the favourite can't be found. 630 */ 631 public function test_find_favourite_nonexistent_favourite() { 632 list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses(); 633 634 // Confirm we get an exception. 635 $favouritesrepo = new favourite_repository($user1context); 636 $this->expectException(\dml_exception::class); 637 $favouritesrepo->find_favourite($user1context->instanceid, 'core_course', 'course', 0, $course1context->id); 638 } 639 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body