Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 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  declare(strict_types=1);
  18  
  19  namespace core_reportbuilder\local\report;
  20  
  21  use advanced_testcase;
  22  use coding_exception;
  23  use context_system;
  24  use core_reportbuilder\local\helpers\database;
  25  use core_reportbuilder\system_report_available;
  26  use core_reportbuilder\system_report_factory;
  27  use lang_string;
  28  use ReflectionClass;
  29  
  30  /**
  31   * Unit tests for report base class
  32   *
  33   * @package     core_reportbuilder
  34   * @covers      \core_reportbuilder\local\report\base
  35   * @copyright   2021 David Matamoros <davidmc@moodle.com>
  36   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class base_test extends advanced_testcase {
  39  
  40      /**
  41       * Load required class
  42       */
  43      public static function setUpBeforeClass(): void {
  44          global $CFG;
  45          require_once("{$CFG->dirroot}/reportbuilder/tests/fixtures/system_report_available.php");
  46      }
  47  
  48      /**
  49       * Test for add_base_condition_simple
  50       */
  51      public function test_add_base_condition_simple(): void {
  52          $this->resetAfterTest();
  53  
  54          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
  55          $systemreport->add_base_condition_simple('username', 'admin');
  56          [$where, $params] = $systemreport->get_base_condition();
  57          $this->assertStringMatchesFormat('username = :%a', $where);
  58          $this->assertEqualsCanonicalizing(['admin'], $params);
  59      }
  60  
  61      /**
  62       * Test for add_base_condition_simple null
  63       */
  64      public function test_add_base_condition_simple_null(): void {
  65          $this->resetAfterTest();
  66  
  67          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
  68          $systemreport->add_base_condition_simple('username', null);
  69          [$where, $params] = $systemreport->get_base_condition();
  70          $this->assertEquals('username IS NULL', $where);
  71          $this->assertEmpty($params);
  72      }
  73  
  74      /**
  75       * Test for adding SQL base condition to a report
  76       */
  77      public function test_add_base_condition_sql(): void {
  78          $this->resetAfterTest();
  79  
  80          $parameter = database::generate_param_name();
  81  
  82          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
  83          $systemreport->add_base_condition_sql("username = :{$parameter}", [$parameter => 'admin']);
  84  
  85          [$where, $params] = $systemreport->get_base_condition();
  86          $this->assertEquals("username = :{$parameter}", $where);
  87          $this->assertEquals([$parameter => 'admin'], $params);
  88      }
  89  
  90      /**
  91       * Test for adding multiple SQL base condition to a report
  92       */
  93      public function test_add_base_condition_sql_multiple(): void {
  94          $this->resetAfterTest();
  95  
  96          [$paramusername, $paramemail] = database::generate_param_names(2);
  97  
  98          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
  99          $systemreport->add_base_condition_sql("username = :{$paramusername}", [$paramusername => 'admin']);
 100          $systemreport->add_base_condition_sql("email = :{$paramemail}", [$paramemail => 'admin@example.com']);
 101  
 102          [$where, $params] = $systemreport->get_base_condition();
 103          $this->assertEquals("username = :{$paramusername} AND email = :{$paramemail}", $where);
 104          $this->assertEquals([$paramusername => 'admin', $paramemail => 'admin@example.com'], $params);
 105      }
 106  
 107      /**
 108       * Test for adding empty SQL base condition to a report
 109       */
 110      public function test_add_base_condition_sql_empty_clause(): void {
 111          $this->resetAfterTest();
 112  
 113          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 114          $systemreport->add_base_condition_sql('username IS NOT NULL');
 115          $systemreport->add_base_condition_sql('');
 116  
 117          [$where, $params] = $systemreport->get_base_condition();
 118          $this->assertEquals("username IS NOT NULL", $where);
 119          $this->assertEmpty($params);
 120      }
 121  
 122      /**
 123       * Test for adding SQL base condition to a report with invalid parameter
 124       */
 125      public function test_add_base_condition_sql_invalid_parameter(): void {
 126          $this->resetAfterTest();
 127  
 128          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 129  
 130          $this->expectException(coding_exception::class);
 131          $this->expectExceptionMessage('Invalid parameter names');
 132          $systemreport->add_base_condition_sql("username = :param", ['param' => 'admin']);
 133      }
 134  
 135      /**
 136       * Test getting report base conditions, where none have been set
 137       */
 138      public function test_get_base_condition_default(): void {
 139          $this->resetAfterTest();
 140  
 141          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 142  
 143          [$where, $params] = $systemreport->get_base_condition();
 144          $this->assertEmpty($where);
 145          $this->assertEmpty($params);
 146      }
 147  
 148      /**
 149       * Test for get_filter_instances
 150       */
 151      public function test_get_filter_instances(): void {
 152          $this->resetAfterTest();
 153  
 154          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance(),
 155              '', '', 0, ['withfilters' => true]);
 156          $filters = $systemreport->get_filter_instances();
 157          $this->assertCount(1, $filters);
 158          $this->assertInstanceOf(\core_reportbuilder\local\filters\text::class, reset($filters));
 159      }
 160  
 161      /**
 162       * Test for set_downloadable
 163       */
 164      public function test_set_downloadable(): void {
 165          $this->resetAfterTest();
 166  
 167          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 168          $systemreport->set_downloadable(true, 'testfilename');
 169          $this->assertTrue($systemreport->is_downloadable());
 170          $this->assertEquals('testfilename', $systemreport->get_downloadfilename());
 171  
 172          $systemreport->set_downloadable(false, 'anothertestfilename');
 173          $this->assertFalse($systemreport->is_downloadable());
 174          $this->assertEquals('anothertestfilename', $systemreport->get_downloadfilename());
 175      }
 176  
 177      /**
 178       * Test for get_context
 179       */
 180      public function test_get_context(): void {
 181          $this->resetAfterTest();
 182  
 183          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 184          $this->assertEquals(context_system::instance(), $systemreport->get_context());
 185  
 186          $course = $this->getDataGenerator()->create_course();
 187          $contextcourse = \context_course::instance($course->id);
 188          $systemreport2 = system_report_factory::create(system_report_available::class, $contextcourse);
 189          $this->assertEquals($contextcourse, $systemreport2->get_context());
 190      }
 191  
 192      /**
 193       * Test entity annotation
 194       */
 195      public function test_annotate_entity(): void {
 196          $this->resetAfterTest();
 197  
 198          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 199  
 200          $method = (new ReflectionClass($systemreport))->getMethod('annotate_entity');
 201          $method->setAccessible(true);
 202  
 203          $method->invoke($systemreport, 'test', new lang_string('yes'));
 204          $this->assertEquals(new lang_string('yes'), $systemreport->get_entity_title('test'));
 205      }
 206  
 207      /**
 208       * Test entity annotation for invalid entity name
 209       */
 210      public function test_annotate_entity_invalid(): void {
 211          $this->resetAfterTest();
 212  
 213          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 214  
 215          $method = (new ReflectionClass($systemreport))->getMethod('annotate_entity');
 216          $method->setAccessible(true);
 217  
 218          $this->expectException(coding_exception::class);
 219          $this->expectExceptionMessage('Entity name must be comprised of alphanumeric character, underscore or dash');
 220          $method->invoke($systemreport, '', new lang_string('yes'));
 221      }
 222  
 223      /**
 224       * Test entity annotation for duplicated entity name
 225       */
 226      public function test_annotate_entity_duplicate(): void {
 227          $this->resetAfterTest();
 228  
 229          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 230  
 231          $method = (new ReflectionClass($systemreport))->getMethod('annotate_entity');
 232          $method->setAccessible(true);
 233  
 234          $method->invoke($systemreport, 'test', new lang_string('yes'));
 235  
 236          // Adding a second time with the same name should trigger exception.
 237          $this->expectException(coding_exception::class);
 238          $this->expectExceptionMessage('Duplicate entity name (test)');
 239          $method->invoke($systemreport, 'test', new lang_string('no'));
 240      }
 241  
 242      /**
 243       * Test for get_column
 244       */
 245      public function test_get_column(): void {
 246          $this->resetAfterTest();
 247  
 248          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 249          $column = $systemreport->get_column('user:username');
 250          $this->assertInstanceOf(column::class, $column);
 251  
 252          $column = $systemreport->get_column('user:nonexistingcolumn');
 253          $this->assertNull($column);
 254      }
 255  
 256      /**
 257       * Test for get_filter
 258       */
 259      public function test_get_filter(): void {
 260          $this->resetAfterTest();
 261  
 262          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance(),
 263              '', '', 0, ['withfilters' => true]);
 264          $filter = $systemreport->get_filter('user:username');
 265          $this->assertInstanceOf(filter::class, $filter);
 266  
 267          $filter = $systemreport->get_filter('user:nonexistingfilter');
 268          $this->assertNull($filter);
 269      }
 270  
 271      /**
 272       * Test for get_report_persistent
 273       */
 274      public function test_get_report_persistent(): void {
 275          $this->resetAfterTest();
 276  
 277          $systemreport = system_report_factory::create(system_report_available::class, context_system::instance());
 278          $persistent = $systemreport->get_report_persistent();
 279          $this->assertEquals(system_report_available::class, $persistent->get('source'));
 280      }
 281  }