MDL-49409 mod_data: Create exporters for record and content
[moodle.git] / mod / data / tests / externallib_test.php
CommitLineData
067b3fda
JL
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 * Database module external functions tests
19 *
20 * @package mod_data
21 * @category external
22 * @copyright 2015 Juan Leyva <juan@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @since Moodle 2.9
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30
31require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32
33/**
34 * Database module external functions tests
35 *
36 * @package mod_data
37 * @category external
38 * @copyright 2015 Juan Leyva <juan@moodle.com>
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 * @since Moodle 2.9
41 */
42class mod_data_external_testcase extends externallib_advanced_testcase {
43
9fac7c86
JL
44 /**
45 * Set up for every test
46 */
47 public function setUp() {
48 global $DB;
49 $this->resetAfterTest();
50 $this->setAdminUser();
51
52 // Setup test data.
53 $this->course = $this->getDataGenerator()->create_course();
54 $this->data = $this->getDataGenerator()->create_module('data', array('course' => $this->course->id));
55 $this->context = context_module::instance($this->data->cmid);
56 $this->cm = get_coursemodule_from_instance('data', $this->data->id);
57
58 // Create users.
59 $this->student1 = self::getDataGenerator()->create_user();
60 $this->student2 = self::getDataGenerator()->create_user();
61 $this->teacher = self::getDataGenerator()->create_user();
62
63 // Users enrolments.
64 $this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
65 $this->teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
66 $this->getDataGenerator()->enrol_user($this->student1->id, $this->course->id, $this->studentrole->id, 'manual');
67 $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id, 'manual');
68 $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, $this->teacherrole->id, 'manual');
69 }
70
067b3fda
JL
71 /**
72 * Test get databases by courses
73 */
74 public function test_mod_data_get_databases_by_courses() {
75 global $DB;
76
77 $this->resetAfterTest(true);
78
79 // Create users.
80 $student = self::getDataGenerator()->create_user();
81 $teacher = self::getDataGenerator()->create_user();
82
83 // Set to the student user.
84 self::setUser($student);
85
86 // Create courses to add the modules.
87 $course1 = self::getDataGenerator()->create_course();
88 $course2 = self::getDataGenerator()->create_course();
89
90 // First database.
91 $record = new stdClass();
92 $record->introformat = FORMAT_HTML;
93 $record->course = $course1->id;
94 $database1 = self::getDataGenerator()->create_module('data', $record);
95
96 // Second database.
97 $record = new stdClass();
98 $record->introformat = FORMAT_HTML;
99 $record->course = $course2->id;
100 $database2 = self::getDataGenerator()->create_module('data', $record);
101
102 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
103 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
104
105 // Users enrolments.
106 $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
107 $this->getDataGenerator()->enrol_user($teacher->id, $course1->id, $teacherrole->id, 'manual');
108
109 // Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
110 $enrol = enrol_get_plugin('manual');
111 $enrolinstances = enrol_get_instances($course2->id, true);
112 foreach ($enrolinstances as $courseenrolinstance) {
113 if ($courseenrolinstance->enrol == "manual") {
114 $instance2 = $courseenrolinstance;
115 break;
116 }
117 }
118 $enrol->enrol_user($instance2, $student->id, $studentrole->id);
119
120 // Create what we expect to be returned when querying the two courses.
121 // First for the student user.
122 $expectedfields = array('id', 'coursemodule', 'course', 'name', 'comments', 'timeavailablefrom',
123 'timeavailableto', 'timeviewfrom', 'timeviewto', 'requiredentries', 'requiredentriestoview',
f97305b0
JL
124 'intro', 'introformat', 'introfiles', 'maxentries', 'rssarticles', 'singletemplate', 'listtemplate',
125 'listtemplateheader', 'listtemplatefooter', 'addtemplate', 'rsstemplate', 'rsstitletemplate',
126 'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', 'defaultsort', 'defaultsortdir', 'manageapproved');
067b3fda
JL
127
128 // Add expected coursemodule.
129 $database1->coursemodule = $database1->cmid;
7ef49bd3 130 $database1->introfiles = [];
067b3fda 131 $database2->coursemodule = $database2->cmid;
7ef49bd3 132 $database2->introfiles = [];
067b3fda
JL
133
134 $expected1 = array();
135 $expected2 = array();
136 foreach ($expectedfields as $field) {
f97305b0
JL
137 if ($field == 'approval' or $field == 'manageapproved') {
138 $database1->{$field} = (bool) $database1->{$field};
139 $database2->{$field} = (bool) $database2->{$field};
140 }
067b3fda
JL
141 $expected1[$field] = $database1->{$field};
142 $expected2[$field] = $database2->{$field};
143 }
8352aa50
JL
144 $expected1['comments'] = (bool) $expected1['comments'];
145 $expected2['comments'] = (bool) $expected2['comments'];
067b3fda
JL
146
147 $expecteddatabases = array();
148 $expecteddatabases[] = $expected2;
149 $expecteddatabases[] = $expected1;
150
151 // Call the external function passing course ids.
152 $result = mod_data_external::get_databases_by_courses(array($course2->id, $course1->id));
8352aa50 153 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
067b3fda
JL
154 $this->assertEquals($expecteddatabases, $result['databases']);
155
156 // Call the external function without passing course id.
157 $result = mod_data_external::get_databases_by_courses();
8352aa50 158 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
067b3fda
JL
159 $this->assertEquals($expecteddatabases, $result['databases']);
160
161 // Unenrol user from second course and alter expected databases.
162 $enrol->unenrol_user($instance2, $student->id);
163 array_shift($expecteddatabases);
164
165 // Call the external function without passing course id.
166 $result = mod_data_external::get_databases_by_courses();
8352aa50 167 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
067b3fda
JL
168 $this->assertEquals($expecteddatabases, $result['databases']);
169
170 // Call for the second course we unenrolled the user from, expected warning.
171 $result = mod_data_external::get_databases_by_courses(array($course2->id));
172 $this->assertCount(1, $result['warnings']);
8352aa50 173 $this->assertEquals('1', $result['warnings'][0]['warningcode']);
067b3fda
JL
174 $this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
175
176 // Now, try as a teacher for getting all the additional fields.
177 self::setUser($teacher);
178
f97305b0 179 $additionalfields = array('scale', 'assessed', 'assesstimestart', 'assesstimefinish', 'editany', 'notification', 'timemodified');
067b3fda
JL
180
181 foreach ($additionalfields as $field) {
f97305b0
JL
182 if ($field == 'editany') {
183 $database1->{$field} = (bool) $database1->{$field};
8352aa50 184 }
f97305b0 185 $expecteddatabases[0][$field] = $database1->{$field};
067b3fda
JL
186 }
187 $result = mod_data_external::get_databases_by_courses();
8352aa50
JL
188 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
189 $this->assertEquals($expecteddatabases, $result['databases']);
190
191 // Admin should get all the information.
192 self::setAdminUser();
193
194 $result = mod_data_external::get_databases_by_courses(array($course1->id));
195 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
067b3fda
JL
196 $this->assertEquals($expecteddatabases, $result['databases']);
197 }
9fac7c86
JL
198
199 /**
200 * Test view_database invalid id.
201 */
202 public function test_view_database_invalid_id() {
203
204 // Test invalid instance id.
205 $this->setExpectedException('moodle_exception');
206 mod_data_external::view_database(0);
207 }
208
209 /**
210 * Test view_database not enrolled user.
211 */
212 public function test_view_database_not_enrolled_user() {
213
214 $usernotenrolled = self::getDataGenerator()->create_user();
215 $this->setUser($usernotenrolled);
216
217 $this->setExpectedException('moodle_exception');
218 mod_data_external::view_database(0);
219 }
220
221 /**
222 * Test view_database no capabilities.
223 */
224 public function test_view_database_no_capabilities() {
225 // Test user with no capabilities.
226 // We need a explicit prohibit since this capability is allowed for students by default.
227 assign_capability('mod/data:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
228 accesslib_clear_all_caches_for_unit_testing();
229
230 $this->setExpectedException('moodle_exception');
231 mod_data_external::view_database(0);
232 }
233
234 /**
235 * Test view_database.
236 */
237 public function test_view_database() {
238
239 // Test user with full capabilities.
240 $this->setUser($this->student1);
241
242 // Trigger and capture the event.
243 $sink = $this->redirectEvents();
244
245 $result = mod_data_external::view_database($this->data->id);
246 $result = external_api::clean_returnvalue(mod_data_external::view_database_returns(), $result);
247
248 $events = $sink->get_events();
249 $this->assertCount(1, $events);
250 $event = array_shift($events);
251
252 // Checking that the event contains the expected values.
253 $this->assertInstanceOf('\mod_data\event\course_module_viewed', $event);
254 $this->assertEquals($this->context, $event->get_context());
255 $moodledata = new \moodle_url('/mod/data/view.php', array('id' => $this->cm->id));
256 $this->assertEquals($moodledata, $event->get_url());
257 $this->assertEventContextNotUsed($event);
258 $this->assertNotEmpty($event->get_name());
259 }
cac43b9b
JL
260
261 /**
262 * Test get_data_access_information for student.
263 */
264 public function test_get_data_access_information_student() {
265 global $DB;
266 // Modify the database to add access restrictions.
267 $this->data->timeavailablefrom = time() + DAYSECS;
268 $this->data->requiredentries = 2;
269 $this->data->requiredentriestoview = 2;
270 $DB->update_record('data', $this->data);
271
272 // Test user with full capabilities.
273 $this->setUser($this->student1);
274
275 $result = mod_data_external::get_data_access_information($this->data->id);
276 $result = external_api::clean_returnvalue(mod_data_external::get_data_access_information_returns(), $result);
277
278 $this->assertEquals(0, $result['groupid']);
279
280 $this->assertFalse($result['canmanageentries']);
281 $this->assertFalse($result['canapprove']);
282 $this->assertTrue($result['canaddentry']); // It return true because it doen't check time restrictions.
283 $this->assertFalse($result['timeavailable']);
284 $this->assertFalse($result['inreadonlyperiod']);
285 $this->assertEquals(0, $result['numentries']);
286 $this->assertEquals($this->data->requiredentries, $result['entrieslefttoadd']);
287 $this->assertEquals($this->data->requiredentriestoview, $result['entrieslefttoview']);
288 }
289
290 /**
291 * Test get_data_access_information for teacher.
292 */
293 public function test_get_data_access_information_teacher() {
294 global $DB;
295 // Modify the database to add access restrictions.
296 $this->data->timeavailablefrom = time() + DAYSECS;
297 $this->data->requiredentries = 2;
298 $this->data->requiredentriestoview = 2;
299 $DB->update_record('data', $this->data);
300
301 // Test user with full capabilities.
302 $this->setUser($this->teacher);
303
304 $result = mod_data_external::get_data_access_information($this->data->id);
305 $result = external_api::clean_returnvalue(mod_data_external::get_data_access_information_returns(), $result);
306
307 $this->assertEquals(0, $result['groupid']);
308
309 $this->assertTrue($result['canmanageentries']);
310 $this->assertTrue($result['canapprove']);
311 $this->assertTrue($result['canaddentry']); // It return true because it doen't check time restrictions.
312 $this->assertTrue($result['timeavailable']);
313 $this->assertFalse($result['inreadonlyperiod']);
314 $this->assertEquals(0, $result['numentries']);
315 $this->assertEquals(0, $result['entrieslefttoadd']);
316 $this->assertEquals(0, $result['entrieslefttoview']);
317 }
067b3fda 318}