Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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_group\reportbuilder\datasource;
20
 
21
use core_customfield_generator;
22
use core_reportbuilder_generator;
23
use core_reportbuilder_testcase;
24
use core_reportbuilder\local\filters\{boolean_select, date, select, text};
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
global $CFG;
29
require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
30
 
31
/**
32
 * Unit tests for groups datasource
33
 *
34
 * @package     core_group
35
 * @covers      \core_group\reportbuilder\datasource\groups
36
 * @copyright   2022 Paul Holden <paulh@moodle.com>
37
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
39
class groups_test extends core_reportbuilder_testcase {
40
 
41
    /**
42
     * Test default datasource
43
     */
44
    public function test_datasource_default(): void {
45
        $this->resetAfterTest();
46
 
47
        $course = $this->getDataGenerator()->create_course();
48
        $userone = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe']);
49
        $usertwo = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Amy']);
50
 
51
        $groupone = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Zebras']);
52
        $grouptwo = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Aardvarks']);
53
 
54
        $this->getDataGenerator()->create_group_member(['groupid' => $groupone->id, 'userid' => $userone->id]);
55
        $this->getDataGenerator()->create_group_member(['groupid' => $groupone->id, 'userid' => $usertwo->id]);
56
 
57
        /** @var core_reportbuilder_generator $generator */
58
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
59
        $report = $generator->create_report(['name' => 'Groups', 'source' => groups::class, 'default' => 1]);
60
 
61
        $content = $this->get_custom_report_content($report->get('id'));
62
 
63
        // Default columns are course, group, user. Sorted by each.
64
        $courseurl = course_get_url($course);
65
        $this->assertEquals([
66
            ["<a href=\"{$courseurl}\">{$course->fullname}</a>", $grouptwo->name, ''],
67
            ["<a href=\"{$courseurl}\">{$course->fullname}</a>", $groupone->name, fullname($usertwo)],
68
            ["<a href=\"{$courseurl}\">{$course->fullname}</a>", $groupone->name, fullname($userone)],
69
        ], array_map('array_values', $content));
70
    }
71
 
72
    /**
73
     * Test datasource groupings reports
74
     */
75
    public function test_datasource_groupings(): void {
76
        $this->resetAfterTest();
77
 
78
        $course = $this->getDataGenerator()->create_course();
79
 
80
        // Create group, add to grouping.
81
        $groupone = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Group A']);
82
        $grouping = $this->getDataGenerator()->create_grouping(['courseid' => $course->id]);
83
        $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $groupone->id]);
84
 
85
        // Create second group, no grouping.
86
        $grouptwo = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'name' => 'Group B']);
87
 
88
        /** @var core_reportbuilder_generator $generator */
89
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
90
        $report = $generator->create_report(['name' => 'Groups', 'source' => groups::class, 'default' => 0]);
91
 
92
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']);
93
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:name']);
94
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:name', 'sortenabled' => 1]);
95
 
96
        $content = $this->get_custom_report_content($report->get('id'));
97
        $this->assertCount(2, $content);
98
 
99
        $this->assertEquals([
100
            [
101
                $course->fullname,
102
                $grouping->name,
103
                $groupone->name,
104
            ],
105
            [
106
                $course->fullname,
107
                null,
108
                $grouptwo->name,
109
            ],
110
        ], array_map('array_values', $content));
111
    }
112
 
113
    /**
114
     * Test datasource columns that aren't added by default
115
     */
116
    public function test_datasource_non_default_columns(): void {
117
        $this->resetAfterTest();
118
        $this->setAdminUser();
119
 
120
        $course = $this->getDataGenerator()->create_course();
121
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
122
 
123
        /** @var core_customfield_generator $generator */
124
        $generator = $this->getDataGenerator()->get_plugin_generator('core_customfield');
125
 
126
        // Create group with custom field, and single group member.
127
        $groupfieldcategory = $generator->create_category(['component' => 'core_group', 'area' => 'group']);
128
        $generator->create_field(['categoryid' => $groupfieldcategory->get('id'), 'shortname' => 'hi']);
129
 
130
        $group = $this->getDataGenerator()->create_group([
131
            'courseid' => $course->id,
132
            'idnumber' => 'G101',
133
            'enrolmentkey' => 'S',
134
            'description' => 'My group',
135
            'customfield_hi' => 'Hello',
136
        ]);
137
        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);
138
 
139
        // Create grouping with custom field, and single group.
140
        $groupingfieldcategory = $generator->create_category(['component' => 'core_group', 'area' => 'grouping']);
141
        $generator->create_field(['categoryid' => $groupingfieldcategory->get('id'), 'shortname' => 'bye']);
142
 
143
        $grouping = $this->getDataGenerator()->create_grouping([
144
            'courseid' => $course->id,
145
            'idnumber' => 'GR101',
146
            'description' => 'My grouping',
147
            'customfield_bye' => 'Goodbye',
148
        ]);
149
        $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $group->id]);
150
 
151
        /** @var core_reportbuilder_generator $generator */
152
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
153
        $report = $generator->create_report(['name' => 'Groups', 'source' => groups::class, 'default' => 0]);
154
 
