Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 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 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 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 the approved 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;
  31  
  32  /**
  33   * Tests for the \core_privacy API's approved contextlist 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
  38   */
  39  class contextlist_test extends advanced_testcase {
  40  
  41      /**
  42       * Ensure that valid SQL results in the relevant contexts being added.
  43       *
  44       * @covers ::add_from_sql
  45       */
  46      public function test_add_from_sql() {
  47          global $DB;
  48  
  49          $sql = "SELECT c.id FROM {context} c";
  50          $params = [];
  51          $allcontexts = $DB->get_records_sql($sql, $params);
  52  
  53          $uit = new contextlist();
  54          $uit->add_from_sql($sql, $params);
  55  
  56          $this->assertCount(count($allcontexts), $uit);
  57      }
  58  
  59      /**
  60       * Ensure that valid system context id is added.
  61       *
  62       * @covers ::add_system_context
  63       */
  64      public function test_add_system_context() {
  65          $cl = new contextlist();
  66          $cl->add_system_context();
  67  
  68          $this->assertCount(1, $cl);
  69  
  70          foreach ($cl->get_contexts() as $context) {
  71              $this->assertEquals(SYSCONTEXTID, $context->id);
  72          }
  73      }
  74  
  75      /**
  76       * Ensure that a valid user context id is added.
  77       *
  78       * @covers ::add_user_context
  79       */
  80      public function test_add_user_context() {
  81          $this->resetAfterTest();
  82  
  83          $user = $this->getDataGenerator()->create_user();
  84          $this->getDataGenerator()->create_user();
  85  
  86          $cl = new contextlist();
  87          $cl->add_user_context($user->id);
  88  
  89          $this->assertCount(1, $cl);
  90  
  91          foreach ($cl->get_contexts() as $context) {
  92              $this->assertEquals(\context_user::instance($user->id)->id, $context->id);
  93          }
  94      }
  95  
  96      /**
  97       * Ensure that valid user contexts are added.
  98       *
  99       * @covers ::add_user_contexts
 100       */
 101      public function test_add_user_contexts() {
 102          $this->resetAfterTest();
 103  
 104          $user1 = $this->getDataGenerator()->create_user();
 105          $user2 = $this->getDataGenerator()->create_user();
 106          $this->getDataGenerator()->create_user();
 107  
 108          $cl = new contextlist();
 109          $cl->add_user_contexts([$user1->id, $user2->id]);
 110  
 111          $this->assertCount(2, $cl);
 112  
 113          $contexts = $cl->get_contextids();
 114          $this->assertContains(\context_user::instance($user1->id)->id, $contexts);
 115          $this->assertContains(\context_user::instance($user2->id)->id, $contexts);
 116      }
 117  
 118      /**
 119       * Test {@link \core_privacy\local\request\contextlist::test_guess_id_field_from_sql()} implementation.
 120       *
 121       * @dataProvider data_guess_id_field_from_sql
 122       * @param string $sql Input SQL we try to extract the context id field name from.
 123       * @param string $expected Expected detected value.
 124       * @covers ::guess_id_field_from_sql
 125       */
 126      public function test_guess_id_field_from_sql($sql, $expected) {
 127  
 128          $rc = new \ReflectionClass(contextlist::class);
 129          $rcm = $rc->getMethod('guess_id_field_from_sql');
 130          $rcm->setAccessible(true);
 131          $actual = $rcm->invoke(new contextlist(), $sql);
 132  
 133          $this->assertEquals($expected, $actual, 'Unable to guess context id field in: '.$sql);
 134      }
 135  
 136      /**
 137       * Provides data sets for {@link self::test_guess_id_field_from_sql()}.
 138       *
 139       * @return array
 140       */
 141      public function data_guess_id_field_from_sql() {
 142          return [
 143              'easy' => [
 144                  'SELECT contextid FROM {foo}',
 145                  'contextid',
 146              ],
 147              'with_distinct' => [
 148                  'SELECT DISTINCT contextid FROM {foo}',
 149                  'contextid',
 150              ],
 151              'with_dot' => [
 152                  'SELECT cx.id FROM {foo} JOIN {context} cx ON blahblahblah',
 153                  'id',
 154              ],
 155              'letter_case_does_not_matter' => [
 156                  'Select ctxid From {foo} Where bar = ?',
 157                  'ctxid',
 158              ],
 159              'alias' => [
 160                  'SELECT foo.contextid AS ctx FROM {bar} JOIN {foo} ON bar.id = foo.barid',
 161                  'ctx',
 162              ],
 163              'tabs' => [
 164                  "SELECT\tctxid\t\tFROM foo f",
 165                  'ctxid',
 166              ],
 167              'whitespace' => [
 168                  "SELECT
 169                      ctxid\t
 170                     \tFROM foo f",
 171                  'ctxid',
 172              ],
 173              'just_number' => [
 174                  '1',
 175                  '1',
 176              ],
 177              'select_number' => [
 178                  'SELECT 2',
 179                  '2',
 180              ],
 181              'select_number_with_semicolon' => [
 182                  'SELECT 3;',
 183                  '3',
 184              ],
 185              'select_number_from_table' => [
 186                  'SELECT 4 FROM users',
 187                  '4',
 188              ],
 189              'select_with_complex_subqueries' => [
 190                  'SELECT id FROM table WHERE id IN (
 191                       SELECT x FROM xtable
 192                       UNION
 193                       SELECT y FROM (
 194                           SELECT y FROM ytable
 195                           JOIN ztable ON (z = y)))',
 196                  'id'
 197              ],
 198              'invalid_union_with_first_being_column_name' => [
 199                  'SELECT id FROM table UNION SELECT 1 FROM table',
 200                  ''
 201              ],
 202              'invalid_union_with_first_being_numeric' => [
 203                  'SELECT 1 FROM table UNION SELECT id FROM table',
 204                  ''
 205              ],
 206              'invalid_union_without_from' => [
 207                  'SELECT 1 UNION SELECT id FROM table',
 208                  ''
 209              ],
 210              'invalid_1' => [
 211                  'SELECT 1+1',
 212                  '',
 213              ],
 214              'invalid_2' => [
 215                  'muhehe',
 216                  '',
 217              ],
 218          ];
 219      }
 220  }