Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 core_question;
18
 
19
use question_bank;
20
use question_hint;
21
use question_test_recordset;
22
use question_usage_by_activity;
23
use testable_question_engine_unit_of_work;
24
 
25
defined('MOODLE_INTERNAL') || die();
26
 
27
global $CFG;
28
require_once(__DIR__ . '/../lib.php');
29
require_once(__DIR__ . '/helpers.php');
30
 
31
/**
32
 * Unit tests for the {@link question_engine_unit_of_work} class.
33
 *
34
 * @package    core_question
35
 * @category   test
36
 * @copyright  2012 The Open University
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
39
class unitofwork_test extends \data_loading_method_test_base {
40
    /** @var question_usage_by_activity the test question usage. */
41
    protected $quba;
42
 
43
    /** @var int the slot number of the one qa in the test usage.*/
44
    protected $slot;
45
 
46
    /** @var testable_question_engine_unit_of_work the unit of work we are testing. */
47
    protected $observer;
48
 
49
    protected function setUp(): void {
50
        // Create a usage in an initial state, with one shortanswer question added,
51
        // and attempted in interactive mode submitted responses 'toad' then 'frog'.
52
        // Then set it to use a new unit of work for any subsequent changes.
53
        // Create a short answer question.
54
        $question = \test_question_maker::make_question('shortanswer');
55
        $question->hints = array(
56
            new question_hint(0, 'This is the first hint.', FORMAT_HTML),
57
            new question_hint(0, 'This is the second hint.', FORMAT_HTML),
58
        );
59
        $question->id = -1;
60
        question_bank::start_unit_test();
61
        question_bank::load_test_question_data($question);
62
 
63
        $this->setup_initial_test_state($this->get_test_data());
64
     }
65
 
66
    public function tearDown(): void {
67
        question_bank::end_unit_test();
68
    }
69
 
70
    protected function setup_initial_test_state($testdata) {
71
        $records = new question_test_recordset($testdata);
72
 
73
        $this->quba = question_usage_by_activity::load_from_records($records, 1);
74
 
75
        $this->slot = 1;
76
        $this->observer = new testable_question_engine_unit_of_work($this->quba);
77
        $this->quba->set_observer($this->observer);
78
    }
79
 
80
    protected function get_test_data() {
81
        return array(
82
        array('qubaid', 'contextid', 'component', 'preferredbehaviour',
83
                                                'questionattemptid', 'contextid', 'questionusageid', 'slot',
84
                                                               'behaviour', 'questionid', 'variant', 'maxmark', 'minfraction', 'maxfraction', 'flagged',
85
                                                                                                              'questionsummary', 'rightanswer', 'responsesummary', 'timemodified',
86
                                                                                                                                     'attemptstepid', 'sequencenumber', 'state', 'fraction',
87
                                                                                                                                                                     'timecreated', 'userid', 'name', 'value'),
88
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 1, 0, 'todo',             null, 1256233700, 1, '-_triesleft', 3),
89
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 2, 1, 'todo',             null, 1256233720, 1, 'answer',     'toad'),
90
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 2, 1, 'todo',             null, 1256233720, 1, '-submit',     1),
91
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 2, 1, 'todo',             null, 1256233720, 1, '-_triesleft', 1),
92
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 3, 2, 'todo',             null, 1256233740, 1, '-tryagain',   1),
93
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 5, 3, 'gradedright', 0.6666667, 1256233790, 1, 'answer',     'frog'),
94
        array(1, 1, 'unit_test', 'interactive', 1, 123, 1, 1, 'interactive', -1, 1, 1.0000000, 0.0000000, 1.0000000, 0, '', '', '', 1256233790, 5, 3, 'gradedright', 0.6666667, 1256233790, 1, '-submit',     1),
95
        );
96
    }
97
 
11 efrain 98
    public function test_initial_state(): void {
1 efrain 99
        $this->assertFalse($this->observer->get_modified());
100
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
101
        $this->assertEquals(0, count($this->observer->get_attempts_modified()));
102
        $this->assertEquals(0, count($this->observer->get_steps_added()));
103
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
104
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
105
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
106
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
107
    }
108
 
11 efrain 109
    public function test_update_usage(): void {
1 efrain 110
 
111
        $this->quba->set_preferred_behaviour('deferredfeedback');
112
 
113
        $this->assertTrue($this->observer->get_modified());
114
    }
115
 
