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_blog\reportbuilder\datasource;
20
 
21
use context_system;
22
use context_user;
23
use core_blog_generator;
24
use core_comment_generator;
25
use core_reportbuilder_generator;
26
use core_reportbuilder_testcase;
27
use core_reportbuilder\local\filters\{boolean_select, date, select, text};
28
 
29
defined('MOODLE_INTERNAL') || die();
30
 
31
global $CFG;
32
require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
33
 
34
/**
35
 * Unit tests for blogs datasource
36
 *
37
 * @package     core_blog
38
 * @covers      \core_blog\reportbuilder\datasource\blogs
39
 * @copyright   2022 Paul Holden <paulh@moodle.com>
40
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class blogs_test extends core_reportbuilder_testcase {
43
 
44
    /**
45
     * Test default datasource
46
     */
47
    public function test_datasource_default(): void {
48
        $this->resetAfterTest();
49
 
50
        /** @var core_blog_generator $blogsgenerator */
51
        $blogsgenerator = $this->getDataGenerator()->get_plugin_generator('core_blog');
52
 
53
        // Our first user will create a course blog.
54
        $course = $this->getDataGenerator()->create_course();
55
        $userone = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe']);
56
        $courseblog = $blogsgenerator->create_entry(['publishstate' => 'site', 'userid' => $userone->id,
57
            'subject' => 'Course', 'summary' => 'Course summary', 'courseid' => $course->id]);
58
 
59
        // Our second user will create a personal and site blog.
60
        $usertwo = $this->getDataGenerator()->create_user(['firstname' => 'Amy']);
61
        $personalblog = $blogsgenerator->create_entry(['publishstate' => 'draft', 'userid' => $usertwo->id,
62
            'subject' => 'Personal', 'summary' => 'Personal summary']);
63
 
64
        $this->waitForSecond(); // For consistent ordering we need distinct time for second user blogs.
65
        $siteblog = $blogsgenerator->create_entry(['publishstate' => 'public', 'userid' => $usertwo->id,
66
            'subject' => 'Site', 'summary' => 'Site summary']);
67
 
68
        /** @var core_reportbuilder_generator $generator */
69
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
70
        $report = $generator->create_report(['name' => 'Blogs', 'source' => blogs::class, 'default' => 1]);
71
 
72
        $content = $this->get_custom_report_content($report->get('id'));
73
 
74
        // Default columns are user, course, title, time created. Sorted by user and time created.
75
        $this->assertEquals([
76
            [fullname($usertwo), '', $personalblog->subject, userdate($personalblog->created)],
77
            [fullname($usertwo), '', $siteblog->subject, userdate($siteblog->created)],
78
            [fullname($userone), $course->fullname, $courseblog->subject, userdate($courseblog->created)],
79
        ], array_map('array_values', $content));
80
    }
81
 
82
    /**
83
     * Test datasource columns that aren't added by default
84
     */
