See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 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 /** 18 * Tests for tour. 19 * 20 * @package tool_usertours 21 * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 global $CFG; 28 require_once($CFG->libdir . '/formslib.php'); 29 30 use tool_usertours\tour; 31 32 /** 33 * Tests for tour. 34 * 35 * @package tool_usertours 36 * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class tour_testcase extends advanced_testcase { 40 41 /** 42 * @var moodle_database 43 */ 44 protected $db; 45 46 /** 47 * Setup to store the DB reference. 48 */ 49 public function setUp() { 50 global $DB; 51 52 $this->db = $DB; 53 } 54 55 /** 56 * Tear down to restore the original DB reference. 57 */ 58 public function tearDown() { 59 global $DB; 60 61 $DB = $this->db; 62 } 63 64 /** 65 * Helper to mock the database. 66 * 67 * @return \PHPUnit\Framework\MockObject\MockObject 68 */ 69 public function mock_database() { 70 global $DB; 71 72 $DB = $this->getMockBuilder(\moodle_database::class) 73 ->getMock() 74 ; 75 76 return $DB; 77 } 78 79 /** 80 * Data provider for the dirty value tester. 81 * 82 * @return array 83 */ 84 public function dirty_value_provider() { 85 return [ 86 'name' => [ 87 'name', 88 ['Lorem'], 89 ], 90 'description' => [ 91 'description', 92 ['Lorem'], 93 ], 94 'pathmatch' => [ 95 'pathmatch', 96 ['Lorem'], 97 ], 98 'enabled' => [ 99 'enabled', 100 ['Lorem'], 101 ], 102 'sortorder' => [ 103 'sortorder', 104 [1], 105 ], 106 'config' => [ 107 'config', 108 ['key', 'value'], 109 ], 110 ]; 111 } 112 113 /** 114 * Test that setters mark things as dirty. 115 * 116 * @dataProvider dirty_value_provider 117 * @param string $name The name of the key being tested 118 * @param mixed $value The value being set 119 */ 120 public function test_dirty_values($name, $value) { 121 $tour = new \tool_usertours\tour(); 122 $method = 'set_' . $name; 123 call_user_func_array([$tour, $method], $value); 124 125 $rc = new \ReflectionClass(\tool_usertours\tour::class); 126 $rcp = $rc->getProperty('dirty'); 127 $rcp->setAccessible(true); 128 129 $this->assertTrue($rcp->getValue($tour)); 130 } 131 132 /** 133 * Data provider for the get_ tests. 134 * 135 * @return array 136 */ 137 public function getter_provider() { 138 return [ 139 'id' => [ 140 'id', 141 rand(1, 100), 142 ], 143 'name' => [ 144 'name', 145 'Lorem', 146 ], 147 'description' => [ 148 'description', 149 'Lorem', 150 ], 151 'pathmatch' => [ 152 'pathmatch', 153 'Lorem', 154 ], 155 'enabled' => [ 156 'enabled', 157 'Lorem', 158 ], 159 'sortorder' => [ 160 'sortorder', 161 rand(1, 100), 162 ], 163 'config' => [ 164 'config', 165 ['key', 'value'], 166 ], 167 ]; 168 } 169 170 /** 171 * Test that getters return the configured value. 172 * 173 * @dataProvider getter_provider 174 * @param string $key The name of the key being tested 175 * @param mixed $value The value being set 176 */ 177 public function test_getters($key, $value) { 178 $tour = new \tool_usertours\tour(); 179 180 $rc = new \ReflectionClass(tour::class); 181 182 $rcp = $rc->getProperty($key); 183 $rcp->setAccessible(true); 184 $rcp->setValue($tour, $value); 185 186 $getter = 'get_' . $key; 187 188 $this->assertEquals($value, $tour->$getter()); 189 } 190 191 /** 192 * Ensure that non-dirty tours are not persisted. 193 */ 194 public function test_persist_non_dirty() { 195 $tour = $this->getMockBuilder(tour::class) 196 ->setMethods(['to_record']) 197 ->getMock() 198 ; 199 200 $tour->expects($this->never()) 201 ->method('to_record') 202 ; 203 204 $this->assertSame($tour, $tour->persist()); 205 } 206 207 /** 208 * Ensure that new dirty tours are persisted. 209 */ 210 public function test_persist_dirty_new() { 211 // Mock the database. 212 $DB = $this->mock_database(); 213 214 $DB->expects($this->never()) 215 ->method('update_record') 216 ; 217 218 $id = rand(1, 100); 219 $DB->expects($this->once()) 220 ->method('insert_record') 221 ->willReturn($id) 222 ; 223 224 // Mock the tour. 225 $tour = $this->getMockBuilder(tour::class) 226 ->setMethods([ 227 'to_record', 228 'reload', 229 ]) 230 ->getMock() 231 ; 232 233 $tour->expects($this->once()) 234 ->method('to_record') 235 ; 236 237 $tour->expects($this->once()) 238 ->method('reload') 239 ; 240 241 $rc = new \ReflectionClass(tour::class); 242 243 $rcp = $rc->getProperty('dirty'); 244 $rcp->setAccessible(true); 245 $rcp->setValue($tour, true); 246 247 $this->assertSame($tour, $tour->persist()); 248 249 $rcp = $rc->getProperty('id'); 250 $rcp->setAccessible(true); 251 $this->assertEquals($id, $rcp->getValue($tour)); 252 } 253 254 /** 255 * Ensure that non-dirty, forced tours are persisted. 256 */ 257 public function test_persist_force_new() { 258 global $DB; 259 260 // Mock the database. 261 $DB = $this->mock_database(); 262 263 $DB->expects($this->never()) 264 ->method('update_record') 265 ; 266 267 $id = rand(1, 100); 268 $DB->expects($this->once()) 269 ->method('insert_record') 270 ->willReturn($id) 271 ; 272 273 // Mock the tour. 274 $tour = $this->getMockBuilder(tour::class) 275 ->setMethods([ 276 'to_record', 277 'reload', 278 ]) 279 ->getMock() 280 ; 281 282 $tour->expects($this->once()) 283 ->method('to_record') 284 ; 285 286 $tour->expects($this->once()) 287 ->method('reload') 288 ; 289 290 $this->assertSame($tour, $tour->persist(true)); 291 292 $rc = new \ReflectionClass(tour::class); 293 $rcp = $rc->getProperty('id'); 294 $rcp->setAccessible(true); 295 $this->assertEquals($id, $rcp->getValue($tour)); 296 } 297 298 /** 299 * Ensure that dirty tours are persisted. 300 */ 301 public function test_persist_dirty_existing() { 302 // Mock the database. 303 $DB = $this->mock_database(); 304 $DB->expects($this->once()) 305 ->method('update_record') 306 ->willReturn($this->returnSelf()) 307 ; 308 309 $DB->expects($this->never()) 310 ->method('insert_record') 311 ; 312 313 // Mock the tour. 314 $tour = $this->getMockBuilder(tour::class) 315 ->setMethods([ 316 'to_record', 317 'reload', 318 ]) 319 ->getMock() 320 ; 321 322 $tour->expects($this->once()) 323 ->method('to_record') 324 ; 325 326 $tour->expects($this->once()) 327 ->method('reload') 328 ; 329 330 $rc = new \ReflectionClass(tour::class); 331 332 $rcp = $rc->getProperty('id'); 333 $rcp->setAccessible(true); 334 $rcp->setValue($tour, 42); 335 336 $rcp = $rc->getProperty('dirty'); 337 $rcp->setAccessible(true); 338 $rcp->setValue($tour, true); 339 340 $this->assertSame($tour, $tour->persist()); 341 } 342 343 /** 344 * Ensure that non-dirty, forced tours are persisted. 345 */ 346 public function test_persist_force() { 347 global $DB; 348 349 // Mock the database. 350 $DB = $this->mock_database(); 351 352 $DB->expects($this->once()) 353 ->method('update_record') 354 ->willReturn($this->returnSelf()) 355 ; 356 357 $DB->expects($this->never()) 358 ->method('insert_record') 359 ; 360 361 // Mock the tour. 362 $tour = $this->getMockBuilder(tour::class) 363 ->setMethods([ 364 'to_record', 365 'reload', 366 ]) 367 ->getMock() 368 ; 369 370 $tour->expects($this->once()) 371 ->method('to_record') 372 ; 373 374 $tour->expects($this->once()) 375 ->method('reload') 376 ; 377 378 $rc = new \ReflectionClass(tour::class); 379 380 $rcp = $rc->getProperty('id'); 381 $rcp->setAccessible(true); 382 $rcp->setValue($tour, 42); 383 384 $rcp = $rc->getProperty('dirty'); 385 $rcp->setAccessible(true); 386 $rcp->setValue($tour, true); 387 388 $this->assertSame($tour, $tour->persist(true)); 389 } 390 391 /** 392 * Test setting config. 393 */ 394 public function test_set_config() { 395 $tour = new \tool_usertours\tour(); 396 397 $tour->set_config('key', 'value'); 398 $tour->set_config('another', [ 399 'foo' => 'bar', 400 ]); 401 402 $rc = new \ReflectionClass(tour::class); 403 $rcp = $rc->getProperty('config'); 404 $rcp->setAccessible(true); 405 $this->assertEquals((object) [ 406 'key' => 'value', 407 'another' => [ 408 'foo' => 'bar', 409 ], 410 ], $rcp->getValue($tour)); 411 } 412 413 /** 414 * Test get_config with no keys provided. 415 */ 416 public function test_get_config_no_keys() { 417 $tour = new \tool_usertours\tour(); 418 419 $rc = new \ReflectionClass(tour::class); 420 $rcp = $rc->getProperty('config'); 421 $rcp->setAccessible(true); 422 423 $allvalues = (object) [ 424 'some' => 'value', 425 'another' => 42, 426 'key' => [ 427 'somethingelse', 428 ], 429 ]; 430 431 $rcp->setValue($tour, $allvalues); 432 433 $this->assertEquals($allvalues, $tour->get_config()); 434 } 435 436 /** 437 * Data provider for get_config. 438 * 439 * @return array 440 */ 441 public function get_config_provider() { 442 $allvalues = (object) [ 443 'some' => 'value', 444 'another' => 42, 445 'key' => [ 446 'somethingelse', 447 ], 448 ]; 449 450 return [ 451 'No nitial config' => [ 452 null, 453 null, 454 null, 455 (object) [], 456 ], 457 'All values' => [ 458 $allvalues, 459 null, 460 null, 461 $allvalues, 462 ], 463 'Valid string value' => [ 464 $allvalues, 465 'some', 466 null, 467 'value', 468 ], 469 'Valid array value' => [ 470 $allvalues, 471 'key', 472 null, 473 ['somethingelse'], 474 ], 475 'Invalid value' => [ 476 $allvalues, 477 'notavalue', 478 null, 479 null, 480 ], 481 'Configuration value' => [ 482 $allvalues, 483 'placement', 484 null, 485 \tool_usertours\configuration::get_default_value('placement'), 486 ], 487 'Invalid value with default' => [ 488 $allvalues, 489 'notavalue', 490 'somedefault', 491 'somedefault', 492 ], 493 ]; 494 } 495 496 /** 497 * Test get_config with valid keys provided. 498 * 499 * @dataProvider get_config_provider 500 * @param object $values The config values 501 * @param string $key The key 502 * @param mixed $default The default value 503 * @param mixed $expected The expected value 504 */ 505 public function test_get_config_valid_keys($values, $key, $default, $expected) { 506 $tour = new \tool_usertours\tour(); 507 508 $rc = new \ReflectionClass(tour::class); 509 $rcp = $rc->getProperty('config'); 510 $rcp->setAccessible(true); 511 $rcp->setValue($tour, $values); 512 513 $this->assertEquals($expected, $tour->get_config($key, $default)); 514 } 515 516 /** 517 * Check that a tour which has never been persisted is removed correctly. 518 */ 519 public function test_remove_non_persisted() { 520 $tour = $this->getMockBuilder(tour::class) 521 ->setMethods([ 522 'get_steps', 523 ]) 524 ->getMock() 525 ; 526 527 $tour->expects($this->never()) 528 ->method('get_steps') 529 ; 530 531 // Mock the database. 532 $DB = $this->mock_database(); 533 $DB->expects($this->never()) 534 ->method('delete_records') 535 ; 536 537 $this->assertNull($tour->remove()); 538 } 539 540 /** 541 * Check that a tour which has been persisted is removed correctly. 542 */ 543 public function test_remove_persisted() { 544 $id = rand(1, 100); 545 546 $tour = $this->getMockBuilder(tour::class) 547 ->setMethods([ 548 'get_steps', 549 ]) 550 ->getMock() 551 ; 552 553 $rc = new \ReflectionClass(tour::class); 554 $rcp = $rc->getProperty('id'); 555 $rcp->setAccessible(true); 556 $rcp->setValue($tour, $id); 557 558 $step = $this->getMockBuilder(\tool_usertours\step::class) 559 ->setMethods([ 560 'remove', 561 ]) 562 ->getMock() 563 ; 564 565 $tour->expects($this->once()) 566 ->method('get_steps') 567 ->willReturn([$step]) 568 ; 569 570 // Mock the database. 571 $DB = $this->mock_database(); 572 573 $DB->expects($this->exactly(3)) 574 ->method('delete_records') 575 ->withConsecutive( 576 [$this->equalTo('tool_usertours_tours'), $this->equalTo(['id' => $id])], 577 [$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_LAST_COMPLETED_BY_USER . $id])], 578 [$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_REQUESTED_BY_USER . $id])] 579 ) 580 ->willReturn(null) 581 ; 582 583 $DB->expects($this->once()) 584 ->method('get_records') 585 ->with($this->equalTo('tool_usertours_tours'), $this->equalTo(null)) 586 ->willReturn([]) 587 ; 588 589 $this->assertNull($tour->remove()); 590 } 591 592 /** 593 * Teset that sortorder is reset according to sortorder with values from 0. 594 */ 595 public function test_reset_step_sortorder() { 596 $tour = new \tool_usertours\tour(); 597 598 $mockdata = []; 599 for ($i = 4; $i >= 0; $i--) { 600 $id = rand($i * 10, ($i * 10) + 9); 601 $mockdata[] = (object) ['id' => $id]; 602 $expectations[] = [$this->equalTo('tool_usertours_steps'), $this->equalTo('sortorder'), 4 - $i, ['id' => $id]]; 603 } 604 605 // Mock the database. 606 $DB = $this->mock_database(); 607 $DB->expects($this->once()) 608 ->method('get_records') 609 ->willReturn($mockdata) 610 ; 611 612 $setfield = $DB->expects($this->exactly(5)) 613 ->method('set_field') 614 ; 615 call_user_func_array([$setfield, 'withConsecutive'], $expectations); 616 617 $tour->reset_step_sortorder(); 618 } 619 620 /** 621 * Test that a disabled tour should never be shown to users. 622 */ 623 public function test_should_show_for_user_disabled() { 624 $tour = new \tool_usertours\tour(); 625 $tour->set_enabled(false); 626 627 $this->assertFalse($tour->should_show_for_user()); 628 } 629 630 /** 631 * Provider for should_show_for_user. 632 * 633 * @return array 634 */ 635 public function should_show_for_user_provider() { 636 $time = time(); 637 return [ 638 'Not seen by user at all' => [ 639 null, 640 null, 641 null, 642 true, 643 ], 644 'Completed by user before majorupdatetime' => [ 645 $time - DAYSECS, 646 null, 647 $time, 648 true, 649 ], 650 'Completed by user since majorupdatetime' => [ 651 $time, 652 null, 653 $time - DAYSECS, 654 false, 655 ], 656 'Requested by user before current completion' => [ 657 $time, 658 $time - DAYSECS, 659 null, 660 false, 661 ], 662 'Requested by user since completion' => [ 663 $time - DAYSECS, 664 $time, 665 null, 666 true, 667 ], 668 ]; 669 } 670 671 /** 672 * Test that a disabled tour should never be shown to users. 673 * 674 * @dataProvider should_show_for_user_provider 675 * @param mixed $completiondate The user's completion date for this tour 676 * @param mixed $requesteddate The user's last requested date for this tour 677 * @param mixed $updateddate The date this tour was last updated 678 * @param string $expectation The expected tour key 679 */ 680 public function test_should_show_for_user($completiondate, $requesteddate, $updateddate, $expectation) { 681 // Uses user preferences so we must be in a user context. 682 $this->resetAfterTest(); 683 $this->setAdminUser(); 684 685 $tour = $this->getMockBuilder(tour::class) 686 ->setMethods([ 687 'get_id', 688 'get_config', 689 'is_enabled', 690 ]) 691 ->getMock() 692 ; 693 694 $tour->method('is_enabled') 695 ->willReturn(true) 696 ; 697 698 $id = rand(1, 100); 699 $tour->method('get_id') 700 ->willReturn($id) 701 ; 702 703 if ($completiondate !== null) { 704 set_user_preference(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER . $id, $completiondate); 705 } 706 707 if ($requesteddate !== null) { 708 set_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id, $requesteddate); 709 } 710 711 if ($updateddate !== null) { 712 $tour->expects($this->once()) 713 ->method('get_config') 714 ->willReturn($updateddate) 715 ; 716 } 717 718 $this->assertEquals($expectation, $tour->should_show_for_user()); 719 } 720 721 /** 722 * Provider for get_tour_key. 723 * 724 * @return array 725 */ 726 public function get_tour_key_provider() { 727 $id = rand(1, 100); 728 $time = time(); 729 730 return [ 731 'No initial values' => [ 732 $id, 733 [null, $time], 734 $this->greaterThanOrEqual($time), 735 true, 736 null, 737 sprintf('tool_usertours_\d_%d_%s', $id, $time), 738 ], 739 740 'Initial tour time, no user pref' => [ 741 $id, 742 [$time], 743 null, 744 false, 745 null, 746 sprintf('tool_usertours_\d_%d_%s', $id, $time), 747 ], 748 'Initial tour time, with user reset lower' => [ 749 $id, 750 [$time], 751 null, 752 false, 753 $time - DAYSECS, 754 sprintf('tool_usertours_\d_%d_%s', $id, $time), 755 ], 756 'Initial tour time, with user reset higher' => [ 757 $id, 758 [$time], 759 null, 760 false, 761 $time + DAYSECS, 762 sprintf('tool_usertours_\d_%d_%s', $id, $time + DAYSECS), 763 ], 764 ]; 765 } 766 767 /** 768 * Test that get_tour_key provides the anticipated unique keys. 769 * 770 * @dataProvider get_tour_key_provider 771 * @param int $id The tour ID 772 * @param array $getconfig The mocked values for get_config calls 773 * @param array $setconfig The mocked values for set_config calls 774 * @param bool $willpersist Whether a persist is expected 775 * @param mixed $userpref The value to set for the user preference 776 * @param string $expectation The expected tour key 777 */ 778 public function test_get_tour_key($id, $getconfig, $setconfig, $willpersist, $userpref, $expectation) { 779 // Uses user preferences so we must be in a user context. 780 $this->resetAfterTest(); 781 $this->setAdminUser(); 782 783 $tour = $this->getMockBuilder(tour::class) 784 ->setMethods([ 785 'get_config', 786 'set_config', 787 'get_id', 788 'persist', 789 ]) 790 ->getMock() 791 ; 792 793 if ($getconfig) { 794 $tour->expects($this->exactly(count($getconfig))) 795 ->method('get_config') 796 ->will(call_user_func_array([$this, 'onConsecutiveCalls'], $getconfig)) 797 ; 798 } 799 800 if ($setconfig) { 801 $tour->expects($this->once()) 802 ->method('set_config') 803 ->with($this->equalTo('majorupdatetime'), $setconfig) 804 ->will($this->returnSelf()) 805 ; 806 } else { 807 $tour->expects($this->never()) 808 ->method('set_config') 809 ; 810 } 811 812 if ($willpersist) { 813 $tour->expects($this->once()) 814 ->method('persist') 815 ; 816 } else { 817 $tour->expects($this->never()) 818 ->method('persist') 819 ; 820 } 821 822 $tour->expects($this->any()) 823 ->method('get_id') 824 ->willReturn($id) 825 ; 826 827 if ($userpref !== null) { 828 set_user_preference(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id, $userpref); 829 } 830 831 $this->assertRegExp( 832 '/' . $expectation . '/', 833 $tour->get_tour_key() 834 ); 835 } 836 837 /** 838 * Ensure that the request_user_reset function sets an appropriate value for the tour. 839 */ 840 public function test_requested_user_reset() { 841 $tour = $this->getMockBuilder(tour::class) 842 ->setMethods([ 843 'get_id', 844 ]) 845 ->getMock() 846 ; 847 848 $id = rand(1, 100); 849 $time = time(); 850 851 $tour->expects($this->once()) 852 ->method('get_id') 853 ->willReturn($id) 854 ; 855 856 $tour->request_user_reset(); 857 858 $this->assertGreaterThanOrEqual($time, get_user_preferences(\tool_usertours\tour::TOUR_REQUESTED_BY_USER . $id)); 859 } 860 861 /** 862 * Ensure that the request_user_reset function sets an appropriate value for the tour. 863 */ 864 public function test_mark_user_completed() { 865 $tour = $this->getMockBuilder(tour::class) 866 ->setMethods([ 867 'get_id', 868 ]) 869 ->getMock() 870 ; 871 872 $id = rand(1, 100); 873 $time = time(); 874 875 $tour->expects($this->once()) 876 ->method('get_id') 877 ->willReturn($id) 878 ; 879 880 $tour->mark_user_completed(); 881 882 $this->assertGreaterThanOrEqual($time, get_user_preferences(\tool_usertours\tour::TOUR_LAST_COMPLETED_BY_USER . $id)); 883 } 884 885 /** 886 * Provider for the is_first_tour and is_last_tour tests. 887 * 888 * @return array 889 */ 890 public function sortorder_first_last_provider() { 891 $topcount = rand(10, 100); 892 return [ 893 'Only tour => first + last' => [ 894 0, 895 true, 896 1, 897 true, 898 ], 899 'First tour of many' => [ 900 0, 901 true, 902 $topcount, 903 false, 904 ], 905 'Last tour of many' => [ 906 $topcount - 1, 907 false, 908 $topcount, 909 true, 910 ], 911 'Middle tour of many' => [ 912 5, 913 false, 914 $topcount, 915 false, 916 ], 917 ]; 918 } 919 920 /** 921 * Test the is_first_tour() function. 922 * 923 * @dataProvider sortorder_first_last_provider 924 * @param int $sortorder The new sort order 925 * @param bool $isfirst Whether this is the first tour 926 * @param int $total The number of tours 927 * @param bool $islast Whether this is the last tour 928 */ 929 public function test_is_first_tour($sortorder, $isfirst, $total, $islast) { 930 $tour = new \tool_usertours\tour(); 931 932 $rc = new \ReflectionClass(tour::class); 933 $rcp = $rc->getProperty('sortorder'); 934 $rcp->setAccessible(true); 935 $rcp->setValue($tour, $sortorder); 936 937 $this->assertEquals($isfirst, $tour->is_first_tour()); 938 } 939 940 /** 941 * Test the is_last_tour() function. 942 * 943 * @dataProvider sortorder_first_last_provider 944 * @param int $sortorder The new sort order 945 * @param bool $isfirst Whether this is the first tour 946 * @param int $total The number of tours 947 * @param bool $islast Whether this is the last tour 948 */ 949 public function test_is_last_tour_calculated($sortorder, $isfirst, $total, $islast) { 950 $tour = new \tool_usertours\tour(); 951 952 $rc = new \ReflectionClass(tour::class); 953 $rcp = $rc->getProperty('sortorder'); 954 $rcp->setAccessible(true); 955 $rcp->setValue($tour, $sortorder); 956 957 // The total will be calculated. 958 $DB = $this->mock_database(); 959 $DB->expects($this->once()) 960 ->method('count_records') 961 ->willReturn($total) 962 ; 963 $this->assertEquals($islast, $tour->is_last_tour()); 964 } 965 966 /** 967 * Test the is_last_tour() function. 968 * 969 * @dataProvider sortorder_first_last_provider 970 * @param int $sortorder The new sort order 971 * @param bool $isfirst Whether this is the first tour 972 * @param int $total The number of tours 973 * @param bool $islast Whether this is the last tour 974 */ 975 public function test_is_last_tour_provided($sortorder, $isfirst, $total, $islast) { 976 $tour = new \tool_usertours\tour(); 977 978 $rc = new \ReflectionClass(tour::class); 979 $rcp = $rc->getProperty('sortorder'); 980 $rcp->setAccessible(true); 981 $rcp->setValue($tour, $sortorder); 982 983 // The total is provided. 984 // No DB calls expected. 985 $DB = $this->mock_database(); 986 $DB->expects($this->never()) 987 ->method('count_records') 988 ->willReturn(0) 989 ; 990 $this->assertEquals($islast, $tour->is_last_tour($total)); 991 } 992 993 /** 994 * Data provider for the get_filter_values tests. 995 * 996 * @return array 997 */ 998 public function get_filter_values_provider() { 999 $cheese = ['cheddar', 'boursin', 'mozzarella']; 1000 $horses = ['coolie', 'dakota', 'leo', 'twiggy']; 1001 return [ 1002 'No config' => [ 1003 [], 1004 'cheese', 1005 [], 1006 ], 1007 'Some config for another filter' => [ 1008 [ 1009 'horses' => $horses, 1010 ], 1011 'cheese', 1012 [], 1013 ], 1014 'Some config for this filter' => [ 1015 [ 1016 'horses' => $horses, 1017 ], 1018 'horses', 1019 $horses, 1020 ], 1021 'Some config for several filters' => [ 1022 [ 1023 'horses' => $horses, 1024 'cheese' => $cheese 1025 ], 1026 'horses', 1027 $horses, 1028 ], 1029 ]; 1030 } 1031 1032 /** 1033 * Tests for the get_filter_values function. 1034 * 1035 * @dataProvider get_filter_values_provider 1036 * @param array $fullconfig The config value being tested 1037 * @param string $filtername The name of the filter being tested 1038 * @param array $expectedvalues The expected result 1039 */ 1040 public function test_get_filter_values($fullconfig, $filtername, $expectedvalues) { 1041 $tour = $this->getMockBuilder(tour::class) 1042 ->setMethods(['get_config']) 1043 ->getMock(); 1044 1045 $tour->expects($this->once()) 1046 ->method('get_config') 1047 ->will($this->returnValue($fullconfig)); 1048 1049 $this->assertEquals($expectedvalues, $tour->get_filter_values($filtername)); 1050 } 1051 1052 /** 1053 * Data provider for set_filter_values tests. 1054 * 1055 * @return array 1056 */ 1057 public function set_filter_values_provider() { 1058 $cheese = ['cheddar', 'boursin', 'mozzarella']; 1059 $horses = ['coolie', 'dakota', 'leo', 'twiggy']; 1060 1061 return [ 1062 'No initial value' => [ 1063 [], 1064 'cheese', 1065 $cheese, 1066 ['cheese' => $cheese], 1067 ], 1068 'Existing filter merged' => [ 1069 ['horses' => $horses], 1070 'cheese', 1071 $cheese, 1072 ['horses' => $horses, 'cheese' => $cheese], 1073 ], 1074 'Existing filter updated' => [ 1075 ['cheese' => $cheese], 1076 'cheese', 1077 ['cheddar'], 1078 ['cheese' => ['cheddar']], 1079 ], 1080 'Existing filter updated with merge' => [ 1081 ['horses' => $horses, 'cheese' => $cheese], 1082 'cheese', 1083 ['cheddar'], 1084 ['horses' => $horses, 'cheese' => ['cheddar']], 1085 ], 1086 ]; 1087 } 1088 1089 /** 1090 * Base tests for set_filter_values. 1091 * 1092 * @dataProvider set_filter_values_provider 1093 * @param array $currentvalues The current value 1094 * @param string $filtername The name of the filter to add to 1095 * @param array $newvalues The new values to store 1096 * @param array $expectedvalues The combined values 1097 */ 1098 public function test_set_filter_values_merge($currentvalues, $filtername, $newvalues, $expectedvalues) { 1099 $tour = $this->getMockBuilder(tour::class) 1100 ->setMethods(['get_config', 'set_config']) 1101 ->getMock(); 1102 1103 $tour->expects($this->once()) 1104 ->method('get_config') 1105 ->will($this->returnValue($currentvalues)); 1106 1107 $tour->expects($this->once()) 1108 ->method('set_config') 1109 ->with( 1110 $this->equalTo('filtervalues'), 1111 $this->equalTo($expectedvalues) 1112 ); 1113 1114 $tour->set_filter_values($filtername, $newvalues); 1115 } 1116 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body