155
        // Course (just to test join).
156
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:shortname']);
157
 
158
        // Group.
159
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:idnumber']);
160
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:description']);
161
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:enrolmentkey']);
162
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:visibility']);
163
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:participation']);
164
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:picture']);
165
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:timecreated']);
166
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:timemodified']);
167
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:customfield_hi']);
168
 
169
        // Grouping.
170
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:name']);
171
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:idnumber']);
172
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:description']);
173
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:timecreated']);
174
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:timemodified']);
175
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'grouping:customfield_bye']);
176
 
177
        // Group member.
178
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group_member:timeadded']);
179
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group_member:component']);
180
 
181
        // User (just to test join).
182
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:username']);
183
 
184
        $content = $this->get_custom_report_content($report->get('id'));
185
        $this->assertCount(1, $content);
186
 
187
        [
188
            $courseshortname,
189
            $groupidnumber,
190
            $groupdescription,
191
            $groupenrolmentkey,
192
            $groupvisibility,
193
            $groupparticipation,
194
            $grouppicture,
195
            $grouptimecreated,
196
            $grouptimemodified,
197
            $groupcustomfield,
198
            $groupingname,
199
            $groupingidnumber,
200
            $groupingdescription,
201
            $groupingtimecreated,
202
            $groupingtimemodified,
203
            $groupingcustomfield,
204
            $groupmembertimeadded,
205
            $groupmemebercomponent,
206
            $userusername,
207
        ] = array_values($content[0]);
208
 
209
        $this->assertEquals($course->shortname, $courseshortname);
210
        $this->assertEquals('G101', $groupidnumber);
211
        $this->assertEquals(format_text($group->description), $groupdescription);
212
        $this->assertEquals('S', $groupenrolmentkey);
213
        $this->assertEquals('Visible', $groupvisibility);
214
        $this->assertEquals('Yes', $groupparticipation);
215
        $this->assertEmpty($grouppicture);
216
        $this->assertNotEmpty($grouptimecreated);
217
        $this->assertNotEmpty($grouptimemodified);
218
        $this->assertEquals('Hello', $groupcustomfield);
219
        $this->assertEquals($grouping->name, $groupingname);
220
        $this->assertEquals('GR101', $groupingidnumber);
221
        $this->assertEquals(format_text($grouping->description), $groupingdescription);
222
        $this->assertNotEmpty($groupingtimecreated);
223
        $this->assertNotEmpty($groupingtimemodified);
224
        $this->assertEquals('Goodbye', $groupingcustomfield);
225
        $this->assertNotEmpty($groupmembertimeadded);
226
        $this->assertEmpty($groupmemebercomponent);
227
        $this->assertEquals($user->username, $userusername);
228
    }
229
 
230
    /**
231
     * Data provider for {@see test_datasource_filters}
232
     *
233
     * @return array[]
234
     */
