Files
moodle/reportbuilder/tests/local/entities/user_test.php
T
Sara Arjona 7a63ff9f0b MDL-70794 reportbuilder: introduce the concept of report entities.
Entities are re-usable collections of report columns and filters. When
creating system reports, we can re-use those elements from entities
without having to know specific details about their implementation.

They can be joined to reports, or other entities, using standard SQL
query syntax.

Define base classes, and create two example entities: course and user.

Co-Authored-By: David Matamoros <davidmc@moodle.com>
2021-07-28 16:40:50 +01:00

291 lines
11 KiB
PHP

<?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\entities;
use advanced_testcase;
use core_reportbuilder\local\filters\boolean_select;
use core_reportbuilder\local\filters\date;
use moodle_url;
use core_reportbuilder\manager;
use core_reportbuilder\testable_system_report_table;
use core_reportbuilder\user_entity_report;
use core_reportbuilder\local\filters\text;
use core_reportbuilder\local\helpers\user_filter_manager;
/**
* Unit tests for user entity
*
* @package core_reportbuilder
* @covers \core_reportbuilder\local\entities\base
* @covers \core_reportbuilder\local\entities\user
* @covers \core_reportbuilder\local\helpers\user_profile_fields
* @covers \core_reportbuilder\local\report\base
* @covers \core_reportbuilder\system_report
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class user_testcase extends advanced_testcase {
/**
* Load required classes
*/
public static function setUpBeforeClass(): void {
global $CFG;
require_once("{$CFG->dirroot}/reportbuilder/tests/fixtures/testable_system_report_table.php");
require_once("{$CFG->dirroot}/reportbuilder/tests/fixtures/user_entity_report.php");
require_once("{$CFG->dirroot}/user/profile/lib.php");
}
/**
* Test callbacks are correctly applied for those columns using them
*/
public function test_columns_with_callbacks(): void {
$this->resetAfterTest();
// Add a couple of user profile fields to show on the report.
$this->getDataGenerator()->create_custom_profile_field(['datatype' => 'text',
'shortname' => 'favcolor', 'name' => 'Favorite color']);
$this->getDataGenerator()->create_custom_profile_field(['datatype' => 'text',
'shortname' => 'favsuperpower', 'name' => 'Favorite super power']);
$user = $this->getDataGenerator()->create_user([
'suspended' => 1,
'confirmed' => 0,
'country' => 'ES',
'profile_field_favcolor' => 'Blue',
'profile_field_favsuperpower' => 'Time travel',
]);
$tablerows = $this->get_report_table_rows();
$userrows = array_filter($tablerows, static function(array $row) use ($user): bool {
return $row['username'] === $user->username;
});
$userrow = reset($userrows);
$this->assertEquals('Yes', $userrow['suspended']);
$this->assertEquals('No', $userrow['confirmed']);
$this->assertEquals('Spain', $userrow['country']);
$this->assertEquals('Blue', $userrow['profilefield_favcolor']);
$this->assertEquals('Time travel', $userrow['profilefield_favsuperpower']);
}
/**
* Test the formatted user fullname columns
*/
public function test_fullname_columns(): void {
global $OUTPUT;
$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user([]);
$tablerows = $this->get_report_table_rows();
$userrows = array_filter($tablerows, static function(array $row) use ($user): bool {
return $row['username'] === $user->username;
});
$userrow = reset($userrows);
$userfullname = fullname($user);
$userprofile = (new moodle_url('/user/profile.php', ['id' => $user->id]))->out();
$userpicture = $OUTPUT->user_picture($user, ['link' => false, 'alttext' => false]);
$this->assertEquals($userfullname, $userrow['fullname']);
$this->assertEquals('<a href="' . $userprofile . '">' . $userfullname . '</a>', $userrow['fullnamewithlink']);
$this->assertEquals($userpicture . $userfullname, $userrow['fullnamewithpicture']);
$this->assertEquals('<a href="' . $userprofile . '">' . $userpicture . $userfullname . '</a>',
$userrow['fullnamewithpicturelink']);
}
/**
* Test picture column callback
*/
public function test_picture_column(): void {
global $OUTPUT;
$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user([]);
$tablerows = $this->get_report_table_rows();
$userrows = array_filter($tablerows, static function(array $row) use ($user): bool {
return $row['username'] === $user->username;
});
$userrow = reset($userrows);
$userpicture = $OUTPUT->user_picture($user, ['link' => false, 'alttext' => false]);
$this->assertEquals($userpicture, $userrow['picture']);
}
/**
* Test filtering report by user fields
*/
public function test_filters(): void {
$this->resetAfterTest();
$this->getDataGenerator()->create_user(['firstname' => 'Daffy', 'lastname' => 'Duck', 'email' => 'daffy@test.com',
'city' => 'LA', 'lastaccess' => time() - YEARSECS, 'suspended' => 1]);
$this->getDataGenerator()->create_user(['firstname' => 'Donald', 'lastname' => 'Duck', 'email' => 'donald@test.com',
'city' => 'Chicago', 'lastaccess' => time(), 'suspended' => 0]);
// Filter by fullname field.
$filtervalues = [
'user:fullname_operator' => text::IS_EQUAL_TO,
'user:fullname_value' => 'Daffy Duck',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Daffy Duck',
], array_column($tablerows, 'fullname'));
// Filter by firstname field.
$filtervalues = [
'user:firstname_operator' => text::CONTAINS,
'user:firstname_value' => 'Donald',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Donald Duck',
], array_column($tablerows, 'fullname'));
// Filter by lastname field.
$filtervalues = [
'user:lastname_operator' => text::CONTAINS,
'user:lastname_value' => 'Duck',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEqualsCanonicalizing([
'Donald Duck',
'Daffy Duck',
], array_column($tablerows, 'fullname'));
// Filter by email field.
$filtervalues = [
'user:email_operator' => text::IS_EQUAL_TO,
'user:email_value' => 'donald@test.com',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Donald Duck',
], array_column($tablerows, 'fullname'));
// Filter by city field.
$filtervalues = [
'user:city_operator' => text::IS_EQUAL_TO,
'user:city_value' => 'Chicago',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Donald Duck',
], array_column($tablerows, 'fullname'));
// Filter by city field.
$filtervalues = [
'user:city_operator' => text::IS_EQUAL_TO,
'user:city_value' => 'Chicago',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Donald Duck',
], array_column($tablerows, 'fullname'));
// Filter by lastaccess field.
$filtervalues = [
'user:lastaccess_operator' => date::DATE_RANGE,
'user:lastaccess_from' => time() - YEARSECS - 100,
'user:lastaccess_to' => time() - YEARSECS + 100,
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Daffy Duck',
], array_column($tablerows, 'fullname'));
// Filter by suspened field.
$filtervalues = [
'user:suspended_operator' => boolean_select::CHECKED,
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Daffy Duck',
], array_column($tablerows, 'fullname'));
}
/**
* Test filtering report by a user profile field
*/
public function test_userprofilefield_filter(): void {
$this->resetAfterTest();
// Add a user profile field to show on the report.
$this->getDataGenerator()->create_custom_profile_field(['datatype' => 'text',
'shortname' => 'favcolor', 'name' => 'Favorite color']);
$this->getDataGenerator()->create_user(['firstname' => 'Daffy', 'lastname' => 'Duck', 'profile_field_favcolor' => 'Blue']);
$this->getDataGenerator()->create_user(['firstname' => 'Donald', 'lastname' => 'Duck',
'profile_field_favcolor' => 'Green']);
$filtervalues = [
'user:profilefield_favcolor_operator' => text::IS_EQUAL_TO,
'user:profilefield_favcolor_value' => 'Green',
];
$tablerows = $this->get_report_table_rows($filtervalues);
$this->assertEquals([
'Donald Duck',
], array_column($tablerows, 'fullname'));
}
/**
* Tests the helper method for selecting all of a users' name fields
*/
public function test_get_name_fields_select(): void {
global $DB;
$fields = user::get_name_fields_select('u');
$user = $DB->get_record_sql("SELECT {$fields} FROM {user} u WHERE username = :username", ['username' => 'admin']);
// Ensure we received back all name fields.
$this->assertEqualsCanonicalizing([
'firstname',
'lastname',
'firstnamephonetic',
'lastnamephonetic',
'middlename',
'alternatename',
], array_keys((array) $user));
}
/**
* Helper method to create the report, and return it's rows
*
* @param array $filtervalues
* @return array
*/
private function get_report_table_rows(array $filtervalues = []): array {
$report = manager::create_report_persistent((object) [
'type' => user_entity_report::TYPE_SYSTEM_REPORT,
'source' => user_entity_report::class,
]);
user_filter_manager::set($report->get('id'), $filtervalues);
return testable_system_report_table::create($report->get('id'), [])->get_table_rows();
}
}