Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>.namespace mod_forum;use mod_forum_tests_generator_trait;defined('MOODLE_INTERNAL') || die();require_once(__DIR__ . '/generator_trait.php');/*** The exported_posts builder tests.** @package mod_forum* @copyright 2019 Ryan Wyllie <ryan@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class builders_exported_posts_test extends \advanced_testcase {// Make use of the test generator trait.use mod_forum_tests_generator_trait;/** @var \mod_forum\local\builders\exported_posts */private $builder;/*** Set up function for tests.*/public function setUp(): void {// We must clear the subscription caches. This has to be done both before each test, and after in case of other// tests using these functions.\mod_forum\subscriptions::reset_forum_cache();$builderfactory = \mod_forum\local\container::get_builder_factory();$this->builder = $builderfactory->get_exported_posts_builder();}/*** Tear down function for tests.*/public function tearDown(): void {// We must clear the subscription caches. This has to be done both before each test, and after in case of other// tests using these functions.\mod_forum\subscriptions::reset_forum_cache();}/*** Convert the stdClass values into their proper entity classes.** @param stdClass[] $forums List of forums* @param stdClass[] $discussions List of discussions* @param stdClass[] $posts List of posts* @return array*/private function convert_to_entities(array $forums, array $discussions, array $posts) {global $DB;$entityfactory = \mod_forum\local\container::get_entity_factory();return [// Forums.array_map(function($forum) use ($entityfactory, $DB) {$course = $DB->get_record('course', ['id' => $forum->course]);$coursemodule = get_coursemodule_from_instance('forum', $forum->id);$context = \context_module::instance($coursemodule->id);return $entityfactory->get_forum_from_stdClass($forum, $context, $coursemodule, $course);}, $forums),// Discussions.array_map(function($discussion) use ($entityfactory) {return $entityfactory->get_discussion_from_stdClass($discussion);}, $discussions),// Posts.array_map(function($post) use ($entityfactory) {return $entityfactory->get_post_from_stdClass($post);}, $posts)];}/*** Test the build function throws exception if not given all of the forums for* the list of posts.*/public function test_build_throws_exception_on_missing_forums(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user = $datagenerator->create_user();$course = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user);[$discussion2, $post2] = $this->helper_post_to_forum($forum2, $user);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2],[$post1, $post2]);$this->expectException('moodle_exception');$this->builder->build($user, [$forums[0]], $discussions, $posts);}/*** Test the build function throws exception if not given all of the discussions for* the list of posts.*/public function test_build_throws_exception_on_missing_discussions(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user = $datagenerator->create_user();$course = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user);[$discussion2, $post2] = $this->helper_post_to_forum($forum2, $user);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2],[$post1, $post2]);$this->expectException('moodle_exception');$this->builder->build($user, $forums, [$discussions[0]], $posts);}/*** Test the build function returns the exported posts in the order that the posts are* given.*/public function test_build_returns_posts_in_order(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$course = $datagenerator->create_course();$user1 = $datagenerator->create_and_enrol($course);$user2 = $datagenerator->create_and_enrol($course);$forum1 = $datagenerator->create_module('forum', ['course' => $course->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user1);[$discussion2, $post2] = $this->helper_post_to_forum($forum1, $user2);$post3 = $this->helper_reply_to_post($post1, $user1);$post4 = $this->helper_reply_to_post($post1, $user2);[$discussion3, $post5] = $this->helper_post_to_forum($forum2, $user1);[$discussion4, $post6] = $this->helper_post_to_forum($forum2, $user2);$post7 = $this->helper_reply_to_post($post2, $user1);$post8 = $this->helper_reply_to_post($post2, $user2);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2, $discussion3, $discussion4],[$post1, $post2, $post3, $post4, $post5, $post6, $post7, $post8]);// Randomly order the posts.shuffle($posts);$exportedposts = $this->builder->build($user1, $forums, $discussions, $posts);$expectedpostids = array_map(function($post) {return $post->get_id();}, $posts);$actualpostids = array_map(function($exportedpost) {return (int) $exportedpost->id;}, $exportedposts);$this->assertEquals($expectedpostids, $actualpostids);}/*** Test the build function loads authors.*/public function test_build_loads_authors(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user1 = $datagenerator->create_user();$user2 = $datagenerator->create_user();$user3 = $datagenerator->create_user();$course = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user1);[$discussion2, $post2] = $this->helper_post_to_forum($forum1, $user2);$post3 = $this->helper_reply_to_post($post1, $user1);$post4 = $this->helper_reply_to_post($post1, $user2);[$discussion3, $post5] = $this->helper_post_to_forum($forum2, $user1);[$discussion4, $post6] = $this->helper_post_to_forum($forum2, $user2);// These 2 replies from user 3 won't be inlcuded in the export.$post7 = $this->helper_reply_to_post($post2, $user3);$post8 = $this->helper_reply_to_post($post2, $user3);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2, $discussion3, $discussion4],[$post1, $post2, $post3, $post4, $post5, $post6]);$datagenerator->enrol_user($user1->id, $course->id);$exportedposts = $this->builder->build($user1, $forums, $discussions, $posts);// We didn't include any posts from user 3 so we shouldn't see the authors// that match that user.$expectedids = [$user1->id, $user2->id];$actualids = array_unique(array_map(function($exportedpost) {return (int) $exportedpost->author->id;}, $exportedposts));sort($expectedids);sort($actualids);$this->assertEquals($expectedids, $actualids);}/*** Test the build function loads attachments.*/public function test_build_loads_attachments(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user1 = $datagenerator->create_user();$user2 = $datagenerator->create_user();$user3 = $datagenerator->create_user();$course = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user1);[$discussion2, $post2] = $this->helper_post_to_forum($forum1, $user2);$post3 = $this->helper_reply_to_post($post1, $user1);$post4 = $this->helper_reply_to_post($post1, $user2);[$discussion3, $post5] = $this->helper_post_to_forum($forum2, $user1);[$discussion4, $post6] = $this->helper_post_to_forum($forum2, $user2);$post7 = $this->helper_reply_to_post($post5, $user3);$post8 = $this->helper_reply_to_post($post5, $user3);$filestorage = get_file_storage();[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2, $discussion3, $discussion4],[$post1, $post2, $post3, $post4, $post5, $post6, $post7, $post8]);// Add an attachment to a post in forum 1.$attachment1 = $filestorage->create_file_from_string(['contextid' => $forums[0]->get_context()->id,'component' => 'mod_forum','filearea' => 'attachment','itemid' => $post1->id,'filepath' => '/','filename' => 'example1.jpg',],'image contents');// Add an attachment to a post in forum 2.$attachment2 = $filestorage->create_file_from_string(['contextid' => $forums[1]->get_context()->id,'component' => 'mod_forum','filearea' => 'attachment','itemid' => $post7->id,'filepath' => '/','filename' => 'example2.jpg',],'image contents');// Enrol the user so that they can see the posts.$datagenerator->enrol_user($user1->id, $course->id);$exportedposts = $this->builder->build($user1, $forums, $discussions, $posts);$expected = ['example1.jpg', 'example2.jpg'];$actual = array_reduce($exportedposts, function($carry, $exportedpost) {if (!empty($exportedpost->attachments)) {foreach ($exportedpost->attachments as $attachment) {$carry[] = $attachment->filename;}}return $carry;}, []);sort($expected);sort($actual);$this->assertEquals($expected, $actual);}/*** Test the build function loads author groups.*/public function test_build_loads_author_groups(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user1 = $datagenerator->create_user();$user2 = $datagenerator->create_user();$user3 = $datagenerator->create_user();$course1 = $datagenerator->create_course();$course2 = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course1->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course1->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user1);[$discussion2, $post2] = $this->helper_post_to_forum($forum1, $user2);$post3 = $this->helper_reply_to_post($post1, $user1);$post4 = $this->helper_reply_to_post($post1, $user2);[$discussion3, $post5] = $this->helper_post_to_forum($forum2, $user1);[$discussion4, $post6] = $this->helper_post_to_forum($forum2, $user2);$post7 = $this->helper_reply_to_post($post5, $user3);$post8 = $this->helper_reply_to_post($post5, $user3);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2, $discussion3, $discussion4],[$post1, $post2, $post3, $post4, $post5, $post6, $post7, $post8]);// Enrol the user so that they can see the posts.$datagenerator->enrol_user($user1->id, $course1->id);$datagenerator->enrol_user($user1->id, $course2->id);$datagenerator->enrol_user($user2->id, $course1->id);$datagenerator->enrol_user($user2->id, $course2->id);$datagenerator->enrol_user($user3->id, $course1->id);$datagenerator->enrol_user($user3->id, $course2->id);$group1 = $datagenerator->create_group(['courseid' => $course1->id]);$group2 = $datagenerator->create_group(['courseid' => $course1->id]);// This group shouldn't be included in the results since it's in a different course.$group3 = $datagenerator->create_group(['courseid' => $course2->id]);$datagenerator->create_group_member(['userid' => $user1->id, 'groupid' => $group1->id]);$datagenerator->create_group_member(['userid' => $user2->id, 'groupid' => $group1->id]);$datagenerator->create_group_member(['userid' => $user1->id, 'groupid' => $group2->id]);$datagenerator->create_group_member(['userid' => $user1->id, 'groupid' => $group3->id]);$exportedposts = $this->builder->build($user1, $forums, $discussions, $posts);$expected = [$user1->id => [$group1->id, $group2->id],$user2->id => [$group1->id],$user3->id => []];$actual = array_reduce($exportedposts, function($carry, $exportedpost) {$author = $exportedpost->author;$authorid = $author->id;if (!isset($carry[$authorid])) {$carry[$authorid] = array_map(function($group) {return $group['id'];}, $author->groups);}return $carry;}, []);$this->assertEquals($expected, $actual);}/*** Test the build function loads tags.*/public function test_build_loads_tags(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user1 = $datagenerator->create_user();$user2 = $datagenerator->create_user();$user3 = $datagenerator->create_user();$course1 = $datagenerator->create_course();$course2 = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course1->id]);$forum2 = $datagenerator->create_module('forum', ['course' => $course1->id]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user1);[$discussion2, $post2] = $this->helper_post_to_forum($forum1, $user2);$post3 = $this->helper_reply_to_post($post1, $user1);$post4 = $this->helper_reply_to_post($post1, $user2);[$discussion3, $post5] = $this->helper_post_to_forum($forum2, $user1);[$discussion4, $post6] = $this->helper_post_to_forum($forum2, $user2);$post7 = $this->helper_reply_to_post($post5, $user3);$post8 = $this->helper_reply_to_post($post5, $user3);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2, $discussion3, $discussion4],[$post1, $post2, $post3, $post4, $post5, $post6, $post7, $post8]);// Enrol the user so that they can see the posts.$datagenerator->enrol_user($user1->id, $course1->id);$datagenerator->enrol_user($user1->id, $course2->id);$datagenerator->enrol_user($user2->id, $course1->id);$datagenerator->enrol_user($user2->id, $course2->id);$datagenerator->enrol_user($user3->id, $course1->id);$datagenerator->enrol_user($user3->id, $course2->id);\core_tag_tag::set_item_tags('mod_forum', 'forum_posts', $post1->id, $forums[0]->get_context(), ['foo', 'bar']);\core_tag_tag::set_item_tags('mod_forum', 'forum_posts', $post4->id, $forums[0]->get_context(), ['foo', 'baz']);\core_tag_tag::set_item_tags('mod_forum', 'forum_posts', $post7->id, $forums[1]->get_context(), ['bip']);$exportedposts = $this->builder->build($user1, $forums, $discussions, $posts);$expected = [$post1->id => ['foo', 'bar'],$post4->id => ['foo', 'baz'],$post7->id => ['bip']];$actual = array_reduce($exportedposts, function($carry, $exportedpost) {if (!empty($exportedpost->tags)) {$carry[$exportedpost->id] = array_map(function($tag) {return $tag['displayname'];}, $exportedpost->tags);}return $carry;}, []);$this->assertEquals($expected, $actual);}/*** Test the build function loads read_receipts.*/public function test_build_loads_read_receipts(): void {$this->resetAfterTest();$datagenerator = $this->getDataGenerator();$user1 = $datagenerator->create_user(['trackforums' => 1]);$user2 = $datagenerator->create_user(['trackforums' => 0]);$course1 = $datagenerator->create_course();$course2 = $datagenerator->create_course();$forum1 = $datagenerator->create_module('forum', ['course' => $course1->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL]);$forum2 = $datagenerator->create_module('forum', ['course' => $course1->id, 'trackingtype' => FORUM_TRACKING_OFF]);[$discussion1, $post1] = $this->helper_post_to_forum($forum1, $user1);[$discussion2, $post2] = $this->helper_post_to_forum($forum1, $user2);$post3 = $this->helper_reply_to_post($post1, $user1);$post4 = $this->helper_reply_to_post($post1, $user2);[$discussion3, $post5] = $this->helper_post_to_forum($forum2, $user1);[$discussion4, $post6] = $this->helper_post_to_forum($forum2, $user2);$post7 = $this->helper_reply_to_post($post5, $user1);$post8 = $this->helper_reply_to_post($post5, $user1);[$forums, $discussions, $posts] = $this->convert_to_entities([$forum1, $forum2],[$discussion1, $discussion2, $discussion3, $discussion4],[$post1, $post2, $post3, $post4, $post5, $post6, $post7, $post8]);// Enrol the user so that they can see the posts.$datagenerator->enrol_user($user1->id, $course1->id);$datagenerator->enrol_user($user1->id, $course2->id);$datagenerator->enrol_user($user2->id, $course1->id);$datagenerator->enrol_user($user2->id, $course2->id);forum_tp_add_read_record($user1->id, $post1->id);forum_tp_add_read_record($user1->id, $post4->id);forum_tp_add_read_record($user1->id, $post7->id);forum_tp_add_read_record($user2->id, $post1->id);forum_tp_add_read_record($user2->id, $post4->id);forum_tp_add_read_record($user2->id, $post7->id);// User 1 has tracking enabled.$exportedposts = $this->builder->build($user1, $forums, $discussions, $posts);$expected = [// Tracking set for forum 1 for user 1.$post1->id => false,$post2->id => true,$post3->id => true,$post4->id => false,// Tracking is off for forum 2 so everything should be null.$post5->id => null,$post6->id => null,$post7->id => null,$post8->id => null];$actual = array_reduce($exportedposts, function($carry, $exportedpost) {$carry[$exportedpost->id] = $exportedpost->unread;return $carry;}, []);$this->assertEquals($expected, $actual);// User 2 has tracking disabled.$exportedposts = $this->builder->build($user2, $forums, $discussions, $posts);// Tracking is off for user 2 so everything should be null.$expected = [$post1->id => null,$post2->id => null,$post3->id => null,$post4->id => null,$post5->id => null,$post6->id => null,$post7->id => null,$post8->id => null];$actual = array_reduce($exportedposts, function($carry, $exportedpost) {$carry[$exportedpost->id] = $exportedpost->unread;return $carry;}, []);$this->assertEquals($expected, $actual);}}