Differences Between: [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_group\reportbuilder\datasource; 20 21 use core_customfield_generator; 22 use core_reportbuilder_generator; 23 use core_reportbuilder_testcase; 24 use core_reportbuilder\local\filters\{boolean_select, date, select, text}; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php"); 30 31 /** 32 * Unit tests for groups datasource 33 * 34 * @package core_group 35 * @covers \core_group\reportbuilder\datasource\groups 36 * @copyright 2022 Paul Holden <paulh@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class groups_test extends core_reportbuilder_testcase { 40 41 /** 42 * Test default datasource 43 */ 44 public function test_datasource_default(): void { 45 $this->resetAfterTest(); 46 47 $course = $this->getDataGenerator()->create_course(); 48 $userone = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe']); 49 $usertwo = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Amy']); 50 51 $groupone = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Zebras']); 52 $grouptwo = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Aardvarks']); 53 54 $this->getDataGenerator()->create_group_member(['groupid' => $groupone->id, 'userid' => $userone->id]); 55 $this->getDataGenerator()->create_group_member(['groupid' => $groupone->id, 'userid' => $usertwo->id]); 56 57 /** @var core_reportbuilder_generator $generator */ 58 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 59 $report = $generator->create_report(['name' => 'Groups', 'source' => groups::class, 'default' => 1]); 60 61 $content = $this->get_custom_report_content($report->get('id')); 62 63 // Default columns are course, group, user. Sorted by each. 64 $courseurl = course_get_url($course); 65 $this->assertEquals([ 66 ["<a href=\"{$courseurl}\">{$course->fullname}</a>", $grouptwo->name, ''], 67 ["<a href=\"{$courseurl}\">{$course->fullname}</a>", $groupone->name, fullname($usertwo)], 68 ["<a href=\"{$courseurl}\">{$course->fullname}</a>", $groupone->name, fullname($userone)], 69 ], array_map('array_values', $content)); 70 } 71 72 /** 73 * Test datasource groupings reports 74 */ 75 public function test_datasource_groupings(): void { 76 $this->resetAfterTest(); 77 78 $course = $this->getDataGenerator()->create_course(); 79 80 // Create group, add to grouping. 81 $groupone = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Group A']); 82 $grouping = $this->getDataGenerator()->create_grouping(['courseid' => $course->id]); 83 $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $groupone->id]); 84 85 // Create second group, no grouping. 86 $grouptwo = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Group B']); 87 88 /** @var core_reportbuilder_generator $generator */ 89 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 90 $report = $generator->create_report(['name' => 'Groups', 'source' => groups::class, 'default' => 0]); 91 92 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']); 93 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:name']); 94 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:name', 'sortenabled' => 1]); 95 96 $content = $this->get_custom_report_content($report->get('id')); 97 $this->assertCount(2, $content); 98 99 $this->assertEquals([ 100 [ 101 $course->fullname, 102 $grouping->name, 103 $groupone->name, 104 ], 105 [ 106 $course->fullname, 107 null, 108 $grouptwo->name, 109 ], 110 ], array_map('array_values', $content)); 111 } 112 113 /** 114 * Test datasource columns that aren't added by default 115 */ 116 public function test_datasource_non_default_columns(): void { 117 $this->resetAfterTest(); 118 $this->setAdminUser(); 119 120 $course = $this->getDataGenerator()->create_course(); 121 $user = $this->getDataGenerator()->create_and_enrol($course, 'student'); 122 123 /** @var core_customfield_generator $generator */ 124 $generator = $this->getDataGenerator()->get_plugin_generator('core_customfield'); 125 126 // Create group with custom field, and single group member. 127 $groupfieldcategory = $generator->create_category(['component' => 'core_group', 'area' => 'group']); 128 $generator->create_field(['categoryid' => $groupfieldcategory->get('id'), 'shortname' => 'hi']); 129 130 $group = $this->getDataGenerator()->create_group([ 131 'courseid' => $course->id, 132 'idnumber' => 'G101', 133 'enrolmentkey' => 'S', 134 'description' => 'My group', 135 'customfield_hi' => 'Hello', 136 ]); 137 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 138 139 // Create grouping with custom field, and single group. 140 $groupingfieldcategory = $generator->create_category(['component' => 'core_group', 'area' => 'grouping']); 141 $generator->create_field(['categoryid' => $groupingfieldcategory->get('id'), 'shortname' => 'bye']); 142 143 $grouping = $this->getDataGenerator()->create_grouping([ 144 'courseid' => $course->id, 145 'idnumber' => 'GR101', 146 'description' => 'My grouping', 147 'customfield_bye' => 'Goodbye', 148 ]); 149 $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $group->id]); 150 151 /** @var core_reportbuilder_generator $generator */ 152 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 153 $report = $generator->create_report(['name' => 'Groups', 'source' => groups::class, 'default' => 0]); 154 155 // Course (just to test join). 156 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:shortname']); 157 158 // Group. 159 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:idnumber']); 160 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:description']); 161 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:enrolmentkey']); 162 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:visibility']); 163 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:participation']); 164 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:picture']); 165 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:timecreated']); 166 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:timemodified']); 167 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:customfield_hi']); 168 169 // Grouping. 170 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:name']); 171 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:idnumber']); 172 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:description']); 173 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:timecreated']); 174 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:timemodified']); 175 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:customfield_bye']); 176 177 // Group member. 178 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group_member:timeadded']); 179 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group_member:component']); 180 181 // User (just to test join). 182 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:username']); 183 184 $content = $this->get_custom_report_content($report->get('id')); 185 $this->assertCount(1, $content); 186 187 [ 188 $courseshortname, 189 $groupidnumber, 190 $groupdescription, 191 $groupenrolmentkey, 192 $groupvisibility, 193 $groupparticipation, 194 $grouppicture, 195 $grouptimecreated, 196 $grouptimemodified, 197 $groupcustomfield, 198 $groupingname, 199 $groupingidnumber, 200 $groupingdescription, 201 $groupingtimecreated, 202 $groupingtimemodified, 203 $groupingcustomfield, 204 $groupmembertimeadded, 205 $groupmemebercomponent, 206 $userusername, 207 ] = array_values($content[0]); 208 209 $this->assertEquals($course->shortname, $courseshortname); 210 $this->assertEquals('G101', $groupidnumber); 211 $this->assertEquals(format_text($group->description), $groupdescription); 212 $this->assertEquals('S', $groupenrolmentkey); 213 $this->assertEquals('Visible', $groupvisibility); 214 $this->assertEquals('Yes', $groupparticipation); 215 $this->assertEmpty($grouppicture); 216 $this->assertNotEmpty($grouptimecreated); 217 $this->assertNotEmpty($grouptimemodified); 218 $this->assertEquals('Hello', $groupcustomfield); 219 $this->assertEquals($grouping->name, $groupingname); 220 $this->assertEquals('GR101', $groupingidnumber); 221 $this->assertEquals(format_text($grouping->description), $groupingdescription); 222 $this->assertNotEmpty($groupingtimecreated); 223 $this->assertNotEmpty($groupingtimemodified); 224 $this->assertEquals('Goodbye', $groupingcustomfield); 225 $this->assertNotEmpty($groupmembertimeadded); 226 $this->assertEmpty($groupmemebercomponent); 227 $this->assertEquals($user->username, $userusername); 228 } 229 230 /** 231 * Data provider for {@see test_datasource_filters} 232 * 233 * @return array[] 234 */ 235 public function datasource_filters_provider(): array { 236 return [ 237 // Course (just to test join). 238 'Filter course name' => ['course:fullname', [ 239 'course:fullname_operator' => text::IS_EQUAL_TO, 240 'course:fullname_value' => 'Test course', 241 ], true], 242 'Filter course name (no match)' => ['course:fullname', [ 243 'course:fullname_operator' => text::IS_NOT_EQUAL_TO, 244 'course:fullname_value' => 'Test course', 245 ], false], 246 247 // Group. 248 'Filter group name' => ['group:name', [ 249 'group:name_operator' => text::IS_EQUAL_TO, 250 'group:name_value' => 'Test group', 251 ], true], 252 'Filter group name (no match)' => ['group:name', [ 253 'group:name_operator' => text::IS_NOT_EQUAL_TO, 254 'group:name_value' => 'Test group', 255 ], false], 256 'Filter group idnumber' => ['group:idnumber', [ 257 'group:idnumber_operator' => text::IS_EQUAL_TO, 258 'group:idnumber_value' => 'G101', 259 ], true], 260 'Filter group idnumber (no match)' => ['group:idnumber', [ 261 'group:idnumber_operator' => text::IS_NOT_EQUAL_TO, 262 'group:idnumber_value' => 'G101', 263 ], false], 264 'Filter group visibility' => ['group:visibility', [ 265 'group:visibility_operator' => select::EQUAL_TO, 266 'group:visibility_value' => 0, // Visible to everyone. 267 ], true], 268 'Filter group visibility (no match)' => ['group:visibility', [ 269 'group:visibility_operator' => select::EQUAL_TO, 270 'group:visibility_value' => 1, // Visible to members only. 271 ], false], 272 'Filter group participation' => ['group:participation', [ 273 'group:participation_operator' => boolean_select::CHECKED, 274 ], true], 275 'Filter group participation (no match)' => ['group:participation', [ 276 'group:participation_operator' => boolean_select::NOT_CHECKED, 277 ], false], 278 'Filter group time created' => ['group:timecreated', [ 279 'group:timecreated_operator' => date::DATE_RANGE, 280 'group:timecreated_from' => 1622502000, 281 ], true], 282 'Filter group time created (no match)' => ['group:timecreated', [ 283 'group:timecreated_operator' => date::DATE_RANGE, 284 'group:timecreated_to' => 1622502000, 285 ], false], 286 287 // Grouping. 288 'Filter grouping name' => ['grouping:name', [ 289 'grouping:name_operator' => text::IS_EQUAL_TO, 290 'grouping:name_value' => 'Test grouping', 291 ], true], 292 'Filter grouping name (no match)' => ['grouping:name', [ 293 'grouping:name_operator' => text::IS_NOT_EQUAL_TO, 294 'grouping:name_value' => 'Test grouping', 295 ], false], 296 'Filter grouping idnumber' => ['grouping:idnumber', [ 297 'grouping:idnumber_operator' => text::IS_EQUAL_TO, 298 'grouping:idnumber_value' => 'GR101', 299 ], true], 300 'Filter grouping idnumber (no match)' => ['grouping:idnumber', [ 301 'grouping:idnumber_operator' => text::IS_NOT_EQUAL_TO, 302 'grouping:idnumber_value' => 'GR101', 303 ], false], 304 'Filter grouping time created' => ['grouping:timecreated', [ 305 'grouping:timecreated_operator' => date::DATE_RANGE, 306 'grouping:timecreated_from' => 1622502000, 307 ], true], 308 'Filter grouping time created (no match)' => ['grouping:timecreated', [ 309 'grouping:timecreated_operator' => date::DATE_RANGE, 310 'grouping:timecreated_to' => 1622502000, 311 ], false], 312 313 // Group member. 314 'Filter group member time added' => ['group_member:timeadded', [ 315 'group_member:timeadded_operator' => date::DATE_RANGE, 316 'group_member:timeadded_from' => 1622502000, 317 ], true], 318 'Filter group member time added (no match)' => ['group_member:timeadded', [ 319 'group_member:timeadded_operator' => date::DATE_RANGE, 320 'group_member:timeadded_to' => 1622502000, 321 ], false], 322 323 // User (just to test join). 324 'Filter user username' => ['user:username', [ 325 'user:username_operator' => text::IS_EQUAL_TO, 326 'user:username_value' => 'testuser', 327 ], true], 328 'Filter user username (no match)' => ['user:username', [ 329 'user:username_operator' => text::IS_NOT_EQUAL_TO, 330 'user:username_value' => 'testuser', 331 ], false], 332 ]; 333 } 334 335 /** 336 * Test datasource filters 337 * 338 * @param string $filtername 339 * @param array $filtervalues 340 * @param bool $expectmatch 341 * 342 * @dataProvider datasource_filters_provider 343 */ 344 public function test_datasource_filters( 345 string $filtername, 346 array $filtervalues, 347 bool $expectmatch 348 ): void { 349 $this->resetAfterTest(); 350 351 $course = $this->getDataGenerator()->create_course(['fullname' => 'Test course']); 352 $user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['username' => 'testuser']); 353 354 $group = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'idnumber' => 'G101', 'name' => 'Test group']); 355 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 356 357 $grouping = $this->getDataGenerator()->create_grouping(['courseid' => $course->id, 'idnumber' => 'GR101', 358 'name' => 'Test grouping']); 359 $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $group->id]); 360 361 /** @var core_reportbuilder_generator $generator */ 362 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 363 364 // Create report containing single column, and given filter. 365 $report = $generator->create_report(['name' => 'Tasks', 'source' => groups::class, 'default' => 0]); 366 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:idnumber']); 367 368 // Add filter, set it's values. 369 $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]); 370 $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues); 371 372 if ($expectmatch) { 373 $this->assertCount(1, $content); 374 $this->assertEquals('G101', reset($content[0])); 375 } else { 376 $this->assertEmpty($content); 377 } 378 } 379 380 /** 381 * Stress test datasource 382 * 383 * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php 384 */ 385 public function test_stress_datasource(): void { 386 if (!PHPUNIT_LONGTEST) { 387 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 388 } 389 390 $this->resetAfterTest(); 391 392 $course = $this->getDataGenerator()->create_course(['fullname' => 'Test course']); 393 $user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['username' => 'testuser']); 394 395 $group = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'idnumber' => 'G101', 'name' => 'Test group']); 396 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 397 398 $grouping = $this->getDataGenerator()->create_grouping(['courseid' => $course->id, 'idnumber' => 'GR101', 399 'name' => 'Test grouping']); 400 $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $group->id]); 401 402 $this->datasource_stress_test_columns(groups::class); 403 $this->datasource_stress_test_columns_aggregation(groups::class); 404 $this->datasource_stress_test_conditions(groups::class, 'group:idnumber'); 405 } 406 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body