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