MDL-70153 qtype_essay: Add behat test for attachments max size
[moodle.git] / question / engine / tests / questionattempt_db_test.php
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/>.
17 /**
18  * This file contains tests for the question_attempt class.
19  *
20  * Action methods like start, process_action and finish are assumed to be
21  * tested by walkthrough tests in the various behaviours.
22  *
23  * @package    moodlecore
24  * @subpackage questionengine
25  * @copyright  2009 The Open University
26  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27  */
30 defined('MOODLE_INTERNAL') || die();
32 global $CFG;
33 require_once(__DIR__ . '/../lib.php');
34 require_once(__DIR__ . '/helpers.php');
37 /**
38  * Unit tests for loading data into the {@link question_attempt} class.
39  *
40  * @copyright  2009 The Open University
41  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42  */
43 class question_attempt_db_test extends data_loading_method_test_base {
44     public function test_load() {
45         $records = new question_test_recordset(array(
46             array('questionattemptid', 'contextid', 'questionusageid', 'slot',
47                                    'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged',
48                                                                                        'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
49                                                                                                                'attemptstepid', 'sequencenumber', 'state', 'fraction',
50                                                                                                                                                 'timecreated', 'userid', 'name', 'value'),
51             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo',              null, 1256233700, 1,       null, null),
52             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 2, 1, 'complete',          null, 1256233705, 1,   'answer',  '1'),
53             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 1, '', '', '', 1256233790, 3, 2, 'complete',          null, 1256233710, 1,   'answer',  '0'),
54             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 4, 3, 'complete',          null, 1256233715, 1,   'answer',  '1'),
55             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 5, 4, 'gradedright',  1.0000000, 1256233720, 1,  '-finish',  '1'),
56             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-comment', 'Not good enough!'),
57             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1,    '-mark',  '1'),
58             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 6, 5, 'mangrpartial', 0.5000000, 1256233790, 1, '-maxmark',  '2'),
59         ));
61         $question = test_question_maker::make_question('truefalse', 'true');
62         $question->id = -1;
64         question_bank::start_unit_test();
65         question_bank::load_test_question_data($question);
66         $qa = question_attempt::load_from_records($records, 1, new question_usage_null_observer(), 'deferredfeedback');
67         question_bank::end_unit_test();
69         $this->assertEquals($question->questiontext, $qa->get_question(false)->questiontext);
71         $this->assertEquals(6, $qa->get_num_steps());
73         $step = $qa->get_step(0);
74         $this->assertEquals(question_state::$todo, $step->get_state());
75         $this->assertNull($step->get_fraction());
76         $this->assertEquals(1256233700, $step->get_timecreated());
77         $this->assertEquals(1, $step->get_user_id());
78         $this->assertEquals(array(), $step->get_all_data());
80         $step = $qa->get_step(1);
81         $this->assertEquals(question_state::$complete, $step->get_state());
82         $this->assertNull($step->get_fraction());
83         $this->assertEquals(1256233705, $step->get_timecreated());
84         $this->assertEquals(1, $step->get_user_id());
85         $this->assertEquals(array('answer' => '1'), $step->get_all_data());
87         $step = $qa->get_step(2);
88         $this->assertEquals(question_state::$complete, $step->get_state());
89         $this->assertNull($step->get_fraction());
90         $this->assertEquals(1256233710, $step->get_timecreated());
91         $this->assertEquals(1, $step->get_user_id());
92         $this->assertEquals(array('answer' => '0'), $step->get_all_data());
94         $step = $qa->get_step(3);
95         $this->assertEquals(question_state::$complete, $step->get_state());
96         $this->assertNull($step->get_fraction());
97         $this->assertEquals(1256233715, $step->get_timecreated());
98         $this->assertEquals(1, $step->get_user_id());
99         $this->assertEquals(array('answer' => '1'), $step->get_all_data());
101         $step = $qa->get_step(4);
102         $this->assertEquals(question_state::$gradedright, $step->get_state());
103         $this->assertEquals(1, $step->get_fraction());
104         $this->assertEquals(1256233720, $step->get_timecreated());
105         $this->assertEquals(1, $step->get_user_id());
106         $this->assertEquals(array('-finish' => '1'), $step->get_all_data());
108         $step = $qa->get_step(5);
109         $this->assertEquals(question_state::$mangrpartial, $step->get_state());
110         $this->assertEquals(0.5, $step->get_fraction());
111         $this->assertEquals(1256233790, $step->get_timecreated());
112         $this->assertEquals(1, $step->get_user_id());
113         $this->assertEquals(array('-comment' => 'Not good enough!', '-mark' => '1', '-maxmark' => '2'),
114                 $step->get_all_data());
115     }
117     public function test_load_missing_question() {
118         $records = new question_test_recordset(array(
119             array('questionattemptid', 'contextid', 'questionusageid', 'slot',
120                                    'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged',
121                                                                                        'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
122                                                                                                                'attemptstepid', 'sequencenumber', 'state', 'fraction',
123                                                                                                                                                 'timecreated', 'userid', 'name', 'value'),
124             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo',              null, 1256233700, 1,       null, null),
125         ));
127         question_bank::start_unit_test();
128         $qa = question_attempt::load_from_records($records, 1, new question_usage_null_observer(), 'deferredfeedback');
129         question_bank::end_unit_test();
131         $missingq = question_bank::get_qtype('missingtype')->make_deleted_instance(-1, 2);
132         $this->assertEquals($missingq, $qa->get_question(false));
134         $this->assertEquals(1, $qa->get_num_steps());
136         $step = $qa->get_step(0);
137         $this->assertEquals(question_state::$todo, $step->get_state());
138         $this->assertNull($step->get_fraction());
139         $this->assertEquals(1256233700, $step->get_timecreated());
140         $this->assertEquals(1, $step->get_user_id());
141         $this->assertEquals(array(), $step->get_all_data());
142     }
144     public function test_load_with_autosaved_data() {
145         $records = new question_test_recordset(array(
146             array('questionattemptid', 'contextid', 'questionusageid', 'slot',
147                                    'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged',
148                                                                                        'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
149                                                                                                              'attemptstepid', 'sequencenumber', 'state', 'fraction',
150                                                                                                                                                 'timecreated', 'userid', 'name', 'value'),
151             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 4, -3, 'complete',          null, 1256233715, 1,   'answer',  '1'),
152             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 1,  0, 'todo',              null, 1256233700, 1,       null, null),
153             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 2,  1, 'complete',          null, 1256233705, 1,   'answer',  '1'),
154             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 1, '', '', '', 1256233790, 3,  2, 'complete',          null, 1256233710, 1,   'answer',  '0'),
155         ));
157         $question = test_question_maker::make_question('truefalse', 'true');
158         $question->id = -1;
160         question_bank::start_unit_test();
161         question_bank::load_test_question_data($question);
162         $qa = question_attempt::load_from_records($records, 1, new question_usage_null_observer(), 'deferredfeedback');
163         question_bank::end_unit_test();
165         $this->assertEquals($question->questiontext, $qa->get_question(false)->questiontext);
167         $this->assertEquals(4, $qa->get_num_steps());
168         $this->assertTrue($qa->has_autosaved_step());
170         $step = $qa->get_step(0);
171         $this->assertEquals(question_state::$todo, $step->get_state());
172         $this->assertNull($step->get_fraction());
173         $this->assertEquals(1256233700, $step->get_timecreated());
174         $this->assertEquals(1, $step->get_user_id());
175         $this->assertEquals(array(), $step->get_all_data());
177         $step = $qa->get_step(1);
178         $this->assertEquals(question_state::$complete, $step->get_state());
179         $this->assertNull($step->get_fraction());
180         $this->assertEquals(1256233705, $step->get_timecreated());
181         $this->assertEquals(1, $step->get_user_id());
182         $this->assertEquals(array('answer' => '1'), $step->get_all_data());
184         $step = $qa->get_step(2);
185         $this->assertEquals(question_state::$complete, $step->get_state());
186         $this->assertNull($step->get_fraction());
187         $this->assertEquals(1256233710, $step->get_timecreated());
188         $this->assertEquals(1, $step->get_user_id());
189         $this->assertEquals(array('answer' => '0'), $step->get_all_data());
191         $step = $qa->get_step(3);
192         $this->assertEquals(question_state::$complete, $step->get_state());
193         $this->assertNull($step->get_fraction());
194         $this->assertEquals(1256233715, $step->get_timecreated());
195         $this->assertEquals(1, $step->get_user_id());
196         $this->assertEquals(array('answer' => '1'), $step->get_all_data());
197     }
199     public function test_load_with_unnecessary_autosaved_data() {
200         // The point here is that the somehow (probably due to two things
201         // happening concurrently, we have autosaved data in the database that
202         // has already been superceded by real data, so it should be ignored.
203         // There is also a second lot of redundant data to delete.
204         $records = new question_test_recordset(array(
205             array('questionattemptid', 'contextid', 'questionusageid', 'slot',
206                                    'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged',
207                                                                                        'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
208                                                                                                              'attemptstepid', 'sequencenumber', 'state', 'fraction',
209                                                                                                                                                 'timecreated', 'userid', 'name', 'value'),
210             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 5, -2, 'complete',          null, 1256233715, 1,   'answer',  '0'),
211             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 4, -1, 'complete',          null, 1256233715, 1,   'answer',  '0'),
212             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 1,  0, 'todo',              null, 1256233700, 1,       null, null),
213             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 2,  1, 'complete',          null, 1256233705, 1,   'answer',  '1'),
214             array(1, 123, 1, 1, 'deferredfeedback', -1, 1, 2.0000000, 0.0000000, 1.0000000, 1, '', '', '', 1256233790, 3,  2, 'complete',          null, 1256233710, 1,   'answer',  '0'),
215         ));
217         $question = test_question_maker::make_question('truefalse', 'true');
218         $question->id = -1;
220         question_bank::start_unit_test();
221         question_bank::load_test_question_data($question);
222         $observer = new testable_question_engine_unit_of_work(
223                 question_engine::make_questions_usage_by_activity('unit_test', context_system::instance()));
224         $qa = question_attempt::load_from_records($records, 1, $observer, 'deferredfeedback');
225         question_bank::end_unit_test();
227         $this->assertEquals($question->questiontext, $qa->get_question(false)->questiontext);
229         $this->assertEquals(3, $qa->get_num_steps());
230         $this->assertFalse($qa->has_autosaved_step());
232         $step = $qa->get_step(0);
233         $this->assertEquals(question_state::$todo, $step->get_state());
234         $this->assertNull($step->get_fraction());
235         $this->assertEquals(1256233700, $step->get_timecreated());
236         $this->assertEquals(1, $step->get_user_id());
237         $this->assertEquals(array(), $step->get_all_data());
239         $step = $qa->get_step(1);
240         $this->assertEquals(question_state::$complete, $step->get_state());
241         $this->assertNull($step->get_fraction());
242         $this->assertEquals(1256233705, $step->get_timecreated());
243         $this->assertEquals(1, $step->get_user_id());
244         $this->assertEquals(array('answer' => '1'), $step->get_all_data());
246         $step = $qa->get_step(2);
247         $this->assertEquals(question_state::$complete, $step->get_state());
248         $this->assertNull($step->get_fraction());
249         $this->assertEquals(1256233710, $step->get_timecreated());
250         $this->assertEquals(1, $step->get_user_id());
251         $this->assertEquals(array('answer' => '0'), $step->get_all_data());
253         $this->assertEquals(2, count($observer->get_steps_deleted()));
254     }