Search moodle.org's
Developer Documentation

  • 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.
  •    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  }