MDL-81434 reportbuilder: ensure filter/condition parameter uniqueness.

This change fixes an edge case that could be triggered by creating a
custom report that contained a filter instance that was active as both
a filter and condition, where the filter instance provides parameters
to it's SQL fragment.

There is only one such filter present currently with which we can test
this, see 2f9001cbe9.
This commit is contained in:
Paul Holden 2024-04-04 12:26:18 +01:00
parent 462d5f04a8
commit 9b827c09ce
No known key found for this signature in database
GPG key ID: A81A96D6045F6164
5 changed files with 116 additions and 11 deletions

View file

@ -22,6 +22,7 @@ use core_badges_generator;
use core_reportbuilder_generator;
use core_reportbuilder_testcase;
use core_reportbuilder\local\filters\{boolean_select, date, select, tags, text};
use core_reportbuilder\manager;
defined('MOODLE_INTERNAL') || die();
@ -37,7 +38,7 @@ require_once("{$CFG->libdir}/badgeslib.php");
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class badges_test extends core_reportbuilder_testcase {
final class badges_test extends core_reportbuilder_testcase {
/**
* Test default datasource
@ -200,12 +201,53 @@ class badges_test extends core_reportbuilder_testcase {
$this->assertEquals($course->fullname, $coursename);
}
/**
* Test creating a report containing "expiry" as both a condition and a filter
*
* This is really testing that it's possible to do so, for a filter instance that returns SQL parameters
*/
public function test_report_expiry_condition_and_filter(): void {
$this->resetAfterTest();
/** @var core_badges_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
$badgeone = $generator->create_badge(['name' => 'Badge 1', 'expiredate' => 10]);
$badgetwo = $generator->create_badge(['name' => 'Badge 2', 'expiredate' => 20]);
$badgethree = $generator->create_badge(['name' => 'Badge 3', 'expiredate' => 30]);
/** @var core_reportbuilder_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
$report = $generator->create_report(['name' => 'Badges', 'source' => badges::class, 'default' => 0]);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:name']);
$generator->create_condition(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:expiry']);
$generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:expiry']);
// Load report instance, set condition.
$instance = manager::get_report_from_persistent($report);
$instance->set_condition_values([
'badge:expiry_operator' => date::DATE_RANGE,
'badge:expiry_from' => 15,
]);
// Set filter.
$content = $this->get_custom_report_content($report->get('id'), 0, [
'badge:expiry_operator' => date::DATE_RANGE,
'badge:expiry_to' => 25,
]);
$this->assertEquals([
[$badgetwo->name],
], array_map('array_values', $content));
}
/**
* Data provider for {@see test_datasource_filters}
*
* @return array[]
*/
public function datasource_filters_provider(): array {
public static function datasource_filters_provider(): array {
return [
// Badge.
'Filter badge name' => ['badge:name', [