Proyectos de Subversion Moodle

Rev

| 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
/**
18
 * Privacy test for the event monitor
19
 *
20
 * @package    mod_assignment
21
 * @category   test
22
 * @copyright  2018 Zig Tan <zig@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
namespace mod_assignment\privacy;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
require_once(__DIR__ . '/../../lib.php');
30
 
31
use mod_assignment\privacy\provider;
32
use core_privacy\local\request\approved_contextlist;
33
use core_privacy\local\request\transform;
34
use core_privacy\local\request\writer;
35
use core_privacy\tests\provider_testcase;
36
 
37
/**
38
 * Privacy test for the event monitor
39
 *
40
 * @package    mod_assignment
41
 * @category   test
42
 * @copyright  2018 Zig Tan <zig@moodle.com>
43
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44
 */
45
class provider_test extends provider_testcase {
46
 
47
    /**
48
     * @var int array   Array of test student ids associated for Course 1.
49
     */
50
    private $course1students = [];
51
 
52
    /**
53
     * @var int array   Array of test student ids associated for Course 2.
54
     */
55
    private $course2students = [];
56
 
57
    /**
58
     * @var int array   Array of test assignments associated for Course 1.
59
     */
60
    private $course1assignments = [];
61
 
62
    /**
63
     * @var int array   Array of test assignments associated for Course 2.
64
     */
65
    private $course2assignments = [];
66
 
67
    /**
68
     * Test for provider::get_contexts_for_userid().
69
     *
70
     * @throws coding_exception
71
     */
72
    public function test_get_contexts_for_userid() {
73
        global $DB;
74
 
75
        $this->resetAfterTest(true);
76
        $this->create_courses_and_assignments();
77
 
78
        // Get Teacher 1 to test get_contexts_for_userid().
79
        $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
80
        $contextids = provider::get_contexts_for_userid($teacher1->id);
81
        // Verify there should be 4 contexts, as Teacher 1 has submitted tests and marked Assignments in Course 1 and 2.
82
        $this->assertEquals(4, count($contextids->get_contextids()));
83
 
84
        // Get Teacher 2 to test get_contexts_for_userid().
85
        $teacher2 = $DB->get_record('user', ['username' => 'teacher2']);
86
        $contextids = provider::get_contexts_for_userid($teacher2->id);
87
        // Verify there should be 0 contexts, as teacher 2 has not marked any Assignments.
88
        $this->assertEquals(0, count($contextids->get_contextids()));
89
 
90
        // Get Student 1 to test get_contexts_for_userid().
91
        $student1 = $DB->get_record('user', ['username' => 'student1']);
92
        $contextids = provider::get_contexts_for_userid($student1->id);
93
        // Verify there should be 2 contexts, as student 1 added submissions for both Assignments in Course 1.
94
        $this->assertEquals(2, count($contextids->get_contextids()));
95
 
96
        // Get Student 2 to test get_contexts_for_userid().
97
        $student2 = $DB->get_record('user', ['username' => 'student2']);
98
        $contextids = provider::get_contexts_for_userid($student2->id);
99
        // Verify there should be 2 context, as student 2 added submissions for both Assignments in Course 2.
100
        $this->assertEquals(2, count($contextids->get_contextids()));
101
    }
102
 
103
    /**
104
     * Test that the correct userids are returned for a specific context.
105
     */
106
    public function test_get_users_in_context() {
107
 
108
        $this->resetAfterTest(true);
109
 
110
        $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
111
        $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
112
        // Student 3 should not turn up in the results of this test.
113
        $student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
114
        $teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']);
115
 
116
        $course = $this->getDataGenerator()->create_course();
117
        $course1assignment1 = $this->getDataGenerator()->create_module('assignment',
118
            [
119
                'course' => $course->id,
120
                'name' => 'Course 1 - Assignment 1 (onlinetext)',
121
                'assignmenttype' => 'onlinetext',
122
            ]
123
        );
124
        // Create a second assignment in the same course.
125
        $course1assignment2 = $this->getDataGenerator()->create_module('assignment',
126
            [
127
                'course' => $course->id,
128
                'name' => 'Course 1 - Assignment 1 (onlinetext)',
129
                'assignmenttype' => 'onlinetext',
130
            ]
131
        );
132
 
133
        $this->add_assignment_submission(
134
            $course1assignment1,
135
            $student1,
136
            "Course 1 - Ass 1: Student1 Test Submission"
137
        );
138
 
139
        $this->add_assignment_submission(
140
            $course1assignment1,
141
            $student2,
142
            "Course 1 - Ass 1: Student2 Test Submission"
143
        );
144
        // Add a submission for the second assignment.
145
        $this->add_assignment_submission(
146
            $course1assignment2,
147
            $student3,
148
            "Course 1 - Ass 2: Student3 Test Submission"
149
        );
150
 
151
        $submissions = $this->get_course_assignment_submissions($course->id);
152
        foreach ($submissions as $submission) {
153
            $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50);
154
        }
155
 
156
        $c1ass1ctx = \context_module::instance($course1assignment1->cmid);
157
        $userlist = new \core_privacy\local\request\userlist($c1ass1ctx, 'mod_assignment');
158
 
159
        provider::get_users_in_context($userlist);
160
        $userids = $userlist->get_userids();
161
 
162
        // This is both students and the teacher who marked both assignments.
163
        $this->assertCount(3, $userids);
164
        // Make sure that student 3 is not in the returned userids.
165
        $this->assertFalse(in_array($student3->id, $userids));
166
        // Try with the course context.
167
        $coursecontext = \context_course::instance($course->id);
168
        $userlist = new \core_privacy\local\request\userlist($coursecontext, 'mod_assignment');
169
        provider::get_users_in_context($userlist);
170
        $this->assertEmpty($userlist->get_userids());
171
    }
