Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.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 the abstract contextlist Class
  19   *
  20   * @package     core_privacy
  21   * @category    test
  22   * @copyright   2018 Andrew Nicols <andrew@nicols.co.uk>
  23   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  global $CFG;
  29  
  30  use \core_privacy\local\request\contextlist_base;
  31  
  32  /**
  33   * Tests for the \core_privacy API's contextlist base functionality.
  34   *
  35   * @copyright   2018 Andrew Nicols <andrew@nicols.co.uk>
  36   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   * @coversDefaultClass \core_privacy\local\request\contextlist_base
  38   */
  39  class contextlist_base_test extends advanced_testcase {
  40      /**
  41       * Ensure that get_contextids returns the list of unique contextids.
  42       *
  43       * @dataProvider    get_contextids_provider
  44       * @param   array   $input List of context IDs
  45       * @param   array   $expected list of contextids
  46       * @param   int     $count Expected count
  47       * @covers ::get_contextids
  48       */
  49      public function test_get_contextids($input, $expected, $count) {
  50          $uit = new test_contextlist_base();
  51          $uit->set_contextids($input);
  52  
  53          $result = $uit->get_contextids();
  54          $this->assertCount($count, $result);
  55  
  56          // Note: Array order is not guaranteed and should not matter.
  57          foreach ($expected as $contextid) {
  58              $this->assertNotFalse(array_search($contextid, $result));
  59          }
  60      }
  61  
  62      /**
  63       * Provider for the list of contextids.
  64       *
  65       * @return array
  66       */
  67      public function get_contextids_provider() {
  68          return [
  69              'basic' => [
  70                  [1, 2, 3, 4, 5],
  71                  [1, 2, 3, 4, 5],
  72                  5,
  73              ],
  74              'duplicates' => [
  75                  [1, 1, 2, 2, 3, 4, 5],
  76                  [1, 2, 3, 4, 5],
  77                  5,
  78              ],
  79              'Mixed order with duplicates' => [
  80                  [5, 4, 2, 5, 4, 1, 3, 4, 1, 5, 5, 5, 2, 4, 1, 2],
  81                  [1, 2, 3, 4, 5],
  82                  5,
  83              ],
  84          ];
  85      }
  86  
  87      /**
  88       * Ensure that get_contexts returns the correct list of contexts.
  89       *
  90       * @covers ::get_contexts
  91       */
  92      public function test_get_contexts() {
  93          global $DB;
  94  
  95          $contexts = [];
  96          $contexts[] = \context_system::instance();
  97          $contexts[] = \context_user::instance(\core_user::get_user_by_username('admin')->id);
  98  
  99          $ids = [];
 100          foreach ($contexts as $context) {
 101              $ids[] = $context->id;
 102          }
 103  
 104          $uit = new test_contextlist_base();
 105          $uit->set_contextids($ids);
 106  
 107          $result = $uit->get_contexts();
 108          $this->assertCount(count($contexts), $result);
 109          foreach ($contexts as $context) {
 110              $this->assertNotFalse(array_search($context, $result));
 111          }
 112      }
 113  
 114      /**
 115       * Ensure that the contextlist_base is countable.
 116       *
 117       * @dataProvider    get_contextids_provider
 118       * @param   array   $input List of context IDs
 119       * @param   array   $expected list of contextids
 120       * @param   int     $count Expected count
 121       * @covers ::count
 122       */
 123      public function test_countable($input, $expected, $count) {
 124          $uit = new test_contextlist_base();
 125          $uit->set_contextids($input);
 126  
 127          $this->assertCount($count, $uit);
 128      }
 129  
 130      /**
 131       * Ensure that the contextlist_base iterates over the set of contexts.
 132       *
 133       * @covers ::current
 134       * @covers ::key
 135       * @covers ::next
 136       * @covers ::rewind
 137       * @covers ::valid
 138       */
 139      public function test_context_iteration() {
 140          global $DB;
 141  
 142          $allcontexts = $DB->get_records('context');
 143          $contexts = [];
 144          foreach ($allcontexts as $context) {
 145              $contexts[] = \context::instance_by_id($context->id);
 146          }
 147  
 148          $uit = new test_contextlist_base();
 149          $uit->set_contextids(array_keys($allcontexts));
 150  
 151          foreach ($uit as $key => $context) {
 152              $this->assertNotFalse(array_search($context, $contexts));
 153          }
 154      }
 155  
 156      /**
 157       * Test that deleting a context results in current returning nothing.
 158       *
 159       * @covers ::current
 160       */
 161      public function test_current_context_one_context() {
 162          global $DB;
 163  
 164          $this->resetAfterTest();
 165  
 166          $data = (object) [
 167              'contextlevel' => CONTEXT_BLOCK,
 168              'instanceid' => 45,
 169              'path' => '1/5/67/107',
 170              'depth' => 4
 171          ];
 172  
 173          $contextid = $DB->insert_record('context', $data);
 174  
 175          $contextbase = new test_contextlist_base();
 176          $contextbase->set_contextids([$contextid]);
 177          $this->assertCount(1, $contextbase);
 178          $currentcontext = $contextbase->current();
 179          $this->assertEquals($contextid, $currentcontext->id);
 180          $DB->delete_records('context', ['id' => $contextid]);
 181          context_helper::reset_caches();
 182          $this->assertEmpty($contextbase->current());
 183      }
 184  
 185      /**
 186       * Test that deleting a context results in the next record being returned.
 187       *
 188       * @covers ::current
 189       */
 190      public function test_current_context_two_contexts() {
 191          global $DB;
 192  
 193          $this->resetAfterTest();
 194  
 195          $data = (object) [
 196              'contextlevel' => CONTEXT_BLOCK,
 197              'instanceid' => 45,
 198              'path' => '1/5/67/107',
 199              'depth' => 4
 200          ];
 201  
 202          $contextid1 = $DB->insert_record('context', $data);
 203  
 204          $data = (object) [
 205              'contextlevel' => CONTEXT_BLOCK,
 206              'instanceid' => 47,
 207              'path' => '1/5/54/213',
 208              'depth' => 4
 209          ];
 210  
 211          $contextid2 = $DB->insert_record('context', $data);
 212  
 213          $contextbase = new test_contextlist_base();
 214          $contextbase->set_contextids([$contextid1, $contextid2]);
 215          $this->assertCount(2, $contextbase);
 216          $DB->delete_records('context', ['id' => $contextid1]);
 217          context_helper::reset_caches();
 218          // Current should return context 2.
 219          $this->assertEquals($contextid2, $contextbase->current()->id);
 220      }
 221  
 222      /**
 223       * Test that if there are no non-deleted contexts that nothing is returned.
 224       *
 225       * @covers ::get_contexts
 226       */
 227      public function test_get_contexts_all_deleted() {
 228          global $DB;
 229  
 230          $this->resetAfterTest();
 231  
 232          $data = (object) [
 233              'contextlevel' => CONTEXT_BLOCK,
 234              'instanceid' => 45,
 235              'path' => '1/5/67/107',
 236              'depth' => 4
 237          ];
 238  
 239          $contextid = $DB->insert_record('context', $data);
 240  
 241          $contextbase = new test_contextlist_base();
 242          $contextbase->set_contextids([$contextid]);
 243          $this->assertCount(1, $contextbase);
 244          $DB->delete_records('context', ['id' => $contextid]);
 245          context_helper::reset_caches();
 246          $this->assertEmpty($contextbase->get_contexts());
 247      }
 248  
 249      /**
 250       * Test that get_contexts() returns only active contexts.
 251       *
 252       * @covers ::get_contexts
 253       */
 254      public function test_get_contexts_one_deleted() {
 255          global $DB;
 256  
 257          $this->resetAfterTest();
 258  
 259          $data = (object) [
 260              'contextlevel' => CONTEXT_BLOCK,
 261              'instanceid' => 45,
 262              'path' => '1/5/67/107',
 263              'depth' => 4
 264          ];
 265  
 266          $contextid1 = $DB->insert_record('context', $data);
 267  
 268          $data = (object) [
 269              'contextlevel' => CONTEXT_BLOCK,
 270              'instanceid' => 47,
 271              'path' => '1/5/54/213',
 272              'depth' => 4
 273          ];
 274  
 275          $contextid2 = $DB->insert_record('context', $data);
 276  
 277          $contextbase = new test_contextlist_base();
 278          $contextbase->set_contextids([$contextid1, $contextid2]);
 279          $this->assertCount(2, $contextbase);
 280          $DB->delete_records('context', ['id' => $contextid1]);
 281          context_helper::reset_caches();
 282          $contexts = $contextbase->get_contexts();
 283          $this->assertCount(1, $contexts);
 284          $context = array_shift($contexts);
 285          $this->assertEquals($contextid2, $context->id);
 286      }
 287  }
 288  
 289  /**
 290   * A test class extending the contextlist_base allowing setting of the
 291   * contextids.
 292   *
 293   * @copyright   2018 Andrew Nicols <andrew@nicols.co.uk>
 294   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 295   */
 296  class test_contextlist_base extends contextlist_base {
 297      /**
 298       * Set the contextids for the test class.
 299       *
 300       * @param   int[]   $contexids  The list of contextids to use.
 301       */
 302      public function set_contextids(array $contextids) {
 303          parent::set_contextids($contextids);
 304      }
 305  }