11 efrain 116
    public function test_add_question(): void {
1 efrain 117
 
118
        $slot = $this->quba->add_question(\test_question_maker::make_question('truefalse'));
119
 
120
        $newattempts = $this->observer->get_attempts_added();
121
        $this->assertEquals(1, count($newattempts));
122
        $this->assertTrue($this->quba->get_question_attempt($slot) === reset($newattempts));
123
        $this->assertSame($slot, key($newattempts));
124
 
125
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
126
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
127
    }
128
 
11 efrain 129
    public function test_add_and_start_question(): void {
1 efrain 130
 
131
        $slot = $this->quba->add_question(\test_question_maker::make_question('truefalse'));
132
                $this->quba->start_question($slot);
133
 
134
        // The point here is that, although we have added a step, it is not listed
135
        // separately becuase it is part of a newly added attempt, and all steps
136
        // for a newly added attempt are automatically added to the DB, so it does
137
        // not need to be tracked separately.
138
        $newattempts = $this->observer->get_attempts_added();
139
        $this->assertEquals(1, count($newattempts));
140
        $this->assertTrue($this->quba->get_question_attempt($slot) === reset($newattempts));
141
        $this->assertSame($slot, key($newattempts));
142
        $this->assertEquals(0, count($this->observer->get_steps_added()));
143
 
144
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
145
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
146
    }
147
 
11 efrain 148
    public function test_process_action(): void {
1 efrain 149
 
150
        $this->quba->manual_grade($this->slot, 'Actually, that is not quite right', 0.5, FORMAT_HTML);
151
 
152
        // Here, however, were we are adding a step to an existing qa, we do need to track that.
153
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
154
 
155
        $updatedattempts = $this->observer->get_attempts_modified();
156
        $this->assertEquals(1, count($updatedattempts));
157
 
158
        $updatedattempt = reset($updatedattempts);
159
        $this->assertTrue($this->quba->get_question_attempt($this->slot) === $updatedattempt);
160
        $this->assertSame($this->slot, key($updatedattempts));
161
 
162
        $newsteps = $this->observer->get_steps_added();
163
        $this->assertEquals(1, count($newsteps));
164
 
165
        list($newstep, $qaid, $seq) = reset($newsteps);
166
        $this->assertSame($this->quba->get_question_attempt($this->slot)->get_last_step(), $newstep);
167
 
168
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
169
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
170
    }
171
 
11 efrain 172
    public function test_regrade_same_steps(): void {
1 efrain 173
 
174
        // Change the question in a minor way and regrade.
175
        $this->quba->get_question($this->slot, false)->answers[14]->fraction = 0.5;
176
        $this->quba->regrade_all_questions();
177
 
178
        // Here, the qa, and all the steps, should be marked as updated.
179
        // Here, however, were we are adding a step to an existing qa, we do need to track that.
180
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
181
        $this->assertEquals(0, count($this->observer->get_steps_added()));
182
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
183
 
184
        $updatedattempts = $this->observer->get_attempts_modified();
185
        $this->assertEquals(1, count($updatedattempts));
186
 
187
        $updatedattempt = reset($updatedattempts);
188
        $this->assertTrue($this->quba->get_question_attempt($this->slot) === $updatedattempt);
189
 
190
        $updatedsteps = $this->observer->get_steps_modified();
191
        $this->assertEquals($updatedattempt->get_num_steps(), count($updatedsteps));
192
 
193
        foreach ($updatedattempt->get_step_iterator() as $seq => $step) {
194
            $this->assertSame(array($step, $updatedattempt->get_database_id(), $seq),
195
                    $updatedsteps[$seq]);
196
        }
197
 
198
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
199
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
200
    }
201
 
11 efrain 202
    public function test_regrade_losing_steps(): void {
1 efrain 203
 
204
        // Change the question so that 'toad' is also right, and regrade. This
205
        // will mean that the try again, and second try states are no longer
206
        // needed, so they should be dropped.
207
        $this->quba->get_question($this->slot, false)->answers[14]->fraction = 1;
208
        $this->quba->regrade_all_questions();
209
 
210
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
211
        $this->assertEquals(0, count($this->observer->get_steps_added()));
212
 
213
        $updatedattempts = $this->observer->get_attempts_modified();
214
        $this->assertEquals(1, count($updatedattempts));
215
 
216
        $updatedattempt = reset($updatedattempts);
217
        $this->assertTrue($this->quba->get_question_attempt($this->slot) === $updatedattempt);
218
 
219
        $updatedsteps = $this->observer->get_steps_modified();
220
        $this->assertEquals($updatedattempt->get_num_steps(), count($updatedsteps));
221
 
222
        foreach ($updatedattempt->get_step_iterator() as $seq => $step) {
223
            $this->assertSame(array($step, $updatedattempt->get_database_id(), $seq),
224
                    $updatedsteps[$seq]);
225
        }
226
 
227
        $deletedsteps = $this->observer->get_steps_deleted();
228
        $this->assertEquals(2, count($deletedsteps));
229
 
230
        $firstdeletedstep = reset($deletedsteps);
231
        $this->assertEquals(array('-tryagain' => 1), $firstdeletedstep->get_all_data());
232
 
233
        $seconddeletedstep = end($deletedsteps);
234
        $this->assertEquals(array('answer' => 'frog', '-submit' => 1),
235
                $seconddeletedstep->get_all_data());
236
 
237
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
238
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
239
    }