172
 
173
    /**
174
     * Test for provider::export_user_data().
175
     *
176
     * @throws coding_exception
177
     */
178
    public function test_export_user_data_teacher() {
179
        global $DB;
180
 
181
        $this->resetAfterTest(true);
182
        $this->create_courses_and_assignments();
183
 
184
        // Test Teacher 1 export_data_for_user() - marking assignment submissions for both Course 1 and 2.
185
        $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
186
 
187
        $contextlist = provider::get_contexts_for_userid($teacher1->id);
188
        $approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids());
189
 
190
        // Verify Teacher 1 has four contexts.
191
        $this->assertCount(4, $contextlist->get_contextids());
192
 
193
        // Retrieve Assignment Submissions data for Teacher 1.
194
        provider::export_user_data($approvedcontextlist);
195
 
196
        $contexts = $contextlist->get_contexts();
197
 
198
        // Context 1 - Course 1's Assignment 1 -- (onlinetext).
199
        $context = \context_module::instance($this->course1assignments['ass1']->cmid);
200
        $this->assertContains($context, $contexts);
201
 
202
        $writer = writer::with_context($context);
203
        $subcontexts = [
204
            get_string('privacy:markedsubmissionspath', 'mod_assignment'),
205
            transform::user($teacher1->id)
206
        ];
207
        // Verify the test assignment submission from Teacher 1 exists.
208
        $submission = $writer->get_data($subcontexts);
209
        $this->assertEquals('<p>Course 1 - Ass 1: Teacher Test Submission</p>', $submission->data1);
210
 
211
        foreach ($this->course1students as $student) {
212
            $subcontexts = [
213
                get_string('privacy:markedsubmissionspath', 'mod_assignment'),
214
                transform::user($student->id)
215
            ];
216
            // Verify the student assignment submissions exists.
217
            $submission = $writer->get_data($subcontexts);
218
            $this->assertEquals("<p>Course 1 - Ass 1: " . $student->id . "</p>", $submission->data1);
219
        }
