From e7e62a4b2ed930fa20a094141269db86158abd0b Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Tue, 4 Feb 2020 08:19:02 +0000 Subject: [PATCH] MDL-62707 search: account for no matching courses when listing areas. When limiting the list of courses during retrieval of the search areas the user can access, make sure we have some contexts before looking for blocks. --- search/classes/manager.php | 4 ++-- search/tests/manager_test.php | 38 ++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/search/classes/manager.php b/search/classes/manager.php index b13f152034e..c0a1c5fa3f5 100644 --- a/search/classes/manager.php +++ b/search/classes/manager.php @@ -823,8 +823,8 @@ class manager { } } - // Add all supported block contexts, in a single query for performance. - if (!empty($areasbylevel[CONTEXT_BLOCK])) { + // Add all supported block contexts for course contexts that user can access, in a single query for performance. + if (!empty($areasbylevel[CONTEXT_BLOCK]) && !empty($coursecontextids)) { // Get list of all block types we care about. $blocklist = []; foreach ($areasbylevel[CONTEXT_BLOCK] as $areaid => $searchclass) { diff --git a/search/tests/manager_test.php b/search/tests/manager_test.php index 0a52f5fc48a..217dcb4ac23 100644 --- a/search/tests/manager_test.php +++ b/search/tests/manager_test.php @@ -791,7 +791,6 @@ class search_manager_testcase extends advanced_testcase { $this->assertEquals($contexts['block_html-content'], $limitedcontexts['block_html-content']); // Get block context ids for the blocks that appear. - global $DB; $blockcontextids = $DB->get_fieldset_sql(' SELECT x.id FROM {block_instances} bi @@ -811,6 +810,43 @@ class search_manager_testcase extends advanced_testcase { $this->assertCount(1, $contexts['block_html-content']); } + /** + * Tests retrieval of users search areas when limiting to a course the user is not enrolled in + */ + public function test_search_users_accesses_limit_non_enrolled_course() { + global $DB; + + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + + $search = testable_core_search::instance(); + $search->add_core_search_areas(); + + $course = $this->getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + + // Limit courses to search to only those the user is enrolled in. + set_config('searchallavailablecourses', 0); + + $usercontexts = $search->get_areas_user_accesses([$course->id])->usercontexts; + $this->assertNotEmpty($usercontexts); + $this->assertArrayNotHasKey('core_course-course', $usercontexts); + + // This config ensures the search will also include courses the user can view. + set_config('searchallavailablecourses', 1); + + // Allow "Authenticated user" role to view the course without being enrolled in it. + $userrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST); + role_change_permission($userrole->id, $context, 'moodle/course:view', CAP_ALLOW); + + $usercontexts = $search->get_areas_user_accesses([$course->id])->usercontexts; + $this->assertNotEmpty($usercontexts); + $this->assertArrayHasKey('core_course-course', $usercontexts); + $this->assertEquals($context->id, reset($usercontexts['core_course-course'])); + } + /** * Test get_areas_user_accesses with regard to the 'all available courses' config option. *