240
 
11 efrain 241
    public function test_tricky_regrade(): void {
1 efrain 242
 
243
        // The tricky thing here is that we take a half-complete question-attempt,
244
        // and then as one transaction, we submit some more responses, and then
245
        // change the question attempt as in test_regrade_losing_steps, and regrade
246
        // before the steps are even written to the database the first time.
247
        $somedata = $this->get_test_data();
248
        $somedata = array_slice($somedata, 0, 5);
249
        $this->setup_initial_test_state($somedata);
250
 
251
        $this->quba->process_action($this->slot, array('-tryagain' => 1));
252
        $this->quba->process_action($this->slot, array('answer' => 'frog', '-submit' => 1));
253
        $this->quba->finish_all_questions();
254
 
255
        $this->quba->get_question($this->slot, false)->answers[14]->fraction = 1;
256
        $this->quba->regrade_all_questions();
257
 
258
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
259
 
260
        $updatedattempts = $this->observer->get_attempts_modified();
261
        $this->assertEquals(1, count($updatedattempts));
262
 
263
        $updatedattempt = reset($updatedattempts);
264
        $this->assertTrue($this->quba->get_question_attempt($this->slot) === $updatedattempt);
265
 
266
        $this->assertEquals(0, count($this->observer->get_steps_added()));
267
 
268
        $updatedsteps = $this->observer->get_steps_modified();
269
        $this->assertEquals($updatedattempt->get_num_steps(), count($updatedsteps));
270
 
271
        foreach ($updatedattempt->get_step_iterator() as $seq => $step) {
272
            $this->assertSame(array($step, $updatedattempt->get_database_id(), $seq),
273
                    $updatedsteps[$seq]);
274
        }
275
 
276
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
277
 
278
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
279
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
280
    }
281
 
11 efrain 282
    public function test_move_question(): void {
1 efrain 283
 
284
        $q = \test_question_maker::make_question('truefalse');
285
        $newslot = $this->quba->add_question_in_place_of_other($this->slot, $q);
286
        $this->quba->start_question($this->slot);
287
 
288
        $addedattempts = $this->observer->get_attempts_added();
289
        $this->assertEquals(1, count($addedattempts));
290
        $addedattempt = reset($addedattempts);
291
        $this->assertSame($this->quba->get_question_attempt($this->slot), $addedattempt);
292
 
293
        $updatedattempts = $this->observer->get_attempts_modified();
294
        $this->assertEquals(1, count($updatedattempts));
295
        $updatedattempt = reset($updatedattempts);
296
        $this->assertSame($this->quba->get_question_attempt($newslot), $updatedattempt);
297
 
298
        $this->assertEquals(0, count($this->observer->get_steps_added()));
299
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
300
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
301
 
302
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
303
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
304
    }
305
 
11 efrain 306
    public function test_move_question_then_modify(): void {
1 efrain 307
 
308
        $q = \test_question_maker::make_question('truefalse');
309
        $newslot = $this->quba->add_question_in_place_of_other($this->slot, $q);
310
        $this->quba->start_question($this->slot);
311
        $this->quba->process_action($this->slot, array('answer' => 'frog', '-submit' => 1));
312
        $this->quba->manual_grade($newslot, 'Test', 0.5, FORMAT_HTML);
313
 
314
        $addedattempts = $this->observer->get_attempts_added();
315
        $this->assertEquals(1, count($addedattempts));
316
        $addedattempt = reset($addedattempts);
317
        $this->assertSame($this->quba->get_question_attempt($this->slot), $addedattempt);
318
 
319
        $updatedattempts = $this->observer->get_attempts_modified();
320
        $this->assertEquals(1, count($updatedattempts));
321
        $updatedattempt = reset($updatedattempts);
322
        $this->assertSame($this->quba->get_question_attempt($newslot), $updatedattempt);
323
 
324
        $newsteps = $this->observer->get_steps_added();
325
        $this->assertEquals(1, count($newsteps));
326
        list($newstep, $qaid, $seq) = reset($newsteps);
327
        $this->assertSame($this->quba->get_question_attempt($newslot)->get_last_step(), $newstep);
328
 
329
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
330
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
331
 
332
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
333
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
334
    }