220
 
221
        // Context 2 - Course 1's Assignment 2 -- (single file upload).
222
        $context = \context_module::instance($this->course1assignments['ass2']->cmid);
223
        $this->assertContains($context, $contexts);
224
 
225
        $writer = writer::with_context($context);
226
        foreach ($this->course1students as $student) {
227
            $subcontexts = [
228
                get_string('privacy:markedsubmissionspath', 'mod_assignment'),
229
                transform::user($student->id)
230
            ];
231
            // Verify the student assignment submissions exists.
232
            $submission = $writer->get_data($subcontexts);
233
            $this->assertEquals("<p>Course 1 - Ass 2: " . $student->id . "</p>", $submission->data1);
234
 
235
            // Verify the student assignment submission file upload exists.
236
            $submissionfiles = $writer->get_files($subcontexts);
237
            $this->assertTrue(array_key_exists('Student' . $student->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles));
238
        }
239
 
240
        // Context 3 - Course 2's Assignment 1 -- (offline).
241
        $context = \context_module::instance($this->course2assignments['ass1']->cmid);
242
        $this->assertContains($context, $contexts);
243
 
244
        $writer = writer::with_context($context);
245
        foreach ($this->course2students as $student) {
246
            $subcontexts = [
247
                get_string('privacy:markedsubmissionspath', 'mod_assignment'),
248
                transform::user($student->id)
249
            ];
250
            // Verify the student assignment submissions exists.
251
            $submission = $writer->get_data($subcontexts);
252
            $this->assertEquals("<p>Course 2 - Ass 1: " . $student->id . "</p>", $submission->data1);
253
        }
254
 
255
        // Context 4 - Course 2's Assignment 2 -- (multiple file upload).
256
        $context = \context_module::instance($this->course2assignments['ass2']->cmid);
257
        $this->assertContains($context, $contexts);
258
 
259
        $writer = writer::with_context($context);
260
        foreach ($this->course2students as $student) {
261
            $subcontexts = [
262
                get_string('privacy:markedsubmissionspath', 'mod_assignment'),
263
                transform::user($student->id)
264
            ];
265
            // Verify the student assignment submissions exists.
266
            $submission = $writer->get_data($subcontexts);
267
            $this->assertEquals("<p>Course 2 - Ass 2: " . $student->id . "</p>", $submission->data1);
268
 
269
            // Verify the student assignment submission file upload exists.
270
            $submissionfiles = $writer->get_files($subcontexts);
271
            $this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles));
272
            $this->assertTrue(array_key_exists('Student' . $student->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles));
273
        }
274
    }
275
 
276
    /**
277
     * Test for provider::export_user_data().
278
     *
279
     * @throws dml_exception
280
     */
281
    public function test_export_user_data_student() {
282
        global $DB;
283
 
284
        $this->resetAfterTest(true);
285
        $this->create_courses_and_assignments();
286
 
287
        // Test Student 1 export_data_for_user() - added assignment submissions for both assignments in Course 1.
288
        $student1 = $DB->get_record('user', ['username' => 'student1']);
289
 
290
        $contextlist = provider::get_contexts_for_userid($student1->id);
291
        $approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids());
292
 
293
        // Retrieve Assignment Submissions data for Student 1.
294
        provider::export_user_data($approvedcontextlist);
295
        $contexts = $contextlist->get_contexts();
296
 
297
        // Context 1 - Course 1's Assignment 1 -- (onlinetext).
298
        $context = \context_module::instance($this->course1assignments['ass1']->cmid);
299
        $this->assertContains($context, $contexts);
300
 
301
        $writer = writer::with_context($context);
302
        $subcontexts = [
303
            get_string('privacy:submissionpath', 'mod_assignment')
304
        ];
305
 
306
        // Verify the student assignment submissions exists.
307
        $submission = $writer->get_data($subcontexts);
