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  declare(strict_types=1);
  18  
  19  namespace core_reportbuilder\local\helpers;
  20  
  21  use advanced_testcase;
  22  use context_system;
  23  use core_reportbuilder_generator;
  24  use core_reportbuilder\reportbuilder\audience\manual;
  25  use core_user\reportbuilder\datasource\users;
  26  
  27  /**
  28   * Unit tests for audience helper
  29   *
  30   * @package     core_reportbuilder
  31   * @covers      \core_reportbuilder\local\helpers\audience
  32   * @copyright   2021 David Matamoros <davidmc@moodle.com>
  33   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  class audience_test extends advanced_testcase {
  36  
  37       /**
  38        * Test reports list is empty for a normal user without any audience records configured
  39        */
  40      public function test_reports_list_no_access(): void {
  41          $this->resetAfterTest();
  42  
  43          $reports = audience::user_reports_list();
  44          $this->assertEmpty($reports);
  45      }
  46  
  47      /**
  48       * Test get_base_records()
  49       */
  50      public function test_get_base_records(): void {
  51          $this->resetAfterTest();
  52  
  53          /** @var core_reportbuilder_generator $generator */
  54          $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
  55  
  56          // Report with no audiences.
  57          $report = $generator->create_report([
  58              'name' => 'My report',
  59              'source' => users::class,
  60              'default' => false,
  61          ]);
  62          $baserecords = audience::get_base_records($report->get('id'));
  63          $this->assertEmpty($baserecords);
  64  
  65          // Create a couple of manual audience types.
  66          $user1 = $this->getDataGenerator()->create_user();
  67          $user2 = $this->getDataGenerator()->create_user();
  68          $audience1 = $generator->create_audience([
  69              'reportid' => $report->get('id'),
  70              'classname' => manual::class,
  71              'configdata' => ['users' => [$user1->id, $user2->id]],
  72          ]);
  73  
  74          $user3 = $this->getDataGenerator()->create_user();
  75          $audience2 = $generator->create_audience([
  76              'reportid' => $report->get('id'),
  77              'classname' => manual::class,
  78              'configdata' => ['users' => [$user3->id]],
  79          ]);
  80  
  81          $baserecords = audience::get_base_records($report->get('id'));
  82          $this->assertCount(2, $baserecords);
  83          $this->assertContainsOnlyInstancesOf(manual::class, $baserecords);
  84  
  85          // Set invalid classname of first audience, should be excluded in subsequent request.
  86          $audience1->get_persistent()->set('classname', '\invalid')->save();
  87  
  88          $baserecords = audience::get_base_records($report->get('id'));
  89          $this->assertCount(1, $baserecords);
  90  
  91          $baserecord = reset($baserecords);
  92          $this->assertInstanceOf(manual::class, $baserecord);
  93          $this->assertEquals($audience2->get_persistent()->get('id'), $baserecord->get_persistent()->get('id'));
  94      }
  95  
  96      /**
  97       * Test get_allowed_reports()
  98       */
  99      public function test_get_allowed_reports(): void {
 100          $this->resetAfterTest();
 101  
 102          /** @var core_reportbuilder_generator $generator */
 103          $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
 104  
 105          $user1 = $this->getDataGenerator()->create_user();
 106          $user2 = $this->getDataGenerator()->create_user();
 107          self::setUser($user1);
 108  
 109          // No reports.
 110          $reports = audience::get_allowed_reports();
 111          $this->assertEmpty($reports);
 112  
 113          $report1 = $generator->create_report([
 114              'name' => 'My report',
 115              'source' => users::class,
 116              'default' => false,
 117          ]);
 118          $report2 = $generator->create_report([
 119              'name' => 'My report',
 120              'source' => users::class,
 121              'default' => false,
 122          ]);
 123          $report3 = $generator->create_report([
 124              'name' => 'My report',
 125              'source' => users::class,
 126              'default' => false,
 127          ]);
 128  
 129          // Reports with no audiences set.
 130          $reports = audience::get_allowed_reports();
 131          $this->assertEmpty($reports);
 132  
 133          $generator->create_audience([
 134              'reportid' => $report1->get('id'),
 135              'classname' => manual::class,
 136              'configdata' => ['users' => [$user1->id, $user2->id]],
 137          ]);
 138          $generator->create_audience([
 139              'reportid' => $report2->get('id'),
 140              'classname' => manual::class,
 141              'configdata' => ['users' => [$user2->id]],
 142          ]);
 143          $generator->create_audience([
 144              'reportid' => $report3->get('id'),
 145              'classname' => manual::class,
 146              'configdata' => ['users' => [$user1->id]],
 147          ]);
 148  
 149          // Purge cache, to ensure allowed reports are re-calculated.
 150          audience::purge_caches();
 151  
 152          $reports = audience::get_allowed_reports();
 153          $this->assertEqualsCanonicalizing([$report1->get('id'), $report3->get('id')], $reports);
 154  
 155          // User2 can access report1 and report2.
 156          $reports = audience::get_allowed_reports((int) $user2->id);
 157          $this->assertEqualsCanonicalizing([$report1->get('id'), $report2->get('id')], $reports);
 158      }
 159  
 160      /**
 161       * Test user_reports_list()
 162       */
 163      public function test_user_reports_list(): void {
 164          $this->resetAfterTest();
 165  
 166          /** @var core_reportbuilder_generator $generator */
 167          $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
 168  
 169          $user1 = $this->getDataGenerator()->create_user();
 170          $user2 = $this->getDataGenerator()->create_user();
 171          $user3 = $this->getDataGenerator()->create_user();
 172          self::setUser($user1);
 173  
 174          $reports = audience::user_reports_list();
 175          $this->assertEmpty($reports);
 176  
 177          $report1 = $generator->create_report([
 178              'name' => 'My report',
 179              'source' => users::class,
 180              'default' => false,
 181          ]);
 182          $report2 = $generator->create_report([
 183              'name' => 'My report',
 184              'source' => users::class,
 185              'default' => false,
 186          ]);
 187          $report3 = $generator->create_report([
 188              'name' => 'My report',
 189              'source' => users::class,
 190              'default' => false,
 191          ]);
 192  
 193          $generator->create_audience([
 194              'reportid' => $report1->get('id'),
 195              'classname' => manual::class,
 196              'configdata' => ['users' => [$user1->id, $user2->id]],
 197          ]);
 198          $generator->create_audience([
 199              'reportid' => $report2->get('id'),
 200              'classname' => manual::class,
 201              'configdata' => ['users' => [$user2->id]],
 202          ]);
 203          $generator->create_audience([
 204              'reportid' => $report3->get('id'),
 205              'classname' => manual::class,
 206              'configdata' => ['users' => [$user1->id]],
 207          ]);
 208  
 209          // Purge cache, to ensure allowed reports are re-calculated.
 210          audience::purge_caches();
 211  
 212          // User1 can access report1 and report3.
 213          $reports = audience::user_reports_list();
 214          $this->assertEqualsCanonicalizing([$report1->get('id'), $report3->get('id')], $reports);
 215  
 216          // User2 can access report1 and report2.
 217          $reports = audience::user_reports_list((int) $user2->id);
 218          $this->assertEqualsCanonicalizing([$report1->get('id'), $report2->get('id')], $reports);
 219  
 220          // User3 can not access any report.
 221          $reports = audience::user_reports_list((int) $user3->id);
 222          $this->assertEmpty($reports);
 223      }
 224  
 225      /**
 226       * Test get_all_audiences_menu_types()
 227       */
 228      public function test_get_all_audiences_menu_types(): void {
 229          $this->resetAfterTest();
 230  
 231          // Test with user that has no permission to add audiences.
 232          $user1 = $this->getDataGenerator()->create_user();
 233          $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description');
 234          assign_capability('moodle/user:viewalldetails', CAP_PROHIBIT, $roleid, context_system::instance()->id);
 235          role_assign($roleid, $user1->id, context_system::instance()->id);
 236          self::setUser($user1);
 237          $categories = audience::get_all_audiences_menu_types();
 238          $this->assertEmpty($categories);
 239  
 240          self::setAdminUser();
 241          $categories = audience::get_all_audiences_menu_types();
 242          $category = array_filter($categories, function ($category) {
 243              return $category['name'] === 'Site';
 244          });
 245          $category = reset($category);
 246          // We don't use assertEqual here to avoid this test failing when more audience types get created.
 247          $this->assertGreaterThanOrEqual(3, $category['items']);
 248      }
 249  }