335
 
11 efrain 336
    public function test_move_question_then_move_again(): void {
1 efrain 337
        $originalqa = $this->quba->get_question_attempt($this->slot);
338
 
339
        $q1 = \test_question_maker::make_question('truefalse');
340
        $newslot = $this->quba->add_question_in_place_of_other($this->slot, $q1);
341
        $this->quba->start_question($this->slot);
342
 
343
        $q2 = \test_question_maker::make_question('truefalse');
344
        $newslot2 = $this->quba->add_question_in_place_of_other($newslot, $q2);
345
        $this->quba->start_question($newslot);
346
 
347
        $addedattempts = $this->observer->get_attempts_added();
348
        $this->assertEquals(2, count($addedattempts));
349
 
350
        $updatedattempts = $this->observer->get_attempts_modified();
351
        $this->assertEquals(1, count($updatedattempts));
352
        $updatedattempt = reset($updatedattempts);
353
        $this->assertSame($originalqa, $updatedattempt);
354
 
355
        $this->assertEquals(0, count($this->observer->get_steps_added()));
356
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
357
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
358
 
359
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
360
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
361
    }
362
 
11 efrain 363
    public function test_set_max_mark(): void {
1 efrain 364
        $this->quba->set_max_mark($this->slot, 6.0);
365
        $this->assertEqualsWithDelta(4.0, $this->quba->get_total_mark(), 0.0000005);
366
 
367
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
368
 
369
        $updatedattempts = $this->observer->get_attempts_modified();
370
        $this->assertEquals(1, count($updatedattempts));
371
        $updatedattempt = reset($updatedattempts);
372
        $this->assertSame($this->quba->get_question_attempt($this->slot), $updatedattempt);
373
 
374
        $this->assertEquals(0, count($this->observer->get_steps_added()));
375
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
376
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
377
 
378
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
379
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
380
    }
381
 
11 efrain 382
    public function test_set_question_attempt_metadata(): void {
1 efrain 383
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'a value');
384
        $this->assertEquals('a value', $this->quba->get_question_attempt_metadata($this->slot, 'metathingy'));
385
 
386
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
387
        $this->assertEquals(0, count($this->observer->get_attempts_modified()));
388
 
389
        $this->assertEquals(0, count($this->observer->get_steps_added()));
390
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
391
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
392
 
393
        $this->assertEquals(array($this->slot => array('metathingy' => $this->quba->get_question_attempt($this->slot))),
394
                $this->observer->get_metadata_added());
395
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
396
    }
397
 
11 efrain 398
    public function test_set_question_attempt_metadata_then_change(): void {
1 efrain 399
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'a value');
400
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'different value');
401
        $this->assertEquals('different value', $this->quba->get_question_attempt_metadata($this->slot, 'metathingy'));
402
 
403
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
404
        $this->assertEquals(0, count($this->observer->get_attempts_modified()));
405
 
406
        $this->assertEquals(0, count($this->observer->get_steps_added()));
407
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
408
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
409
 
410
        $this->assertEquals(array($this->slot => array('metathingy' => $this->quba->get_question_attempt($this->slot))),
411
                $this->observer->get_metadata_added());
412
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
413
    }
414
 
11 efrain 415
    public function test_set_metadata_previously_set_but_dont_actually_change(): void {
1 efrain 416
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'a value');
417
        $this->observer = new testable_question_engine_unit_of_work($this->quba);
418
        $this->quba->set_observer($this->observer);
419
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'a value');
420
        $this->assertEquals('a value', $this->quba->get_question_attempt_metadata($this->slot, 'metathingy'));
421
 
422
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
423
        $this->assertEquals(0, count($this->observer->get_attempts_modified()));
424
 
425
        $this->assertEquals(0, count($this->observer->get_steps_added()));
426
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
427
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
428
 
429
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
430
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
431
    }
432
 
11 efrain 433
    public function test_set_metadata_previously_set(): void {
1 efrain 434
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'a value');
435
        $this->observer = new testable_question_engine_unit_of_work($this->quba);
436
        $this->quba->set_observer($this->observer);
437
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'different value');
438
        $this->assertEquals('different value', $this->quba->get_question_attempt_metadata($this->slot, 'metathingy'));
439
 
440
        $this->assertEquals(0, count($this->observer->get_attempts_added()));
441
        $this->assertEquals(0, count($this->observer->get_attempts_modified()));
442
 
443
        $this->assertEquals(0, count($this->observer->get_steps_added()));
