Proyectos de Subversion Moodle

Rev

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