Merge branch 'MDL-29320-master' of git://github.com/junpataleta/moodle
[moodle.git] / completion / tests / bulk_update_test.php
CommitLineData
06cdda46
MG
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 * External completion functions unit tests
19 *
20 * @package core_completion
21 * @copyright 2017 Marina Glancy
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die();
26
27global $CFG;
28require_once($CFG->libdir . '/completionlib.php');
29
30/**
31 * External completion functions unit tests
32 *
33 * @package core_completion
34 * @copyright 2017 Marina Glancy
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class core_completion_bulk_update_testcase extends advanced_testcase {
38
39 /**
40 * Provider for test_bulk_form_submit_single
41 * @return array
42 */
43 public function bulk_form_submit_single_provider() {
44 return [
45 'assign-1' => ['assign', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionsubmit' => 1]],
46 'assign-2' => ['assign', ['completion' => COMPLETION_TRACKING_MANUAL]],
47 'book-1' => ['book', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
48 'book-2' => ['book', ['completion' => COMPLETION_TRACKING_MANUAL]],
49 'chat-1' => ['chat', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
50 'chat-2' => ['chat', ['completion' => COMPLETION_TRACKING_MANUAL]],
51 'choice-1' => ['choice', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionsubmit' => 1]],
52 'choice-2' => ['choice', ['completion' => COMPLETION_TRACKING_MANUAL]],
53 'data-1' => ['data', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
54 'data-2' => ['data', ['completion' => COMPLETION_TRACKING_MANUAL]],
61167c16
MG
55 'data-3' => ['data',
56 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1, 'completionentries' => 3,
57 'completionentriesenabled' => 1],
58 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1, 'completionentries' => 3]],
7f53e8aa
MG
59 'feedback-1' => ['feedback', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 0,
60 'completionsubmit' => 1]],
06cdda46
MG
61 'feedback-2' => ['feedback', ['completion' => COMPLETION_TRACKING_MANUAL]],
62 'folder-1' => ['folder', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
63 'folder-2' => ['folder', ['completion' => COMPLETION_TRACKING_MANUAL]],
64 'forum-1' => ['forum',
65 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completiondiscussions' => 1,
66 'completiondiscussionsenabled' => 1],
67 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completiondiscussions' => 1]],
68 'forum-2' => ['forum', ['completion' => COMPLETION_TRACKING_MANUAL]],
69 'glossary-1' => ['glossary',
70 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1, 'completionentries' => 3,
71 'completionentriesenabled' => 1],
72 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1, 'completionentries' => 3]],
73 'glossary-2' => ['glossary', ['completion' => COMPLETION_TRACKING_MANUAL]],
74 'imscp-1' => ['imscp', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
75 'imscp-2' => ['imscp', ['completion' => COMPLETION_TRACKING_MANUAL]],
76 'label-1' => ['label', ['completion' => COMPLETION_TRACKING_MANUAL]],
77 'lesson-1' => ['lesson', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionendreached' => 1]],
78 'lesson-2' => ['lesson', ['completion' => COMPLETION_TRACKING_MANUAL]],
79 'lti-1' => ['lti', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
80 'lti-2' => ['lti', ['completion' => COMPLETION_TRACKING_MANUAL]],
81 'page-1' => ['page', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
82 'page-2' => ['page', ['completion' => COMPLETION_TRACKING_MANUAL]],
83 'quiz-1' => ['quiz', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionpass' => 1]],
84 'quiz-2' => ['quiz', ['completion' => COMPLETION_TRACKING_MANUAL]],
85 'resource-1' => ['resource', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
86 'resource-2' => ['resource', ['completion' => COMPLETION_TRACKING_MANUAL]],
87 'scorm-1' => ['scorm',
88 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionscorerequired' => 1,
89 'completionstatusrequired' => [2 => 'passed']],
90 ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionscorerequired' => 1,
91 'completionstatusrequired' => 2]],
92 'scorm-2' => ['scorm', ['completion' => COMPLETION_TRACKING_MANUAL]],
93 'survey-1' => ['survey', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionsubmit' => 1]],
94 'survey-2' => ['survey', ['completion' => COMPLETION_TRACKING_MANUAL]],
95 'url-1' => ['url', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
96 'url-2' => ['url', ['completion' => COMPLETION_TRACKING_MANUAL]],
97 'wiki-1' => ['wiki', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
98 'wiki-2' => ['wiki', ['completion' => COMPLETION_TRACKING_MANUAL]],
99 'workshop-1' => ['workshop', ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1]],
100 'workshop-2' => ['workshop', ['completion' => COMPLETION_TRACKING_MANUAL]],
101 ];
102 }
103
104 /**
105 * Creates an instance of bulk edit completion form for one activity, validates and saves it
106 *
107 * @dataProvider bulk_form_submit_single_provider
108 * @param string $modname
109 * @param array $submitdata data to use in mock form submit
110 * @param array|null $validatedata data to validate the
111 */
112 public function test_bulk_form_submit_single($modname, $submitdata, $validatedata = null) {
113 global $DB;
114
115 if ($validatedata === null) {
116 $validatedata = $submitdata;
117 }
118
119 $this->resetAfterTest();
120 $this->setAdminUser();
121 list($course, $cms) = $this->create_course_and_modules([$modname]);
122
123 // Submit the bulk completion form with the provided data and make sure it returns the same data.
124 core_completion_bulkedit_form::mock_submit(['id' => $course->id, 'cmid' => array_keys($cms)] + $submitdata, []);
125 $form = new core_completion_bulkedit_form(null, ['cms' => $cms]);
126 $this->assertTrue($form->is_validated());
127 $data = $form->get_data();
128 foreach ($validatedata as $key => $value) {
129 $this->assertEquals($value, $data->$key);
130 }
131
132 // Apply completion rules to the modules.
133 $manager = new core_completion\manager($course->id);
134 $manager->apply_completion($data, $form->has_custom_completion_rules());
135
136 // Make sure either course_modules or instance table was respectfully updated.
137 $cm = reset($cms);
138 $cmrec = $DB->get_record('course_modules', ['id' => $cm->id]);
139 $instancerec = $DB->get_record($modname, ['id' => $cm->instance]);
140 foreach ($validatedata as $key => $value) {
141 if (property_exists($cmrec, $key)) {
142 $this->assertEquals($value, $cmrec->$key);
143 } else {
144 $this->assertEquals($value, $instancerec->$key);
145 }
146 }
147 }
148
149 /**
150 * Creates a course and the number of modules
151 * @param array $modulenames
152 * @return array array of two elements - course and list of cm_info objects
153 */
154 protected function create_course_and_modules($modulenames) {
155 global $CFG, $PAGE;
156
157 $CFG->enablecompletion = true;
158 $course = $this->getDataGenerator()->create_course(['enablecompletion' => 1], ['createsections' => true]);
159 $PAGE->set_course($course);
160
161 $cmids = [];
162 foreach ($modulenames as $modname) {
163 $module = $this->getDataGenerator()->create_module($modname, ['course' => $course->id]);
164 $cmids[] = $module->cmid;
165 }
166 $modinfo = get_fast_modinfo($course);
167 $cms = [];
168 foreach ($cmids as $cmid) {
169 $cms[$cmid] = $modinfo->get_cm($cmid);
170 }
171 return [$course, $cms];
172 }
173
174 /**
175 * Provider for test_bulk_form_submit_multiple
176 * @return array
177 */
178 public function bulk_form_submit_multiple_provider() {
179 return [
b17ee682
JD
180 'Several modules with the same module type (choice)' => [
181 [
182 'modulenames' => ['choice', 'choice', 'choice'],
183 'submitdata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionsubmit' => 1],
184 'validatedata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionsubmit' => 1],
185 'cmdata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC],
186 'instancedata' => [['completionsubmit' => 1], ['completionsubmit' => 1], ['completionsubmit' => 1]]
187 ]
188 ],
189 'Several modules with different module type' => [
190 [
191 'modulenames' => ['choice', 'forum'],
06cdda46
MG
192 'submitdata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1],
193 'validatedata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1],
194 'cmdata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC],
b17ee682
JD
195 'instancedata' => null
196 ]
197 ],
198 'Setting manual completion (completionview shoud be ignored)' => [
199 [
200 'modulenames' => ['scorm', 'forum', 'label', 'assign'],
06cdda46
MG
201 'submitdata' => ['completion' => COMPLETION_TRACKING_MANUAL, 'completionview' => 1],
202 'validatedata' => [],
203 'cmdata' => ['completion' => COMPLETION_TRACKING_MANUAL, 'completionview' => 0],
b17ee682
JD
204 'instancedata' => null
205 ]
206 ],
207 'If at least one module does not support completionsubmit it can\'t be set' => [
208 [
209 'modulenames' => ['survey', 'wiki'],
06cdda46
MG
210 'submitdata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1, 'completionsubmit' => 1],
211 'validatedata' => [],
212 'cmdata' => ['completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1],
b17ee682
JD
213 'instancedata' => [['completionsubmit' => 0], []]
214 ]
215 ]
06cdda46
MG
216 ];
217 }
218
219 /**
220 * Use bulk completion edit for updating multiple modules
221 *
222 * @dataProvider bulk_form_submit_multiple_provider
7f53e8aa 223 * @param array $providerdata
06cdda46
MG
224 */
225 public function test_bulk_form_submit_multiple($providerdata) {
226 global $DB;
227
228 $modulenames = $providerdata['modulenames'];
229 $submitdata = $providerdata['submitdata'];
230 $validatedata = $providerdata['validatedata'];
231 $cmdata = $providerdata['cmdata'];
232 $instancedata = $providerdata['instancedata'];
233
234 $this->resetAfterTest();
235 $this->setAdminUser();
236 list($course, $cms) = $this->create_course_and_modules($modulenames);
237
238 // Submit the bulk completion form with the provided data and make sure it returns the same data.
239 core_completion_bulkedit_form::mock_submit(['id' => $course->id, 'cmid' => array_keys($cms)] + $submitdata, []);
240 $form = new core_completion_bulkedit_form(null, ['cms' => $cms]);
241 $this->assertTrue($form->is_validated());
242 $data = $form->get_data();
243 foreach ($validatedata as $key => $value) {
244 $this->assertEquals($value, $data->$key);
245 }
246
247 // Apply completion rules to the modules.
248 $manager = new core_completion\manager($course->id);
249 $manager->apply_completion($data, $form->has_custom_completion_rules());
250
251 // Make sure either course_modules or instance table was respectfully updated.
252 $cnt = 0;
253 foreach ($cms as $cm) {
254 $cmrec = $DB->get_record('course_modules', ['id' => $cm->id]);
255 $instancerec = $DB->get_record($cm->modname, ['id' => $cm->instance]);
256 foreach ($cmdata as $key => $value) {
6c481358
MG
257 $this->assertEquals($value, $cmrec->$key, 'Error asserting that value for the field ' . $key.' ' .
258 $cmrec->$key . ' matches expected value ' . $value);
06cdda46
MG
259 }
260 if ($instancedata) {
261 foreach ($instancedata[$cnt] as $key => $value) {
6c481358
MG
262 $this->assertEquals($value, $instancerec->$key, 'Error asserting that value for the field ' . $key . ' '.
263 $instancerec->$key . ' matches expected value ' . $value);
06cdda46
MG
264 }
265 }
266 $cnt++;
267 }
268 }
269}