444
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
445
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
446
 
447
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
448
        $this->assertEquals(array($this->slot => array('metathingy' => $this->quba->get_question_attempt($this->slot))),
449
                $this->observer->get_metadata_modified());
450
    }
451
 
11 efrain 452
    public function test_set_metadata_in_new_question(): void {
1 efrain 453
        $newslot = $this->quba->add_question(\test_question_maker::make_question('truefalse'));
454
        $this->quba->start_question($newslot);
455
        $this->quba->set_question_attempt_metadata($newslot, 'metathingy', 'a value');
456
        $this->assertEquals('a value', $this->quba->get_question_attempt_metadata($newslot, 'metathingy'));
457
 
458
        $this->assertEquals(array($newslot => $this->quba->get_question_attempt($newslot)),
459
                $this->observer->get_attempts_added());
460
        $this->assertEquals(0, count($this->observer->get_attempts_modified()));
461
 
462
        $this->assertEquals(0, count($this->observer->get_steps_added()));
463
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
464
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
465
 
466
        $this->assertEquals(0, count($this->observer->get_metadata_added()));
467
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
468
    }
469
 
11 efrain 470
    public function test_set_metadata_then_move(): void {
1 efrain 471
        $this->quba->set_question_attempt_metadata($this->slot, 'metathingy', 'a value');
472
        $q = \test_question_maker::make_question('truefalse');
473
        $newslot = $this->quba->add_question_in_place_of_other($this->slot, $q);
474
        $this->quba->start_question($this->slot);
475
        $this->assertEquals('a value', $this->quba->get_question_attempt_metadata($newslot, 'metathingy'));
476
 
477
        $this->assertEquals(array($this->slot => $this->quba->get_question_attempt($this->slot)),
478
                $this->observer->get_attempts_added());
479
        $this->assertEquals(array($newslot => $this->quba->get_question_attempt($newslot)),
480
                $this->observer->get_attempts_modified());
481
 
482
        $this->assertEquals(0, count($this->observer->get_steps_added()));
483
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
484
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
485
 
486
        $this->assertEquals(array($newslot => array('metathingy' => $this->quba->get_question_attempt($newslot))),
487
                $this->observer->get_metadata_added());
488
        $this->assertEquals(0, count($this->observer->get_metadata_modified()));
489
    }
490
 
11 efrain 491
    public function test_move_then_set_metadata(): void {
1 efrain 492
        $q = \test_question_maker::make_question('truefalse');
493
        $newslot = $this->quba->add_question_in_place_of_other($this->slot, $q);
494
        $this->quba->start_question($this->slot);
495
        $this->quba->set_question_attempt_metadata($newslot, 'metathingy', 'a value');
496
        $this->assertEquals('a value', $this->quba->get_question_attempt_metadata($newslot, 'metathingy'));
497
 
498
        $this->assertEquals(array($this->slot => $this->quba->get_question_attempt($this->slot)),
499
                $this->observer->get_attempts_added());
500
        $this->assertEquals(array($newslot => $this->quba->get_question_attempt($newslot)),
501
                $this->observer->get_attempts_modified());
502
 
503
        $this->assertEquals(0, count($this->observer->get_steps_added()));
504
        $this->assertEquals(0, count($this->observer->get_steps_modified()));
505
        $this->assertEquals(0, count($this->observer->get_steps_deleted()));
506
 
507
        $this->assertEquals(array($newslot => array('metathingy' => $this->quba->get_question_attempt($newslot))),
508
                $this->observer->get_metadata_added());
509
    }
510
 
511
    /**
512
     * Test add_question_in_place_of_other function.
513
     *
514
     * @covers ::add_question_in_place_of_other
515
     */
516
    public function test_replace_old_attempt(): void {
517
        // Create a new question.
518
        $q = \test_question_maker::make_question('truefalse');
519
        $currentquestion = $this->quba->get_question_attempt($this->slot)->get_question();
520
        // Replace the current question in the slot with a new one.
521
        $slot = $this->quba->add_question_in_place_of_other($this->slot, $q, null, false);
522
        $newquestion = $this->quba->get_question_attempt($slot)->get_question();
523
 
524
        $this->assertEquals($this->slot, $slot);
525
        $this->assertEquals($q->name, $newquestion->name);
526
        $this->assertCount(4, $this->observer->get_steps_deleted());
527
        $this->assertCount(1, $this->observer->get_attempts_modified());
528
        $this->assertCount(0, $this->observer->get_attempts_added());
529
        $this->assertNotEquals($currentquestion->id, $newquestion->id);
530
    }
531
}