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 core_reportbuilder_generator; 22 use core_reportbuilder_testcase; 23 use core_reportbuilder\local\entities\user; 24 use core_reportbuilder\local\filters\boolean_select; 25 use core_reportbuilder\local\filters\date; 26 use core_reportbuilder\local\filters\select; 27 use core_reportbuilder\local\filters\text; 28 use core_reportbuilder\local\helpers\user_filter_manager; 29 use core_reportbuilder\local\report\column; 30 use core_reportbuilder\local\report\filter; 31 use core_user\reportbuilder\datasource\users; 32 33 defined('MOODLE_INTERNAL') || die(); 34 35 global $CFG; 36 require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php"); 37 38 /** 39 * Unit tests for user profile fields helper 40 * 41 * @package core_reportbuilder 42 * @covers \core_reportbuilder\local\helpers\user_profile_fields 43 * @copyright 2021 David Matamoros <davidmc@moodle.com> 44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 45 */ 46 class user_profile_fields_test extends core_reportbuilder_testcase { 47 48 /** 49 * Generate custom profile fields, one of each type 50 * 51 * @return user_profile_fields 52 */ 53 private function generate_userprofilefields(): user_profile_fields { 54 $this->getDataGenerator()->create_custom_profile_field([ 55 'shortname' => 'checkbox', 'name' => 'Checkbox field', 'datatype' => 'checkbox']); 56 57 $this->getDataGenerator()->create_custom_profile_field([ 58 'shortname' => 'datetime', 'name' => 'Date field', 'datatype' => 'datetime', 'param2' => 2022, 'param3' => 0]); 59 60 $this->getDataGenerator()->create_custom_profile_field([ 61 'shortname' => 'menu', 'name' => 'Menu field', 'datatype' => 'menu', 'param1' => "Cat\nDog"]); 62 63 $this->getDataGenerator()->create_custom_profile_field([ 64 'shortname' => 'Social', 'name' => 'msn', 'datatype' => 'social', 'param1' => 'msn']); 65 66 $this->getDataGenerator()->create_custom_profile_field([ 67 'shortname' => 'text', 'name' => 'Text field', 'datatype' => 'text']); 68 69 $this->getDataGenerator()->create_custom_profile_field([ 70 'shortname' => 'textarea', 'name' => 'Textarea field', 'datatype' => 'textarea']); 71 72 $userentity = new user(); 73 $useralias = $userentity->get_table_alias('user'); 74 75 // Create an instance of the userprofilefield helper. 76 return new user_profile_fields("$useralias.id", $userentity->get_entity_name()); 77 } 78 79 /** 80 * Test for get_columns 81 */ 82 public function test_get_columns(): void { 83 $this->resetAfterTest(); 84 85 $userentity = new user(); 86 $useralias = $userentity->get_table_alias('user'); 87 88 // Get pre-existing user profile fields. 89 $initialuserprofilefields = new user_profile_fields("$useralias.id", $userentity->get_entity_name()); 90 $initialcolumns = $initialuserprofilefields->get_columns(); 91 $initialcolumntitles = array_map(static function(column $column): string { 92 return $column->get_title(); 93 }, $initialcolumns); 94 $initialcolumntypes = array_map(static function(column $column): int { 95 return $column->get_type(); 96 }, $initialcolumns); 97 98 // Add new custom profile fields. 99 $userprofilefields = $this->generate_userprofilefields(); 100 $columns = $userprofilefields->get_columns(); 101 102 // Columns count should be equal to start + 6. 103 $this->assertCount(count($initialcolumns) + 6, $columns); 104 $this->assertContainsOnlyInstancesOf(column::class, $columns); 105 106 // Assert column titles. 107 $columntitles = array_map(static function(column $column): string { 108 return $column->get_title(); 109 }, $columns); 110 $expectedcolumntitles = array_merge($initialcolumntitles, [ 111 'Checkbox field', 112 'Date field', 113 'Menu field', 114 'MSN ID', 115 'Text field', 116 'Textarea field', 117 ]); 118 $this->assertEquals($expectedcolumntitles, $columntitles); 119 120 // Assert column types. 121 $columntypes = array_map(static function(column $column): int { 122 return $column->get_type(); 123 }, $columns); 124 $expectedcolumntypes = array_merge($initialcolumntypes, [ 125 column::TYPE_BOOLEAN, 126 column::TYPE_TIMESTAMP, 127 column::TYPE_TEXT, 128 column::TYPE_TEXT, 129 column::TYPE_TEXT, 130 column::TYPE_LONGTEXT, 131 ]); 132 $this->assertEquals($expectedcolumntypes, $columntypes); 133 } 134 135 /** 136 * Test for add_join 137 */ 138 public function test_add_join(): void { 139 $this->resetAfterTest(); 140 141 $userprofilefields = $this->generate_userprofilefields(); 142 $columns = $userprofilefields->get_columns(); 143 $this->assertCount(1, ($columns[0])->get_joins()); 144 145 $userprofilefields->add_join('JOIN {test} t ON t.id = id'); 146 $columns = $userprofilefields->get_columns(); 147 $this->assertCount(2, ($columns[0])->get_joins()); 148 } 149 150 /** 151 * Test for add_joins 152 */ 153 public function test_add_joins(): void { 154 $this->resetAfterTest(); 155 156 $userprofilefields = $this->generate_userprofilefields(); 157 $columns = $userprofilefields->get_columns(); 158 $this->assertCount(1, ($columns[0])->get_joins()); 159 160 $userprofilefields->add_joins(['JOIN {test} t ON t.id = id', 'JOIN {test2} t2 ON t2.id = id']); 161 $columns = $userprofilefields->get_columns(); 162 $this->assertCount(3, ($columns[0])->get_joins()); 163 } 164 165 /** 166 * Test for get_filters 167 */ 168 public function test_get_filters(): void { 169 $this->resetAfterTest(); 170 171 $userentity = new user(); 172 $useralias = $userentity->get_table_alias('user'); 173 174 // Get pre-existing user profile fields. 175 $initialuserprofilefields = new user_profile_fields("$useralias.id", $userentity->get_entity_name()); 176 $initialfilters = $initialuserprofilefields->get_filters(); 177 $initialfilterheaders = array_map(static function(filter $filter): string { 178 return $filter->get_header(); 179 }, $initialfilters); 180 181 // Add new custom profile fields. 182 $userprofilefields = $this->generate_userprofilefields(); 183 $filters = $userprofilefields->get_filters(); 184 185 // Filters count should be equal to start + 6. 186 $this->assertCount(count($initialfilters) + 6, $filters); 187 $this->assertContainsOnlyInstancesOf(filter::class, $filters); 188 189 // Assert filter headers. 190 $filterheaders = array_map(static function(filter $filter): string { 191 return $filter->get_header(); 192 }, $filters); 193 $expectedfilterheaders = array_merge($initialfilterheaders, [ 194 'Checkbox field', 195 'Date field', 196 'Menu field', 197 'MSN ID', 198 'Text field', 199 'Textarea field', 200 ]); 201 $this->assertEquals($expectedfilterheaders, $filterheaders); 202 } 203 204 /** 205 * Test that adding user profile field columns to a report returns expected values 206 */ 207 public function test_custom_report_content(): void { 208 $this->resetAfterTest(); 209 210 $userprofilefields = $this->generate_userprofilefields(); 211 212 // Create test subject with user profile fields content. 213 $user = $this->getDataGenerator()->create_user([ 214 'firstname' => 'Zebedee', 215 'profile_field_checkbox' => true, 216 'profile_field_datetime' => '2021-12-09', 217 'profile_field_menu' => 'Cat', 218 'profile_field_Social' => 12345, 219 'profile_field_text' => 'Hello', 220 'profile_field_textarea' => 'Goodbye', 221 ]); 222 223 /** @var core_reportbuilder_generator $generator */ 224 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 225 $report = $generator->create_report(['name' => 'Users', 'source' => users::class, 'default' => 0]); 226 227 // Add user profile field columns to the report. 228 $firstname = $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:firstname']); 229 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_checkbox']); 230 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_datetime']); 231 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_menu']); 232 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_Social']); 233 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_text']); 234 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_textarea']); 235 236 // Sort the report, Admin -> Zebedee for consistency. 237 report::toggle_report_column_sorting($report->get('id'), $firstname->get('id'), true); 238 239 $content = $this->get_custom_report_content($report->get('id')); 240 $this->assertEquals([ 241 [ 242 'c0_firstname' => 'Admin', 243 'c1_data' => '', 244 'c2_data' => 'Not set', 245 'c3_data' => '', 246 'c4_data' => '', 247 'c5_data' => '', 248 'c6_data' => '', 249 ], [ 250 'c0_firstname' => 'Zebedee', 251 'c1_data' => 'Yes', 252 'c2_data' => '9 December 2021', 253 'c3_data' => 'Cat', 254 'c4_data' => '12345', 255 'c5_data' => 'Hello', 256 'c6_data' => '<div class="no-overflow">Goodbye</div>', 257 ], 258 ], $content); 259 } 260 261 /** 262 * Data provider for {@see test_custom_report_filter} 263 * 264 * @return array[] 265 */ 266 public function custom_report_filter_provider(): array { 267 return [ 268 'Filter by checkbox profile field' => ['user:profilefield_checkbox', [ 269 'user:profilefield_checkbox_operator' => boolean_select::CHECKED, 270 ], 'testuser'], 271 'Filter by checkbox profile field (empty)' => ['user:profilefield_checkbox', [ 272 'user:profilefield_checkbox_operator' => boolean_select::NOT_CHECKED, 273 ], 'admin'], 274 'Filter by datetime profile field' => ['user:profilefield_datetime', [ 275 'user:profilefield_datetime_operator' => date::DATE_RANGE, 276 'user:profilefield_datetime_from' => 1622502000, 277 ], 'testuser'], 278 'Filter by datetime profile field (empty)' => ['user:profilefield_datetime', [ 279 'user:profilefield_datetime_operator' => date::DATE_EMPTY, 280 ], 'admin'], 281 'Filter by menu profile field' => ['user:profilefield_menu', [ 282 'user:profilefield_menu_operator' => select::EQUAL_TO, 283 'user:profilefield_menu_value' => 'Dog', 284 ], 'testuser'], 285 'Filter by menu profile field (empty)' => ['user:profilefield_menu', [ 286 'user:profilefield_menu_operator' => select::NOT_EQUAL_TO, 287 'user:profilefield_menu_value' => 'Dog', 288 ], 'admin'], 289 'Filter by social profile field' => ['user:profilefield_Social', [ 290 'user:profilefield_Social_operator' => text::IS_EQUAL_TO, 291 'user:profilefield_Social_value' => '12345', 292 ], 'testuser'], 293 'Filter by social profile field (empty)' => ['user:profilefield_Social', [ 294 'user:profilefield_Social_operator' => text::IS_EMPTY, 295 ], 'admin'], 296 'Filter by text profile field' => ['user:profilefield_text', [ 297 'user:profilefield_text_operator' => text::IS_EQUAL_TO, 298 'user:profilefield_text_value' => 'Hello', 299 ], 'testuser'], 300 'Filter by text profile field (empty)' => ['user:profilefield_text', [ 301 'user:profilefield_text_operator' => text::IS_NOT_EQUAL_TO, 302 'user:profilefield_text_value' => 'Hello', 303 ], 'admin'], 304 'Filter by textarea profile field' => ['user:profilefield_textarea', [ 305 'user:profilefield_textarea_operator' => text::IS_EQUAL_TO, 306 'user:profilefield_textarea_value' => 'Goodbye', 307 ], 'testuser'], 308 'Filter by textarea profile field (empty)' => ['user:profilefield_textarea', [ 309 'user:profilefield_textarea_operator' => text::DOES_NOT_CONTAIN, 310 'user:profilefield_textarea_value' => 'Goodbye', 311 ], 'admin'], 312 ]; 313 } 314 315 /** 316 * Test filtering report by custom profile fields 317 * 318 * @param string $filtername 319 * @param array $filtervalues 320 * @param string $expectmatchuser 321 * 322 * @dataProvider custom_report_filter_provider 323 */ 324 public function test_custom_report_filter(string $filtername, array $filtervalues, string $expectmatchuser): void { 325 $this->resetAfterTest(); 326 327 $userprofilefields = $this->generate_userprofilefields(); 328 329 // Create test subject with user profile fields content. 330 $user = $this->getDataGenerator()->create_user([ 331 'username' => 'testuser', 332 'profile_field_checkbox' => true, 333 'profile_field_datetime' => '2021-12-09', 334 'profile_field_menu' => 'Dog', 335 'profile_field_Social' => '12345', 336 'profile_field_text' => 'Hello', 337 'profile_field_textarea' => 'Goodbye', 338 ]); 339 340 /** @var core_reportbuilder_generator $generator */ 341 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 342 343 // Create report containing single column, and given filter. 344 $report = $generator->create_report(['name' => 'Users', 'source' => users::class, 'default' => 0]); 345 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:username']); 346 347 // Add filter, set it's values. 348 $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]); 349 user_filter_manager::set($report->get('id'), $filtervalues); 350 351 $content = $this->get_custom_report_content($report->get('id')); 352 353 $this->assertCount(1, $content); 354 $this->assertEquals($expectmatchuser, reset($content[0])); 355 } 356 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body