Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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