Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   1  <?php
   2  // This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
  16  
  17  namespace core\context;
  18  
  19  use core\context, core\context_helper;
  20  
  21  /**
  22   * Unit tests for course context class.
  23   *
  24   * NOTE: more tests are in lib/tests/accesslib_test.php
  25   *
  26   * @package   core
  27   * @copyright Petr Skoda
  28   * @license   https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29   * @coversDefaultClass \core\context\course
  30   */
  31  class course_test extends \advanced_testcase {
  32      /**
  33       * Tests legacy class.
  34       * @coversNothing
  35       */
  36      public function test_legacy_classname() {
  37          global $SITE;
  38          $course = $SITE;
  39          $context = \context_course::instance($course->id);
  40          $this->assertInstanceOf(course::class, $context);
  41          $this->assertInstanceOf(\context_course::class, $context);
  42      }
  43  
  44      /**
  45       * Tests covered methods.
  46       * @covers ::instance
  47       * @covers \core\context::instance_by_id
  48       */
  49      public function test_factory_methods() {
  50          global $SITE;
  51          $course = $SITE;
  52          $context = course::instance($course->id);
  53          $this->assertInstanceOf(course::class, $context);
  54          $this->assertSame($course->id, $context->instanceid);
  55  
  56          $context = context::instance_by_id($context->id);
  57          $this->assertInstanceOf(course::class, $context);
  58          $this->assertSame($course->id, $context->instanceid);
  59      }
  60  
  61      /**
  62       * Tests covered method.
  63       * @covers ::get_short_name
  64       */
  65      public function test_get_short_name() {
  66          $this->assertSame('course', course::get_short_name());
  67      }
  68  
  69      /**
  70       * Tests levels.
  71       * @coversNothing
  72       */
  73      public function test_level() {
  74          $this->assertSame(50, course::LEVEL);
  75          $this->assertSame(CONTEXT_COURSE, course::LEVEL);
  76      }
  77  
  78      /**
  79       * Tests covered method.
  80       * @covers ::get_level_name
  81       */
  82      public function test_get_level_name() {
  83          $this->assertSame('Course', course::get_level_name());
  84      }
  85  
  86      /**
  87       * Tests covered method.
  88       * @covers ::get_context_name
  89       */
  90      public function test_get_context_name() {
  91          $this->resetAfterTest();
  92  
  93          $course = $this->getDataGenerator()->create_course(['fullname' => 'Test course', 'shortname' => 'TST']);
  94          $context = course::instance($course->id);
  95  
  96          $this->assertSame('Course: Test course', $context->get_context_name());
  97          $this->assertSame('Course: Test course', $context->get_context_name(true));
  98          $this->assertSame('Test course', $context->get_context_name(false));
  99          $this->assertSame('TST', $context->get_context_name(false, true));
 100          $this->assertSame('Course: TST', $context->get_context_name(true, true, false));
 101      }
 102  
 103      /**
 104       * Tests covered method.
 105       * @covers ::get_url
 106       */
 107      public function test_get_url() {
 108          $this->resetAfterTest();
 109  
 110          $course = $this->getDataGenerator()->create_course();
 111          $context = course::instance($course->id);
 112  
 113          $expected = new \moodle_url('/course/view.php', ['id' => $course->id]);
 114          $url = $context->get_url();
 115          $this->assertInstanceOf(\moodle_url::class, $url);
 116          $this->assertSame($expected->out(), $url->out());
 117      }
 118  
 119      /**
 120       * Tests covered methods.
 121       * @covers ::get_instance_table()
 122       * @covers ::get_behat_reference_columns()
 123       * @covers \core\context_helper::resolve_behat_reference
 124       */
 125      public function test_resolve_behat_reference() {
 126          $this->resetAfterTest();
 127  
 128          $instance = $this->getDataGenerator()->create_course(['shortname' => 'xyz']);
 129          $context = context\course::instance($instance->id);
 130  
 131          $result = context_helper::resolve_behat_reference('Course', $instance->shortname);
 132          $this->assertSame($context->id, $result->id);
 133  
 134          $result = context_helper::resolve_behat_reference('course', $instance->shortname);
 135          $this->assertSame($context->id, $result->id);
 136  
 137          $result = context_helper::resolve_behat_reference('50', $instance->shortname);
 138          $this->assertSame($context->id, $result->id);
 139  
 140          $result = context_helper::resolve_behat_reference('Course', 'dshjkdshjkhjsadjhdsa');
 141          $this->assertNull($result);
 142  
 143          $result = context_helper::resolve_behat_reference('Course', '');
 144          $this->assertNull($result);
 145      }
 146  
 147      /**
 148       * Tests covered method.
 149       * @covers ::get_compatible_role_archetypes
 150       */
 151      public function test_get_compatible_role_archetypes() {
 152          global $DB;
 153  
 154          $allarchetypes = $DB->get_fieldset_select('role', 'DISTINCT archetype', 'archetype IS NOT NULL');
 155          foreach ($allarchetypes as $allarchetype) {
 156              $levels = context_helper::get_compatible_levels($allarchetype);
 157              if ($allarchetype === 'editingteacher' || $allarchetype === 'teacher'
 158                  || $allarchetype === 'student' || $allarchetype === 'manager') {
 159                  $this->assertContains(course::LEVEL, $levels, "$allarchetype is expected to be compatible with context");
 160              } else {
 161                  $this->assertNotContains(course::LEVEL, $levels, "$allarchetype is not expected to be compatible with context");
 162              }
 163          }
 164      }
 165  
 166      /**
 167       * Tests covered method.
 168       * @covers ::get_possible_parent_levels
 169       */
 170      public function test_get_possible_parent_levels() {
 171          $this->assertSame([coursecat::LEVEL], course::get_possible_parent_levels());
 172      }
 173  
 174      /**
 175       * Tests covered method.
 176       * @covers ::get_capabilities
 177       */
 178      public function test_get_capabilities() {
 179          $this->resetAfterTest();
 180  
 181          $course = $this->getDataGenerator()->create_course();
 182          $context = course::instance($course->id);
 183  
 184          $capabilities = $context->get_capabilities();
 185          $capabilities = convert_to_array($capabilities);
 186          $capabilities = array_column($capabilities, 'name');
 187          $this->assertContains('moodle/course:view', $capabilities);
 188          $this->assertContains('mod/page:view', $capabilities);
 189          $this->assertContains('mod/url:view', $capabilities);
 190          $this->assertNotContains('moodle/category:manage', $capabilities);
 191          $this->assertNotContains('moodle/user:viewalldetails', $capabilities);
 192      }
 193  
 194      /**
 195       * Tests covered method.
 196       * @covers ::create_level_instances
 197       */
 198      public function test_create_level_instances() {
 199          global $DB;
 200          $this->resetAfterTest();
 201  
 202          $course = $this->getDataGenerator()->create_course();
 203          $coursecontext = course::instance($course->id);
 204  
 205          $DB->delete_records('context', ['id' => $coursecontext->id]);
 206          context_helper::create_instances(course::LEVEL);
 207          $record = $DB->get_record('context', ['contextlevel' => course::LEVEL, 'instanceid' => $course->id], '*', MUST_EXIST);
 208      }
 209  
 210      /**
 211       * Tests covered method.
 212       * @covers ::get_child_contexts
 213       */
 214      public function test_get_child_contexts() {
 215          $this->resetAfterTest();
 216  
 217          $course = $this->getDataGenerator()->create_course();
 218          $page = $this->getDataGenerator()->create_module('page', ['course' => $course->id, 'name' => 'Pokus']);
 219  
 220          $context = course::instance($course->id);
 221          $children = $context->get_child_contexts();
 222          $this->assertCount(1, $children);
 223          $childcontext = reset($children);
 224          $this->assertInstanceOf(module::class, $childcontext);
 225          $this->assertEquals($page->cmid, $childcontext->instanceid);
 226      }
 227  
 228      /**
 229       * Tests covered method.
 230       * @covers ::get_cleanup_sql
 231       */
 232      public function test_get_cleanup_sql() {
 233          global $DB;
 234          $this->resetAfterTest();
 235  
 236          $course = $this->getDataGenerator()->create_course();
 237          $coursecontext = course::instance($course->id);
 238  
 239          $DB->delete_records('course', ['id' => $course->id]);
 240  
 241          context_helper::cleanup_instances();
 242          $this->assertFalse($DB->record_exists('context', ['contextlevel' => course::LEVEL, 'instanceid' => $course->id]));
 243      }
 244  
 245      /**
 246       * Tests covered method.
 247       * @covers ::build_paths
 248       */
 249      public function test_build_paths() {
 250          global $DB;
 251          $this->resetAfterTest();
 252  
 253          $course = $this->getDataGenerator()->create_course();
 254          $coursecontext = course::instance($course->id);
 255          $syscontext = system::instance();
 256  
 257          $DB->set_field('context', 'depth', 1, ['id' => $coursecontext->id]);
 258          $DB->set_field('context', 'path', '/0', ['id' => $coursecontext->id]);
 259  
 260          context_helper::build_all_paths(true);
 261  
 262          $record = $DB->get_record('context', ['id' => $coursecontext->id]);
 263          $categorycontext = coursecat::instance($course->category);
 264          $this->assertSame('3', $record->depth);
 265          $this->assertSame('/' . $syscontext->id . '/' . $categorycontext->id . '/' . $record->id, $record->path);
 266      }
 267  
 268      /**
 269       * Tests covered method.
 270       * @covers ::set_locked
 271       */
 272      public function test_set_locked() {
 273          global $DB;
 274          $this->resetAfterTest();
 275  
 276          $course1 = $this->getDataGenerator()->create_course();
 277          $context1 = course::instance($course1->id);
 278  
 279          $context1->set_locked(true);
 280          $context1 = course::instance($course1->id);
 281          $this->assertTrue($context1->locked);
 282          $record = $DB->get_record('context', ['id' => $context1->id]);
 283          $this->assertSame('1', $record->locked);
 284  
 285          $context1->set_locked(false);
 286          $context1 = course::instance($course1->id);
 287          $this->assertFalse($context1->locked);
 288          $record = $DB->get_record('context', ['id' => $context1->id]);
 289          $this->assertSame('0', $record->locked);
 290      }
 291  }