diff --git a/lib/tests/questionlib_test.php b/lib/tests/questionlib_test.php
index ee793d90435..4b8e6ed6bad 100644
--- a/lib/tests/questionlib_test.php
+++ b/lib/tests/questionlib_test.php
@@ -1304,4 +1304,150 @@ class core_questionlib_testcase extends advanced_testcase {
             }
         }
     }
+
+    /**
+     * question_sort_tags() includes the tags for all questions in the list.
+     */
+    public function test_question_sort_tags_includes_question_tags() {
+
+        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
+        $question1 = $questions[0];
+        $question2 = $questions[1];
+        $qcontext = context::instance_by_id($qcat->contextid);
+
+        core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo', 'bar']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['baz', 'bop']);
+
+        foreach ($questions as $question) {
+            $tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
+            $categorycontext = context::instance_by_id($qcat->contextid);
+            $tagobjects = question_sort_tags($tags, $categorycontext);
+            $expectedtags = [];
+            $actualtags = $tagobjects->tags;
+            foreach ($tagobjects->tagobjects as $tag) {
+                $expectedtags[$tag->id] = $tag->name;
+            }
+
+            // The question should have a tags property populated with each tag id
+            // and display name as a key vale pair.
+            $this->assertEquals($expectedtags, $actualtags);
+
+            $actualtagobjects = $tagobjects->tagobjects;
+            sort($tags);
+            sort($actualtagobjects);
+
+            // The question should have a full set of each tag object.
+            $this->assertEquals($tags, $actualtagobjects);
+            // The question should not have any course tags.
+            $this->assertEmpty($tagobjects->coursetagobjects);
+        }
+    }
+
+    /**
+     * question_sort_tags() includes course tags for all questions in the list.
+     */
+    public function test_question_sort_tags_includes_question_course_tags() {
+        global $DB;
+
+        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
+        $question1 = $questions[0];
+        $question2 = $questions[1];
+        $coursecontext = context_course::instance($course->id);
+
+        core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo', 'bar']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['baz', 'bop']);
+
+        foreach ($questions as $question) {
+            $tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
+            $tagobjects = question_sort_tags($tags, $qcat);
+
+            $expectedtags = [];
+            $actualtags = $tagobjects->coursetags;
+            foreach ($actualtags as $coursetagid => $coursetagname) {
+                $expectedtags[$coursetagid] = $coursetagname;
+            }
+
+            // The question should have a tags property populated with each tag id
+            // and display name as a key vale pair.
+            $this->assertEquals($expectedtags, $actualtags);
+
+            $actualtagobjects = $tagobjects->coursetagobjects;
+            sort($tags);
+            sort($actualtagobjects);
+
+            // The question should have a full set of each tag object.
+            $this->assertEquals($tags, $actualtagobjects);
+            // The question should not have any course tags.
+            $this->assertEmpty($tagobjects->tagobjects);
+        }
+    }
+
+    /**
+     * question_sort_tags() should return tags from all course contexts by default.
+     */
+    public function test_question_sort_tags_includes_multiple_courses_tags() {
+        global $DB;
+
+        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
+        $question1 = $questions[0];
+        $question2 = $questions[1];
+        $coursecontext = context_course::instance($course->id);
+        // Create a sibling course.
+        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
+        $siblingcoursecontext = context_course::instance($siblingcourse->id);
+
+        // Create course tags.
+        core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['c1']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['c1']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['c2']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['c2']);
+
+        foreach ($questions as $question) {
+            $tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
+            $tagobjects = question_sort_tags($tags, $qcat);
+            $this->assertCount(2, $tagobjects->coursetagobjects);
+
+            foreach ($tagobjects->coursetagobjects as $tag) {
+                if ($tag->name == 'c1') {
+                    $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
+                } else {
+                    $this->assertEquals($siblingcoursecontext->id, $tag->taginstancecontextid);
+                }
+            }
+        }
+    }
+
+    /**
+     * question_sort_tags() should filter the course tags by the given list of courses.
+     */
+    public function test_question_sort_tags_includes_filter_course_tags() {
+        global $DB;
+
+        list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
+        $question1 = $questions[0];
+        $question2 = $questions[1];
+        $coursecontext = context_course::instance($course->id);
+        // Create a sibling course.
+        $siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
+        $siblingcoursecontext = context_course::instance($siblingcourse->id);
+
+        // Create course tags.
+        core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['foo']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['bar']);
+        // Create sibling course tags. These should be filtered out.
+        core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['filtered1']);
+        core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['filtered2']);
+
+        foreach ($questions as $question) {
+            $tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
+            $tagobjects = question_sort_tags($tags, $qcat, [$course]);
+            foreach ($tagobjects->coursetagobjects as $tag) {
+
+                // We should only be seeing course tags from $course. The tags from
+                // $siblingcourse should have been filtered out.
+                $this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
+            }
+        }
+    }
+
 }