308
        $this->assertEquals("<p>Course 1 - Ass 1: " . $student1->id . "</p>", $submission->data1);
309
 
310
        // Context 2 - Course 1's Assignment 2 -- (single file upload).
311
        $context = \context_module::instance($this->course1assignments['ass2']->cmid);
312
        $this->assertContains($context, $contexts);
313
 
314
        $writer = writer::with_context($context);
315
        $subcontexts = [
316
            get_string('privacy:submissionpath', 'mod_assignment')
317
        ];
318
 
319
        // Verify the student assignment submission exists.
320
        $submission = $writer->get_data($subcontexts);
321
        $this->assertEquals("<p>Course 1 - Ass 2: " . $student1->id . "</p>", $submission->data1);
322
 
323
        // Verify the student assignment submission file upload exists.
324
        $submissionfiles = $writer->get_files($subcontexts);
325
        $this->assertTrue(array_key_exists('Student' . $student1->id . '-Course1-Ass2-(File 1 of 1)', $submissionfiles));
326
 
327
        // Test Student 2 export_data_for_user() - added assignment submissions for both assignments in Course 2.
328
        $student2 = $DB->get_record('user', ['username' => 'student2']);
329
 
330
        $contextlist = provider::get_contexts_for_userid($student2->id);
331
        $approvedcontextlist = new approved_contextlist($student2, 'mod_assignment', $contextlist->get_contextids());
332
 
333
        // Retrieve Assignment Submissions data for Student 2.
334
        provider::export_user_data($approvedcontextlist);
335
        $contexts = $contextlist->get_contexts();
336
 
337
        // Context 1 - Course 2's Assignment 1 -- (offline).
338
        $context = \context_module::instance($this->course2assignments['ass1']->cmid);
339
        $this->assertContains($context, $contexts);
340
 
341
        $writer = writer::with_context($context);
342
        $subcontexts = [
343
            get_string('privacy:submissionpath', 'mod_assignment')
344
        ];
345
 
346
        // Verify the student assignment submissions exists.
347
        $submission = $writer->get_data($subcontexts);
348
        $this->assertEquals("<p>Course 2 - Ass 1: " . $student2->id . "</p>", $submission->data1);
349
 
350
        // Context 2 - Course 2's Assignment 2 -- (multiple file upload).
351
        $context = \context_module::instance($this->course2assignments['ass2']->cmid);
352
        $this->assertContains($context, $contexts);
353
 
354
        $writer = writer::with_context($context);
355
        $subcontexts = [
356
            get_string('privacy:submissionpath', 'mod_assignment')
357
        ];
358
 
359
        // Verify the student assignment submission exists.
360
        $submission = $writer->get_data($subcontexts);
361
        $this->assertEquals("<p>Course 2 - Ass 2: " . $student2->id . "</p>", $submission->data1);
362
 
363
        // Verify the student assignment submission file upload exists.
364
        $submissionfiles = $writer->get_files($subcontexts);
365
        $this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 1 of 2)', $submissionfiles));
366
        $this->assertTrue(array_key_exists('Student' . $student2->id . '-Course2-Ass2-(File 2 of 2)', $submissionfiles));
367
    }
368
 
369
    /**
370
     * Test for provider::delete_data_for_all_users_in_context().
371
     *
372
     * @throws dml_exception
373
     */
374
    public function test_delete_data_for_all_users_in_context() {
375
        global $DB;
376
 
377
        $this->resetAfterTest(true);
378
        $this->create_courses_and_assignments();
379
 
380
        // Test teacher1 delete_data_for_all_users_in_context().
381
        $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
382
        $contextlist = provider::get_contexts_for_userid($teacher1->id);
383
 
384
        foreach ($contextlist as $context) {
385
            provider::delete_data_for_all_users_in_context($context);
386
 
387
            // Verify assignment submission(s) were deleted for the context.
388
            $deleted = $this->get_assignment_submissions($context->id);
389
            $this->assertCount(0, $deleted);
390
 
391
            // Verify all the file submissions associated with the context for all users were deleted.
392
            $files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $context->id]);
