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_course\reportbuilder\datasource; 20 21 use core_reportbuilder_generator; 22 use core_reportbuilder_testcase; 23 use core_reportbuilder\local\filters\{select, text}; 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 global $CFG; 28 require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php"); 29 30 /** 31 * Unit tests for course categories datasource 32 * 33 * @package core_course 34 * @covers \core_course\reportbuilder\datasource\categories 35 * @copyright 2023 Paul Holden <paulh@moodle.com> 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class categories_test extends core_reportbuilder_testcase { 39 40 /** 41 * Test default datasource 42 */ 43 public function test_datasource_default(): void { 44 $this->resetAfterTest(); 45 46 $category = $this->getDataGenerator()->create_category(['name' => 'Zoo', 'idnumber' => 'Z01']); 47 $course = $this->getDataGenerator()->create_course(['category' => $category->id]); 48 49 /** @var core_reportbuilder_generator $generator */ 50 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 51 $report = $generator->create_report(['name' => 'My report', 'source' => categories::class, 'default' => 1]); 52 53 $content = $this->get_custom_report_content($report->get('id')); 54 $this->assertCount(2, $content); 55 56 // Default columns are name, idnumber, coursecount. Sorted by name ascending. 57 $this->assertEquals([ 58 [get_string('defaultcategoryname'), '', 0], 59 [$category->get_formatted_name(), $category->idnumber, 1], 60 ], array_map('array_values', $content)); 61 } 62 63 /** 64 * Test datasource columns that aren't added by default 65 */ 66 public function test_datasource_non_default_columns(): void { 67 global $DB; 68 69 $this->resetAfterTest(); 70 71 $category = $this->getDataGenerator()->create_category(['name' => 'Zoo', 'idnumber' => 'Z01', 'description' => 'Animals']); 72 $course = $this->getDataGenerator()->create_course(['category' => $category->id, 'fullname' => 'Zebra']); 73 74 // Add a cohort. 75 $cohort = $this->getDataGenerator()->create_cohort(['contextid' => $category->get_context()->id, 'name' => 'My cohort']); 76 77 // Assign a role. 78 $managerrole = $DB->get_field('role', 'id', ['shortname' => 'manager']); 79 $user = $this->getDataGenerator()->create_user(); 80 role_assign($managerrole, $user->id, $category->get_context()->id); 81 82 /** @var core_reportbuilder_generator $generator */ 83 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 84 $report = $generator->create_report(['name' => 'My report', 'source' => categories::class, 'default' => 0]); 85 86 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course_category:namewithlink', 87 'sortenabled' => 1]); 88 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course_category:path']); 89 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course_category:description']); 90 91 // Add column from each of our entities. 92 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']); 93 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'cohort:name']); 94 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'role:name']); 95 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:fullname']); 96 97 $content = $this->get_custom_report_content($report->get('id')); 98 $this->assertCount(2, $content); 99 100 [$namewithlink, $path, $description, $coursename, $cohortname, $rolename, $userfullname] = array_values($content[0]); 101 $this->assertStringContainsString(get_string('defaultcategoryname'), $namewithlink); 102 $this->assertEquals(get_string('defaultcategoryname'), $path); 103 $this->assertEmpty($description); 104 $this->assertEmpty($coursename); 105 $this->assertEmpty($cohortname); 106 $this->assertEmpty($rolename); 107 $this->assertEmpty($userfullname); 108 109 [$namewithlink, $path, $description, $coursename, $cohortname, $rolename, $userfullname] = array_values($content[1]); 110 $this->assertStringContainsString($category->get_formatted_name(), $namewithlink); 111 $this->assertEquals($category->get_nested_name(false), $path); 112 $this->assertEquals(format_text($category->description, $category->descriptionformat), $description); 113 $this->assertEquals($course->fullname, $coursename); 114 $this->assertEquals($cohort->name, $cohortname); 115 $this->assertEquals('Manager', $rolename); 116 $this->assertEquals(fullname($user), $userfullname); 117 } 118 119 /** 120 * Data provider for {@see test_datasource_filters} 121 * 122 * @return array[] 123 */ 124 public static function datasource_filters_provider(): array { 125 global $DB; 126 127 return [ 128 // Category. 129 'Filter category (no match)' => ['course_category:name', [ 130 'course_category:name_value' => -1, 131 ], false], 132 'Filter category name' => ['course_category:text', [ 133 'course_category:text_operator' => text::IS_EQUAL_TO, 134 'course_category:text_value' => 'Zoo', 135 ], true], 136 'Filter category name (no match)' => ['course_category:text', [ 137 'course_category:text_operator' => text::IS_EQUAL_TO, 138 'course_category:text_value' => 'Plants', 139 ], false], 140 'Filter category idnumber' => ['course_category:idnumber', [ 141 'course_category:idnumber_operator' => text::IS_EQUAL_TO, 142 'course_category:idnumber_value' => 'Z01', 143 ], true], 144 'Filter category idnumber (no match)' => ['course_category:idnumber', [ 145 'course_category:idnumber_operator' => text::IS_EQUAL_TO, 146 'course_category:idnumber_value' => 'P01', 147 ], false], 148 149 // Course. 150 'Filter course fullname' => ['course:fullname', [ 151 'course:fullname_operator' => text::IS_EQUAL_TO, 152 'course:fullname_value' => 'Zebra', 153 ], true], 154 'Filter course fullname (no match)' => ['course:fullname', [ 155 'course:fullname_operator' => text::IS_EQUAL_TO, 156 'course:fullname_value' => 'Python', 157 ], false], 158 159 // Cohort. 160 'Filter cohort name' => ['cohort:name', [ 161 'cohort:name_operator' => text::IS_EQUAL_TO, 162 'cohort:name_value' => 'My cohort', 163 ], true], 164 'Filter cohort name (no match)' => ['cohort:name', [ 165 'cohort:name_operator' => text::IS_EQUAL_TO, 166 'cohort:name_value' => 'Not my cohort', 167 ], false], 168 169 // Role. 170 'Filter role' => ['role:name', [ 171 'role:name_operator' => select::EQUAL_TO, 172 'role:name_value' => $DB->get_field('role', 'id', ['shortname' => 'manager']), 173 ], true], 174 'Filter role (no match)' => ['role:name', [ 175 'role:name_operator' => select::EQUAL_TO, 176 'role:name_value' => -1, 177 ], false], 178 179 // User. 180 'Filter user firstname' => ['user:firstname', [ 181 'user:firstname_operator' => text::IS_EQUAL_TO, 182 'user:firstname_value' => 'Zoe', 183 ], true], 184 'Filter user firstname (no match)' => ['user:firstname', [ 185 'user:firstname_operator' => text::IS_EQUAL_TO, 186 'user:firstname_value' => 'Pedro', 187 ], false], 188 ]; 189 } 190 191 /** 192 * Test datasource filters 193 * 194 * @param string $filtername 195 * @param array $filtervalues 196 * @param bool $expectmatch 197 * 198 * @dataProvider datasource_filters_provider 199 */ 200 public function test_datasource_filters(string $filtername, array $filtervalues, bool $expectmatch): void { 201 global $DB; 202 203 $this->resetAfterTest(); 204 205 $category = $this->getDataGenerator()->create_category(['name' => 'Zoo', 'idnumber' => 'Z01']); 206 $course = $this->getDataGenerator()->create_course(['category' => $category->id, 'fullname' => 'Zebra']); 207 208 // Add a cohort. 209 $cohort = $this->getDataGenerator()->create_cohort(['contextid' => $category->get_context()->id, 'name' => 'My cohort']); 210 211 // Assign a role. 212 $managerrole = $DB->get_field('role', 'id', ['shortname' => 'manager']); 213 $user = $this->getDataGenerator()->create_user(['firstname' => 'Zoe']); 214 role_assign($managerrole, $user->id, $category->get_context()->id); 215 216 /** @var core_reportbuilder_generator $generator */ 217 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 218 219 // Create report containing single idnumber column, and given filter. 220 $report = $generator->create_report(['name' => 'My report', 'source' => categories::class, 'default' => 0]); 221 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course_category:idnumber']); 222 223 // Add filter, set it's values. 224 $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]); 225 $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues); 226 227 if ($expectmatch) { 228 $this->assertCount(1, $content); 229 $this->assertEquals($category->idnumber, reset($content[0])); 230 } else { 231 $this->assertEmpty($content); 232 } 233 } 234 235 /** 236 * Stress test datasource 237 * 238 * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php 239 */ 240 public function test_stress_datasource(): void { 241 if (!PHPUNIT_LONGTEST) { 242 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 243 } 244 245 $this->resetAfterTest(); 246 247 $category = $this->getDataGenerator()->create_category(['name' => 'My category']); 248 249 $this->datasource_stress_test_columns(categories::class); 250 $this->datasource_stress_test_columns_aggregation(categories::class); 251 $this->datasource_stress_test_conditions(categories::class, 'course_category:idnumber'); 252 } 253 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body