See Release Notes
Long Term Support Release
Differences Between: [Versions 401 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_tag\reportbuilder\datasource; 20 21 use context_course; 22 use context_user; 23 use core_collator; 24 use core_reportbuilder_generator; 25 use core_reportbuilder_testcase; 26 use core_reportbuilder\local\filters\{boolean_select, date, select}; 27 use core_reportbuilder\local\filters\tags as tags_filter; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php"); 33 34 /** 35 * Unit tests for tags datasource 36 * 37 * @package core_tag 38 * @covers \core_tag\reportbuilder\datasource\tags 39 * @copyright 2022 Paul Holden <paulh@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class tags_test extends core_reportbuilder_testcase { 43 44 /** 45 * Test default datasource 46 */ 47 public function test_datasource_default(): void { 48 $this->resetAfterTest(); 49 50 $course = $this->getDataGenerator()->create_course(['tags' => ['Horses']]); 51 $coursecontext = context_course::instance($course->id); 52 53 $user = $this->getDataGenerator()->create_user(['interests' => ['Pies']]); 54 $usercontext = context_user::instance($user->id); 55 56 /** @var core_reportbuilder_generator $generator */ 57 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 58 $report = $generator->create_report(['name' => 'Notes', 'source' => tags::class, 'default' => 1]); 59 60 $content = $this->get_custom_report_content($report->get('id')); 61 $this->assertCount(2, $content); 62 63 // Consistent order (course, user), just in case. 64 core_collator::asort_array_of_arrays_by_key($content, 'c3_contextid'); 65 $content = array_values($content); 66 67 // Default columns are collection, tag name, tag standard, instance context. 68 [$courserow, $userrow] = array_map('array_values', $content); 69 70 $this->assertEquals('Default collection', $courserow[0]); 71 $this->assertStringContainsString('Horses', $courserow[1]); 72 $this->assertEquals('No', $courserow[2]); 73 $this->assertEquals($coursecontext->get_context_name(), $courserow[3]); 74 75 $this->assertEquals('Default collection', $userrow[0]); 76 $this->assertStringContainsString('Pies', $userrow[1]); 77 $this->assertEquals('No', $courserow[2]); 78 $this->assertEquals($usercontext->get_context_name(), $userrow[3]); 79 } 80 81 /** 82 * Test datasource columns that aren't added by default 83 */ 84 public function test_datasource_non_default_columns(): void { 85 $this->resetAfterTest(); 86 87 $this->getDataGenerator()->create_tag(['name' => 'Horses', 'description' => 'Neigh', 'flag' => 2]); 88 $course = $this->getDataGenerator()->create_course(['tags' => ['Horses']]); 89 $coursecontext = context_course::instance($course->id); 90 91 /** @var core_reportbuilder_generator $generator */ 92 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 93 $report = $generator->create_report(['name' => 'Notes', 'source' => tags::class, 'default' => 0]); 94 95 // Collection. 96 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'collection:default']); 97 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'collection:component']); 98 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'collection:searchable']); 99 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'collection:customurl']); 100 101 // Tag. 102 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']); 103 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:description']); 104 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:flagged']); 105 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:timemodified']); 106 107 // Instance. 108 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:contexturl']); 109 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:area']); 110 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:component']); 111 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:itemtype']); 112 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:itemid']); 113 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:timecreated']); 114 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'instance:timemodified']); 115 116 $content = $this->get_custom_report_content($report->get('id')); 117 $this->assertCount(1, $content); 118 119 $courserow = array_values($content[0]); 120 121 // Collection. 122 $this->assertEquals('Yes', $courserow[0]); 123 $this->assertEmpty($courserow[1]); 124 $this->assertEquals('Yes', $courserow[2]); 125 $this->assertEmpty($courserow[3]); 126 127 // Tag. 128 $this->assertEquals('Horses', $courserow[4]); 129 $this->assertEquals('<div class="text_to_html">Neigh</div>', $courserow[5]); 130 $this->assertEquals('Yes', $courserow[6]); 131 $this->assertNotEmpty($courserow[7]); 132 133 // Instance. 134 $this->assertEquals('<a href="' . $coursecontext->get_url() . '">' . $coursecontext->get_context_name() . '</a>', 135 $courserow[8]); 136 $this->assertEquals('Courses', $courserow[9]); 137 $this->assertEquals('core', $courserow[10]); 138 $this->assertEquals('course', $courserow[11]); 139 $this->assertEquals($course->id, $courserow[12]); 140 $this->assertNotEmpty($courserow[13]); 141 $this->assertNotEmpty($courserow[14]); 142 } 143 144 /** 145 * Data provider for {@see test_datasource_filters} 146 * 147 * @return array[] 148 */ 149 public function datasource_filters_provider(): array { 150 return [ 151 // Collection. 152 'Filter collection name' => ['collection:name', [ 153 'collection:name_operator' => select::NOT_EQUAL_TO, 154 'collection:name_value' => -1, 155 ], true], 156 'Filter collection default' => ['collection:default', [ 157 'collection:default_operator' => boolean_select::CHECKED, 158 ], true], 159 'Filter collection default (no match)' => ['collection:default', [ 160 'collection:default_operator' => boolean_select::NOT_CHECKED, 161 ], false], 162 'Filter collection searchable' => ['collection:searchable', [ 163 'collection:searchable_operator' => boolean_select::CHECKED, 164 ], true], 165 'Filter collection searchable (no match)' => ['collection:searchable', [ 166 'collection:searchable_operator' => boolean_select::NOT_CHECKED, 167 ], false], 168 169 // Tag. 170 'Filter tag name equal to' => ['tag:name', [ 171 'tag:name_operator' => tags_filter::EQUAL_TO, 172 'tag:name_value' => [-1], 173 ], false], 174 'Filter tag name not equal to' => ['tag:name', [ 175 'tag:name_operator' => tags_filter::NOT_EQUAL_TO, 176 'tag:name_value' => [-1], 177 ], true], 178 'Filter tag name empty' => ['tag:name', [ 179 'tag:name_operator' => tags_filter::EMPTY, 180 ], false], 181 'Filter tag name not empty' => ['tag:name', [ 182 'tag:name_operator' => tags_filter::NOT_EMPTY, 183 ], true], 184 'Filter tag standard' => ['tag:standard', [ 185 'tag:standard_operator' => boolean_select::NOT_CHECKED, 186 ], true], 187 'Filter tag standard (no match)' => ['tag:standard', [ 188 'tag:standard_operator' => boolean_select::CHECKED, 189 ], false], 190 'Filter tag flagged' => ['tag:flagged', [ 191 'tag:flagged_operator' => boolean_select::CHECKED, 192 ], true], 193 'Filter tag flagged (no match)' => ['tag:flagged', [ 194 'tag:flagged_operator' => boolean_select::NOT_CHECKED, 195 ], false], 196 'Filter tag time modified' => ['tag:timemodified', [ 197 'tag:timemodified_operator' => date::DATE_RANGE, 198 'tag:timemodified_from' => 1622502000, 199 ], true], 200 'Filter tag time modified (no match)' => ['tag:timemodified', [ 201 'tag:timemodified_operator' => date::DATE_RANGE, 202 'tag:timemodified_to' => 1622502000, 203 ], false], 204 205 // Instance. 206 'Filter instance tag area' => ['instance:area', [ 207 'instance:area_operator' => select::EQUAL_TO, 208 'instance:area_value' => 'core/course', 209 ], true], 210 'Filter instance tag area (no match)' => ['instance:area', [ 211 'instance:area_operator' => select::NOT_EQUAL_TO, 212 'instance:area_value' => 'core/course', 213 ], false], 214 'Filter instance time created' => ['instance:timecreated', [ 215 'instance:timecreated_operator' => date::DATE_RANGE, 216 'instance:timecreated_from' => 1622502000, 217 ], true], 218 'Filter instance time created (no match)' => ['instance:timecreated', [ 219 'instance:timecreated_operator' => date::DATE_RANGE, 220 'instance:timecreated_to' => 1622502000, 221 ], false], 222 'Filter instance time modified' => ['instance:timemodified', [ 223 'instance:timemodified_operator' => date::DATE_RANGE, 224 'instance:timemodified_from' => 1622502000, 225 ], true], 226 'Filter instance time modified (no match)' => ['instance:timemodified', [ 227 'instance:timemodified_operator' => date::DATE_RANGE, 228 'instance:timemodified_to' => 1622502000, 229 ], false], 230 ]; 231 } 232 233 /** 234 * Test datasource filters 235 * 236 * @param string $filtername 237 * @param array $filtervalues 238 * @param bool $expectmatch 239 * 240 * @dataProvider datasource_filters_provider 241 */ 242 public function test_datasource_filters( 243 string $filtername, 244 array $filtervalues, 245 bool $expectmatch 246 ): void { 247 $this->resetAfterTest(); 248 249 $this->getDataGenerator()->create_tag(['name' => 'Horses', 'flag' => 2]); 250 $this->getDataGenerator()->create_course(['tags' => ['Horses']]); 251 252 /** @var core_reportbuilder_generator $generator */ 253 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 254 255 // Create report containing single tag name, and given filter. 256 $report = $generator->create_report(['name' => 'Tasks', 'source' => tags::class, 'default' => 0]); 257 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']); 258 259 // Add filter, set it's values. 260 $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]); 261 $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues); 262 263 if ($expectmatch) { 264 $this->assertCount(1, $content); 265 $this->assertEquals('Horses', reset($content[0])); 266 } else { 267 $this->assertEmpty($content); 268 } 269 } 270 271 /** 272 * Stress test datasource 273 * 274 * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php 275 */ 276 public function test_stress_datasource(): void { 277 if (!PHPUNIT_LONGTEST) { 278 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 279 } 280 281 $this->resetAfterTest(); 282 283 $this->getDataGenerator()->create_course(['tags' => ['Horses']]); 284 285 $this->datasource_stress_test_columns(tags::class); 286 $this->datasource_stress_test_columns_aggregation(tags::class); 287 $this->datasource_stress_test_conditions(tags::class, 'tag:name'); 288 } 289 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body