393
            $this->assertEquals(0, count($files));
394
        }
395
    }
396
 
397
    /**
398
     * Test for provider::delete_data_for_user().
399
     *
400
     * @throws dml_exception
401
     */
402
    public function test_delete_data_for_user() {
403
        global $DB;
404
 
405
        $this->resetAfterTest(true);
406
        $this->create_courses_and_assignments();
407
 
408
        // Test Teacher 1 delete_data_for_user(), should only remove the 1 test submission added by Teacher 1.
409
        // Should not remove any assignment submission records marked by the teacher.
410
        $teacher1 = $DB->get_record('user', ['username' => 'teacher1']);
411
        $contextlist = provider::get_contexts_for_userid($teacher1->id);
412
        $approvedcontextlist = new approved_contextlist($teacher1, 'mod_assignment', $contextlist->get_contextids());
413
        provider::delete_data_for_user($approvedcontextlist);
414
 
415
        // Verify the submissions submitted by students still exists.
416
        $markedsubmissions = $DB->get_records('assignment_submissions', ['teacher' => $teacher1->id]);
417
        $this->assertCount(4, $markedsubmissions);
418
 
419
        // Test student 1 delete_data_for_user().
420
        $student1 = $DB->get_record('user', ['username' => 'student1']);
421
        $contextlist = provider::get_contexts_for_userid($student1->id);
422
        $approvedcontextlist = new approved_contextlist($student1, 'mod_assignment', $contextlist->get_contextids());
423
        provider::delete_data_for_user($approvedcontextlist);
424
 
425
        // Verify student 1's assignment submissions were deleted.
426
        $assignmentsubmissions = $DB->get_records('assignment_submissions', ['userid' => $student1->id]);
427
        $this->assertEquals(0, count($assignmentsubmissions));
428
 
429
        // Verify student 1's file submissions were deleted.
430
        foreach ($contextlist->get_contextids() as $contextid) {
431
            $files = $DB->get_records('files', ['component' => 'mod_assignment', 'filearea' => 'submission', 'contextid' => $contextid]);
432
            $this->assertEquals(0, count($files));
433
        }
434
    }
435
 
436
    /**
437
     * Test the deletion of a data for users.
438
     */
439
    public function test_delete_data_for_users() {
440
        global $DB;
441
        $this->resetAfterTest();
442
 
443
        $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
444
        $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
445
        $student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
446
 
447
        $course = $this->getDataGenerator()->create_course();
448
        $course1assignment = $this->getDataGenerator()->create_module('assignment',
449
            [
450
                'course' => $course->id,
451
                'name' => 'Course 1 - Assignment 1 (single file upload)',
452
                'assignmenttype' => 'uploadsingle'
453
            ]
454
        );
455
        $context = \context_module::instance($course1assignment->cmid);
456
 
457
        // Student one submission.
458
        $this->add_file_assignment_submission(
459
            $course1assignment,
460
            $student1,
461
            "Course 1 - Ass 2: " . $student1->id,
462
            'Student' . $student1->id . '-Course1-Ass2'
463
        );
464
        // Student two submission.
465
        $this->add_file_assignment_submission(
466
            $course1assignment,
467
            $student2,
468
            "Course 1 - Ass 2: " . $student2->id,
469
            'Student' . $student2->id . '-Course1-Ass2'
470
        );
471
        // Student three submission to be retained.
472
        $this->add_file_assignment_submission(
473
            $course1assignment,
474
            $student3,
475
            "Course 1 - Ass 2: " . $student3->id,
476
            'Student' . $student3->id . '-Course1-Ass2'
477
        );
478
 
479
        $files = $DB->get_records('files', [
480
            'component' => 'mod_assignment',
481
            'filearea' => 'submission',
482
            'contextid' => $context->id
483
        ]);
484
        $this->assertCount(6, $files);
485
 
486
        $submissions = $this->get_assignment_submissions($context->id);
487
        $this->assertCount(3, $submissions);
488
 
489
        $userlist = new \core_privacy\local\request\approved_userlist($context, 'mod_assignment', [$student1->id, $student2->id]);
490
        provider::delete_data_for_users($userlist);
491
 
492
        $files = $DB->get_records('files', [
493
            'component' => 'mod_assignment',
494
            'filearea' => 'submission',
495
            'contextid' => $context->id
496
        ]);
497
        $this->assertCount(2, $files);
498
 
499
        $submissions = $this->get_assignment_submissions($context->id);
500
        $this->assertCount(1, $submissions);
501
    }
