Proyectos de Subversion Moodle

Rev

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