MDL-62707 search: account for no matching courses when listing areas.
authorPaul Holden <paulh@moodle.com>
Tue, 4 Feb 2020 08:19:02 +0000 (08:19 +0000)
committerPaul Holden <paulh@moodle.com>
Fri, 4 Dec 2020 09:43:17 +0000 (09:43 +0000)
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
search/tests/manager_test.php

index b13f152..c0a1c5f 100644 (file)
@@ -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) {
index 0a52f5f..217dcb4 100644 (file)
@@ -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.
      *