502
 
503
    // Start of helper functions.
504
 
505
    /**
506
     * Helper function to setup Course, users, and assignments for testing.
507
     */
508
    protected function create_courses_and_assignments() {
509
        // Create Courses, Users, and Assignments.
510
        $course1 = $this->getDataGenerator()->create_course(['shortname' => 'course1']);
511
        $course2 = $this->getDataGenerator()->create_course(['shortname' => 'course2']);
512
 
513
        $teacher1 = $this->getDataGenerator()->create_user(['username' => 'teacher1']);
514
        $teacher2 = $this->getDataGenerator()->create_user(['username' => 'teacher2']);
515
 
516
        $student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
517
        $student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
518
 
519
        $this->course1students = [
520
            $student1
521
        ];
522
 
523
        $this->course2students = [
524
            $student2
525
        ];
526
 
527
        $course1assignment1 = $this->getDataGenerator()->create_module('assignment',
528
            [
529
                'course' => $course1->id,
530
                'name' => 'Course 1 - Assignment 1 (onlinetext)',
531
                'assignmenttype' => 'onlinetext',
532
            ]
533
        );
534
        $course1assignment2 = $this->getDataGenerator()->create_module('assignment',
535
            [
536
                'course' => $course1->id,
537
                'name' => 'Course 1 - Assignment 2 (single file upload)',
538
                'assignmenttype' => 'uploadsingle',
539
            ]
540
        );
541
 
542
        $this->course1assignments = [
543
            'ass1' => $course1assignment1,
544
            'ass2' => $course1assignment2
545
        ];
546
 
547
        $course2assignment1 = $this->getDataGenerator()->create_module('assignment',
548
            [
549
                'course' => $course2->id,
550
                'name' => 'Course 2 - Assignment 1 (offline)',
551
                'assignmenttype' => 'offline',
552
            ]
553
        );
554
        $course2assignment2 = $this->getDataGenerator()->create_module('assignment',
555
            [
556
                'course' => $course2->id,
557
                'name' => 'Course 2 - Assignment 2 (multiple file upload)',
558
                'assignmenttype' => 'upload',
559
            ]
560
        );
561
 
562
        $this->course2assignments = [
563
            'ass1' => $course2assignment1,
564
            'ass2' => $course2assignment2
565
        ];
566
 
567
        // Teacher 1 add test assignment submission for Course 1 - Assignment 1.
568
        $this->add_assignment_submission(
569
            $course1assignment1,
570
            $teacher1,
571
            "Course 1 - Ass 1: Teacher Test Submission"
572
        );
573
 
574
        // Student 1 add assignment submissions for Course 1 - Assignment 1 and 2.
575
        $this->add_assignment_submission(
576
            $course1assignment1,
577
            $student1,
578
            "Course 1 - Ass 1: " . $student1->id
579
        );
580
        $this->add_file_assignment_submission(
581
            $course1assignment2,
582
            $student1,
583
            "Course 1 - Ass 2: " . $student1->id,
584
            'Student' . $student1->id . '-Course1-Ass2'
585
        );
586
 
587
        // Student 2 add assignment submissions for Course 2 - Assignment 1 and 2.
588
        $this->add_assignment_submission(
589
            $course2assignment1,
590
            $student2,
591
            "Course 2 - Ass 1: " . $student2->id
592
        );
593
        $this->add_file_assignment_submission(
594
            $course2assignment2,
595
            $student2,
596
            "Course 2 - Ass 2: " . $student2->id,
597
            'Student' . $student2->id . '-Course2-Ass2',
598
            2
599
        );
600
 
601
        // Teacher 1 to mark assignment submissions for Course 1's Assignment 1 and 2.
602
        $course1submissions = $this->get_course_assignment_submissions($course1->id);
603
        foreach ($course1submissions as $submission) {
604
            $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 49);
605
        }
