[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/question/engine/tests/ -> datalib_reporting_queries_test.php (source)

   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  /**
  18   * Unit tests for the parts of {@link question_engine_data_mapper} related to reporting.
  19   *
  20   * @package   core_question
  21   * @category  test
  22   * @copyright 2013 The Open University
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  require_once (__DIR__ . '/../lib.php');
  31  require_once (__DIR__ . '/helpers.php');
  32  
  33  
  34  /**
  35   * Unit tests for the parts of {@link question_engine_data_mapper} related to reporting.
  36   *
  37   * @copyright 2013 The Open University
  38   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class question_engine_data_mapper_reporting_testcase extends qbehaviour_walkthrough_test_base {
  41  
  42      /** @var question_engine_data_mapper */
  43      protected $dm;
  44  
  45      /** @var qtype_shortanswer_question */
  46      protected $sa;
  47  
  48      /** @var qtype_essay_question */
  49      protected $essay;
  50  
  51      /** @var array */
  52      protected $usageids = array();
  53  
  54      /** @var qubaid_condition */
  55      protected $bothusages;
  56  
  57      /** @var array */
  58      protected $allslots = array();
  59  
  60      /**
  61       * Test the various methods that load data for reporting.
  62       *
  63       * Since these methods need an expensive set-up, and then only do read-only
  64       * operations on the data, we use a single method to do the set-up, which
  65       * calls diffents methods to test each query.
  66       */
  67      public function test_reporting_queries() {
  68          // We create two usages, each with two questions, a short-answer marked
  69          // out of 5, and and essay marked out of 10.
  70          //
  71          // In the first usage, the student answers the short-answer
  72          // question correctly, and enters something in the essay.
  73          //
  74          // In the second useage, the student answers the short-answer question
  75          // wrongly, and leaves the essay blank.
  76          $this->resetAfterTest();
  77          $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
  78          $cat = $generator->create_question_category();
  79          $this->sa = $generator->create_question('shortanswer', null,
  80                  array('category' => $cat->id));
  81          $this->essay = $generator->create_question('essay', null,
  82                  array('category' => $cat->id));
  83  
  84          $this->usageids = array();
  85  
  86          // Create the first usage.
  87          $q = question_bank::load_question($this->sa->id);
  88          $this->start_attempt_at_question($q, 'interactive', 5);
  89          $this->allslots[] = $this->slot;
  90          $this->process_submission(array('answer' => 'cat'));
  91          $this->process_submission(array('answer' => 'frog', '-submit' => 1));
  92  
  93          $q = question_bank::load_question($this->essay->id);
  94          $this->start_attempt_at_question($q, 'interactive', 10);
  95          $this->allslots[] = $this->slot;
  96          $this->process_submission(array('answer' => '<p>The cat sat on the mat.</p>', 'answerformat' => FORMAT_HTML));
  97  
  98          $this->finish();
  99          $this->save_quba();
 100          $this->usageids[] = $this->quba->get_id();
 101  
 102          // Create the second usage.
 103          $this->quba = question_engine::make_questions_usage_by_activity('unit_test',
 104                  context_system::instance());
 105  
 106          $q = question_bank::load_question($this->sa->id);
 107          $this->start_attempt_at_question($q, 'interactive', 5);
 108          $this->process_submission(array('answer' => 'fish'));
 109  
 110          $q = question_bank::load_question($this->essay->id);
 111          $this->start_attempt_at_question($q, 'interactive', 10);
 112  
 113          $this->finish();
 114          $this->save_quba();
 115          $this->usageids[] = $this->quba->get_id();
 116  
 117          // Set up some things the tests will need.
 118          $this->dm = new question_engine_data_mapper();
 119          $this->bothusages = new qubaid_list($this->usageids);
 120  
 121          // Now test the various queries.
 122          $this->dotest_load_questions_usages_latest_steps();
 123          $this->dotest_load_questions_usages_question_state_summary();
 124          $this->dotest_load_questions_usages_where_question_in_state();
 125          $this->dotest_load_average_marks();
 126          $this->dotest_sum_usage_marks_subquery();
 127          $this->dotest_question_attempt_latest_state_view();
 128      }
 129  
 130      /**
 131       * This test is executed by {@link test_reporting_queries()}.
 132       */
 133      protected function dotest_load_questions_usages_latest_steps() {
 134          $rawstates = $this->dm->load_questions_usages_latest_steps($this->bothusages, $this->allslots,
 135                  'qa.id AS questionattemptid, qa.questionusageid, qa.slot, ' .
 136                  'qa.questionid, qa.maxmark, qas.sequencenumber, qas.state');
 137  
 138          $states = array();
 139          foreach ($rawstates as $state) {
 140              $states[$state->questionusageid][$state->slot] = $state;
 141              unset($state->questionattemptid);
 142              unset($state->questionusageid);
 143              unset($state->slot);
 144          }
 145  
 146          $state = $states[$this->usageids[0]][$this->allslots[0]];
 147          $this->assertEquals((object) array(
 148              'questionid'     => $this->sa->id,
 149              'maxmark'        => '5.0000000',
 150              'sequencenumber' => 2,
 151              'state'          => (string) question_state::$gradedright,
 152          ), $state);
 153  
 154          $state = $states[$this->usageids[0]][$this->allslots[1]];
 155          $this->assertEquals((object) array(
 156              'questionid'     => $this->essay->id,
 157              'maxmark'        => '10.0000000',
 158              'sequencenumber' => 2,
 159              'state'          => (string) question_state::$needsgrading,
 160          ), $state);
 161  
 162          $state = $states[$this->usageids[1]][$this->allslots[0]];
 163          $this->assertEquals((object) array(
 164              'questionid'     => $this->sa->id,
 165              'maxmark'        => '5.0000000',
 166              'sequencenumber' => 2,
 167              'state'          => (string) question_state::$gradedwrong,
 168          ), $state);
 169  
 170          $state = $states[$this->usageids[1]][$this->allslots[1]];
 171          $this->assertEquals((object) array(
 172              'questionid'     => $this->essay->id,
 173              'maxmark'        => '10.0000000',
 174              'sequencenumber' => 1,
 175              'state'          => (string) question_state::$gaveup,
 176          ), $state);
 177      }
 178  
 179      /**
 180       * This test is executed by {@link test_reporting_queries()}.
 181       */
 182      protected function dotest_load_questions_usages_question_state_summary() {
 183          $summary = $this->dm->load_questions_usages_question_state_summary(
 184                  $this->bothusages, $this->allslots);
 185  
 186          $this->assertEquals($summary[$this->allslots[0] . ',' . $this->sa->id],
 187                  (object) array(
 188                      'slot' => $this->allslots[0],
 189                      'questionid' => $this->sa->id,
 190                      'name' => $this->sa->name,
 191                      'inprogress' => 0,
 192                      'needsgrading' => 0,
 193                      'autograded' => 2,
 194                      'manuallygraded' => 0,
 195                      'all' => 2,
 196                  ));
 197          $this->assertEquals($summary[$this->allslots[1] . ',' . $this->essay->id],
 198                  (object) array(
 199                      'slot' => $this->allslots[1],
 200                      'questionid' => $this->essay->id,
 201                      'name' => $this->essay->name,
 202                      'inprogress' => 0,
 203                      'needsgrading' => 1,
 204                      'autograded' => 1,
 205                      'manuallygraded' => 0,
 206                      'all' => 2,
 207                  ));
 208      }
 209  
 210      /**
 211       * This test is executed by {@link test_reporting_queries()}.
 212       */
 213      protected function dotest_load_questions_usages_where_question_in_state() {
 214          $this->assertEquals(
 215                  array(array($this->usageids[0], $this->usageids[1]), 2),
 216                  $this->dm->load_questions_usages_where_question_in_state($this->bothusages,
 217                  'all', $this->allslots[1], null, 'questionusageid'));
 218  
 219          $this->assertEquals(
 220                  array(array($this->usageids[0], $this->usageids[1]), 2),
 221                  $this->dm->load_questions_usages_where_question_in_state($this->bothusages,
 222                  'autograded', $this->allslots[0], null, 'questionusageid'));
 223  
 224          $this->assertEquals(
 225                  array(array($this->usageids[0]), 1),
 226                  $this->dm->load_questions_usages_where_question_in_state($this->bothusages,
 227                  'needsgrading', $this->allslots[1], null, 'questionusageid'));
 228      }
 229  
 230      /**
 231       * This test is executed by {@link test_reporting_queries()}.
 232       */
 233      protected function dotest_load_average_marks() {
 234          $averages = $this->dm->load_average_marks($this->bothusages);
 235  
 236          $this->assertEquals(array(
 237              $this->allslots[0] => (object) array(
 238                  'slot'            => $this->allslots[0],
 239                  'averagefraction' => 0.5,
 240                  'numaveraged'     => 2,
 241              ),
 242              $this->allslots[1] => (object) array(
 243                  'slot'            => $this->allslots[1],
 244                  'averagefraction' => 0,
 245                  'numaveraged'     => 1,
 246              ),
 247          ), $averages);
 248      }
 249  
 250      /**
 251       * This test is executed by {@link test_reporting_queries()}.
 252       */
 253      protected function dotest_sum_usage_marks_subquery() {
 254          global $DB;
 255  
 256          $totals = $DB->get_records_sql_menu("SELECT qu.id, ({$this->dm->sum_usage_marks_subquery('qu.id')}) AS totalmark
 257                    FROM {question_usages} qu
 258                   WHERE qu.id IN ({$this->usageids[0]}, {$this->usageids[1]})");
 259  
 260          $this->assertNull($totals[$this->usageids[0]]); // Since a question requires grading.
 261  
 262          $this->assertNotNull($totals[$this->usageids[1]]); // Grrr! PHP null == 0 makes this hard.
 263          $this->assertEquals(0, $totals[$this->usageids[1]]);
 264      }
 265  
 266      /**
 267       * This test is executed by {@link test_reporting_queries()}.
 268       */
 269      protected function dotest_question_attempt_latest_state_view() {
 270          global $DB;
 271  
 272          list($inlineview, $viewparams) = $this->dm->question_attempt_latest_state_view(
 273                  'lateststate', $this->bothusages);
 274  
 275          $rawstates = $DB->get_records_sql("
 276                  SELECT lateststate.questionattemptid,
 277                         qu.id AS questionusageid,
 278                         lateststate.slot,
 279                         lateststate.questionid,
 280                         lateststate.maxmark,
 281                         lateststate.sequencenumber,
 282                         lateststate.state
 283                    FROM {question_usages} qu
 284               LEFT JOIN $inlineview ON lateststate.questionusageid = qu.id
 285                   WHERE qu.id IN ({$this->usageids[0]}, {$this->usageids[1]})", $viewparams);
 286  
 287          $states = array();
 288          foreach ($rawstates as $state) {
 289              $states[$state->questionusageid][$state->slot] = $state;
 290              unset($state->questionattemptid);
 291              unset($state->questionusageid);
 292              unset($state->slot);
 293          }
 294  
 295          $state = $states[$this->usageids[0]][$this->allslots[0]];
 296          $this->assertEquals((object) array(
 297              'questionid'     => $this->sa->id,
 298              'maxmark'        => '5.0000000',
 299              'sequencenumber' => 2,
 300              'state'          => (string) question_state::$gradedright,
 301          ), $state);
 302  
 303          $state = $states[$this->usageids[0]][$this->allslots[1]];
 304          $this->assertEquals((object) array(
 305              'questionid'     => $this->essay->id,
 306              'maxmark'        => '10.0000000',
 307              'sequencenumber' => 2,
 308              'state'          => (string) question_state::$needsgrading,
 309          ), $state);
 310  
 311          $state = $states[$this->usageids[1]][$this->allslots[0]];
 312          $this->assertEquals((object) array(
 313              'questionid'     => $this->sa->id,
 314              'maxmark'        => '5.0000000',
 315              'sequencenumber' => 2,
 316              'state'          => (string) question_state::$gradedwrong,
 317          ), $state);
 318  
 319          $state = $states[$this->usageids[1]][$this->allslots[1]];
 320          $this->assertEquals((object) array(
 321              'questionid'     => $this->essay->id,
 322              'maxmark'        => '10.0000000',
 323              'sequencenumber' => 1,
 324              'state'          => (string) question_state::$gaveup,
 325          ), $state);
 326      }
 327  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1