MDL-53966 lesson: Allow maximum number of attempts to be unlimited
[moodle.git] / mod / lesson / tests / locallib_test.php
CommitLineData
f847669e
AG
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 * locallib tests.
19 *
20 * @package mod_lesson
21 * @category test
22 * @copyright 2016 Adrian Greeve <adrian@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29
30require_once($CFG->dirroot.'/mod/lesson/locallib.php');
31
32/**
33 * locallib testcase.
34 *
35 * @package mod_lesson
36 * @category test
37 * @copyright 2016 Adrian Greeve <adrian@moodle.com>
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 */
40class mod_lesson_locallib_testcase extends advanced_testcase {
41
42 /**
43 * Test duplicating a lesson page element.
44 */
45 public function test_duplicate_page() {
46 global $DB;
47
48 $this->resetAfterTest();
49 $this->setAdminUser();
50 $course = $this->getDataGenerator()->create_course();
51 $lessonmodule = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
52 // Convert to a lesson object.
5a766a9e 53 $lesson = new lesson($lessonmodule);
f847669e
AG
54
55 // Set up a generator to create content.
56 $generator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
57 $tfrecord = $generator->create_question_truefalse($lesson);
58 $lesson->duplicate_page($tfrecord->id);
59
60 // Lesson pages.
61 $records = $DB->get_records('lesson_pages', array('qtype' => 2));
62 $sameelements = array('lessonid', 'qtype', 'qoption', 'layout', 'display', 'title', 'contents', 'contentsformat');
63 $baserecord = array_shift($records);
64 $secondrecord = array_shift($records);
65 foreach ($sameelements as $element) {
66 $this->assertEquals($baserecord->$element, $secondrecord->$element);
67 }
68 // Need lesson answers as well.
69 $baserecordanswers = array_values($DB->get_records('lesson_answers', array('pageid' => $baserecord->id)));
70 $secondrecordanswers = array_values($DB->get_records('lesson_answers', array('pageid' => $secondrecord->id)));
71 $sameanswerelements = array('lessonid', 'jumpto', 'grade', 'score', 'flags', 'answer', 'answerformat', 'response',
72 'responseformat');
73 foreach ($baserecordanswers as $key => $baseanswer) {
74 foreach ($sameanswerelements as $element) {
75 $this->assertEquals($baseanswer->$element, $secondrecordanswers[$key]->$element);
76 }
77 }
78 }
a4ffdbf3
JMV
79
80 /**
81 * Test test_lesson_get_user_deadline().
82 */
83 public function test_lesson_get_user_deadline() {
84 global $DB;
85
86 $this->resetAfterTest();
87 $this->setAdminUser();
88
89 $basetimestamp = time(); // The timestamp we will base the enddates on.
90
91 // Create generator, course and lessons.
92 $student1 = $this->getDataGenerator()->create_user();
93 $student2 = $this->getDataGenerator()->create_user();
94 $student3 = $this->getDataGenerator()->create_user();
95 $teacher = $this->getDataGenerator()->create_user();
96 $course = $this->getDataGenerator()->create_course();
97 $lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
98
99 // Both lessons close in two hours.
100 $lesson1 = $lessongenerator->create_instance(array('course' => $course->id, 'deadline' => $basetimestamp + 7200));
101 $lesson2 = $lessongenerator->create_instance(array('course' => $course->id, 'deadline' => $basetimestamp + 7200));
102 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
103 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
104
105 $student1id = $student1->id;
106 $student2id = $student2->id;
107 $student3id = $student3->id;
108 $teacherid = $teacher->id;
109
110 // Users enrolments.
111 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
112 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
113 $this->getDataGenerator()->enrol_user($student1id, $course->id, $studentrole->id, 'manual');
114 $this->getDataGenerator()->enrol_user($student2id, $course->id, $studentrole->id, 'manual');
115 $this->getDataGenerator()->enrol_user($student3id, $course->id, $studentrole->id, 'manual');
116 $this->getDataGenerator()->enrol_user($teacherid, $course->id, $teacherrole->id, 'manual');
117
118 // Create groups.
119 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
120 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
121 $group1id = $group1->id;
122 $group2id = $group2->id;
123 $this->getDataGenerator()->create_group_member(array('userid' => $student1id, 'groupid' => $group1id));
124 $this->getDataGenerator()->create_group_member(array('userid' => $student2id, 'groupid' => $group2id));
125
126 // Group 1 gets an group override for lesson 1 to close in three hours.
127 $record1 = (object) [
128 'lessonid' => $lesson1->id,
129 'groupid' => $group1id,
130 'deadline' => $basetimestamp + 10800 // In three hours.
131 ];
132 $DB->insert_record('lesson_overrides', $record1);
133
134 // Let's test lesson 1 closes in three hours for user student 1 since member of group 1.
135 // lesson 2 closes in two hours.
136 $this->setUser($student1id);
137 $params = new stdClass();
138
139 $comparearray = array();
140 $object = new stdClass();
141 $object->id = $lesson1->id;
142 $object->userdeadline = $basetimestamp + 10800; // The overriden deadline for lesson 1.
143
144 $comparearray[$lesson1->id] = $object;
145
146 $object = new stdClass();
147 $object->id = $lesson2->id;
148 $object->userdeadline = $basetimestamp + 7200; // The unchanged deadline for lesson 2.
149
150 $comparearray[$lesson2->id] = $object;
151
152 $this->assertEquals($comparearray, lesson_get_user_deadline($course->id));
153
154 // Let's test lesson 1 closes in two hours (the original value) for user student 3 since member of no group.
155 $this->setUser($student3id);
156 $params = new stdClass();
157
158 $comparearray = array();
159 $object = new stdClass();
160 $object->id = $lesson1->id;
161 $object->userdeadline = $basetimestamp + 7200; // The original deadline for lesson 1.
162
163 $comparearray[$lesson1->id] = $object;
164
165 $object = new stdClass();
166 $object->id = $lesson2->id;
167 $object->userdeadline = $basetimestamp + 7200; // The original deadline for lesson 2.
168
169 $comparearray[$lesson2->id] = $object;
170
171 $this->assertEquals($comparearray, lesson_get_user_deadline($course->id));
172
173 // User 2 gets an user override for lesson 1 to close in four hours.
174 $record2 = (object) [
175 'lessonid' => $lesson1->id,
176 'userid' => $student2id,
177 'deadline' => $basetimestamp + 14400 // In four hours.
178 ];
179 $DB->insert_record('lesson_overrides', $record2);
180
181 // Let's test lesson 1 closes in four hours for user student 2 since personally overriden.
182 // lesson 2 closes in two hours.
183 $this->setUser($student2id);
184
185 $comparearray = array();
186 $object = new stdClass();
187 $object->id = $lesson1->id;
188 $object->userdeadline = $basetimestamp + 14400; // The overriden deadline for lesson 1.
189
190 $comparearray[$lesson1->id] = $object;
191
192 $object = new stdClass();
193 $object->id = $lesson2->id;
194 $object->userdeadline = $basetimestamp + 7200; // The unchanged deadline for lesson 2.
195
196 $comparearray[$lesson2->id] = $object;
197
198 $this->assertEquals($comparearray, lesson_get_user_deadline($course->id));
199
200 // Let's test a teacher sees the original times.
201 // lesson 1 and lesson 2 close in two hours.
202 $this->setUser($teacherid);
203
204 $comparearray = array();
205 $object = new stdClass();
206 $object->id = $lesson1->id;
207 $object->userdeadline = $basetimestamp + 7200; // The unchanged deadline for lesson 1.
208
209 $comparearray[$lesson1->id] = $object;
210
211 $object = new stdClass();
212 $object->id = $lesson2->id;
213 $object->userdeadline = $basetimestamp + 7200; // The unchanged deadline for lesson 2.
214
215 $comparearray[$lesson2->id] = $object;
216
217 $this->assertEquals($comparearray, lesson_get_user_deadline($course->id));
218 }
cea8e276
P
219
220 public function test_is_participant() {
221 global $USER, $DB;
222 $this->resetAfterTest();
223 $this->setAdminUser();
224 $course = $this->getDataGenerator()->create_course();
225 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
226 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student', [], 'manual', 0, 0, ENROL_USER_SUSPENDED);
227 $lessonmodule = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
228
229 // Login as student.
230 $this->setUser($student);
231 // Convert to a lesson object.
232 $lesson = new lesson($lessonmodule);
233 $this->assertEquals(true, $lesson->is_participant($student->id),
234 'Student is enrolled, active and can participate');
235
236 // Login as student2.
237 $this->setUser($student2);
238 $this->assertEquals(false, $lesson->is_participant($student2->id),
239 'Student is enrolled, suspended and can NOT participate');
240
241 // Login as an admin.
242 $this->setAdminUser();
243 $this->assertEquals(false, $lesson->is_participant($USER->id),
244 'Admin is not enrolled and can NOT participate');
245
246 $this->getDataGenerator()->enrol_user(2, $course->id);
247 $this->assertEquals(true, $lesson->is_participant($USER->id),
248 'Admin is enrolled and can participate');
249
250 $this->getDataGenerator()->enrol_user(2, $course->id, [], 'manual', 0, 0, ENROL_USER_SUSPENDED);
251 $this->assertEquals(true, $lesson->is_participant($USER->id),
252 'Admin is enrolled, suspended and can participate');
253 }
252e85be
MG
254
255 /**
256 * Data provider for test_get_last_attempt.
257 *
258 * @return array
259 */
260 public function test_get_last_attempt_dataprovider() {
261 return [
262 [0, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 3]],
263 [1, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 1]],
264 [2, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 2]],
265 [3, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 3]],
266 [4, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 3]],
267 ];
268 }
269
270 /**
271 * Test the get_last_attempt() method.
272 *
273 * @dataProvider test_get_last_attempt_dataprovider
274 * @param int $maxattempts Lesson setting.
275 * @param array $attempts The list of student attempts.
276 * @param object $expected Expected result.
277 */
278 public function test_get_last_attempt($maxattempts, $attempts, $expected) {
279 $this->resetAfterTest();
280 $this->setAdminUser();
281 $course = $this->getDataGenerator()->create_course();
282 $lesson = $this->getDataGenerator()->create_module('lesson', ['course' => $course, 'maxattempts' => $maxattempts]);
283 $lesson = new lesson($lesson);
284 $this->assertEquals($expected, $lesson->get_last_attempt($attempts));
285 }
f847669e 286}