235
    public function datasource_filters_provider(): array {
236
        return [
237
            // Course (just to test join).
238
            'Filter course name' => ['course:fullname', [
239
                'course:fullname_operator' => text::IS_EQUAL_TO,
240
                'course:fullname_value' => 'Test course',
241
            ], true],
242
            'Filter course name (no match)' => ['course:fullname', [
243
                'course:fullname_operator' => text::IS_NOT_EQUAL_TO,
244
                'course:fullname_value' => 'Test course',
245
            ], false],
246
 
247
            // Group.
248
            'Filter group name' => ['group:name', [
249
                'group:name_operator' => text::IS_EQUAL_TO,
250
                'group:name_value' => 'Test group',
251
            ], true],
252
            'Filter group name (no match)' => ['group:name', [
253
                'group:name_operator' => text::IS_NOT_EQUAL_TO,
254
                'group:name_value' => 'Test group',
255
            ], false],
256
            'Filter group idnumber' => ['group:idnumber', [
257
                'group:idnumber_operator' => text::IS_EQUAL_TO,
258
                'group:idnumber_value' => 'G101',
259
            ], true],
260
            'Filter group idnumber (no match)' => ['group:idnumber', [
261
                'group:idnumber_operator' => text::IS_NOT_EQUAL_TO,
262
                'group:idnumber_value' => 'G101',
263
            ], false],
264
            'Filter group visibility' => ['group:visibility', [
265
                'group:visibility_operator' => select::EQUAL_TO,
266
                'group:visibility_value' => 0, // Visible to everyone.
267
            ], true],
268
            'Filter group visibility (no match)' => ['group:visibility', [
269
                'group:visibility_operator' => select::EQUAL_TO,
270
                'group:visibility_value' => 1, // Visible to members only.
271
            ], false],
272
            'Filter group participation' => ['group:participation', [
273
                'group:participation_operator' => boolean_select::CHECKED,
274
            ], true],
275
            'Filter group participation (no match)' => ['group:participation', [
276
                'group:participation_operator' => boolean_select::NOT_CHECKED,
277
            ], false],
278
            'Filter group time created' => ['group:timecreated', [
279
                'group:timecreated_operator' => date::DATE_RANGE,
280
                'group:timecreated_from' => 1622502000,
281
            ], true],
282
            'Filter group time created (no match)' => ['group:timecreated', [
283
                'group:timecreated_operator' => date::DATE_RANGE,
284
                'group:timecreated_to' => 1622502000,
285
            ], false],
286
 
287
            // Grouping.
288
            'Filter grouping name' => ['grouping:name', [
289
                'grouping:name_operator' => text::IS_EQUAL_TO,
290
                'grouping:name_value' => 'Test grouping',
291
            ], true],
292
            'Filter grouping name (no match)' => ['grouping:name', [
293
                'grouping:name_operator' => text::IS_NOT_EQUAL_TO,
294
                'grouping:name_value' => 'Test grouping',
295
            ], false],
296
            'Filter grouping idnumber' => ['grouping:idnumber', [
297
                'grouping:idnumber_operator' => text::IS_EQUAL_TO,
298
                'grouping:idnumber_value' => 'GR101',
299
            ], true],
300
            'Filter grouping idnumber (no match)' => ['grouping:idnumber', [
301
                'grouping:idnumber_operator' => text::IS_NOT_EQUAL_TO,
302
                'grouping:idnumber_value' => 'GR101',
303
            ], false],
304
            'Filter grouping time created' => ['grouping:timecreated', [
305
                'grouping:timecreated_operator' => date::DATE_RANGE,
306
                'grouping:timecreated_from' => 1622502000,
307
            ], true],
308
            'Filter grouping time created (no match)' => ['grouping:timecreated', [
309
                'grouping:timecreated_operator' => date::DATE_RANGE,
310
                'grouping:timecreated_to' => 1622502000,
311
            ], false],
312
 
313
            // Group member.
314
            'Filter group member time added' => ['group_member:timeadded', [
315
                'group_member:timeadded_operator' => date::DATE_RANGE,
316
                'group_member:timeadded_from' => 1622502000,
317
            ], true],
318
            'Filter group member time added (no match)' => ['group_member:timeadded', [
319
                'group_member:timeadded_operator' => date::DATE_RANGE,
320
                'group_member:timeadded_to' => 1622502000,
321
            ], false],
322
 
323
            // User (just to test join).
324
            'Filter user username' => ['user:username', [
325
                'user:username_operator' => text::IS_EQUAL_TO,
326
                'user:username_value' => 'testuser',
327
            ], true],
328
            'Filter user username (no match)' => ['user:username', [
329
                'user:username_operator' => text::IS_NOT_EQUAL_TO,
330
                'user:username_value' => 'testuser',
331
            ], false],
332
        ];
333
    }
334
 
335
    /**
336
     * Test datasource filters
337
     *
338
     * @param string $filtername
339
     * @param array $filtervalues
340
     * @param bool $expectmatch
341
     *
342
     * @dataProvider datasource_filters_provider
343
     */
344
    public function test_datasource_filters(
345
        string $filtername,
346
        array $filtervalues,
347
        bool $expectmatch
348
    ): void {
349
        $this->resetAfterTest();
350
 
351
        $course = $this->getDataGenerator()->create_course(['fullname' => 'Test course']);
352
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['username' => 'testuser']);
353
 
354
        $group = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'idnumber' => 'G101', 'name' => 'Test group']);
355
        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);
356
 
357
        $grouping = $this->getDataGenerator()->create_grouping(['courseid' => $course->id, 'idnumber' => 'GR101',
358
            'name' => 'Test grouping']);
359
        $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $group->id]);
360
 
361
        /** @var core_reportbuilder_generator $generator */
362
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
363
 
364
        // Create report containing single column, and given filter.
365
        $report = $generator->create_report(['name' => 'Tasks', 'source' => groups::class, 'default' => 0]);
366
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'group:idnumber']);
367
 
368
        // Add filter, set it's values.
369
        $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);
370
        $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues);
371
 
372
        if ($expectmatch) {
373
            $this->assertCount(1, $content);
374
            $this->assertEquals('G101', reset($content[0]));
375
        } else {
376
            $this->assertEmpty($content);
377
        }
378
    }
379
 
380
    /**
381
     * Stress test datasource
382
     *
383
     * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php
384
     */
385
    public function test_stress_datasource(): void {
386
        if (!PHPUNIT_LONGTEST) {
387
            $this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
388
        }
389
 
390
        $this->resetAfterTest();
391
 
392
        $course = $this->getDataGenerator()->create_course(['fullname' => 'Test course']);
393
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['username' => 'testuser']);
394
 
395
        $group = $this->getDataGenerator()->create_group(['courseid' => $course->id, 'idnumber' => 'G101', 'name' => 'Test group']);
396
        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);
397
 
398
        $grouping = $this->getDataGenerator()->create_grouping(['courseid' => $course->id, 'idnumber' => 'GR101',
399
            'name' => 'Test grouping']);
400
        $this->getDataGenerator()->create_grouping_group(['groupingid' => $grouping->id, 'groupid' => $group->id]);
401
 
402
        $this->datasource_stress_test_columns(groups::class);
403
        $this->datasource_stress_test_columns_aggregation(groups::class);
404
        $this->datasource_stress_test_conditions(groups::class, 'group:idnumber');
405
    }
406
}