85
    public function test_datasource_non_default_columns(): void {
86
        global $DB;
87
 
88
        $this->resetAfterTest();
89
 
90
        $user = $this->getDataGenerator()->create_user();
91
        $this->setUser($user);
92
 
93
        /** @var core_blog_generator $blogsgenerator */
94
        $blogsgenerator = $this->getDataGenerator()->get_plugin_generator('core_blog');
95
        $blog = $blogsgenerator->create_entry(['publishstate' => 'draft', 'userid' => $user->id, 'subject' => 'My blog',
96
            'summary' => 'Horses', 'tags' => ['horse']]);
97
 
98
        // Add an attachment.
99
        $blog->attachment = 1;
100
        get_file_storage()->create_file_from_string([
101
            'contextid' => context_system::instance()->id,
102
            'component' => 'blog',
103
            'filearea' => 'attachment',
104
            'itemid' => $blog->id,
105
            'filepath' => '/',
106
            'filename' => 'hello.txt',
107
        ], 'hello');
108
 
109
        /** @var core_comment_generator $generator */
110
        $generator = $this->getDataGenerator()->get_plugin_generator('core_comment');
111
        $generator->create_comment([
112
            'context' => context_user::instance($user->id),
113
            'component' => 'blog',
114
            'area' => 'format_blog',
115
            'itemid' => $blog->id,
116
            'content' => 'Cool',
117
        ]);
118
 
119
        // Manually update the created/modified date of the blog.
120
        $blog->created = 1654038000;
121
        $blog->lastmodified = $blog->created + HOURSECS;
122
        $DB->update_record('post', $blog);
123
 
124
        /** @var core_reportbuilder_generator $generator */
125
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
126
        $report = $generator->create_report(['name' => 'Blogs', 'source' => blogs::class, 'default' => 0]);
127
 
128
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:titlewithlink']);
129
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:body']);
130
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:attachment']);
131
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:publishstate']);
132
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:timemodified']);
133
 
134
        // Tag entity (course/user presence already checked by default columns).
135
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']);
136
 
137
        // File entity.
138
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'file:size']);
139
 
140
        // Comment entity.
141
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'comment:content']);
142
 
143
        // Commenter entity.
144
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'commenter:fullname']);
145
 
146
        $content = $this->get_custom_report_content($report->get('id'));
147
        $this->assertCount(1, $content);
148
 
149
        [
150
            $link,
151
            $body,
152
            $attachment,
153
            $publishstate,
154
            $timemodified,
155
            $tags,
156
            $filesize,
157
            $comment,
158
            $commenter,
159
        ] = array_values($content[0]);
160
 
161
        $this->assertEquals("<a href=\"https://www.example.com/moodle/blog/index.php?entryid={$blog->id}\">{$blog->subject}</a>",
162
            $link);
163
        $this->assertStringContainsString('Horses', $body);
164
        $this->assertStringContainsString('hello.txt', $attachment);
165
        $this->assertEquals('Draft', $publishstate);
166
        $this->assertEquals(userdate($blog->lastmodified), $timemodified);
167
        $this->assertEquals('horse', $tags);
168
        $this->assertEquals("5\xc2\xa0bytes", $filesize);
169
        $this->assertEquals(format_text('Cool'), $comment);
170
        $this->assertEquals(fullname($user), $commenter);
171
    }
172
 
173
    /**
174
     * Data provider for {@see test_datasource_filters}
175
     *
176
     * @return array[]
177
     */
178
    public function datasource_filters_provider(): array {
179
        return [
180
            'Filter title' => ['subject', 'Cool', 'blog:title', [
181
                'blog:title_operator' => text::CONTAINS,
182
                'blog:title_value' => 'Cool',
183
            ], true],
184
            'Filter title (no match)' => ['subject', 'Cool', 'blog:title', [
185
                'blog:title_operator' => text::CONTAINS,
186
                'blog:title_value' => 'Beans',
187
            ], false],
188
            'Filter body' => ['summary', 'Awesome', 'blog:body', [
189
                'blog:body_operator' => select::EQUAL_TO,
190
                'blog:body_value' => 'Awesome',
191
            ], true],
192
            'Filter body (no match)' => ['summary', 'Awesome', 'blog:body', [
193
                'blog:body_operator' => select::EQUAL_TO,
194
                'blog:body_value' => 'Beans',
195
            ], false],
196
            'Filter attachment' => ['attachment', 1, 'blog:attachment', [
197
                'blog:attachment_operator' => boolean_select::CHECKED,
198
            ], true],
199
            'Filter attachment (no match)' => ['attachment', 1, 'blog:attachment', [
200
                'blog:attachment_operator' => boolean_select::NOT_CHECKED,
201
            ], false],
202
            'Filter publish state' => ['publishstate', 'site', 'blog:publishstate', [
203
                'blog:publishstate_operator' => select::EQUAL_TO,
204
                'blog:publishstate_value' => 'site',
205
            ], true],
206
            'Filter publish state (no match)' => ['publishstate', 'site', 'blog:publishstate', [
207
                'blog:publishstate_operator' => select::EQUAL_TO,
208
                'blog:publishstate_value' => 'draft',
209
            ], false],
210
            'Filter time created' => ['created', 1654038000, 'blog:timecreated', [
211
                'blog:timecreated_operator' => date::DATE_RANGE,
212
                'blog:timecreated_from' => 1622502000,
213
            ], true],
214
            'Filter time created (no match)' => ['created', 1654038000, 'blog:timecreated', [
215
                'blog:timecreated_operator' => date::DATE_RANGE,
216
                'blog:timecreated_to' => 1622502000,
217
            ], false],
218
            'Filter time modified' => ['lastmodified', 1654038000, 'blog:timemodified', [
219
                'blog:timemodified_operator' => date::DATE_RANGE,
220
                'blog:timemodified_from' => 1622502000,
221
            ], true],
222
            'Filter time modified (no match)' => ['lastmodified', 1654038000, 'blog:timemodified', [
223
                'blog:timemodified_operator' => date::DATE_RANGE,
224
                'blog:timemodified_to' => 1622502000,
225
            ], false],
226
        ];
227
    }
