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_customfield_generator; 22 use core_reportbuilder_generator; 23 use core_reportbuilder_testcase; 24 use core_reportbuilder\local\entities\course; 25 use core_reportbuilder\local\helpers\user_filter_manager; 26 use core_reportbuilder\local\filters\boolean_select; 27 use core_reportbuilder\local\filters\date; 28 use core_reportbuilder\local\filters\select; 29 use core_reportbuilder\local\filters\text; 30 use core_reportbuilder\local\report\column; 31 use core_reportbuilder\local\report\filter; 32 use core_course\reportbuilder\datasource\courses; 33 34 defined('MOODLE_INTERNAL') || die(); 35 36 global $CFG; 37 require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php"); 38 39 /** 40 * Unit tests for custom fields helper 41 * 42 * @package core_reportbuilder 43 * @covers \core_reportbuilder\local\helpers\custom_fields 44 * @copyright 2021 David Matamoros <davidmc@moodle.com> 45 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 46 */ 47 class custom_fields_test extends core_reportbuilder_testcase { 48 49 /** 50 * Generate custom fields, one of each type 51 * 52 * @return custom_fields 53 */ 54 private function generate_customfields(): custom_fields { 55 56 /** @var core_customfield_generator $generator */ 57 $generator = $this->getDataGenerator()->get_plugin_generator('core_customfield'); 58 $category = $generator->create_category([ 59 'component' => 'core_course', 60 'area' => 'course', 61 'itemid' => 0, 62 'contextid' => \context_system::instance()->id 63 ]); 64 65 $generator->create_field( 66 ['categoryid' => $category->get('id'), 'type' => 'text', 'name' => 'Text', 'shortname' => 'text']); 67 68 $generator->create_field( 69 ['categoryid' => $category->get('id'), 'type' => 'checkbox', 'name' => 'Checkbox', 'shortname' => 'checkbox']); 70 71 $generator->create_field( 72 ['categoryid' => $category->get('id'), 'type' => 'date', 'name' => 'Date', 'shortname' => 'date']); 73 74 $generator->create_field( 75 ['categoryid' => $category->get('id'), 'type' => 'select', 'name' => 'Select', 'shortname' => 'select', 76 'configdata' => ['options' => "Cat\nDog", 'defaultvalue' => 'Cat']]); 77 78 $courseentity = new course(); 79 $coursealias = $courseentity->get_table_alias('course'); 80 81 // Create an instance of the customfields helper. 82 return new custom_fields($coursealias . '.id', $courseentity->get_entity_name(), 83 'core_course', 'course'); 84 } 85 86 /** 87 * Test for get_columns 88 */ 89 public function test_get_columns(): void { 90 $this->resetAfterTest(); 91 92 $customfields = $this->generate_customfields(); 93 $columns = $customfields->get_columns(); 94 95 $this->assertCount(4, $columns); 96 $this->assertContainsOnlyInstancesOf(column::class, $columns); 97 98 [$column0, $column1, $column2, $column3] = $columns; 99 $this->assertEqualsCanonicalizing(['Text', 'Checkbox', 'Date', 'Select'], 100 [$column0->get_title(), $column1->get_title(), $column2->get_title(), $column3->get_title()]); 101 102 $this->assertEquals(column::TYPE_TEXT, $column0->get_type()); 103 $this->assertEquals('course', $column0->get_entity_name()); 104 $this->assertStringStartsWith('LEFT JOIN {customfield_data}', $column0->get_joins()[0]); 105 // Column of type TEXT is sortable. 106 $this->assertTrue($column0->get_is_sortable()); 107 } 108 109 /** 110 * Test for add_join 111 */ 112 public function test_add_join(): void { 113 $this->resetAfterTest(); 114 115 $customfields = $this->generate_customfields(); 116 $columns = $customfields->get_columns(); 117 $this->assertCount(1, ($columns[0])->get_joins()); 118 119 $customfields->add_join('JOIN {test} t ON t.id = id'); 120 $columns = $customfields->get_columns(); 121 $this->assertCount(2, ($columns[0])->get_joins()); 122 } 123 124 /** 125 * Test for add_joins 126 */ 127 public function test_add_joins(): void { 128 $this->resetAfterTest(); 129 130 $customfields = $this->generate_customfields(); 131 $columns = $customfields->get_columns(); 132 $this->assertCount(1, ($columns[0])->get_joins()); 133 134 $customfields->add_joins(['JOIN {test} t ON t.id = id', 'JOIN {test2} t2 ON t2.id = id']); 135 $columns = $customfields->get_columns(); 136 $this->assertCount(3, ($columns[0])->get_joins()); 137 } 138 139 /** 140 * Test for get_filters 141 */ 142 public function test_get_filters(): void { 143 $this->resetAfterTest(); 144 145 $customfields = $this->generate_customfields(); 146 $filters = $customfields->get_filters(); 147 148 $this->assertCount(4, $filters); 149 $this->assertContainsOnlyInstancesOf(filter::class, $filters); 150 151 [$filter0, $filter1, $filter2, $filter3] = $filters; 152 $this->assertEqualsCanonicalizing(['Text', 'Checkbox', 'Date', 'Select'], 153 [$filter0->get_header(), $filter1->get_header(), $filter2->get_header(), $filter3->get_header()]); 154 } 155 156 /** 157 * Test that adding custom field columns to a report returns expected values 158 */ 159 public function test_custom_report_content(): void { 160 $this->resetAfterTest(); 161 162 $this->generate_customfields(); 163 164 $course = $this->getDataGenerator()->create_course(['customfields' => [ 165 ['shortname' => 'text', 'value' => 'Hello'], 166 ['shortname' => 'checkbox', 'value' => true], 167 ['shortname' => 'date', 'value' => 1669852800], 168 ['shortname' => 'select', 'value' => 2], 169 ]]); 170 171 /** @var core_reportbuilder_generator $generator */ 172 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 173 $report = $generator->create_report(['name' => 'Courses', 'source' => courses::class, 'default' => 0]); 174 175 // Add user profile field columns to the report. 176 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']); 177 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:customfield_text']); 178 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:customfield_checkbox']); 179 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:customfield_date']); 180 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:customfield_select']); 181 182 $content = $this->get_custom_report_content($report->get('id')); 183 184 $this->assertEquals([ 185 $course->fullname, 186 'Hello', 187 'Yes', 188 userdate(1669852800), 189 'Dog' 190 ], array_values($content[0])); 191 } 192 193 /** 194 * Data provider for {@see test_custom_report_filter} 195 * 196 * @return array[] 197 */ 198 public function custom_report_filter_provider(): array { 199 return [ 200 'Filter by text custom field' => ['course:customfield_text', [ 201 'course:customfield_text_operator' => text::IS_EQUAL_TO, 202 'course:customfield_text_value' => 'Hello', 203 ], true], 204 'Filter by text custom field (no match)' => ['course:customfield_text', [ 205 'course:customfield_text_operator' => text::IS_EQUAL_TO, 206 'course:customfield_text_value' => 'Goodbye', 207 ], false], 208 'Filter by checkbox custom field' => ['course:customfield_checkbox', [ 209 'course:customfield_checkbox_operator' => boolean_select::CHECKED, 210 ], true], 211 'Filter by checkbox custom field (no match)' => ['course:customfield_checkbox', [ 212 'course:customfield_checkbox_operator' => boolean_select::NOT_CHECKED, 213 ], false], 214 'Filter by date custom field' => ['course:customfield_date', [ 215 'course:customfield_date_operator' => date::DATE_RANGE, 216 'course:customfield_date_from' => 1622502000, 217 ], true], 218 'Filter by date custom field (no match)' => ['course:customfield_date', [ 219 'course:customfield_date_operator' => date::DATE_RANGE, 220 'course:customfield_date_to' => 1622502000, 221 ], false], 222 'Filter by select custom field' => ['course:customfield_select', [ 223 'course:customfield_select_operator' => select::EQUAL_TO, 224 'course:customfield_select_value' => 2, 225 ], true], 226 'Filter by select custom field (no match)' => ['course:customfield_select', [ 227 'course:customfield_select_operator' => select::EQUAL_TO, 228 'course:customfield_select_value' => 1, 229 ], false], 230 ]; 231 } 232 233 /** 234 * Test filtering report by custom fields 235 * 236 * @param string $filtername 237 * @param array $filtervalues 238 * @param bool $expectmatch 239 * 240 * @dataProvider custom_report_filter_provider 241 */ 242 public function test_custom_report_filter(string $filtername, array $filtervalues, bool $expectmatch): void { 243 $this->resetAfterTest(); 244 245 $this->generate_customfields(); 246 247 $course = $this->getDataGenerator()->create_course(['customfields' => [ 248 ['shortname' => 'text', 'value' => 'Hello'], 249 ['shortname' => 'checkbox', 'value' => true], 250 ['shortname' => 'date', 'value' => 1669852800], 251 ['shortname' => 'select', 'value' => 2], 252 ]]); 253 254 /** @var core_reportbuilder_generator $generator */ 255 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 256 257 // Create report containing single column, and given filter. 258 $report = $generator->create_report(['name' => 'Users', 'source' => courses::class, 'default' => 0]); 259 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']); 260 261 // Add filter, set it's values. 262 $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]); 263 user_filter_manager::set($report->get('id'), $filtervalues); 264 265 $content = $this->get_custom_report_content($report->get('id')); 266 267 if ($expectmatch) { 268 $this->assertCount(1, $content); 269 $this->assertEquals($course->fullname, reset($content[0])); 270 } else { 271 $this->assertEmpty($content); 272 } 273 } 274 } 275
title
Description
Body
title
Description
Body
title
Description
Body
title
Body