Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>.declare(strict_types=1);namespace core_reportbuilder\local\helpers;use core_reportbuilder_generator;use core_reportbuilder_testcase;use core_reportbuilder\local\entities\user;use core_reportbuilder\local\filters\boolean_select;use core_reportbuilder\local\filters\date;use core_reportbuilder\local\filters\select;use core_reportbuilder\local\filters\text;use core_reportbuilder\local\report\column;use core_reportbuilder\local\report\filter;use core_user\reportbuilder\datasource\users;defined('MOODLE_INTERNAL') || die();global $CFG;require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");/*** Unit tests for user profile fields helper** @package core_reportbuilder* @covers \core_reportbuilder\local\helpers\user_profile_fields* @copyright 2021 David Matamoros <davidmc@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class user_profile_fields_test extends core_reportbuilder_testcase {/*** Generate custom profile fields, one of each type** @return user_profile_fields*/private function generate_userprofilefields(): user_profile_fields {$this->getDataGenerator()->create_custom_profile_field(['shortname' => 'checkbox', 'name' => 'Checkbox field', 'datatype' => 'checkbox']);$this->getDataGenerator()->create_custom_profile_field(['shortname' => 'datetime', 'name' => 'Date field', 'datatype' => 'datetime', 'param2' => 2022, 'param3' => 0]);$this->getDataGenerator()->create_custom_profile_field(['shortname' => 'menu', 'name' => 'Menu field', 'datatype' => 'menu', 'param1' => "Cat\nDog"]);$this->getDataGenerator()->create_custom_profile_field(['shortname' => 'Social', 'name' => 'msn', 'datatype' => 'social', 'param1' => 'msn']);$this->getDataGenerator()->create_custom_profile_field(['shortname' => 'text', 'name' => 'Text field', 'datatype' => 'text']);$this->getDataGenerator()->create_custom_profile_field(['shortname' => 'textarea', 'name' => 'Textarea field', 'datatype' => 'textarea']);$userentity = new user();$useralias = $userentity->get_table_alias('user');// Create an instance of the userprofilefield helper.return new user_profile_fields("$useralias.id", $userentity->get_entity_name());}/*** Test for get_columns*/public function test_get_columns(): void {$this->resetAfterTest();$userentity = new user();$useralias = $userentity->get_table_alias('user');// Get pre-existing user profile fields.$initialuserprofilefields = new user_profile_fields("$useralias.id", $userentity->get_entity_name());$initialcolumns = $initialuserprofilefields->get_columns();$initialcolumntitles = array_map(static function(column $column): string {return $column->get_title();}, $initialcolumns);$initialcolumntypes = array_map(static function(column $column): int {return $column->get_type();}, $initialcolumns);// Add new custom profile fields.$userprofilefields = $this->generate_userprofilefields();$columns = $userprofilefields->get_columns();// Columns count should be equal to start + 6.$this->assertCount(count($initialcolumns) + 6, $columns);$this->assertContainsOnlyInstancesOf(column::class, $columns);// Assert column titles.$columntitles = array_map(static function(column $column): string {return $column->get_title();}, $columns);$expectedcolumntitles = array_merge($initialcolumntitles, ['Checkbox field','Date field','Menu field','MSN ID','Text field','Textarea field',]);$this->assertEquals($expectedcolumntitles, $columntitles);// Assert column types.$columntypes = array_map(static function(column $column): int {return $column->get_type();}, $columns);$expectedcolumntypes = array_merge($initialcolumntypes, [column::TYPE_BOOLEAN,column::TYPE_TIMESTAMP,column::TYPE_TEXT,column::TYPE_TEXT,column::TYPE_TEXT,column::TYPE_LONGTEXT,]);$this->assertEquals($expectedcolumntypes, $columntypes);}/*** Test for add_join*/public function test_add_join(): void {$this->resetAfterTest();$userprofilefields = $this->generate_userprofilefields();$columns = $userprofilefields->get_columns();$this->assertCount(1, ($columns[0])->get_joins());$userprofilefields->add_join('JOIN {test} t ON t.id = id');$columns = $userprofilefields->get_columns();$this->assertCount(2, ($columns[0])->get_joins());}/*** Test for add_joins*/public function test_add_joins(): void {$this->resetAfterTest();$userprofilefields = $this->generate_userprofilefields();$columns = $userprofilefields->get_columns();$this->assertCount(1, ($columns[0])->get_joins());$userprofilefields->add_joins(['JOIN {test} t ON t.id = id', 'JOIN {test2} t2 ON t2.id = id']);$columns = $userprofilefields->get_columns();$this->assertCount(3, ($columns[0])->get_joins());}/*** Test for get_filters*/public function test_get_filters(): void {$this->resetAfterTest();$userentity = new user();$useralias = $userentity->get_table_alias('user');// Get pre-existing user profile fields.$initialuserprofilefields = new user_profile_fields("$useralias.id", $userentity->get_entity_name());$initialfilters = $initialuserprofilefields->get_filters();$initialfilterheaders = array_map(static function(filter $filter): string {return $filter->get_header();}, $initialfilters);// Add new custom profile fields.$userprofilefields = $this->generate_userprofilefields();$filters = $userprofilefields->get_filters();// Filters count should be equal to start + 6.$this->assertCount(count($initialfilters) + 6, $filters);$this->assertContainsOnlyInstancesOf(filter::class, $filters);// Assert filter headers.$filterheaders = array_map(static function(filter $filter): string {return $filter->get_header();}, $filters);$expectedfilterheaders = array_merge($initialfilterheaders, ['Checkbox field','Date field','Menu field','MSN ID','Text field','Textarea field',]);$this->assertEquals($expectedfilterheaders, $filterheaders);}/*** Test that adding user profile field columns to a report returns expected values*/public function test_custom_report_content(): void {$this->resetAfterTest();$userprofilefields = $this->generate_userprofilefields();// Create test subject with user profile fields content.$user = $this->getDataGenerator()->create_user(['firstname' => 'Zebedee','profile_field_checkbox' => true,'profile_field_datetime' => '2021-12-09','profile_field_menu' => 'Cat','profile_field_Social' => 12345,'profile_field_text' => 'Hello','profile_field_textarea' => 'Goodbye',]);/** @var core_reportbuilder_generator $generator */$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');$report = $generator->create_report(['name' => 'Users', 'source' => users::class, 'default' => 0]);// Add user profile field columns to the report.$firstname = $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:firstname']);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_checkbox']);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_datetime']);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_menu']);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_social']);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_text']);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:profilefield_textarea']);// Sort the report, Admin -> Zebedee for consistency.report::toggle_report_column_sorting($report->get('id'), $firstname->get('id'), true);$content = $this->get_custom_report_content($report->get('id'));$this->assertEquals([['c0_firstname' => 'Admin','c1_data' => '','c2_data' => '','c3_data' => '','c4_data' => '','c5_data' => '','c6_data' => '',], ['c0_firstname' => 'Zebedee','c1_data' => 'Yes','c2_data' => '9 December 2021','c3_data' => 'Cat','c4_data' => '12345','c5_data' => 'Hello','c6_data' => '<div class="no-overflow">Goodbye</div>',],], $content);}/*** Data provider for {@see test_custom_report_filter}** @return array[]*/public function custom_report_filter_provider(): array {return ['Filter by checkbox profile field' => ['user:profilefield_checkbox', ['user:profilefield_checkbox_operator' => boolean_select::CHECKED,], 'testuser'],'Filter by checkbox profile field (empty)' => ['user:profilefield_checkbox', ['user:profilefield_checkbox_operator' => boolean_select::NOT_CHECKED,], 'admin'],'Filter by datetime profile field' => ['user:profilefield_datetime', ['user:profilefield_datetime_operator' => date::DATE_RANGE,'user:profilefield_datetime_from' => 1622502000,], 'testuser'],'Filter by datetime profile field (empty)' => ['user:profilefield_datetime', ['user:profilefield_datetime_operator' => date::DATE_EMPTY,], 'admin'],'Filter by menu profile field' => ['user:profilefield_menu', ['user:profilefield_menu_operator' => select::EQUAL_TO,'user:profilefield_menu_value' => 'Dog',], 'testuser'],'Filter by menu profile field (empty)' => ['user:profilefield_menu', ['user:profilefield_menu_operator' => select::NOT_EQUAL_TO,'user:profilefield_menu_value' => 'Dog',], 'admin'],'Filter by social profile field' => ['user:profilefield_social', ['user:profilefield_social_operator' => text::IS_EQUAL_TO,'user:profilefield_social_value' => '12345',], 'testuser'],'Filter by social profile field (empty)' => ['user:profilefield_social', ['user:profilefield_social_operator' => text::IS_EMPTY,], 'admin'],'Filter by text profile field' => ['user:profilefield_text', ['user:profilefield_text_operator' => text::IS_EQUAL_TO,'user:profilefield_text_value' => 'Hello',], 'testuser'],'Filter by text profile field (empty)' => ['user:profilefield_text', ['user:profilefield_text_operator' => text::IS_NOT_EQUAL_TO,'user:profilefield_text_value' => 'Hello',], 'admin'],'Filter by textarea profile field' => ['user:profilefield_textarea', ['user:profilefield_textarea_operator' => text::IS_EQUAL_TO,'user:profilefield_textarea_value' => 'Goodbye',], 'testuser'],'Filter by textarea profile field (empty)' => ['user:profilefield_textarea', ['user:profilefield_textarea_operator' => text::DOES_NOT_CONTAIN,'user:profilefield_textarea_value' => 'Goodbye',], 'admin'],];}/*** Test filtering report by custom profile fields** @param string $filtername* @param array $filtervalues* @param string $expectmatchuser** @dataProvider custom_report_filter_provider*/public function test_custom_report_filter(string $filtername, array $filtervalues, string $expectmatchuser): void {$this->resetAfterTest();$userprofilefields = $this->generate_userprofilefields();// Create test subject with user profile fields content.$user = $this->getDataGenerator()->create_user(['username' => 'testuser','profile_field_checkbox' => true,'profile_field_datetime' => '2021-12-09','profile_field_menu' => 'Dog','profile_field_Social' => '12345','profile_field_text' => 'Hello','profile_field_textarea' => 'Goodbye',]);/** @var core_reportbuilder_generator $generator */$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');// Create report containing single column, and given filter.$report = $generator->create_report(['name' => 'Users', 'source' => users::class, 'default' => 0]);$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:username']);// Add filter, set it's values.$generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);$content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues);$this->assertCount(1, $content);$this->assertEquals($expectmatchuser, reset($content[0]));}/*** Stress test user datasource using profile fields** In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php*/public function test_stress_datasource(): void {if (!PHPUNIT_LONGTEST) {$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');}$this->resetAfterTest();$userprofilefields = $this->generate_userprofilefields();$user = $this->getDataGenerator()->create_user(['profile_field_checkbox' => true,'profile_field_datetime' => '2021-12-09','profile_field_menu' => 'Dog','profile_field_Social' => '12345','profile_field_text' => 'Hello','profile_field_textarea' => 'Goodbye',]);$this->datasource_stress_test_columns(users::class);$this->datasource_stress_test_columns_aggregation(users::class);$this->datasource_stress_test_conditions(users::class, 'user:idnumber');}}