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