606
 
607
        // Teacher 1 to mark assignment submissions for Course 2's Assignment 1 and 2.
608
        $course2submissions = $this->get_course_assignment_submissions($course2->id);
609
        foreach ($course2submissions as $submission) {
610
            $this->mark_assignment_submission($submission->assignment, $submission->id, $teacher1, 50);
611
        }
612
    }
613
 
614
    /**
615
     * Helper function to add an assignment submission for testing.
616
     *
617
     * @param object $assignment        Object containing assignment submission details to create for testing.
618
     * @param object $user              Object of the user making the assignment submission.
619
     * @param string $submissiondata    The onlintext string value of the assignment submission.
620
     * @throws dml_exception
621
     */
622
    protected function add_assignment_submission($assignment, $user, $submissiondata) {
623
        global $DB;
624
 
625
        $submission = (object) [
626
            'assignment' => $assignment->id,
627
            'userid' => $user->id,
628
            'timecreated' => date('U'),
629
            'data1' => '<p>' . $submissiondata . '</p>',
630
            'submissioncomment' => 'My submission by ' . $user->username
631
        ];
632
 
633
        return $DB->insert_record('assignment_submissions', $submission);
634
    }
635
 
636
    /**
637
     * Helper function to add an assignment submission with file submissions for testing.
638
     *
639
     * @param object $assignment        Object containing assignment submission details to create for testing.
640
     * @param object $user              Object of the user making the assignment submission.
641
     * @param string $submissiondata    The onlintext string value of the assignment submission.
642
     * @param string $filename          The filename of the file submission included with the assignment submission.
643
     * @param int $numfiles             The number of files included with the assignment submission.
644
     * @throws dml_exception
645
     * @throws file_exception
646
     * @throws stored_file_creation_exception
647
     */
648
    protected function add_file_assignment_submission($assignment, $user, $submissiondata, $filename, $numfiles = 1) {
649
        global $CFG, $DB;
650
 
651
        $submission = (object) [
652
            'assignment' => $assignment->id,
653
            'userid' => $user->id,
654
            'timecreated' => date('U'),
655
            'data1' => '<p>' . $submissiondata . '</p>',
656
            'numfiles' => $numfiles,
657
            'submissioncomment' => 'My submission by ' . $user->username
658
        ];
659
 
660
        $submissionid = $DB->insert_record('assignment_submissions', $submission);
661
 
662
        // Create a file submission with the test pdf.
663
        $this->setUser($user->id);
664
        $context = \context_module::instance($assignment->cmid);
665
 
666
        $fs = get_file_storage();
667
        $sourcefile = $CFG->dirroot . '/mod/assign/feedback/editpdf/tests/fixtures/submission.pdf';
668
 
669
        for ($f = 1; $f <= $numfiles; $f++) {
670
            $pdfsubmission = (object)array(
671
                'contextid' => $context->id,
672
                'component' => 'mod_assignment',
673
                'filearea' => 'submission',
674
                'itemid' => $submissionid,
675
                'filepath' => '/',
676
                'filename' => $filename . "-(File $f of $numfiles)"
677
            );
678
            $fs->create_file_from_pathname($pdfsubmission, $sourcefile);
679
        }
680
    }
