MDL-61363 question: unit tests for question tags context change

This commit is contained in:
Ryan Wyllie
2018-03-07 10:31:47 +08:00
parent dd69ecb630
commit 79c9ad6277
+531 -7
View File
@@ -76,7 +76,10 @@ class core_questionlib_testcase extends advanced_testcase {
$category = $this->getDataGenerator()->create_category();
// Create course.
$course = $this->getDataGenerator()->create_course(array('numsections' => 5));
$course = $this->getDataGenerator()->create_course(array(
'numsections' => 5,
'category' => $category->id
));
$options = array(
'course' => $course->id,
@@ -88,12 +91,22 @@ class core_questionlib_testcase extends advanced_testcase {
$qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
if ('course' == $type) {
$context = context_course::instance($course->id);
} else if ('category' == $type) {
$context = context_coursecat::instance($category->id);
} else {
$context = context_module::instance($quiz->cmid);
switch ($type) {
case 'course':
$context = context_course::instance($course->id);
break;
case 'category':
$context = context_coursecat::instance($category->id);
break;
case 'system':
$context = context_system::instance();
break;
default:
$context = context_module::instance($quiz->cmid);
break;
}
$qcat = $qgen->create_question_category(array('contextid' => $context->id));
@@ -780,4 +793,515 @@ class core_questionlib_testcase extends advanced_testcase {
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the
* question tags contexts when they are moving down (from system to course
* category context).
*/
public function test_question_move_question_tags_to_new_context_system_to_course_cat_qtags() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
$question1 = $questions[0];
$question2 = $questions[1];
$qcontext = context::instance_by_id($qcat->contextid);
$newcontext = context_coursecat::instance($category->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
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, ['foo', 'bar']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// All of the tags should have their context id set to the new context.
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the question tags
* contexts when they are moving down (from system to course category context)
* but leave any tags in the course context where they are.
*/
public function test_question_move_question_tags_to_new_context_system_to_course_cat_qtags_and_course_tags() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
$question1 = $questions[0];
$question2 = $questions[1];
$qcontext = context::instance_by_id($qcat->contextid);
$coursecontext = context_course::instance($course->id);
$newcontext = context_coursecat::instance($category->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
foreach ($tags as $tag) {
if ($tag->name == 'ctag') {
// Course tags should remain in the course context.
$this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
} else {
// Other tags should be updated.
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the question
* contexts tags when they are moving up (from course category to system context).
*/
public function test_question_move_question_tags_to_new_context_course_cat_to_system_qtags() {
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);
$newcontext = context_system::instance();
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the course category context.
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, ['foo', 'bar']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// All of the tags should have their context id set to the new context.
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the question
* tags contexts when they are moving up (from course category context to system
* context) but leave any tags in the course context where they are.
*/
public function test_question_move_question_tags_to_new_context_course_cat_to_system_qtags_and_course_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);
$coursecontext = context_course::instance($course->id);
$newcontext = context_system::instance();
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
foreach ($tags as $tag) {
if ($tag->name == 'ctag') {
// Course tags should remain in the course context.
$this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
} else {
// Other tags should be updated.
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
}
/**
* question_move_question_tags_to_new_context should merge all tags into the course
* context when moving down from course category context into course context.
*/
public function test_question_move_question_tags_to_new_context_course_cat_to_coures_qtags_and_course_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);
$coursecontext = context_course::instance($course->id);
$newcontext = $coursecontext;
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// Each question should have 2 tags.
$this->assertCount(2, $tags);
foreach ($tags as $tag) {
// All tags should be updated to the course context and merged in.
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* question_move_question_tags_to_new_context should delete all of the tag
* instances from sibling courses when moving the context of a question down
* from a course category into a course context because the other courses will
* no longer have access to the question.
*/
public function test_question_move_question_tags_to_new_context_remove_other_course_tags() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
// Create a sibling course.
$siblingcourse = $this->getDataGenerator()->create_course(['category' => $course->category]);
$question1 = $questions[0];
$question2 = $questions[1];
$qcontext = context::instance_by_id($qcat->contextid);
$coursecontext = context_course::instance($course->id);
$siblingcoursecontext = context_course::instance($siblingcourse->id);
$newcontext = $coursecontext;
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the target course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
// Create tags in the sibling course context. These should be deleted as
// part of the move.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $siblingcoursecontext, ['stag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $siblingcoursecontext, ['stag']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// Each question should have 2 tags, 'foo' and 'ctag'.
$this->assertCount(2, $tags);
foreach ($tags as $tag) {
$tagname = $tag->name;
// The 'stag' should have been deleted because it's in a sibling
// course context.
$this->assertContains($tagname, ['foo', 'ctag']);
// All tags should be in the course context now.
$this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the question
* tags to be the course category context when moving the tags from a course
* context to a course category context.
*/
public function test_question_move_question_tags_to_new_context_course_to_course_cat() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
$question1 = $questions[0];
$question2 = $questions[1];
$qcontext = context::instance_by_id($qcat->contextid);
// Moving up into the course category context.
$newcontext = context_coursecat::instance($category->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// All of the tags should have their context id set to the new context.
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the
* question tags contexts when they are moving down (from system to course
* category context).
*/
public function test_question_move_question_tags_to_new_context_orphaned_tag_contexts() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
$question1 = $questions[0];
$question2 = $questions[1];
$othercategory = $this->getDataGenerator()->create_category();
$qcontext = context::instance_by_id($qcat->contextid);
$newcontext = context_coursecat::instance($category->id);
$othercategorycontext = context_coursecat::instance($othercategory->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the other course category context. These should be
// update to the next context id because they represent erroneous data
// from a time before context id was mandatory in the tag API.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $othercategorycontext, ['bar']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $othercategorycontext, ['bar']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// Each question should have two tags, 'foo' and 'bar'.
$this->assertCount(2, $tags);
// All of the tags should have their context id set to the new context
// (course category context).
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* When moving from a course category context down into an activity context
* all question context tags and course tags (where the course is a parent of
* the activity) should move into the new context.
*/
public function test_question_move_question_tags_to_new_context_course_cat_to_activity_qtags_and_course_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);
$coursecontext = context_course::instance($course->id);
$newcontext = context_module::instance($quiz->cmid);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the course category context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Move the questions to the activity context which is a child context of
// $coursecontext.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// Each question should have 2 tags.
$this->assertCount(2, $tags);
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* When moving from a course category context down into an activity context
* all question context tags and course tags (where the course is a parent of
* the activity) should move into the new context. Tags in course contexts
* that are not a parent of the activity context should be deleted.
*/
public function test_question_move_question_tags_to_new_context_course_cat_to_activity_orphaned_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);
$coursecontext = context_course::instance($course->id);
$newcontext = context_module::instance($quiz->cmid);
$othercourse = $this->getDataGenerator()->create_course();
$othercoursecontext = context_course::instance($othercourse->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the course category context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['ctag']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['ctag']);
// Create tags in the other course context. These should be deleted.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $othercoursecontext, ['delete']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $othercoursecontext, ['delete']);
// Move the questions to the activity context which is a child context of
// $coursecontext.
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// Each question should have 2 tags.
$this->assertCount(2, $tags);
foreach ($tags as $tag) {
// Make sure we don't have any 'delete' tags.
$this->assertContains($tag->name, ['foo', 'ctag']);
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* When moving from a course context down into an activity context all of the
* course tags should move into the activity context.
*/
public function test_question_move_question_tags_to_new_context_course_to_activity_qtags() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('course');
$question1 = $questions[0];
$question2 = $questions[1];
$qcontext = context::instance_by_id($qcat->contextid);
$newcontext = context_module::instance($quiz->cmid);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the course context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* When moving from a course context down into an activity context all of the
* course tags should move into the activity context.
*/
public function test_question_move_question_tags_to_new_context_activity_to_course_qtags() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions();
$question1 = $questions[0];
$question2 = $questions[1];
$qcontext = context::instance_by_id($qcat->contextid);
$newcontext = context_course::instance($course->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the activity context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
foreach ($tags as $tag) {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
}
}
}
/**
* question_move_question_tags_to_new_context should update all of the
* question tags contexts when they are moving down (from system to course
* category context).
*
* Course tags within the new category context should remain while any course
* tags in course contexts that can no longer access the question should be
* deleted.
*/
public function test_question_move_question_tags_to_new_context_system_to_course_cat_with_orphaned_tags() {
list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('system');
$question1 = $questions[0];
$question2 = $questions[1];
$othercategory = $this->getDataGenerator()->create_category();
$othercourse = $this->getDataGenerator()->create_course(['category' => $othercategory->id]);
$qcontext = context::instance_by_id($qcat->contextid);
$newcontext = context_coursecat::instance($category->id);
$othercategorycontext = context_coursecat::instance($othercategory->id);
$coursecontext = context_course::instance($course->id);
$othercoursecontext = context_course::instance($othercourse->id);
foreach ($questions as $question) {
$question->contextid = $qcat->contextid;
}
// Create tags in the system context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $qcontext, ['foo']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $qcontext, ['foo']);
// Create tags in the child course context of the new context.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, ['bar']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, ['bar']);
// Create tags in the other course context. These should be deleted when
// the question moves to the new course category context because this
// course belongs to a different category, which means it will no longer
// have access to the question.
core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $othercoursecontext, ['delete']);
core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $othercoursecontext, ['delete']);
question_move_question_tags_to_new_context($questions, $newcontext);
foreach ($questions as $question) {
$tags = core_tag_tag::get_item_tags('core_question', 'question', $question->id);
// Each question should have two tags, 'foo' and 'bar'.
$this->assertCount(2, $tags);
// All of the tags should have their context id set to the new context
// (course category context).
foreach ($tags as $tag) {
$this->assertContains($tag->name, ['foo', 'bar']);
if ($tag->name == 'foo') {
$this->assertEquals($newcontext->id, $tag->taginstancecontextid);
} else {
$this->assertEquals($coursecontext->id, $tag->taginstancecontextid);
}
}
}
}
}