Differences Between: [Versions 401 and 403] [Versions 402 and 403]
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:body']); 129 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:attachment']); 130 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:publishstate']); 131 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'blog:timemodified']); 132 133 // Tag entity (course/user presence already checked by default columns). 134 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']); 135 136 // File entity. 137 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'file:size']); 138 139 // Comment entity. 140 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'comment:content']); 141 142 // Commenter entity. 143 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'commenter:fullname']); 144 145 $content = $this->get_custom_report_content($report->get('id')); 146 $this->assertCount(1, $content); 147 148 [ 149 $body, 150 $attachment, 151 $publishstate, 152 $timemodified, 153 $tags, 154 $filesize, 155 $comment, 156 $commenter, 157 ] = array_values($content[0]); 158 159 $this->assertStringContainsString('Horses', $body); 160 $this->assertStringContainsString('hello.txt', $attachment); 161 $this->assertEquals('Yourself (draft)', $publishstate); 162 $this->assertEquals(userdate($blog->lastmodified), $timemodified); 163 $this->assertEquals('horse', $tags); 164 $this->assertEquals("5\xc2\xa0bytes", $filesize); 165 $this->assertEquals(format_text('Cool'), $comment); 166 $this->assertEquals(fullname($user), $commenter); 167 } 168 169 /** 170 * Data provider for {@see test_datasource_filters} 171 * 172 * @return array[] 173 */ 174 public function datasource_filters_provider(): array { 175 return [ 176 'Filter title' => ['subject', 'Cool', 'blog:title', [ 177 'blog:title_operator' => text::CONTAINS, 178 'blog:title_value' => 'Cool', 179 ], true], 180 'Filter title (no match)' => ['subject', 'Cool', 'blog:title', [ 181 'blog:title_operator' => text::CONTAINS, 182 'blog:title_value' => 'Beans', 183 ], false], 184 'Filter body' => ['summary', 'Awesome', 'blog:body', [ 185 'blog:body_operator' => select::EQUAL_TO, 186 'blog:body_value' => 'Awesome', 187 ], true], 188 'Filter body (no match)' => ['summary', 'Awesome', 'blog:body', [ 189 'blog:body_operator' => select::EQUAL_TO, 190 'blog:body_value' => 'Beans', 191 ], false], 192 'Filter attachment' => ['attachment', 1, 'blog:attachment', [ 193 'blog:attachment_operator' => boolean_select::CHECKED, 194 ], true], 195 'Filter attachment (no match)' => ['attachment', 1, 'blog:attachment', [ 196 'blog:attachment_operator' => boolean_select::NOT_CHECKED, 197 ], false], 198 'Filter publish state' => ['publishstate', 'site', 'blog:publishstate', [ 199 'blog:publishstate_operator' => select::EQUAL_TO, 200 'blog:publishstate_value' => 'site', 201 ], true], 202 'Filter publish state (no match)' => ['publishstate', 'site', 'blog:publishstate', [ 203 'blog:publishstate_operator' => select::EQUAL_TO, 204 'blog:publishstate_value' => 'draft', 205 ], false], 206 'Filter time created' => ['created', 1654038000, 'blog:timecreated', [ 207 'blog:timecreated_operator' => date::DATE_RANGE, 208 'blog:timecreated_from' => 1622502000, 209 ], true], 210 'Filter time created (no match)' => ['created', 1654038000, 'blog:timecreated', [ 211 'blog:timecreated_operator' => date::DATE_RANGE, 212 'blog:timecreated_to' => 1622502000, 213 ], false], 214 'Filter time modified' => ['lastmodified', 1654038000, 'blog:timemodified', [ 215 'blog:timemodified_operator' => date::DATE_RANGE, 216 'blog:timemodified_from' => 1622502000, 217 ], true], 218 'Filter time modified (no match)' => ['lastmodified', 1654038000, 'blog:timemodified', [ 219 'blog:timemodified_operator' => date::DATE_RANGE, 220 'blog:timemodified_to' => 1622502000, 221 ], false], 222 ]; 223 } 224 225 /** 226 * Test datasource filters 227 * 228 * @param string $field 229 * @param mixed $value 230 * @param string $filtername 231 * @param array $filtervalues 232 * @param bool $expectmatch 233 * 234 * @dataProvider datasource_filters_provider 235 */ 236 public function test_datasource_filters( 237 string $field, 238 $value, 239 string $filtername, 240 array $filtervalues, 241 bool $expectmatch 242 ): void { 243 global $DB; 244 245 $this->resetAfterTest(); 246 247 $user = $this->getDataGenerator()->create_user(); 248 249 /** @var core_blog_generator $blogsgenerator */ 250 $blogsgenerator = $this->getDataGenerator()->get_plugin_generator('core_blog'); 251 252 // Create default blog, then manually override one of it's properties to use for filtering. 253 $blog = $blogsgenerator->create_entry(['userid' => $user->id, 'subject' => 'My blog', 'summary' => 'Horses']); 254 $DB->set_field('post', $field, $value, ['id' => $blog->id]); 255 256 /** @var core_reportbuilder_generator $generator */ 257 $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); 258 259 // Create report containing single user column, and given filter. 260 $report = $generator->create_report(['name' => 'Blogs', 'source' => blogs::class, 'default' => 0]); 261 $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:fullname']); 262 263 // Add filter, set it's values. 264 $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]); 265 $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues); 266 267 if ($expectmatch) { 268 $this->assertCount(1, $content); 269 $this->assertEquals(fullname($user), reset($content[0])); 270 } else { 271 $this->assertEmpty($content); 272 } 273 } 274 275 /** 276 * Stress test datasource 277 * 278 * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php 279 */ 280 public function test_stress_datasource(): void { 281 if (!PHPUNIT_LONGTEST) { 282 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 283 } 284 285 $this->resetAfterTest(); 286 287 $user = $this->getDataGenerator()->create_user(); 288 289 /** @var core_blog_generator $blogsgenerator */ 290 $blogsgenerator = $this->getDataGenerator()->get_plugin_generator('core_blog'); 291 $blogsgenerator->create_entry(['userid' => $user->id, 'subject' => 'My blog', 'summary' => 'Horses']); 292 293 $this->datasource_stress_test_columns(blogs::class); 294 $this->datasource_stress_test_columns_aggregation(blogs::class); 295 $this->datasource_stress_test_conditions(blogs::class, 'blog:title'); 296 } 297 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body