Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 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 base entity
  19   *
  20   * @package     core_reportbuilder
  21   * @copyright   2021 David Matamoros <davidmc@moodle.com>
  22   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  declare(strict_types=1);
  26  
  27  namespace core_reportbuilder\local\entities;
  28  
  29  use advanced_testcase;
  30  use coding_exception;
  31  use lang_string;
  32  use ReflectionClass;
  33  use core_reportbuilder\local\filters\text;
  34  use core_reportbuilder\local\report\column;
  35  use core_reportbuilder\local\report\filter;
  36  
  37  defined('MOODLE_INTERNAL') || die();
  38  
  39  /**
  40   * Unit tests for base entity
  41   *
  42   * @package     core_reportbuilder
  43   * @covers      \core_reportbuilder\local\entities\base
  44   * @copyright   2021 David Matamoros <davidmc@moodle.com>
  45   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  46   */
  47  class base_test extends advanced_testcase {
  48  
  49      /**
  50       * Test entity table alias
  51       */
  52      public function test_get_table_alias(): void {
  53          $entity = new base_test_entity();
  54          $this->assertEquals('m', $entity->get_table_alias('mytable'));
  55      }
  56  
  57      /**
  58       * Test for invalid get table alias
  59       */
  60      public function test_get_table_alias_invalid(): void {
  61          $entity = new base_test_entity();
  62  
  63          $this->expectException(coding_exception::class);
  64          $this->expectExceptionMessage('Coding error detected, it must be fixed by a programmer: ' .
  65              'Invalid table name (nonexistingalias)');
  66          $entity->get_table_alias('nonexistingalias');
  67      }
  68  
  69      /**
  70       * Test setting table alias
  71       */
  72      public function test_set_table_alias(): void {
  73          $entity = new base_test_entity();
  74  
  75          $entity->set_table_alias('mytable', 'newalias');
  76          $this->assertEquals('newalias', $entity->get_table_alias('mytable'));
  77      }
  78  
  79      /**
  80       * Test invalid entity set table alias
  81       */
  82      public function test_set_table_alias_invalid(): void {
  83          $entity = new base_test_entity();
  84  
  85          $this->expectException(coding_exception::class);
  86          $this->expectExceptionMessage('Coding error detected, it must be fixed by a programmer: Invalid table name (nonexistent)');
  87          $entity->set_table_alias('nonexistent', 'newalias');
  88      }
  89  
  90      /**
  91       * Test entity name
  92       */
  93      public function test_set_entity_name(): void {
  94          $entity = new base_test_entity();
  95  
  96          $this->assertEquals('base_test_entity', $entity->get_entity_name());
  97  
  98          $entity->set_entity_name('newentityname');
  99          $this->assertEquals('newentityname', $entity->get_entity_name());
 100      }
 101  
 102      /**
 103       * Test invalid entity name
 104       */
 105      public function test_set_entity_name_invalid(): void {
 106          $entity = new base_test_entity();
 107  
 108          $this->expectException(coding_exception::class);
 109          $this->expectExceptionMessage('Entity name must be comprised of alphanumeric character, underscore or dash');
 110          $entity->set_entity_name('');
 111      }
 112  
 113      /**
 114       * Test entity title
 115       */
 116      public function test_set_entity_title(): void {
 117          $entity = new base_test_entity();
 118  
 119          $this->assertEquals(new lang_string('yes'), $entity->get_entity_title());
 120  
 121          $newtitle = new lang_string('fullname');
 122          $entity->set_entity_title($newtitle);
 123          $this->assertEquals($newtitle, $entity->get_entity_title());
 124      }
 125  
 126      /**
 127       * Test adding single join
 128       */
 129      public function test_add_join(): void {
 130          $entity = new base_test_entity();
 131  
 132          $tablejoin = "JOIN {course} c2 ON c2.id = c1.id";
 133          $entity->add_join($tablejoin);
 134  
 135          $method = (new ReflectionClass(base_test_entity::class))->getMethod('get_joins');
 136          $method->setAccessible(true);
 137          $this->assertEquals([$tablejoin], $method->invoke($entity));
 138      }
 139  
 140      /**
 141       * Test adding multiple joins
 142       */
 143      public function test_add_joins(): void {
 144          $entity = new base_test_entity();
 145  
 146          $tablejoins = [
 147              "JOIN {course} c2 ON c2.id = c1.id",
 148              "JOIN {course} c3 ON c3.id = c1.id",
 149          ];
 150          $entity->add_joins($tablejoins);
 151  
 152          $method = (new ReflectionClass(base_test_entity::class))->getMethod('get_joins');
 153          $method->setAccessible(true);
 154          $this->assertEquals($tablejoins, $method->invoke($entity));
 155      }
 156  
 157      /**
 158       * Test adding duplicate joins
 159       */
 160      public function test_add_duplicate_joins(): void {
 161          $entity = new base_test_entity();
 162  
 163          $tablejoins = [
 164              "JOIN {course} c2 ON c2.id = c1.id",
 165              "JOIN {course} c3 ON c3.id = c1.id",
 166          ];
 167          $entity
 168              ->add_joins($tablejoins)
 169              ->add_joins($tablejoins);
 170  
 171          $method = (new ReflectionClass(base_test_entity::class))->getMethod('get_joins');
 172          $method->setAccessible(true);
 173          $this->assertEquals($tablejoins, $method->invoke($entity));
 174      }
 175  
 176      /**
 177       * Test getting column
 178       */
 179      public function test_get_column(): void {
 180          $entity = (new base_test_entity())->initialise();
 181  
 182          $column = $entity->get_column('test');
 183          $this->assertEquals('base_test_entity:test', $column->get_unique_identifier());
 184      }
 185  
 186      /**
 187       * Test for invalid get column
 188       */
 189      public function test_get_column_invalid(): void {
 190          $entity = (new base_test_entity())->initialise();
 191  
 192          $this->expectException(coding_exception::class);
 193          $this->expectExceptionMessage('Coding error detected, it must be fixed by a programmer: ' .
 194              'Invalid column name (nonexistingcolumn)');
 195          $entity->get_column('nonexistingcolumn');
 196      }
 197  
 198      /**
 199       * Test getting columns
 200       */
 201      public function test_get_columns(): void {
 202          $entity = (new base_test_entity())->initialise();
 203  
 204          $columns = $entity->get_columns();
 205          $this->assertCount(1, $columns);
 206          $this->assertContainsOnlyInstancesOf(column::class, $columns);
 207      }
 208  
 209      /**
 210       * Test getting filter
 211       */
 212      public function test_get_filter(): void {
 213          $entity = (new base_test_entity())->initialise();
 214  
 215          $filter = $entity->get_filter('test');
 216          $this->assertEquals('base_test_entity:test', $filter->get_unique_identifier());
 217      }
 218  
 219      /**
 220       * Test for invalid get filter
 221       */
 222      public function test_get_filter_invalid(): void {
 223          $entity = (new base_test_entity())->initialise();
 224  
 225          $this->expectException(coding_exception::class);
 226          $this->expectExceptionMessage('Coding error detected, it must be fixed by a programmer: ' .
 227              'Invalid filter name (nonexistingfilter)');
 228          $entity->get_filter('nonexistingfilter');
 229      }
 230  
 231      /**
 232       * Test getting filters
 233       */
 234      public function test_get_filters(): void {
 235          $entity = (new base_test_entity())->initialise();
 236  
 237          $filters = $entity->get_filters();
 238          $this->assertCount(1, $filters);
 239          $this->assertContainsOnlyInstancesOf(filter::class, $filters);
 240      }
 241  
 242      /**
 243       * Test getting condition
 244       */
 245      public function test_get_condition(): void {
 246          $entity = (new base_test_entity())->initialise();
 247  
 248          $condition = $entity->get_condition('test');
 249          $this->assertEquals('base_test_entity:test', $condition->get_unique_identifier());
 250      }
 251  
 252      /**
 253       * Test for invalid get condition
 254       */
 255      public function test_get_condition_invalid(): void {
 256          $entity = (new base_test_entity())->initialise();
 257  
 258          $this->expectException(coding_exception::class);
 259          $this->expectExceptionMessage('Coding error detected, it must be fixed by a programmer: ' .
 260              'Invalid condition name (nonexistingcondition)');
 261          $entity->get_condition('nonexistingcondition');
 262      }
 263  
 264      /**
 265       * Test getting conditions
 266       */
 267      public function test_get_conditions(): void {
 268          $entity = (new base_test_entity())->initialise();
 269  
 270          $conditions = $entity->get_conditions();
 271          $this->assertCount(1, $conditions);
 272          $this->assertContainsOnlyInstancesOf(filter::class, $conditions);
 273      }
 274  }
 275  
 276  /**
 277   * Simple implementation of the base entity
 278   */
 279  class base_test_entity extends base {
 280  
 281      /**
 282       * Table aliases
 283       *
 284       * @return array
 285       */
 286      protected function get_default_table_aliases(): array {
 287          return [
 288              'mytable' => 'm',
 289              'myothertable' => 'o',
 290          ];
 291      }
 292  
 293      /**
 294       * Entity title
 295       *
 296       * @return lang_string
 297       */
 298      protected function get_default_entity_title(): lang_string {
 299          return new lang_string('yes');
 300      }
 301  
 302      /**
 303       * Initialise entity
 304       *
 305       * @return base
 306       */
 307      public function initialise(): base {
 308          $column = (new column(
 309              'test',
 310              new lang_string('no'),
 311              $this->get_entity_name()
 312          ))
 313              ->add_field('no');
 314  
 315          $filter = (new filter(
 316              text::class,
 317              'test',
 318              new lang_string('no'),
 319              $this->get_entity_name(),
 320          ))
 321              ->set_field_sql('no');
 322  
 323          return $this
 324              ->add_column($column)
 325              ->add_filter($filter)
 326              ->add_condition($filter);
 327      }
 328  }