Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 400 and 401] [Versions 401 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace qbank_bulkmove;
  18  
  19  use core_question\local\bank\question_edit_contexts;
  20  
  21  defined('MOODLE_INTERNAL') || die();
  22  
  23  global $CFG;
  24  require_once($CFG->dirroot . '/question/editlib.php');
  25  
  26  /**
  27   * Bulk move helper tests.
  28   *
  29   * @package    qbank_bulkmove
  30   * @copyright  2021 Catalyst IT Australia Pty Ltd
  31   * @author     Safat Shahin <safatshahin@catalyst-au.net>
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   * @coversDefaultClass \qbank_bulkmove\helper
  34   */
  35  class helper_test extends \advanced_testcase {
  36  
  37      /**
  38       * @var false|object|\stdClass|null $cat
  39       */
  40      protected $cat;
  41  
  42      /**
  43       * @var \stdClass $questiondata1
  44       */
  45      protected $questiondata1;
  46  
  47      /**
  48       * @var \stdClass $questiondata2
  49       */
  50      protected $questiondata2;
  51  
  52      /**
  53       * @var bool|\context|\context_course $context
  54       */
  55      protected $context;
  56  
  57      /**
  58       * @var \core_question\local\bank\question_edit_contexts $contexts
  59       */
  60      protected $contexts;
  61  
  62      /**
  63       * @var \stdClass $course
  64       */
  65      protected $course;
  66  
  67      /**
  68       * @var array $rawdata
  69       */
  70      protected $rawdata;
  71  
  72      /**
  73       * @var object $secondcategory
  74       */
  75      protected $secondcategory;
  76  
  77      /**
  78       * Setup the test.
  79       */
  80      protected function helper_setup(): void {
  81          $this->resetAfterTest();
  82          $this->setAdminUser();
  83          $generator = $this->getDataGenerator();
  84          /** @var \core_question_generator $questiongenerator */
  85          $questiongenerator = $generator->get_plugin_generator('core_question');
  86  
  87          // Create a course.
  88          $this->course = $generator->create_course();
  89          $this->context = \context_course::instance($this->course->id);
  90  
  91          // Create a question in the default category.
  92          $this->contexts = new question_edit_contexts($this->context);
  93          $this->cat = question_make_default_categories($this->contexts->all());
  94          $this->questiondata1 = $questiongenerator->create_question('numerical', null,
  95              ['name' => 'Example question', 'category' => $this->cat->id]);
  96  
  97          // Create a second category to move questions.
  98          $this->secondcategory = $questiongenerator->create_question_category(['contextid' => $this->context->id,
  99              'parent' => $this->cat->id]);
 100  
 101          // Ensure the question is not in the cache.
 102          $cache = \cache::make('core', 'questiondata');
 103          $cache->delete($this->questiondata1->id);
 104  
 105          $this->questiondata2 = $questiongenerator->create_question('numerical', null,
 106              ['name' => 'Example question second', 'category' => $this->cat->id]);
 107  
 108          // Ensure the question is not in the cache.
 109          $cache = \cache::make('core', 'questiondata');
 110          $cache->delete($this->questiondata2->id);
 111  
 112          // Posted raw data.
 113          $this->rawdata = [
 114              'courseid' => $this->course->id,
 115              'cat' => "{$this->cat->id},{$this->context->id}",
 116              'qpage' => '0',
 117              "q{$this->questiondata1->id}" => '1',
 118              "q{$this->questiondata2->id}" => '1',
 119              'move' => 'Move to'
 120          ];
 121      }
 122  
 123      /**
 124       * Test bulk move of questions.
 125       *
 126       * @covers ::bulk_move_questions
 127       */
 128      public function test_bulk_move_questions() {
 129          $this->helper_setup();
 130          // Verify that the questions are available in the current view.
 131          $view = new \core_question\local\bank\view($this->contexts, new \moodle_url('/'), $this->course);
 132          ob_start();
 133          $pagevars = [
 134              'qpage' => 0,
 135              'qperpage' => DEFAULT_QUESTIONS_PER_PAGE,
 136              'cat' => $this->cat->id . ',' . $this->context->id,
 137              'recurse' => false,
 138              'showhidden' => false,
 139              'qbshowtext' => false
 140          ];
 141          $view->display($pagevars, 'editq');
 142          $html = ob_get_clean();
 143          $this->assertStringContainsString('Example question', $html);
 144          $this->assertStringContainsString('Example question second', $html);
 145  
 146          // Get the processed question ids.
 147          $questionlist = $this->process_question_ids_test();
 148  
 149          helper::bulk_move_questions($questionlist, $this->secondcategory);
 150  
 151          // Verify the questions are not in the current category.
 152          $view = new \core_question\local\bank\view($this->contexts, new \moodle_url('/'), $this->course);
 153          ob_start();
 154          $pagevars = [
 155              'qpage' => 0,
 156              'qperpage' => DEFAULT_QUESTIONS_PER_PAGE,
 157              'cat' => $this->cat->id . ',' . $this->context->id,
 158              'recurse' => false,
 159              'showhidden' => false,
 160              'qbshowtext' => false
 161          ];
 162          $view->display($pagevars, 'editq');
 163          $html = ob_get_clean();
 164          $this->assertStringNotContainsString('Example question', $html);
 165          $this->assertStringNotContainsString('Example question second', $html);
 166  
 167          // Verify the questions are in the new category.
 168          $view = new \core_question\local\bank\view($this->contexts, new \moodle_url('/'), $this->course);
 169          ob_start();
 170          $pagevars = [
 171              'qpage' => 0,
 172              'qperpage' => DEFAULT_QUESTIONS_PER_PAGE,
 173              'cat' => $this->secondcategory->id . ',' . $this->context->id,
 174              'category' => $this->secondcategory->id . ',' . $this->context->id,
 175              'recurse' => false,
 176              'showhidden' => false,
 177              'qbshowtext' => false
 178          ];
 179          $view->display($pagevars, 'editq');
 180          $html = ob_get_clean();
 181          $this->assertStringContainsString('Example question', $html);
 182          $this->assertStringContainsString('Example question second', $html);
 183      }
 184  
 185      /**
 186       * Test the question processing and return the question list.
 187       *
 188       * @return mixed
 189       * @covers ::process_question_ids
 190       */
 191      protected function process_question_ids_test() {
 192          // Test the raw data processing.
 193          list($questionids, $questionlist) = helper::process_question_ids($this->rawdata);
 194          $this->assertEquals([$this->questiondata1->id, $this->questiondata2->id], $questionids);
 195          $this->assertEquals("{$this->questiondata1->id},{$this->questiondata2->id}", $questionlist);
 196          return $questionlist;
 197      }
 198  
 199      /**
 200       * Test the question displaydata.
 201       *
 202       * @covers ::get_displaydata
 203       */
 204      public function test_get_displaydata() {
 205          $this->helper_setup();
 206          $coursecontext = \context_course::instance($this->course->id);
 207          $contexts = new question_edit_contexts($coursecontext);
 208          $addcontexts = $contexts->having_cap('moodle/question:add');
 209          $url = new \moodle_url('/question/bank/bulkmove/move.php');
 210          $displaydata = \qbank_bulkmove\helper::get_displaydata($addcontexts, $url, $url);
 211          $this->assertStringContainsString('Test question category 1', $displaydata['categorydropdown']);
 212          $this->assertStringContainsString('Default for Category 1', $displaydata['categorydropdown']);
 213          $this->assertEquals($url, $displaydata ['moveurl']);
 214          $this->assertEquals($url, $displaydata ['returnurl']);
 215      }
 216  }