Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 38 and 311] [Versions 39 and 311]

   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_calendar;
  18  
  19  defined('MOODLE_INTERNAL') || die();
  20  
  21  require_once (__DIR__ . '/helpers.php');
  22  
  23  /**
  24   * Unit tests for calendar_information.
  25   *
  26   * @package    core_calendar
  27   * @copyright  2017 Andrew Nicols <andrew@nicols.co.uk>
  28   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29   */
  30  class calendar_information_test extends \advanced_testcase {
  31  
  32      /**
  33       * Helper to mock a course and category structure.
  34       *
  35       * @return array
  36       */
  37      protected function mock_structure() {
  38          $this->resetAfterTest();
  39  
  40          $generator = $this->getDataGenerator();
  41  
  42          $categories = [];
  43          $courses = [];
  44  
  45          $categories['A'] = $generator->create_category(['name' => 'A']);
  46          $courses['A.1'] = $generator->create_course(['category' => $categories['A']->id]);
  47          $courses['A.2'] = $generator->create_course(['category' => $categories['A']->id]);
  48          $categories['A1'] = $generator->create_category(['name' => 'A1', 'parent' => $categories['A']->id]);
  49          $courses['A1.1'] = $generator->create_course(['category' => $categories['A1']->id]);
  50          $courses['A1.2'] = $generator->create_course(['category' => $categories['A1']->id]);
  51          $categories['A1i'] = $generator->create_category(['name' => 'A1i', 'parent' => $categories['A1']->id]);
  52          $categories['A1ii'] = $generator->create_category(['name' => 'A1ii', 'parent' => $categories['A1']->id]);
  53          $categories['A2'] = $generator->create_category(['name' => 'A2', 'parent' => $categories['A']->id]);
  54          $courses['A2.1'] = $generator->create_course(['category' => $categories['A2']->id]);
  55          $courses['A2.2'] = $generator->create_course(['category' => $categories['A2']->id]);
  56          $categories['A2i'] = $generator->create_category(['name' => 'A2i', 'parent' => $categories['A2']->id]);
  57          $categories['A2ii'] = $generator->create_category(['name' => 'A2ii', 'parent' => $categories['A2']->id]);
  58          $categories['B'] = $generator->create_category(['name' => 'B']);
  59          $courses['B.1'] = $generator->create_course(['category' => $categories['B']->id]);
  60          $courses['B.2'] = $generator->create_course(['category' => $categories['B']->id]);
  61          $categories['B1'] = $generator->create_category(['name' => 'B1', 'parent' => $categories['B']->id]);
  62          $categories['B1i'] = $generator->create_category(['name' => 'B1i', 'parent' => $categories['B1']->id]);
  63          $categories['B1ii'] = $generator->create_category(['name' => 'B1ii', 'parent' => $categories['B1']->id]);
  64          $categories['B2'] = $generator->create_category(['name' => 'B2', 'parent' => $categories['B']->id]);
  65          $categories['B2i'] = $generator->create_category(['name' => 'B2i', 'parent' => $categories['B2']->id]);
  66          $categories['B2ii'] = $generator->create_category(['name' => 'B2ii', 'parent' => $categories['B2']->id]);
  67          $categories['C'] = $generator->create_category(['name' => 'C']);
  68  
  69          return [$courses, $categories];
  70      }
  71  
  72      /**
  73       * Given a user has no enrolments.
  74       * And I ask for the site information.
  75       * Then I should see the site.
  76       * And I should see no other courses.
  77       * And I should see no categories.
  78       */
  79      public function test_site_visibility_no_enrolment() {
  80          $this->resetAfterTest();
  81          list ($courses, $categories) = $this->mock_structure();
  82  
  83          $generator = $this->getDataGenerator();
  84          $user = $generator->create_user();
  85          $this->setUser($user);
  86  
  87          $calendar = \calendar_information::create(time(), SITEID, null);
  88  
  89          $this->assertCount(1, $calendar->courses);
  90          $this->assertCount(0, $calendar->categories);
  91          $this->assertEquals(SITEID, $calendar->courseid);
  92          $this->assertEquals(SITEID, reset($calendar->courses));
  93          $this->assertEquals(\context_system::instance(), $calendar->context);
  94      }
  95  
  96      /**
  97       * Given a user has no enrolments.
  98       * And I ask for a category.
  99       * Then I should see the category.
 100       * And I should see the category parents.
 101       * And I should see the category descendants.
 102       * And I should see the site course.
 103       * And I should see no other courses.
 104       */
 105      public function test_site_visibility_no_enrolment_category() {
 106          $this->resetAfterTest();
 107          list ($courses, $categories) = $this->mock_structure();
 108  
 109          $generator = $this->getDataGenerator();
 110          $user = $generator->create_user();
 111          $this->setUser($user);
 112  
 113          $category = $categories['A1'];
 114          $calendar = \calendar_information::create(time(), SITEID, $category->id);
 115  
 116          $this->assertCount(1, $calendar->courses);
 117          $this->assertCount(4, $calendar->categories);
 118          $this->assertEquals(SITEID, $calendar->courseid);
 119          $this->assertEquals(SITEID, reset($calendar->courses));
 120          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 121          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 122          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 123          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 124          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
 125      }
 126  
 127      /**
 128       * Given a user has a role assignment to manage a category.
 129       * And I ask for the site information.
 130       * Then I should see that category.
 131       * And I should see the category parents.
 132       * And I should see the category descendants.
 133       * And I should see the site course.
 134       * And I should see no other courses.
 135       */
 136      public function test_site_visibility_category_manager_site() {
 137          global $DB;
 138  
 139          $this->resetAfterTest();
 140          list ($courses, $categories) = $this->mock_structure();
 141  
 142          $generator = $this->getDataGenerator();
 143          $user = $generator->create_user();
 144          $category = $categories['A1'];
 145  
 146          $roles = $DB->get_records('role', [], '', 'shortname, id');
 147          $generator->role_assign($roles['manager']->id, $user->id, \context_coursecat::instance($category->id));
 148  
 149          $this->setUser($user);
 150  
 151          $calendar = \calendar_information::create(time(), SITEID, null);
 152  
 153          $this->assertCount(1, $calendar->courses);
 154          $this->assertCount(4, $calendar->categories);
 155          $this->assertEquals(SITEID, $calendar->courseid);
 156          $this->assertEquals(SITEID, reset($calendar->courses));
 157          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 158          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 159          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 160          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 161          $this->assertEquals(\context_system::instance(), $calendar->context);
 162      }
 163  
 164      /**
 165       * Given a user has a role assignment to manage a category.
 166       * And I ask for that category.
 167       * Then I should see that category.
 168       * And I should see the category parents.
 169       * And I should see the category descendants.
 170       * And I should see the site course.
 171       * And I should see no other courses.
 172       */
 173      public function test_site_visibility_category_manager_own_category() {
 174          global $DB;
 175  
 176          $this->resetAfterTest();
 177          list ($courses, $categories) = $this->mock_structure();
 178  
 179          $generator = $this->getDataGenerator();
 180          $user = $generator->create_user();
 181          $category = $categories['A1'];
 182  
 183          $roles = $DB->get_records('role', [], '', 'shortname, id');
 184          $generator->role_assign($roles['manager']->id, $user->id, \context_coursecat::instance($category->id));
 185  
 186          $this->setUser($user);
 187  
 188          $calendar = \calendar_information::create(time(), SITEID, $category->id);
 189  
 190          $this->assertCount(1, $calendar->courses);
 191          $this->assertCount(4, $calendar->categories);
 192          $this->assertEquals(SITEID, $calendar->courseid);
 193          $this->assertEquals(SITEID, reset($calendar->courses));
 194          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 195          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 196          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 197          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 198          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
 199      }
 200  
 201      /**
 202       * Given a user has a role assignment to manage a category.
 203       * And I ask for the parent of that category.
 204       * Then I should see that category.
 205       * And I should see the category parents.
 206       * And I should see the category descendants.
 207       * And I should see the site course.
 208       * And I should see no other courses.
 209       */
 210      public function test_site_visibility_category_manager_parent_category() {
 211          global $DB;
 212  
 213          $this->resetAfterTest();
 214          list ($courses, $categories) = $this->mock_structure();
 215  
 216          $generator = $this->getDataGenerator();
 217          $user = $generator->create_user();
 218          $category = $categories['A1'];
 219  
 220          $roles = $DB->get_records('role', [], '', 'shortname, id');
 221          $generator->role_assign($roles['manager']->id, $user->id, \context_coursecat::instance($category->id));
 222  
 223          $this->setUser($user);
 224  
 225          $calendar = \calendar_information::create(time(), SITEID, $category->parent);
 226  
 227          $this->assertCount(1, $calendar->courses);
 228          $this->assertCount(7, $calendar->categories);
 229          $this->assertEquals(SITEID, $calendar->courseid);
 230          $this->assertEquals(SITEID, reset($calendar->courses));
 231          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 232          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 233          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 234          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 235          $this->assertEquals(\context_coursecat::instance($category->parent), $calendar->context);
 236      }
 237  
 238      /**
 239       * Given a user has a role assignment to manage a category.
 240       * And I ask for a child of that category.
 241       * Then I should see that category.
 242       * And I should see the category parents.
 243       * And I should see the category descendants.
 244       * And I should see the site course.
 245       * And I should see no other courses.
 246       */
 247      public function test_site_visibility_category_manager_child_category() {
 248          global $DB;
 249  
 250          $this->resetAfterTest();
 251          list ($courses, $categories) = $this->mock_structure();
 252  
 253          $generator = $this->getDataGenerator();
 254          $user = $generator->create_user();
 255          $enrolledcategory = $categories['A1'];
 256          $category = $categories['A1i'];
 257  
 258          $roles = $DB->get_records('role', [], '', 'shortname, id');
 259          $generator->role_assign($roles['manager']->id, $user->id, \context_coursecat::instance($enrolledcategory->id));
 260  
 261          $this->setUser($user);
 262  
 263          $calendar = \calendar_information::create(time(), SITEID, $category->id);
 264  
 265          $this->assertCount(1, $calendar->courses);
 266          $this->assertCount(3, $calendar->categories);
 267          $this->assertEquals(SITEID, $calendar->courseid);
 268          $this->assertEquals(SITEID, reset($calendar->courses));
 269          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 270          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 271          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 272          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
 273      }
 274  
 275      /**
 276       * Given a user has an enrolment in a single course.
 277       * And I ask for the site information.
 278       * Then I should see the site.
 279       * And I should see the course I am enrolled in.
 280       * And I should see the category that my enrolled course is in.
 281       * And I should see the parents of the category that my enrolled course is in.
 282       */
 283      public function test_site_visibility_single_course_site() {
 284          $this->resetAfterTest();
 285          list ($courses, $categories) = $this->mock_structure();
 286  
 287          $generator = $this->getDataGenerator();
 288          $user = $generator->create_user();
 289          $course = $courses['A1.1'];
 290          $category = \core_course_category::get($course->category);
 291          $wrongcategory = $categories['B1'];
 292          $generator->enrol_user($user->id, $course->id);
 293  
 294          $this->setUser($user);
 295  
 296          // Viewing the site as a whole.
 297          // Should see all courses that this user is enrolled in, and their
 298          // categories, and those categories parents.
 299          $calendar = \calendar_information::create(time(), SITEID, null);
 300  
 301          $this->assertCount(2, $calendar->courses);
 302          $this->assertCount(2, $calendar->categories);
 303          $this->assertEquals(SITEID, $calendar->courseid);
 304          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
 305          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 306          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 307          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 308          $this->assertEquals(\context_system::instance(), $calendar->context);
 309      }
 310  
 311      /**
 312       * Given a user has an enrolment in a single course.
 313       * And I ask for the course information.
 314       * Then I should see the site.
 315       * And I should see that course.
 316       * And I should see the category of that course.
 317       * And I should see the parents of that course category.
 318       */
 319      public function test_site_visibility_single_course_course_course() {
 320          $this->resetAfterTest();
 321          list ($courses, $categories) = $this->mock_structure();
 322  
 323          $generator = $this->getDataGenerator();
 324          $user = $generator->create_user();
 325          $course = $courses['A1.1'];
 326          $category = \core_course_category::get($course->category);
 327          $wrongcategory = $categories['B1'];
 328          $generator->enrol_user($user->id, $course->id);
 329  
 330          $this->setUser($user);
 331          $time = time();
 332  
 333          // Viewing the course calendar.
 334          // Should see just this course, and all parent categories.
 335          $calendar = \calendar_information::create($time, $course->id, null);
 336  
 337          $this->assertCount(2, $calendar->courses);
 338          $this->assertCount(2, $calendar->categories);
 339          $this->assertEquals($course->id, $calendar->courseid);
 340          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
 341          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 342          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 343          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 344          $this->assertEquals(\context_course::instance($course->id), $calendar->context);
 345  
 346          // Viewing the course calendar while specifying the category too.
 347          // The category is essentially ignored. No change expected.
 348          $calendarwithcategory = \calendar_information::create($time, $course->id, $category->id);
 349          $this->assertEquals($calendar, $calendarwithcategory);
 350  
 351          // Viewing the course calendar while specifying the wrong category.
 352          // The category is essentially ignored. No change expected.
 353          $calendarwithwrongcategory = \calendar_information::create($time, $course->id, $wrongcategory->id);
 354          $this->assertEquals($calendar, $calendarwithwrongcategory);
 355      }
 356  
 357      /**
 358       * Given a user has an enrolment in a single course.
 359       * And I ask for the category information for the category my course is in.
 360       * Then I should see that category.
 361       * And I should see the category parents.
 362       * And I should see the category descendants.
 363       * And I should see the site.
 364       * And I should see my course.
 365       * And I should see no other courses.
 366       * And I should see no categories.
 367       */
 368      public function test_site_visibility_single_course_category() {
 369          $this->resetAfterTest();
 370          list ($courses, $categories) = $this->mock_structure();
 371  
 372          $generator = $this->getDataGenerator();
 373          $user = $generator->create_user();
 374          $course = $courses['A1.1'];
 375          $category = \core_course_category::get($course->category);
 376          $generator->enrol_user($user->id, $course->id);
 377  
 378          $this->setUser($user);
 379  
 380          // Viewing the category calendar.
 381          // Should see all courses that this user is enrolled in within this
 382          // category, plus the site course, plus the category that course is
 383          // in and it's parents, and it's children.
 384          $calendar = \calendar_information::create(time(), SITEID, $category->id);
 385  
 386          $this->assertCount(2, $calendar->courses);
 387          $this->assertCount(4, $calendar->categories);
 388          $this->assertEquals(SITEID, $calendar->courseid);
 389          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
 390          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 391          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 392          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 393          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 394          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 395          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
 396      }
 397  
 398      /**
 399       * Given a user has an enrolment in a single course.
 400       * And I ask for the category information for the parent of the category my course is in.
 401       * Then I should see that category.
 402       * And I should see the category parents.
 403       * And I should see the category descendants.
 404       * And I should see the site.
 405       * And I should see my course.
 406       * And I should see no other courses.
 407       * And I should see no categories.
 408       */
 409      public function test_site_visibility_single_course_parent_category() {
 410          $this->resetAfterTest();
 411          list ($courses, $categories) = $this->mock_structure();
 412  
 413          $generator = $this->getDataGenerator();
 414          $user = $generator->create_user();
 415          $course = $courses['A1.1'];
 416          $category = \core_course_category::get($course->category);
 417          $generator->enrol_user($user->id, $course->id);
 418  
 419          $this->setUser($user);
 420  
 421          // Viewing the category calendar.
 422          // Should see all courses that this user is enrolled in within this
 423          // category, plus the site course, plus the category that course is
 424          // in and it's parents, and it's children.
 425          $calendar = \calendar_information::create(time(), SITEID, $category->parent);
 426  
 427          $this->assertCount(2, $calendar->courses);
 428          $this->assertCount(7, $calendar->categories);
 429          $this->assertEquals(SITEID, $calendar->courseid);
 430          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
 431          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 432          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 433          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 434          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 435          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 436          $this->assertArrayHasKey($categories['A2']->id, array_flip($calendar->categories));
 437          $this->assertArrayHasKey($categories['A2i']->id, array_flip($calendar->categories));
 438          $this->assertArrayHasKey($categories['A2ii']->id, array_flip($calendar->categories));
 439          $this->assertEquals(\context_coursecat::instance($category->parent), $calendar->context);
 440      }
 441  
 442      /**
 443       * Given a user has an enrolment in a single course.
 444       * And I ask for the category information for the sibling of the category my course is in.
 445       * Then I should see that category.
 446       * And I should see the category parents.
 447       * And I should see the category descendants.
 448       * And I should see the site.
 449       * And I should see my course.
 450       * And I should see no other courses.
 451       * And I should see no categories.
 452       */
 453      public function test_site_visibility_single_course_sibling_category() {
 454          $this->resetAfterTest();
 455          list ($courses, $categories) = $this->mock_structure();
 456  
 457          $generator = $this->getDataGenerator();
 458          $user = $generator->create_user();
 459          $course = $courses['A1.1'];
 460          $category = $categories['A2'];
 461          $generator->enrol_user($user->id, $course->id);
 462  
 463          $this->setUser($user);
 464  
 465          // Viewing the category calendar.
 466          // Should see all courses that this user is enrolled in within this
 467          // category, plus the site course, plus the category that course is
 468          // in and it's parents, and it's children.
 469          $calendar = \calendar_information::create(time(), SITEID, $category->id);
 470  
 471          $this->assertCount(1, $calendar->courses);
 472          $this->assertCount(4, $calendar->categories);
 473          $this->assertEquals(SITEID, $calendar->courseid);
 474          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 475          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 476          $this->assertArrayHasKey($categories['A2']->id, array_flip($calendar->categories));
 477          $this->assertArrayHasKey($categories['A2i']->id, array_flip($calendar->categories));
 478          $this->assertArrayHasKey($categories['A2ii']->id, array_flip($calendar->categories));
 479          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
 480      }
 481  
 482      /**
 483       * Given a user has an enrolment in a single course.
 484       * And I ask for the category information for a different category to the one my course is in.
 485       * Then I should see that category.
 486       * And I should see the category parents.
 487       * And I should see the category descendants.
 488       * And I should see the site.
 489       * And I should see not see my course.
 490       * And I should see no other courses.
 491       * And I should see no categories.
 492       */
 493      public function test_site_visibility_single_course_different_category() {
 494          $this->resetAfterTest();
 495          list ($courses, $categories) = $this->mock_structure();
 496  
 497          $generator = $this->getDataGenerator();
 498          $user = $generator->create_user();
 499          $course = $courses['A1.1'];
 500          $category = \core_course_category::get($course->category);
 501          $wrongcategory = $categories['B1'];
 502          $generator->enrol_user($user->id, $course->id);
 503  
 504          $this->setUser($user);
 505  
 506          // Viewing the category calendar for a category the user doesn't have any enrolments in.
 507          // Should see that category, and all categories underneath it.
 508          $calendar = \calendar_information::create(time(), SITEID, $wrongcategory->id);
 509  
 510          $this->assertCount(1, $calendar->courses);
 511          $this->assertCount(4, $calendar->categories);
 512          $this->assertEquals(SITEID, $calendar->courseid);
 513          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 514          $this->assertArrayHasKey($categories['B']->id, array_flip($calendar->categories));
 515          $this->assertArrayHasKey($categories['B1']->id, array_flip($calendar->categories));
 516          $this->assertArrayHasKey($categories['B1i']->id, array_flip($calendar->categories));
 517          $this->assertArrayHasKey($categories['B1ii']->id, array_flip($calendar->categories));
 518          $this->assertEquals(\context_coursecat::instance($wrongcategory->id), $calendar->context);
 519      }
 520  
 521      /**
 522       * Given a user has an enrolment in two courses in the same category.
 523       * And I ask for the site information.
 524       * Then I should see the site.
 525       * And I should see the course I am enrolled in.
 526       * And I should see the category that my enrolled course is in.
 527       * And I should see the parents of the category that my enrolled course is in.
 528       */
 529      public function test_site_visibility_two_courses_one_category_site() {
 530          $this->resetAfterTest();
 531          list ($courses, $categories) = $this->mock_structure();
 532  
 533          $generator = $this->getDataGenerator();
 534          $user = $generator->create_user();
 535          $coursea = $courses['A.1'];
 536          $courseb = $courses['A.2'];
 537          $category = \core_course_category::get($coursea->category);
 538          $wrongcategory = $categories['B1'];
 539          $generator->enrol_user($user->id, $coursea->id);
 540          $generator->enrol_user($user->id, $courseb->id);
 541  
 542          $this->setUser($user);
 543  
 544          // Viewing the site azs a whole.
 545          // Should see all courses that this user is enrolled in.
 546          $calendar = \calendar_information::create(time(), SITEID, null);
 547  
 548          $this->assertCount(3, $calendar->courses);
 549          $this->assertCount(1, $calendar->categories);
 550          $this->assertEquals(SITEID, $calendar->courseid);
 551          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 552          $this->assertArrayHasKey($coursea->id, array_flip($calendar->courses));
 553          $this->assertArrayHasKey($courseb->id, array_flip($calendar->courses));
 554          $this->assertEquals(\context_system::instance(), $calendar->context);
 555      }
 556  
 557      /**
 558       * Given a user has an enrolment in two courses in the same category.
 559       * And I ask for the course information.
 560       * Then I should see the site.
 561       * And I should see that course.
 562       * And I should see the category that my enrolled courses are in.
 563       * And I should see the parents of the category that my enrolled course are in.
 564       */
 565      public function test_site_visibility_two_courses_one_category_course() {
 566          $this->resetAfterTest();
 567          list ($courses, $categories) = $this->mock_structure();
 568  
 569          $generator = $this->getDataGenerator();
 570          $user = $generator->create_user();
 571          $coursea = $courses['A.1'];
 572          $courseb = $courses['A.2'];
 573          $category = \core_course_category::get($coursea->category);
 574          $wrongcategory = $categories['B1'];
 575          $generator->enrol_user($user->id, $coursea->id);
 576          $generator->enrol_user($user->id, $courseb->id);
 577  
 578          $this->setUser($user);
 579          $time = time();
 580  
 581          // Viewing the course calendar.
 582          // Should see all courses that this user is enrolled in.
 583          $calendar = \calendar_information::create($time, $coursea->id, null);
 584  
 585          $this->assertCount(2, $calendar->courses);
 586          $this->assertCount(1, $calendar->categories);
 587          $this->assertEquals($coursea->id, $calendar->courseid);
 588          $this->assertArrayHasKey($coursea->id, array_flip($calendar->courses));
 589          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 590          $this->assertEquals(\context_course::instance($coursea->id), $calendar->context);
 591  
 592          // Viewing the course calendar while specifying the category too.
 593          // The category is essentially ignored. No change expected.
 594          $calendarwithcategory = \calendar_information::create($time, $coursea->id, $category->id);
 595          $this->assertEquals($calendar, $calendarwithcategory);
 596  
 597          // Viewing the course calendar while specifying the wrong category.
 598          // The category is essentially ignored. No change expected.
 599          $calendarwithwrongcategory = \calendar_information::create($time, $coursea->id, $wrongcategory->id);
 600          $this->assertEquals($calendar, $calendarwithwrongcategory);
 601      }
 602  
 603      /**
 604       * Given a user has an enrolment in two courses in the same category.
 605       * And I ask for the course information of the second course.
 606       * Then I should see the site.
 607       * And I should see that course.
 608       * And I should see the category that my enrolled courses are in.
 609       * And I should see the parents of the category that my enrolled course are in.
 610       */
 611      public function test_site_visibility_two_courses_one_category_courseb() {
 612          $this->resetAfterTest();
 613          list ($courses, $categories) = $this->mock_structure();
 614  
 615          $generator = $this->getDataGenerator();
 616          $user = $generator->create_user();
 617          $coursea = $courses['A.1'];
 618          $courseb = $courses['A.2'];
 619          $category = \core_course_category::get($coursea->category);
 620          $wrongcategory = $categories['B1'];
 621          $generator->enrol_user($user->id, $coursea->id);
 622          $generator->enrol_user($user->id, $courseb->id);
 623  
 624          $this->setUser($user);
 625          $time = time();
 626  
 627          // Viewing the other course calendar.
 628          // Should see all courses that this user is enrolled in.
 629          $calendar = \calendar_information::create($time, $courseb->id, null);
 630  
 631          $this->assertCount(2, $calendar->courses);
 632          $this->assertCount(1, $calendar->categories);
 633          $this->assertEquals($courseb->id, $calendar->courseid);
 634          $this->assertArrayHasKey($courseb->id, array_flip($calendar->courses));
 635          $this->assertArrayNotHasKey($coursea->id, array_flip($calendar->courses));
 636          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 637          $this->assertEquals(\context_course::instance($courseb->id), $calendar->context);
 638  
 639          // Viewing the course calendar while specifying the category too.
 640          // The category is essentially ignored. No change expected.
 641          $calendarwithcategory = \calendar_information::create($time, $courseb->id, $category->id);
 642          $this->assertEquals($calendar, $calendarwithcategory);
 643  
 644          // Viewing the course calendar while specifying the wrong category.
 645          // The category is essentially ignored. No change expected.
 646          $calendarwithcategory = \calendar_information::create($time, $courseb->id, $wrongcategory->id);
 647          $this->assertEquals($calendar, $calendarwithcategory);
 648      }
 649  
 650      /**
 651       * Given a user has an enrolment in two courses in the same category.
 652       * And I ask for the category information.
 653       * Then I should see the site.
 654       * And I should see that course.
 655       * And I should see the category that my enrolled courses are in.
 656       * And I should see the parents of the category that my enrolled course are in.
 657       */
 658      public function test_site_visibility_two_courses_one_category_category() {
 659          $this->resetAfterTest();
 660          list ($courses, $categories) = $this->mock_structure();
 661  
 662          $generator = $this->getDataGenerator();
 663          $user = $generator->create_user();
 664          $coursea = $courses['A.1'];
 665          $courseb = $courses['A.2'];
 666          $category = \core_course_category::get($coursea->category);
 667          $wrongcategory = $categories['B1'];
 668          $generator->enrol_user($user->id, $coursea->id);
 669          $generator->enrol_user($user->id, $courseb->id);
 670  
 671          $this->setUser($user);
 672  
 673          // Viewing the category calendar.
 674          // Should see all courses that this user is enrolled in.
 675          $calendar = \calendar_information::create(time(), SITEID, $category->id);
 676  
 677          $this->assertCount(3, $calendar->courses);
 678          $this->assertCount(7, $calendar->categories);
 679          $this->assertEquals(SITEID, $calendar->courseid);
 680          $this->assertArrayHasKey($coursea->id, array_flip($calendar->courses));
 681          $this->assertArrayHasKey($courseb->id, array_flip($calendar->courses));
 682          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 683          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
 684      }
 685  
 686      /**
 687       * Given a user has an enrolment in two courses in the same category.
 688       * And I ask for the categoy information of a different course.
 689       * Then I should see the site.
 690       * And I should see that course.
 691       * And I should see the category that my enrolled courses are in.
 692       * And I should see the parents of the category that my enrolled course are in.
 693       */
 694      public function test_site_visibility_two_courses_one_category_othercategory() {
 695          $this->resetAfterTest();
 696          list ($courses, $categories) = $this->mock_structure();
 697  
 698          $generator = $this->getDataGenerator();
 699          $user = $generator->create_user();
 700          $coursea = $courses['A.1'];
 701          $courseb = $courses['A.2'];
 702          $category = \core_course_category::get($coursea->category);
 703          $wrongcategory = $categories['B1'];
 704          $generator->enrol_user($user->id, $coursea->id);
 705          $generator->enrol_user($user->id, $courseb->id);
 706  
 707          $this->setUser($user);
 708  
 709          // Viewing the category calendar for a category the user doesn't have any enrolments in.
 710          // Should see that category, and all categories underneath it.
 711          $calendar = \calendar_information::create(time(), SITEID, $wrongcategory->id);
 712  
 713          $this->assertCount(1, $calendar->courses);
 714          $this->assertCount(4, $calendar->categories);
 715          $this->assertEquals(SITEID, $calendar->courseid);
 716          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 717          $this->assertEquals(\context_coursecat::instance($wrongcategory->id), $calendar->context);
 718      }
 719  
 720      /**
 721       * Given a user has an enrolment in two courses in the separate category.
 722       * And I ask for the site informatino.
 723       * Then I should see the site.
 724       * And I should see both course.
 725       * And I should see the categories that my enrolled courses are in.
 726       * And I should see the parents of those categories.
 727       */
 728      public function test_site_visibility_two_courses_two_categories_site() {
 729          $this->resetAfterTest();
 730          list ($courses, $categories) = $this->mock_structure();
 731  
 732          $generator = $this->getDataGenerator();
 733          $user = $generator->create_user();
 734          $coursea = $courses['A.1'];
 735          $courseb = $courses['B.1'];
 736          $categorya = \core_course_category::get($coursea->category);
 737          $categoryb = \core_course_category::get($courseb->category);
 738          $wrongcategory = $categories['C'];
 739          $generator->enrol_user($user->id, $coursea->id);
 740          $generator->enrol_user($user->id, $courseb->id);
 741  
 742          $this->setUser($user);
 743  
 744          // Viewing the site azs a whole.
 745          // Should see all courses that this user is enrolled in.
 746          $calendar = \calendar_information::create(time(), SITEID, null);
 747  
 748          $this->assertCount(3, $calendar->courses);
 749          $this->assertCount(2, $calendar->categories);
 750          $this->assertEquals(SITEID, $calendar->courseid);
 751          $this->assertArrayHasKey($coursea->id, array_flip($calendar->courses));
 752          $this->assertArrayHasKey($courseb->id, array_flip($calendar->courses));
 753          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 754          $this->assertEquals(\context_system::instance(), $calendar->context);
 755      }
 756  
 757      /**
 758       * Given a user has an enrolment in two courses in the separate category.
 759       * And I ask for the course information for one of those courses.
 760       * Then I should see the site.
 761       * And I should see one of the courses.
 762       * And I should see the categories that my enrolled courses are in.
 763       * And I should see the parents of those categories.
 764       */
 765      public function test_site_visibility_two_courses_two_categories_coursea() {
 766          $this->resetAfterTest();
 767          list ($courses, $categories) = $this->mock_structure();
 768  
 769          $generator = $this->getDataGenerator();
 770          $user = $generator->create_user();
 771          $coursea = $courses['A.1'];
 772          $courseb = $courses['B.1'];
 773          $categorya = \core_course_category::get($coursea->category);
 774          $categoryb = \core_course_category::get($courseb->category);
 775          $wrongcategory = $categories['C'];
 776          $generator->enrol_user($user->id, $coursea->id);
 777          $generator->enrol_user($user->id, $courseb->id);
 778  
 779          $this->setUser($user);
 780          $time = time();
 781  
 782          // Viewing the course calendar.
 783          // Should see all courses that this user is enrolled in.
 784          $calendar = \calendar_information::create($time, $coursea->id, null);
 785  
 786          $this->assertCount(2, $calendar->courses);
 787          $this->assertCount(1, $calendar->categories);
 788          $this->assertEquals($coursea->id, $calendar->courseid);
 789          $this->assertArrayHasKey($coursea->id, array_flip($calendar->courses));
 790          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 791          $this->assertEquals(\context_course::instance($coursea->id), $calendar->context);
 792  
 793          // Viewing the course calendar while specifying the categorya too.
 794          // The categorya is essentially ignored. No change expected.
 795          $calendarwithcategory = \calendar_information::create($time, $coursea->id, $categorya->id);
 796          $this->assertEquals($calendar, $calendarwithcategory);
 797  
 798          // Viewing the course calendar while specifying the wrong categorya.
 799          // The categorya is essentially ignored. No change expected.
 800          $calendarwithwrongcategory = \calendar_information::create($time, $coursea->id, $wrongcategory->id);
 801          $this->assertEquals($calendar, $calendarwithwrongcategory);
 802      }
 803  
 804      /**
 805       * Given a user has an enrolment in two courses in the separate category.
 806       * And I ask for the course information for the second of those courses.
 807       * Then I should see the site.
 808       * And I should see one of the courses.
 809       * And I should see the categories that my enrolled courses are in.
 810       * And I should see the parents of those categories.
 811       */
 812      public function test_site_visibility_two_courses_two_categories_courseb() {
 813          $this->resetAfterTest();
 814          list ($courses, $categories) = $this->mock_structure();
 815  
 816          $generator = $this->getDataGenerator();
 817          $user = $generator->create_user();
 818          $coursea = $courses['A.1'];
 819          $courseb = $courses['B.1'];
 820          $categorya = \core_course_category::get($coursea->category);
 821          $categoryb = \core_course_category::get($courseb->category);
 822          $wrongcategory = $categories['C'];
 823          $generator->enrol_user($user->id, $coursea->id);
 824          $generator->enrol_user($user->id, $courseb->id);
 825  
 826          $this->setUser($user);
 827          $time = time();
 828  
 829          // Viewing the other course calendar.
 830          // Should see all courses that this user is enrolled in.
 831          $calendar = \calendar_information::create($time, $courseb->id, null);
 832  
 833          $this->assertCount(2, $calendar->courses);
 834          $this->assertCount(1, $calendar->categories);
 835          $this->assertEquals($courseb->id, $calendar->courseid);
 836          $this->assertArrayHasKey($courseb->id, array_flip($calendar->courses));
 837          $this->assertArrayNotHasKey($coursea->id, array_flip($calendar->courses));
 838          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 839          $this->assertEquals(\context_course::instance($courseb->id), $calendar->context);
 840  
 841          // Viewing the other course calendar while specifying the categorya too.
 842          // The categorya is essentially ignored. No change expected.
 843          $calendarwithcategory = \calendar_information::create($time, $courseb->id, $categoryb->id);
 844          $this->assertEquals($calendar, $calendarwithcategory);
 845  
 846          // Viewing the other course calendar while specifying the wrong categorya.
 847          // The categorya is essentially ignored. No change expected.
 848          $calendarwithwrongcategory = \calendar_information::create($time, $courseb->id, $wrongcategory->id);
 849          $this->assertEquals($calendar, $calendarwithwrongcategory);
 850      }
 851  
 852      /**
 853       * Given a user has an enrolment in two courses in separate categories.
 854       * And I ask for the category information.
 855       * Then I should see the site.
 856       * And I should see one of the courses.
 857       * And I should see the categories that my enrolled courses are in.
 858       * And I should see the parents of those categories.
 859       */
 860      public function test_site_visibility_two_courses_two_categories_category() {
 861          $this->resetAfterTest();
 862          list ($courses, $categories) = $this->mock_structure();
 863  
 864          $generator = $this->getDataGenerator();
 865          $user = $generator->create_user();
 866          $coursea = $courses['A.1'];
 867          $courseb = $courses['B.1'];
 868          $categorya = \core_course_category::get($coursea->category);
 869          $categoryb = \core_course_category::get($courseb->category);
 870          $wrongcategory = $categories['C'];
 871          $generator->enrol_user($user->id, $coursea->id);
 872          $generator->enrol_user($user->id, $courseb->id);
 873  
 874          $this->setUser($user);
 875  
 876          // Viewing the categorya calendar.
 877          // Should see all courses that this user is enrolled in.
 878          $calendar = \calendar_information::create(time(), SITEID, $categorya->id);
 879  
 880          $this->assertCount(2, $calendar->courses);
 881          $this->assertCount(7, $calendar->categories);
 882          $this->assertEquals(SITEID, $calendar->courseid);
 883          $this->assertArrayHasKey($coursea->id, array_flip($calendar->courses));
 884          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 885          $this->assertArrayNotHasKey($courseb->id, array_flip($calendar->courses));
 886          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 887          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 888          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
 889          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
 890          $this->assertEquals(\context_coursecat::instance($categorya->id), $calendar->context);
 891      }
 892  
 893      /**
 894       * Given a user has an enrolment in two courses in the separate category.
 895       * And I ask for the category information of a different category.
 896       * Then I should see the site.
 897       * And I should see one of the courses.
 898       * And I should see the categories that my enrolled courses are in.
 899       * And I should see the parents of those categories.
 900       */
 901      public function test_site_visibility_two_courses_two_categories_different_category() {
 902          $this->resetAfterTest();
 903          list ($courses, $categories) = $this->mock_structure();
 904  
 905          $generator = $this->getDataGenerator();
 906          $user = $generator->create_user();
 907          $coursea = $courses['A.1'];
 908          $courseb = $courses['B.1'];
 909          $categorya = \core_course_category::get($coursea->category);
 910          $categoryb = \core_course_category::get($courseb->category);
 911          $wrongcategory = $categories['C'];
 912          $generator->enrol_user($user->id, $coursea->id);
 913          $generator->enrol_user($user->id, $courseb->id);
 914  
 915          $this->setUser($user);
 916          // Viewing the categorya calendar for a categorya the user doesn't have any enrolments in.
 917          // Should see that categorya, and all categories underneath it.
 918          $calendar = \calendar_information::create(time(), SITEID, $wrongcategory->id);
 919  
 920          $this->assertCount(1, $calendar->courses);
 921          $this->assertCount(1, $calendar->categories);
 922          $this->assertEquals(SITEID, $calendar->courseid);
 923          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 924          $this->assertEquals(\context_coursecat::instance($wrongcategory->id), $calendar->context);
 925      }
 926  
 927      /**
 928       * Given an admin user with no enrolments.
 929       * And I ask for the site information.
 930       * Then I should see the site.
 931       * And I should see no other courses.
 932       * And I should see no categories.
 933       */
 934      public function test_site_visibility_admin_user() {
 935          $this->resetAfterTest();
 936          list ($courses, $categories) = $this->mock_structure();
 937  
 938          $generator = $this->getDataGenerator();
 939          $this->setAdminUser();
 940  
 941          $calendar = \calendar_information::create(time(), SITEID, null);
 942  
 943          $this->assertCount(1, $calendar->courses);
 944          $this->assertCount(0, $calendar->categories);
 945          $this->assertEquals(SITEID, $calendar->courseid);
 946          $this->assertEquals(SITEID, reset($calendar->courses));
 947          $this->assertEquals(\context_system::instance(), $calendar->context);
 948      }
 949  
 950      /**
 951       * Given an admin user with a single enrolments.
 952       * And I ask for the site information.
 953       * Then I should see the site.
 954       * And I should see the course I am enrolled in
 955       * And I should see the category of that course.
 956       * And I should see the parents of that course category.
 957       * And I should see no other courses.
 958       * And I should see no other categories.
 959       */
 960      public function test_site_visibility_admin_user_with_enrolment_site() {
 961          global $USER;
 962  
 963          $this->resetAfterTest();
 964          list ($courses, $categories) = $this->mock_structure();
 965  
 966          $generator = $this->getDataGenerator();
 967          $course = $courses['A1.1'];
 968          $category = \core_course_category::get($course->category);
 969          $this->setAdminUser();
 970          $generator->enrol_user($USER->id, $course->id);
 971  
 972          $calendar = \calendar_information::create(time(), SITEID, null);
 973  
 974          $this->assertCount(2, $calendar->courses);
 975          $this->assertCount(2, $calendar->categories);
 976          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
 977          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
 978          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
 979          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
 980          $this->assertEquals(\context_system::instance(), $calendar->context);
 981      }
 982  
 983      /**
 984       * Given an admin user with a single enrolments.
 985       * And I ask for the course information.
 986       * Then I should see the site.
 987       * And I should see the course I am enrolled in
 988       * And I should see the category of that course.
 989       * And I should see the parents of that course category.
 990       */
 991      public function test_site_visibility_admin_user_with_enrolment_course() {
 992          global $USER;
 993  
 994          $this->resetAfterTest();
 995          list ($courses, $categories) = $this->mock_structure();
 996  
 997          $generator = $this->getDataGenerator();
 998          $course = $courses['A1.1'];
 999          $category = \core_course_category::get($course->category);
1000          $wrongcategory = $categories['B1'];
1001          $this->setAdminUser();
1002          $generator->enrol_user($USER->id, $course->id);
1003  
1004          $time = time();
1005  
1006          $calendar = \calendar_information::create($time, $course->id, null);
1007  
1008          $this->assertCount(2, $calendar->courses);
1009          $this->assertCount(2, $calendar->categories);
1010          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
1011          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
1012          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
1013          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
1014          $this->assertEquals(\context_course::instance($course->id), $calendar->context);
1015  
1016          // Viewing the course calendar while specifying the category too.
1017          // The category is essentially ignored. No change expected.
1018          $calendarwithcategory = \calendar_information::create($time, $course->id, $category->id);
1019          $this->assertEquals($calendar, $calendarwithcategory);
1020  
1021          // Viewing the course calendar while specifying the wrong category.
1022          // The category is essentially ignored. No change expected.
1023          $calendarwithwrongcategory = \calendar_information::create($time, $course->id, $wrongcategory->id);
1024          $this->assertEquals($calendar, $calendarwithwrongcategory);
1025      }
1026  
1027      /**
1028       * Given an admin user with a single enrolments.
1029       * And I ask for the category information for the category my course is in.
1030       * Then I should see that category.
1031       * And I should see the category parents.
1032       * And I should see the category descendants.
1033       * And I should see the site.
1034       * And I should see my course.
1035       * And I should see no other courses.
1036       * And I should see no categories.
1037       */
1038      public function test_site_visibility_admin_user_with_enrolment_category() {
1039          global $USER;
1040  
1041          $this->resetAfterTest();
1042          list ($courses, $categories) = $this->mock_structure();
1043  
1044          $generator = $this->getDataGenerator();
1045          $course = $courses['A1.1'];
1046          $category = \core_course_category::get($course->category);
1047          $wrongcategory = $categories['B1'];
1048          $this->setAdminUser();
1049          $generator->enrol_user($USER->id, $course->id);
1050  
1051          $calendar = \calendar_information::create(time(), SITEID, $category->id);
1052  
1053          $this->assertCount(2, $calendar->courses);
1054          $this->assertCount(4, $calendar->categories);
1055          $this->assertArrayHasKey(SITEID, array_flip($calendar->courses));
1056          $this->assertArrayHasKey($course->id, array_flip($calendar->courses));
1057          $this->assertArrayHasKey($categories['A']->id, array_flip($calendar->categories));
1058          $this->assertArrayHasKey($categories['A1']->id, array_flip($calendar->categories));
1059          $this->assertArrayHasKey($categories['A1i']->id, array_flip($calendar->categories));
1060          $this->assertArrayHasKey($categories['A1ii']->id, array_flip($calendar->categories));
1061          $this->assertEquals(\context_coursecat::instance($category->id), $calendar->context);
1062      }
1063  }