MDL-58885 core_search: Group support unit tests

This commit is contained in:
sam marshall
2018-02-16 16:57:01 +00:00
parent 3261e9237d
commit 163d280053
2 changed files with 233 additions and 30 deletions
+109 -4
View File
@@ -54,7 +54,7 @@ require_once($CFG->dirroot . '/search/engine/solr/tests/fixtures/testable_engine
class search_solr_engine_testcase extends advanced_testcase {
/**
* @var \core_search::manager
* @var \core_search\manager
*/
protected $search = null;
@@ -707,18 +707,18 @@ class search_solr_engine_testcase extends advanced_testcase {
$querydata->q = 'Something1 Something2 Something3 Something4';
// In this first set, it should have determined the first 10 of 40 are bad, so there could be up to 30 left.
$results = $this->engine->execute_query($querydata, true, 5);
$results = $this->engine->execute_query($querydata, (object)['everything' => true], 5);
$this->assertEquals(30, $this->engine->get_query_total_count());
$this->assertCount(5, $results);
// To get to 15, it has to process the first 10 that are bad, 10 that are good, 10 that are bad, then 5 that are good.
// So we now know 20 are bad out of 40.
$results = $this->engine->execute_query($querydata, true, 15);
$results = $this->engine->execute_query($querydata, (object)['everything' => true], 15);
$this->assertEquals(20, $this->engine->get_query_total_count());
$this->assertCount(15, $results);
// Try to get more then all, make sure we still see 20 count and 20 returned.
$results = $this->engine->execute_query($querydata, true, 30);
$results = $this->engine->execute_query($querydata, (object)['everything' => true], 30);
$this->assertEquals(20, $this->engine->get_query_total_count());
$this->assertCount(20, $results);
}
@@ -830,6 +830,111 @@ class search_solr_engine_testcase extends advanced_testcase {
$this->assert_result_titles([], $results);
}
/**
* Tests searching for results in groups, either by specified group ids or based on user
* access permissions.
*/
public function test_groups() {
global $USER;
// Use real search areas.
$this->search->clear_static();
$this->search->add_core_search_areas();
// Create 2 courses and a selection of forums with different group mode.
$generator = $this->getDataGenerator();
$course1 = $generator->create_course(['fullname' => 'Course 1']);
$forum1nogroups = $generator->create_module('forum', ['course' => $course1, 'groupmode' => NOGROUPS]);
$forum1separategroups = $generator->create_module('forum', ['course' => $course1, 'groupmode' => SEPARATEGROUPS]);
$forum1visiblegroups = $generator->create_module('forum', ['course' => $course1, 'groupmode' => VISIBLEGROUPS]);
$course2 = $generator->create_course(['fullname' => 'Course 2']);
$forum2separategroups = $generator->create_module('forum', ['course' => $course2, 'groupmode' => SEPARATEGROUPS]);
// Create two groups on each course.
$group1a = $generator->create_group(['courseid' => $course1->id]);
$group1b = $generator->create_group(['courseid' => $course1->id]);
$group2a = $generator->create_group(['courseid' => $course2->id]);
$group2b = $generator->create_group(['courseid' => $course2->id]);
// Create search records in each activity and (where relevant) in each group.
$forumgenerator = $generator->get_plugin_generator('mod_forum');
$forumgenerator->create_discussion(['course' => $course1->id, 'userid' => $USER->id,
'forum' => $forum1nogroups->id, 'name' => 'F1NG', 'message' => 'xyzzy']);
$forumgenerator->create_discussion(['course' => $course1->id, 'userid' => $USER->id,
'forum' => $forum1separategroups->id, 'name' => 'F1SG-A', 'message' => 'xyzzy',
'groupid' => $group1a->id]);
$forumgenerator->create_discussion(['course' => $course1->id, 'userid' => $USER->id,
'forum' => $forum1separategroups->id, 'name' => 'F1SG-B', 'message' => 'xyzzy',
'groupid' => $group1b->id]);
$forumgenerator->create_discussion(['course' => $course1->id, 'userid' => $USER->id,
'forum' => $forum1visiblegroups->id, 'name' => 'F1VG-A', 'message' => 'xyzzy',
'groupid' => $group1a->id]);
$forumgenerator->create_discussion(['course' => $course1->id, 'userid' => $USER->id,
'forum' => $forum1visiblegroups->id, 'name' => 'F1VG-B', 'message' => 'xyzzy',
'groupid' => $group1b->id]);
$forumgenerator->create_discussion(['course' => $course2->id, 'userid' => $USER->id,
'forum' => $forum2separategroups->id, 'name' => 'F2SG-A', 'message' => 'xyzzy',
'groupid' => $group2a->id]);
$forumgenerator->create_discussion(['course' => $course2->id, 'userid' => $USER->id,
'forum' => $forum2separategroups->id, 'name' => 'F2SG-B', 'message' => 'xyzzy',
'groupid' => $group2b->id]);
$this->search->index();
// Search as admin user should find everything.
$querydata = new stdClass();
$querydata->q = 'xyzzy';
$results = $this->search->search($querydata);
$this->assert_result_titles(
['F1NG', 'F1SG-A', 'F1SG-B', 'F1VG-A', 'F1VG-B', 'F2SG-A', 'F2SG-B'], $results);
// Admin user manually restricts results by groups.
$querydata->groupids = [$group1b->id, $group2a->id];
$results = $this->search->search($querydata);
$this->assert_result_titles(['F1SG-B', 'F1VG-B', 'F2SG-A'], $results);
// Student enrolled in both courses but no groups.
$student1 = $generator->create_user();
$generator->enrol_user($student1->id, $course1->id, 'student');
$generator->enrol_user($student1->id, $course2->id, 'student');
$this->setUser($student1);
unset($querydata->groupids);
$results = $this->search->search($querydata);
$this->assert_result_titles(['F1NG', 'F1VG-A', 'F1VG-B'], $results);
// Student enrolled in both courses and group A in both cases.
$student2 = $generator->create_user();
$generator->enrol_user($student2->id, $course1->id, 'student');
$generator->enrol_user($student2->id, $course2->id, 'student');
groups_add_member($group1a, $student2);
groups_add_member($group2a, $student2);
$this->setUser($student2);
$results = $this->search->search($querydata);
$this->assert_result_titles(['F1NG', 'F1SG-A', 'F1VG-A', 'F1VG-B', 'F2SG-A'], $results);
// Manually restrict results to group B in course 1.
$querydata->groupids = [$group1b->id];
$results = $this->search->search($querydata);
$this->assert_result_titles(['F1VG-B'], $results);
// Manually restrict results to group A in course 1.
$querydata->groupids = [$group1a->id];
$results = $this->search->search($querydata);
$this->assert_result_titles(['F1SG-A', 'F1VG-A'], $results);
// Manager enrolled in both courses (has access all groups).
$manager = $generator->create_user();
$generator->enrol_user($manager->id, $course1->id, 'manager');
$generator->enrol_user($manager->id, $course2->id, 'manager');
$this->setUser($manager);
unset($querydata->groupids);
$results = $this->search->search($querydata);
$this->assert_result_titles(
['F1NG', 'F1SG-A', 'F1SG-B', 'F1VG-A', 'F1VG-B', 'F2SG-A', 'F2SG-B'], $results);
}
/**
* Asserts that the returned documents have the expected titles (regardless of order).
*
+124 -26
View File
@@ -555,20 +555,20 @@ class search_manager_testcase extends advanced_testcase {
$search->add_search_area($mockareaid, new core_mocksearch\search\mock_search_area());
$this->setAdminUser();
$this->assertTrue($search->get_areas_user_accesses());
$this->assertEquals((object)['everything' => true], $search->get_areas_user_accesses());
$sitectx = \context_course::instance(SITEID);
// Can access the frontpage ones.
$this->setUser($noaccess);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals(array($frontpageforumcontext->id => $frontpageforumcontext->id), $contexts[$this->forumpostareaid]);
$this->assertEquals(array($sitectx->id => $sitectx->id), $contexts[$this->mycoursesareaid]);
$mockctxs = array($noaccessctx->id => $noaccessctx->id, $frontpagectx->id => $frontpagectx->id);
$this->assertEquals($mockctxs, $contexts[$mockareaid]);
$this->setUser($teacher);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$frontpageandcourse1 = array($frontpageforumcontext->id => $frontpageforumcontext->id, $context1->id => $context1->id,
$context2->id => $context2->id);
$this->assertEquals($frontpageandcourse1, $contexts[$this->forumpostareaid]);
@@ -579,7 +579,7 @@ class search_manager_testcase extends advanced_testcase {
$this->assertEquals($mockctxs, $contexts[$mockareaid]);
$this->setUser($student);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals($frontpageandcourse1, $contexts[$this->forumpostareaid]);
$this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id),
$contexts[$this->mycoursesareaid]);
@@ -589,39 +589,39 @@ class search_manager_testcase extends advanced_testcase {
// Hide the activity.
set_coursemodule_visible($forum2->cmid, 0);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals(array($frontpageforumcontext->id => $frontpageforumcontext->id, $context1->id => $context1->id),
$contexts[$this->forumpostareaid]);
// Now test course limited searches.
set_coursemodule_visible($forum2->cmid, 1);
$this->getDataGenerator()->enrol_user($student->id, $course2->id, 'student');
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$allcontexts = array($frontpageforumcontext->id => $frontpageforumcontext->id, $context1->id => $context1->id,
$context2->id => $context2->id, $context3->id => $context3->id);
$this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]);
$this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id,
$course2ctx->id => $course2ctx->id), $contexts[$this->mycoursesareaid]);
$contexts = $search->get_areas_user_accesses(array($course1->id, $course2->id));
$contexts = $search->get_areas_user_accesses(array($course1->id, $course2->id))->usercontexts;
$allcontexts = array($context1->id => $context1->id, $context2->id => $context2->id, $context3->id => $context3->id);
$this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]);
$this->assertEquals(array($course1ctx->id => $course1ctx->id,
$course2ctx->id => $course2ctx->id), $contexts[$this->mycoursesareaid]);
$contexts = $search->get_areas_user_accesses(array($course2->id));
$contexts = $search->get_areas_user_accesses(array($course2->id))->usercontexts;
$allcontexts = array($context3->id => $context3->id);
$this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]);
$this->assertEquals(array($course2ctx->id => $course2ctx->id), $contexts[$this->mycoursesareaid]);
$contexts = $search->get_areas_user_accesses(array($course1->id));
$contexts = $search->get_areas_user_accesses(array($course1->id))->usercontexts;
$allcontexts = array($context1->id => $context1->id, $context2->id => $context2->id);
$this->assertEquals($allcontexts, $contexts[$this->forumpostareaid]);
$this->assertEquals(array($course1ctx->id => $course1ctx->id), $contexts[$this->mycoursesareaid]);
// Test context limited search with no course limit.
$contexts = $search->get_areas_user_accesses(false,
[$frontpageforumcontext->id, $course2ctx->id]);
[$frontpageforumcontext->id, $course2ctx->id])->usercontexts;
$this->assertEquals([$frontpageforumcontext->id => $frontpageforumcontext->id],
$contexts[$this->forumpostareaid]);
$this->assertEquals([$course2ctx->id => $course2ctx->id],
@@ -629,19 +629,19 @@ class search_manager_testcase extends advanced_testcase {
// Test context limited search with course limit.
$contexts = $search->get_areas_user_accesses([$course1->id, $course2->id],
[$frontpageforumcontext->id, $course2ctx->id]);
[$frontpageforumcontext->id, $course2ctx->id])->usercontexts;
$this->assertArrayNotHasKey($this->forumpostareaid, $contexts);
$this->assertEquals([$course2ctx->id => $course2ctx->id],
$contexts[$this->mycoursesareaid]);
// Single context and course.
$contexts = $search->get_areas_user_accesses([$course1->id], [$context1->id]);
$contexts = $search->get_areas_user_accesses([$course1->id], [$context1->id])->usercontexts;
$this->assertEquals([$context1->id => $context1->id], $contexts[$this->forumpostareaid]);
$this->assertArrayNotHasKey($this->mycoursesareaid, $contexts);
// For admins, this is still limited only if we specify the things, so it should be same.
$this->setAdminUser();
$contexts = $search->get_areas_user_accesses([$course1->id], [$context1->id]);
$contexts = $search->get_areas_user_accesses([$course1->id], [$context1->id])->usercontexts;
$this->assertEquals([$context1->id => $context1->id], $contexts[$this->forumpostareaid]);
$this->assertArrayNotHasKey($this->mycoursesareaid, $contexts);
}
@@ -722,28 +722,28 @@ class search_manager_testcase extends advanced_testcase {
// Admin gets 'true' result to function regardless of blocks.
$this->setAdminUser();
$this->assertTrue($search->get_areas_user_accesses());
$this->assertEquals((object)['everything' => true], $search->get_areas_user_accesses());
// Student 1 gets all 3 block contexts.
$this->setUser($student1);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertArrayHasKey('block_html-content', $contexts);
$this->assertCount(3, $contexts['block_html-content']);
// Student 2 does not get any blocks.
$this->setUser($student2);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertArrayNotHasKey('block_html-content', $contexts);
// Student 3 gets only two of them.
$this->setUser($student3);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertArrayHasKey('block_html-content', $contexts);
$this->assertCount(2, $contexts['block_html-content']);
// A course limited search for student 1 is the same as the student 3 search.
$this->setUser($student1);
$limitedcontexts = $search->get_areas_user_accesses([$course3->id]);
$limitedcontexts = $search->get_areas_user_accesses([$course3->id])->usercontexts;
$this->assertEquals($contexts['block_html-content'], $limitedcontexts['block_html-content']);
// Get block context ids for the blocks that appear.
@@ -758,12 +758,12 @@ class search_manager_testcase extends advanced_testcase {
// Context limited search (no course).
$contexts = $search->get_areas_user_accesses(false,
[$blockcontextids[0], $blockcontextids[2]]);
[$blockcontextids[0], $blockcontextids[2]])->usercontexts;
$this->assertCount(2, $contexts['block_html-content']);
// Context limited search (with course 3).
$contexts = $search->get_areas_user_accesses([$course2->id, $course3->id],
[$blockcontextids[0], $blockcontextids[2]]);
[$blockcontextids[0], $blockcontextids[2]])->usercontexts;
$this->assertCount(1, $contexts['block_html-content']);
}
@@ -817,16 +817,16 @@ class search_manager_testcase extends advanced_testcase {
// Admin user can access everything.
$this->setAdminUser();
$this->assertTrue($search->get_areas_user_accesses());
$this->assertEquals((object)['everything' => true], $search->get_areas_user_accesses());
// No-access user can access only the front page forum.
$this->setUser($noaccess);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals([$forumfrontctx->id], array_keys($contexts[$this->forumpostareaid]));
// Student can access the front page forum plus the enrolled one.
$this->setUser($student);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals([$forum1ctx->id, $forumfrontctx->id],
array_keys($contexts[$this->forumpostareaid]));
@@ -835,21 +835,119 @@ class search_manager_testcase extends advanced_testcase {
// Admin user can access everything.
$this->setAdminUser();
$this->assertTrue($search->get_areas_user_accesses());
$this->assertEquals((object)['everything' => true], $search->get_areas_user_accesses());
// No-access user can access the front page forum and course 2, 3.
$this->setUser($noaccess);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals([$forum2ctx->id, $forum3ctx->id, $forumfrontctx->id],
array_keys($contexts[$this->forumpostareaid]));
// Student can access the front page forum plus the enrolled one plus courses 2, 3.
$this->setUser($student);
$contexts = $search->get_areas_user_accesses();
$contexts = $search->get_areas_user_accesses()->usercontexts;
$this->assertEquals([$forum1ctx->id, $forum2ctx->id, $forum3ctx->id, $forumfrontctx->id],
array_keys($contexts[$this->forumpostareaid]));
}
/**
* Tests group-related aspects of the get_areas_user_accesses function.
*/
public function test_search_user_accesses_groups() {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
// Create 2 courses each with 2 groups and 2 forums (separate/visible groups).
$generator = $this->getDataGenerator();
$course1 = $generator->create_course();
$course2 = $generator->create_course();
$group1 = $generator->create_group(['courseid' => $course1->id]);
$group2 = $generator->create_group(['courseid' => $course1->id]);
$group3 = $generator->create_group(['courseid' => $course2->id]);
$group4 = $generator->create_group(['courseid' => $course2->id]);
$forum1s = $generator->create_module('forum', ['course' => $course1->id, 'groupmode' => SEPARATEGROUPS]);
$id1s = context_module::instance($forum1s->cmid)->id;
$forum1v = $generator->create_module('forum', ['course' => $course1->id, 'groupmode' => VISIBLEGROUPS]);
$id1v = context_module::instance($forum1v->cmid)->id;
$forum2s = $generator->create_module('forum', ['course' => $course2->id, 'groupmode' => SEPARATEGROUPS]);
$id2s = context_module::instance($forum2s->cmid)->id;
$forum2n = $generator->create_module('forum', ['course' => $course2->id, 'groupmode' => NOGROUPS]);
$id2n = context_module::instance($forum2n->cmid)->id;
// Get search instance.
$search = testable_core_search::instance();
$search->add_core_search_areas();
// User 1 is a manager in one course and a student in the other one. They belong to
// all of the groups 1, 2, 3, and 4.
$user1 = $generator->create_user();
$generator->enrol_user($user1->id, $course1->id, 'manager');
$generator->enrol_user($user1->id, $course2->id, 'student');
groups_add_member($group1, $user1);
groups_add_member($group2, $user1);
groups_add_member($group3, $user1);
groups_add_member($group4, $user1);
$this->setUser($user1);
$accessinfo = $search->get_areas_user_accesses();
$contexts = $accessinfo->usercontexts;
// Double-check all the forum contexts.
$postcontexts = $contexts['mod_forum-post'];
sort($postcontexts);
$this->assertEquals([$id1s, $id1v, $id2s, $id2n], $postcontexts);
// Only the context in the second course (no accessallgroups) is restricted.
$restrictedcontexts = $accessinfo->separategroupscontexts;
sort($restrictedcontexts);
$this->assertEquals([$id2s], $restrictedcontexts);
// Only the groups from the second course (no accessallgroups) are included.
$groupids = $accessinfo->usergroups;
sort($groupids);
$this->assertEquals([$group3->id, $group4->id], $groupids);
// User 2 is a student in each course and belongs to groups 2 and 4.
$user2 = $generator->create_user();
$generator->enrol_user($user2->id, $course1->id, 'student');
$generator->enrol_user($user2->id, $course2->id, 'student');
groups_add_member($group2, $user2);
groups_add_member($group4, $user2);
$this->setUser($user2);
$accessinfo = $search->get_areas_user_accesses();
$contexts = $accessinfo->usercontexts;
// Double-check all the forum contexts.
$postcontexts = $contexts['mod_forum-post'];
sort($postcontexts);
$this->assertEquals([$id1s, $id1v, $id2s, $id2n], $postcontexts);
// Both separate groups forums are restricted.
$restrictedcontexts = $accessinfo->separategroupscontexts;
sort($restrictedcontexts);
$this->assertEquals([$id1s, $id2s], $restrictedcontexts);
// Groups from both courses are included.
$groupids = $accessinfo->usergroups;
sort($groupids);
$this->assertEquals([$group2->id, $group4->id], $groupids);
// User 3 is a manager at system level.
$user3 = $generator->create_user();
role_assign($DB->get_field('role', 'id', ['shortname' => 'manager'], MUST_EXIST), $user3->id,
\context_system::instance());
$this->setUser($user3);
$accessinfo = $search->get_areas_user_accesses();
// Nothing is restricted and no groups are relevant.
$this->assertEquals([], $accessinfo->separategroupscontexts);
$this->assertEquals([], $accessinfo->usergroups);
}
/**
* test_is_search_area
*