228
 
229
    /**
230
     * Test datasource filters
231
     *
232
     * @param string $field
233
     * @param mixed $value
234
     * @param string $filtername
235
     * @param array $filtervalues
236
     * @param bool $expectmatch
237
     *
238
     * @dataProvider datasource_filters_provider
239
     */
240
    public function test_datasource_filters(
241
        string $field,
242
        $value,
243
        string $filtername,
244
        array $filtervalues,
245
        bool $expectmatch
246
    ): void {
247
        global $DB;
248
 
249
        $this->resetAfterTest();
250
 
251
        $user = $this->getDataGenerator()->create_user();
252
 
253
        /** @var core_blog_generator $blogsgenerator */
254
        $blogsgenerator = $this->getDataGenerator()->get_plugin_generator('core_blog');
255
 
256
        // Create default blog, then manually override one of it's properties to use for filtering.
257
        $blog = $blogsgenerator->create_entry(['userid' => $user->id, 'subject' => 'My blog', 'summary' => 'Horses']);
258
        $DB->set_field('post', $field, $value, ['id' => $blog->id]);
259
 
260
        /** @var core_reportbuilder_generator $generator */
261
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
262
 
263
        // Create report containing single user column, and given filter.
264
        $report = $generator->create_report(['name' => 'Blogs', 'source' => blogs::class, 'default' => 0]);
265
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:fullname']);
266
 
267
        // Add filter, set it's values.
268
        $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);
269
        $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues);
270
 
271
        if ($expectmatch) {
272
            $this->assertCount(1, $content);
273
            $this->assertEquals(fullname($user), reset($content[0]));
274
        } else {
275
            $this->assertEmpty($content);
276
        }
277
    }
278
 
279
    /**
280
     * Stress test datasource
281
     *
282
     * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php
283
     */
284
    public function test_stress_datasource(): void {
285
        if (!PHPUNIT_LONGTEST) {
286
            $this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
287
        }
288
 
289
        $this->resetAfterTest();
290
 
291
        $user = $this->getDataGenerator()->create_user();
292
 
293
        /** @var core_blog_generator $blogsgenerator */
294
        $blogsgenerator = $this->getDataGenerator()->get_plugin_generator('core_blog');
295
        $blogsgenerator->create_entry(['userid' => $user->id, 'subject' => 'My blog', 'summary' => 'Horses']);
296
 
297
        $this->datasource_stress_test_columns(blogs::class);
298
        $this->datasource_stress_test_columns_aggregation(blogs::class);
299
        $this->datasource_stress_test_conditions(blogs::class, 'blog:title');
300
    }
301
}