681
 
682
    /**
683
     * Helper function to retrieve the assignment submission records for a given course.
684
     *
685
     * @param int $courseid     The course ID to get assignment submissions by.
686
     * @return array            Array of assignment submission details.
687
     * @throws dml_exception
688
     */
689
    protected function get_course_assignment_submissions($courseid) {
690
        global $DB;
691
 
692
        $sql = "SELECT s.id,
693
                       s.assignment,
694
                       s.userid,
695
                       s.timecreated,
696
                       s.timemodified,
697
                       s.numfiles,
698
                       s.data1,
699
                       s.data2,
700
                       s.grade,
701
                       s.submissioncomment,
702
                       s.format,
703
                       s.teacher,
704
                       s.timemarked,
705
                       s.mailed
706
                  FROM {assignment} a
707
                  JOIN {assignment_submissions} s ON s.assignment = a.id
708
                 WHERE a.course = :courseid";
709
        $params = [
710
            'courseid' => $courseid
711
        ];
712
 
713
        return $DB->get_records_sql($sql, $params);
714
    }
715
 
716
    /**
717
     * Helper function to update an assignment submission with grading details for a teacher.
718
     *
719
     * @param int $assignmentid     The assignment ID to update assignment submissions with marking/graded details.
720
     * @param int $submissionid     The assignment submission ID to update with marking/grading details.
721
     * @param int $teacher          The teacher user ID to making the marking/grading details.
722
     * @param int $gradedata        The grade value set for the marking/grading details.
723
     */
724
    protected function mark_assignment_submission($assignmentid, $submissionid, $teacher, $gradedata) {
725
        global $DB;
726
 
727
        $submission = (object) [
728
            'id' => $submissionid,
729
            'assignment' => $assignmentid,
730
            'grade' => $gradedata,
731
            'teacher' => $teacher->id,
732
            'timemarked' => date('U')
733
        ];
734
 
735
        return $DB->update_record('assignment_submissions', $submission);
736
    }
737
 
738
    /**
739
     * Helper function to retrieve the assignment records for a given context.
740
     *
741
     * @param int $contextid    The context module ID value to retrieve assignment IDs by.
742
     * @return array            Array of assignment IDs.
743
     * @throws dml_exception
744
     */
745
    protected function get_assignments($contextid) {
746
        global $DB;
747
 
748
        $sql = "SELECT a.id
749
                  FROM {assignment} a
750
                  JOIN {course_modules} cm ON a.id = cm.instance
751
                  JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
752
                  JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
753
                 WHERE ctx.id = :contextid";
754
        $params = [
755
            'modulename' => 'assignment',
756
            'contextmodule' => CONTEXT_MODULE,
757
            'contextid' => $contextid
758
        ];
759
 
760
        return $DB->get_records_sql($sql, $params);
761
    }
762
 
763
    /**
764
     * Helper function to retrieve the assignment submission records for a given context.
765
     *
766
     * @param int $contextid    The context module ID value to retrieve assignment submission IDs by.
767
     * @return array            Array of assignment submission IDs.
768
     * @throws dml_exception
769
     */
770
    protected function get_assignment_submissions($contextid) {
771
        global $DB;
772
 
773
        $sql = "SELECT s.id
774
                  FROM {assignment_submissions} s
775
                  JOIN {assignment} a ON a.id = s.assignment
776
                  JOIN {course_modules} cm ON a.id = cm.instance
777
                  JOIN {modules} m ON m.id = cm.module AND m.name = :modulename
778
                  JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :contextmodule
779
                 WHERE ctx.id = :contextid";
780
        $params = [
781
            'modulename' => 'assignment',
782
            'contextmodule' => CONTEXT_MODULE,
783
            'contextid' => $contextid
784
        ];
785
 
786
        return $DB->get_records_sql($sql, $params);
787
    }
788
}