From 6f8c301b7031a2883b9a8f897cb4fcf97e34ac58 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 29 May 2014 11:40:59 +0800 Subject: [PATCH] MDL-42695 mod_forum: Check grouping options when checking group discussion availability --- mod/forum/lib.php | 13 ++ mod/forum/tests/lib_test.php | 386 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+) diff --git a/mod/forum/lib.php b/mod/forum/lib.php index 8e05f86..807847f 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -5389,6 +5389,19 @@ function forum_user_can_see_group_discussion($discussion, $cm, $context) { } } + // If the forum is only available to a specific grouping, make sure that the user is in a group for this grouping. + // Note: This case will only be reached if the discussion was targetted at all participants. + $modinfo = get_fast_modinfo($cm->course); + if ($cm->groupingid > 0) { + $groups = $modinfo->get_groups($cm->groupingid); + foreach ($groups as $group) { + if (groups_is_member($group)) { + return true; + } + } + return false; + } + return true; } diff --git a/mod/forum/tests/lib_test.php b/mod/forum/tests/lib_test.php index 78b4d03..f7b01c0 100644 --- a/mod/forum/tests/lib_test.php +++ b/mod/forum/tests/lib_test.php @@ -689,4 +689,390 @@ class mod_forum_lib_testcase extends advanced_testcase { $this->assertFalse(forum_is_subscribed($user->id, $forum)); } } + + /** + * Test discussion group permission checks for a discussion without + * groups or groupings. + */ + public function test_forum_user_can_see_group_discussion_no_group() { + global $CFG, $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + + $course = $generator->create_course(); + + $record = new stdClass(); + $record->course = $course->id; + + // Create four users: + // * student; + // * teacher (has accessallgroups); + $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); + + $student = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($student->id, $course->id); + + $teacher = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $roleids['teacher']); + + // Create a forum in force subscribe. + $options = array( + 'course' => $course->id, + 'forcesubscribe' => FORUM_FORCESUBSCRIBE, + ); + $forum = $this->getDataGenerator()->create_module('forum', $options); + $cm = get_coursemodule_from_instance('forum', $forum->id); + + // Now we have all of that, create a discussion in the forum for all participants. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $teacher->id; + $record->forum = $forum->id; + $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + $context = context_module::instance($forum->cmid); + + // Now check the results for each of the users. + // All users should be able to see the discussion. + $this->setUser($student->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + $this->setUser($teacher->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + } + + /** + * Test discussion permission checks for groups and groupings when a + * post was made for all participants. + */ + public function test_forum_user_can_see_group_discussion_all_participants() { + global $CFG, $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + + $course = $generator->create_course(); + + $record = new stdClass(); + $record->course = $course->id; + + // Make a test group and place it in a grouping. + $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'G1!')); + $grouping = $generator->create_grouping(array('courseid' => $course->id)); + groups_assign_grouping($grouping->id, $group1->id); + + // Create four users: + // * student in the group; + // * teacher in the group (has accessallgroups); + // * student not in the group; and + // * teacher not in the group (has accessallgroups). + $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); + + $studentin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentin->id, $course->id); + groups_add_member($group1, $studentin); + + $teacherin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherin->id, $course->id, $roleids['teacher']); + groups_add_member($group1, $teacherin); + + $studentout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentout->id, $course->id); + + $teacherout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherout->id, $course->id, $roleids['teacher']); + + + // Create a forum in force subscribe, with separate groups and + // restricted to the grouping. + $options = array( + 'course' => $course->id, + 'forcesubscribe' => FORUM_FORCESUBSCRIBE, + 'grouping' => $grouping->id + ); + $forum = $this->getDataGenerator()->create_module('forum', $options); + $cm = get_coursemodule_from_instance('forum', $forum->id); + + // Now we have all of that, create a discussion in the forum for all participants. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $teacherin->id; + $record->forum = $forum->id; + // This post is for all participants. + $record->groupid = -1; + $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + $context = context_module::instance($forum->cmid); + + // Now check the results for each of the users. + // Firstly all users in the group should be able to see discussion posts. + $this->setUser($studentin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + $this->setUser($teacherin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Secondly, all users with accessallgroups should be able to see + // discussion posts to all participants. + $this->setUser($teacherout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Finally, users without accessallgroups, and who are not in the + // group should not be able to see the discussion. + $this->setUser($studentout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + } + + /** + * Test discussion permission checks for groups and groupings when a + * post was made for a specific group. + */ + public function test_forum_user_can_see_group_discussion_set_group() { + global $CFG, $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + + $course = $generator->create_course(); + + $record = new stdClass(); + $record->course = $course->id; + + // Make a test group. + $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'G1!')); + + // Create four users: + // * student in the group; + // * teacher in the group (has accessallgroups); + // * student not in the group; and + // * teacher not in the group (has accessallgroups). + $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); + + $studentin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentin->id, $course->id); + groups_add_member($group1, $studentin); + + $teacherin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherin->id, $course->id, $roleids['teacher']); + groups_add_member($group1, $teacherin); + + $studentout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentout->id, $course->id); + + $teacherout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherout->id, $course->id, $roleids['teacher']); + + + // Create a forum in force subscribe, with separate groups. + $options = array( + 'course' => $course->id, + 'forcesubscribe' => FORUM_FORCESUBSCRIBE, + ); + $forum = $this->getDataGenerator()->create_module('forum', $options); + $cm = get_coursemodule_from_instance('forum', $forum->id); + + // Now we have all of that, create a discussion in the forum for all participants. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $teacherin->id; + $record->forum = $forum->id; + // This post is for group1. + $record->groupid = $group1->id; + $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + $context = context_module::instance($forum->cmid); + + // Now check the results for each of the users. + // Firstly all users in the group should be able to see discussion posts. + $this->setUser($studentin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + $this->setUser($teacherin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Secondly, all users with accessallgroups should be able to see + // discussion posts to all participants. + $this->setUser($teacherout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Finally, users without accessallgroups, and who are not in the + // group should not be able to see the discussion. + $this->setUser($studentout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + } + + /** + * Test discussion permission checks for groups and groupings when a + * post was made for all participants. + */ + public function test_forum_user_can_see_group_discussion_with_grouping_all_participants() { + global $CFG, $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + + $course = $generator->create_course(); + + $record = new stdClass(); + $record->course = $course->id; + + // Make a test group. + $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'G1!')); + + // Create four users: + // * student in the group; + // * teacher in the group (has accessallgroups); + // * student not in the group; and + // * teacher not in the group (has accessallgroups). + $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); + + $studentin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentin->id, $course->id); + groups_add_member($group1, $studentin); + + $teacherin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherin->id, $course->id, $roleids['teacher']); + groups_add_member($group1, $teacherin); + + $studentout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentout->id, $course->id); + + $teacherout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherout->id, $course->id, $roleids['teacher']); + + + // Create a forum in force subscribe, with separate groups. + $options = array( + 'course' => $course->id, + 'forcesubscribe' => FORUM_FORCESUBSCRIBE, + ); + $forum = $this->getDataGenerator()->create_module('forum', $options); + $cm = get_coursemodule_from_instance('forum', $forum->id); + + // Now we have all of that, create a discussion in the forum for all participants. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $teacherin->id; + $record->forum = $forum->id; + // This post is for all participants. + $record->groupid = -1; + $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + $context = context_module::instance($forum->cmid); + + // Now check the results for each of the users. + // Firstly all users in the group should be able to see discussion posts. + $this->setUser($studentin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + $this->setUser($teacherin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Secondly, all users with accessallgroups should be able to see + // discussion posts to all participants. + $this->setUser($teacherout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Finally, users without accessallgroups, and who are not in the + // group should not be able to see the discussion. + $this->setUser($studentout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + } + + /** + * Test discussion permission checks for groups and groupings when a + * post was made for a specific group. + */ + public function test_forum_user_can_see_group_discussion_with_grouping_set_group() { + global $CFG, $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + + $course = $generator->create_course(); + + $record = new stdClass(); + $record->course = $course->id; + + // Make a test group and place it in a grouping. + $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'G1!')); + $grouping = $generator->create_grouping(array('courseid' => $course->id)); + groups_assign_grouping($grouping->id, $group1->id); + + // Create four users: + // * student in the group; + // * teacher in the group (has accessallgroups); + // * student not in the group; and + // * teacher not in the group (has accessallgroups). + $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); + + $studentin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentin->id, $course->id); + groups_add_member($group1, $studentin); + + $teacherin = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherin->id, $course->id, $roleids['teacher']); + groups_add_member($group1, $teacherin); + + $studentout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($studentout->id, $course->id); + + $teacherout = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($teacherout->id, $course->id, $roleids['teacher']); + + + // Create a forum in force subscribe, with separate groups and + // restricted to the grouping. + $options = array( + 'course' => $course->id, + 'forcesubscribe' => FORUM_FORCESUBSCRIBE, + 'grouping' => $grouping->id + ); + $forum = $this->getDataGenerator()->create_module('forum', $options); + $cm = get_coursemodule_from_instance('forum', $forum->id); + + // Now we have all of that, create a discussion in the forum for all participants. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $teacherin->id; + $record->forum = $forum->id; + // This post is for group 1. + $record->groupid = $group1->id; + $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + $context = context_module::instance($forum->cmid); + + // Now check the results for each of the users. + // Firstly all users in the group should be able to see discussion posts. + $this->setUser($studentin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + $this->setUser($teacherin->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Secondly, all users with accessallgroups should be able to see + // discussion posts to all participants. + $this->setUser($teacherout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + + // Finally, users without accessallgroups, and who are not in the + // group should not be able to see the discussion. + $this->setUser($studentout->id); + $result = forum_user_can_see_group_discussion($discussion, $cm, $context); + $this->assertTrue($result); + } + } -- 1.9.0