Skip to content

Commit

Permalink
MDL-74427 question: Implement get_real_question_ids_in_category()
Browse files Browse the repository at this point in the history
  • Loading branch information
golenkovm committed Apr 27, 2022
1 parent 0127abe commit 10ad537
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 5 deletions.
2 changes: 1 addition & 1 deletion question/category.php
Expand Up @@ -97,7 +97,7 @@
}

question_remove_stale_questions_from_category($param->delete);
$questionstomove = $DB->count_records("question", array("category" => $param->delete));
$questionstomove = count($qcobject->get_real_question_ids_in_category($param->delete));

// Second pass, if we still have questions to move, setup the form.
if ($questionstomove) {
Expand Down
23 changes: 19 additions & 4 deletions question/category_class.php
Expand Up @@ -435,10 +435,8 @@ public function display_move_form($questionsincategory, $category){
}

public function move_questions($oldcat, $newcat){
global $DB;
$questionids = $DB->get_records_select_menu('question',
'category = ? AND (parent = 0 OR parent = id)', array($oldcat), '', 'id,1');
question_move_questions_to_category(array_keys($questionids), $newcat);
$questionids = $this->get_real_question_ids_in_category($oldcat);
question_move_questions_to_category($questionids, $newcat);
}

/**
Expand Down Expand Up @@ -606,4 +604,21 @@ public function update_category($updateid, $newparent, $newname, $newinfo, $newi
redirect($this->pageurl); // Always redirect after successful action.
}
}

/**
* Returns ids of the question in the given question category.
*
* This method only returns the real question. It does not include
* subquestions of question types like multianswer.
*
* @param int $categoryid id of the category.
* @return int[] array of question ids.
*/
public function get_real_question_ids_in_category(int $categoryid): array {
global $DB;
$select = 'category = :categoryid AND (parent = 0 OR parent = id)';
$params = ['categoryid' => $categoryid];
$questionids = $DB->get_records_select('question', $select, $params);
return array_keys($questionids);
}
}
17 changes: 17 additions & 0 deletions question/tests/behat/question_categories.feature
Expand Up @@ -86,3 +86,20 @@ Feature: A teacher can put questions in categories in the question bank
And the field "Select a category" matches value "      Subcategory (1)"
And the "Select a category" select box should contain "Used category"
And the "Select a category" select box should not contain "Used category (1)"

@_file_upload
Scenario: Multi answer questions with their child questions can be moved to another category when the current category is deleted
When I navigate to "Question bank > Import" in current page administration
And I set the field "id_format_xml" to "1"
And I upload "question/format/xml/tests/fixtures/multianswer.xml" file to "Import" filemanager
And I press "id_submitbutton"
And I press "Continue"
And I am on "Course 1" course homepage
And I navigate to "Question bank > Categories" in current page administration
And I click on "Delete" "link" in the "Default for Test images in backup" "list_item"
And I should see "The category 'Default for Test images in backup' contains 1 questions"
And I select "Used category" from the "Category" singleselect
And I press "Save in category"
Then I should not see "Default for Test images in backup"
And I follow "Add category"
And I should see "Used category (2)"
64 changes: 64 additions & 0 deletions question/tests/category_class_test.php
Expand Up @@ -175,4 +175,68 @@ public function test_update_category_try_to_set_duplicate_idnumber() {
$this->assertSame('New name', $newcat->name);
$this->assertNull($newcat->idnumber);
}

/**
* Test that get_real_question_ids_in_category() returns question id
* of a shortanswer question in a category.
*
* @covers ::get_real_question_ids_in_category
*/
public function test_get_real_question_ids_in_category_shortanswer() {
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
$categoryid = $this->topcat->id;

// Short answer question is made of one question.
$shortanswer = $generator->create_question('shortanswer', null, ['category' => $categoryid]);
$questionids = $this->qcobject->get_real_question_ids_in_category($categoryid);
$this->assertCount(1, $questionids);
$this->assertContains($shortanswer->id, $questionids);
}

/**
* Test that get_real_question_ids_in_category() returns question id
* of a multianswer question in a category.
*
* @covers ::get_real_question_ids_in_category
*/
public function test_get_real_question_ids_in_category_multianswer() {
global $DB;
$countq = $DB->count_records('question');

$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
$categoryid = $this->topcat->id;

// Multi answer question is made of one parent and two child questions.
$multianswer = $generator->create_question('multianswer', null, ['category' => $categoryid]);
$questionids = $this->qcobject->get_real_question_ids_in_category($categoryid);
$this->assertCount(1, $questionids);
$this->assertContains($multianswer->id, $questionids);
$this->assertEquals(3, $DB->count_records('question') - $countq);
}

/**
* Test that get_real_question_ids_in_category() returns question id
* of a multianswer question in a category even if their child questions are
* linked to a category that doesn't exist.
*
* @covers ::get_real_question_ids_in_category
*/
public function test_get_real_question_ids_in_category_multianswer_bad_data() {
global $DB;
$countq = $DB->count_records('question');

$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
$categoryid = $this->topcat->id;

// Multi answer question is made of one parent and two child questions.
$multianswer = $generator->create_question('multianswer', null, ['category' => $categoryid]);

// Update category id for child questions to a category that doesn't exist.
$DB->set_field_select('question', 'category', 123456, 'id <> :id', ['id' => $multianswer->id]);

$questionids = $this->qcobject->get_real_question_ids_in_category($categoryid);
$this->assertCount(1, $questionids);
$this->assertContains($multianswer->id, $questionids);
$this->assertEquals(3, $DB->count_records('question') - $countq);
}
}

0 comments on commit 10ad537

Please sign in to comment.