2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Database module external functions tests
22 * @copyright 2015 Juan Leyva <juan@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
31 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
34 * Database module external functions tests
38 * @copyright 2015 Juan Leyva <juan@moodle.com>
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 class mod_data_external_testcase extends externallib_advanced_testcase {
44 /** @var stdClass Test module context. */
47 /** @var stdClass Test course.*/
50 /** @var stdClass Test course module. */
53 /** @var stdClass Test database activity. */
56 /** @var stdClass Test group 1. */
59 /** @var stdClass Test group 2. */
62 /** @var stdClass Test student 1. */
65 /** @var stdClass Test student 2. */
68 /** @var stdClass Test student 3. */
71 /** @var stdClass Test student 4. */
74 /** @var stdClass Student role. */
75 protected $studentrole;
77 /** @var stdClass Test teacher. */
80 /** @var stdClass Teacher role. */
81 protected $teacherrole;
84 * Set up for every test
86 public function setUp() {
88 $this->resetAfterTest();
89 $this->setAdminUser();
92 $course = new stdClass();
93 $course->groupmode = SEPARATEGROUPS;
94 $course->groupmodeforce = true;
95 $this->course = $this->getDataGenerator()->create_course($course);
96 $this->database = $this->getDataGenerator()->create_module('data', array('course' => $this->course->id));
97 $this->context = context_module::instance($this->database->cmid);
98 $this->cm = get_coursemodule_from_instance('data', $this->database->id);
101 $this->student1 = self::getDataGenerator()->create_user(['firstname' => 'Olivia', 'lastname' => 'Smith']);
102 $this->student2 = self::getDataGenerator()->create_user(['firstname' => 'Ezra', 'lastname' => 'Johnson']);
103 $this->student3 = self::getDataGenerator()->create_user(['firstname' => 'Amelia', 'lastname' => 'Williams']);
104 $this->teacher = self::getDataGenerator()->create_user(['firstname' => 'Asher', 'lastname' => 'Jones']);
107 $this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
108 $this->teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
109 $this->getDataGenerator()->enrol_user($this->student1->id, $this->course->id, $this->studentrole->id, 'manual');
110 $this->getDataGenerator()->enrol_user($this->student2->id, $this->course->id, $this->studentrole->id, 'manual');
111 $this->getDataGenerator()->enrol_user($this->student3->id, $this->course->id, $this->studentrole->id, 'manual');
112 $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, $this->teacherrole->id, 'manual');
114 $this->group1 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
115 $this->group2 = $this->getDataGenerator()->create_group(array('courseid' => $this->course->id));
116 groups_add_member($this->group1, $this->student1);
117 groups_add_member($this->group1, $this->student2);
118 groups_add_member($this->group2, $this->student3);
122 * Test get databases by courses
124 public function test_mod_data_get_databases_by_courses() {
127 $this->resetAfterTest(true);
130 $student = self::getDataGenerator()->create_user();
131 $teacher = self::getDataGenerator()->create_user();
133 // Set to the student user.
134 self::setUser($student);
136 // Create courses to add the modules.
137 $course1 = self::getDataGenerator()->create_course();
138 $course2 = self::getDataGenerator()->create_course();
141 $record = new stdClass();
142 $record->introformat = FORMAT_HTML;
143 $record->course = $course1->id;
144 $database1 = self::getDataGenerator()->create_module('data', $record);
147 $record = new stdClass();
148 $record->introformat = FORMAT_HTML;
149 $record->course = $course2->id;
150 $database2 = self::getDataGenerator()->create_module('data', $record);
152 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
153 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
156 $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
157 $this->getDataGenerator()->enrol_user($teacher->id, $course1->id, $teacherrole->id, 'manual');
159 // Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
160 $enrol = enrol_get_plugin('manual');
161 $enrolinstances = enrol_get_instances($course2->id, true);
162 foreach ($enrolinstances as $courseenrolinstance) {
163 if ($courseenrolinstance->enrol == "manual") {
164 $instance2 = $courseenrolinstance;
168 $enrol->enrol_user($instance2, $student->id, $studentrole->id);
170 // Create what we expect to be returned when querying the two courses.
171 // First for the student user.
172 $expectedfields = array('id', 'coursemodule', 'course', 'name', 'comments', 'timeavailablefrom',
173 'timeavailableto', 'timeviewfrom', 'timeviewto', 'requiredentries', 'requiredentriestoview',
174 'intro', 'introformat', 'introfiles', 'maxentries', 'rssarticles', 'singletemplate', 'listtemplate',
175 'listtemplateheader', 'listtemplatefooter', 'addtemplate', 'rsstemplate', 'rsstitletemplate',
176 'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', 'defaultsort', 'defaultsortdir', 'manageapproved');
178 // Add expected coursemodule.
179 $database1->coursemodule = $database1->cmid;
180 $database1->introfiles = [];
181 $database2->coursemodule = $database2->cmid;
182 $database2->introfiles = [];
184 $expected1 = array();
185 $expected2 = array();
186 foreach ($expectedfields as $field) {
187 if ($field == 'approval' or $field == 'manageapproved') {
188 $database1->{$field} = (bool) $database1->{$field};
189 $database2->{$field} = (bool) $database2->{$field};
191 $expected1[$field] = $database1->{$field};
192 $expected2[$field] = $database2->{$field};
194 $expected1['comments'] = (bool) $expected1['comments'];
195 $expected2['comments'] = (bool) $expected2['comments'];
197 $expecteddatabases = array();
198 $expecteddatabases[] = $expected2;
199 $expecteddatabases[] = $expected1;
201 // Call the external function passing course ids.
202 $result = mod_data_external::get_databases_by_courses(array($course2->id, $course1->id));
203 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
204 $this->assertEquals($expecteddatabases, $result['databases']);
206 // Call the external function without passing course id.
207 $result = mod_data_external::get_databases_by_courses();
208 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
209 $this->assertEquals($expecteddatabases, $result['databases']);
211 // Unenrol user from second course and alter expected databases.
212 $enrol->unenrol_user($instance2, $student->id);
213 array_shift($expecteddatabases);
215 // Call the external function without passing course id.
216 $result = mod_data_external::get_databases_by_courses();
217 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
218 $this->assertEquals($expecteddatabases, $result['databases']);
220 // Call for the second course we unenrolled the user from, expected warning.
221 $result = mod_data_external::get_databases_by_courses(array($course2->id));
222 $this->assertCount(1, $result['warnings']);
223 $this->assertEquals('1', $result['warnings'][0]['warningcode']);
224 $this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
226 // Now, try as a teacher for getting all the additional fields.
227 self::setUser($teacher);
229 $additionalfields = array('scale', 'assessed', 'assesstimestart', 'assesstimefinish', 'editany', 'notification', 'timemodified');
231 foreach ($additionalfields as $field) {
232 if ($field == 'editany') {
233 $database1->{$field} = (bool) $database1->{$field};
235 $expecteddatabases[0][$field] = $database1->{$field};
237 $result = mod_data_external::get_databases_by_courses();
238 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
239 $this->assertEquals($expecteddatabases, $result['databases']);
241 // Admin should get all the information.
242 self::setAdminUser();
244 $result = mod_data_external::get_databases_by_courses(array($course1->id));
245 $result = external_api::clean_returnvalue(mod_data_external::get_databases_by_courses_returns(), $result);
246 $this->assertEquals($expecteddatabases, $result['databases']);
250 * Test view_database invalid id.
252 public function test_view_database_invalid_id() {
254 // Test invalid instance id.
255 $this->expectException('moodle_exception');
256 mod_data_external::view_database(0);
260 * Test view_database not enrolled user.
262 public function test_view_database_not_enrolled_user() {
264 $usernotenrolled = self::getDataGenerator()->create_user();
265 $this->setUser($usernotenrolled);
267 $this->expectException('moodle_exception');
268 mod_data_external::view_database(0);
272 * Test view_database no capabilities.
274 public function test_view_database_no_capabilities() {
275 // Test user with no capabilities.
276 // We need a explicit prohibit since this capability is allowed for students by default.
277 assign_capability('mod/data:viewpage', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
278 accesslib_clear_all_caches_for_unit_testing();
280 $this->expectException('moodle_exception');
281 mod_data_external::view_database(0);
285 * Test view_database.
287 public function test_view_database() {
289 // Test user with full capabilities.
290 $this->setUser($this->student1);
292 // Trigger and capture the event.
293 $sink = $this->redirectEvents();
295 $result = mod_data_external::view_database($this->database->id);
296 $result = external_api::clean_returnvalue(mod_data_external::view_database_returns(), $result);
298 $events = $sink->get_events();
299 $this->assertCount(1, $events);
300 $event = array_shift($events);
302 // Checking that the event contains the expected values.
303 $this->assertInstanceOf('\mod_data\event\course_module_viewed', $event);
304 $this->assertEquals($this->context, $event->get_context());
305 $moodledata = new \moodle_url('/mod/data/view.php', array('id' => $this->cm->id));
306 $this->assertEquals($moodledata, $event->get_url());
307 $this->assertEventContextNotUsed($event);
308 $this->assertNotEmpty($event->get_name());
312 * Test get_data_access_information for student.
314 public function test_get_data_access_information_student() {
316 // Modify the database to add access restrictions.
317 $this->database->timeavailablefrom = time() + DAYSECS;
318 $this->database->requiredentries = 2;
319 $this->database->requiredentriestoview = 2;
320 $DB->update_record('data', $this->database);
322 // Test user with full capabilities.
323 $this->setUser($this->student1);
325 $result = mod_data_external::get_data_access_information($this->database->id);
326 $result = external_api::clean_returnvalue(mod_data_external::get_data_access_information_returns(), $result);
328 $this->assertEquals($this->group1->id, $result['groupid']);
330 $this->assertFalse($result['canmanageentries']);
331 $this->assertFalse($result['canapprove']);
332 $this->assertTrue($result['canaddentry']); // It return true because it doen't check time restrictions.
333 $this->assertFalse($result['timeavailable']);
334 $this->assertFalse($result['inreadonlyperiod']);
335 $this->assertEquals(0, $result['numentries']);
336 $this->assertEquals($this->database->requiredentries, $result['entrieslefttoadd']);
337 $this->assertEquals($this->database->requiredentriestoview, $result['entrieslefttoview']);
341 * Test get_data_access_information for teacher.
343 public function test_get_data_access_information_teacher() {
345 // Modify the database to add access restrictions.
346 $this->database->timeavailablefrom = time() + DAYSECS;
347 $this->database->requiredentries = 2;
348 $this->database->requiredentriestoview = 2;
349 $DB->update_record('data', $this->database);
351 // Test user with full capabilities.
352 $this->setUser($this->teacher);
354 $result = mod_data_external::get_data_access_information($this->database->id);
355 $result = external_api::clean_returnvalue(mod_data_external::get_data_access_information_returns(), $result);
357 $this->assertEquals(0, $result['groupid']);
359 $this->assertTrue($result['canmanageentries']);
360 $this->assertTrue($result['canapprove']);
361 $this->assertTrue($result['canaddentry']); // It return true because it doen't check time restrictions.
362 $this->assertTrue($result['timeavailable']);
363 $this->assertFalse($result['inreadonlyperiod']);
364 $this->assertEquals(0, $result['numentries']);
365 $this->assertEquals(0, $result['entrieslefttoadd']);
366 $this->assertEquals(0, $result['entrieslefttoview']);
370 * Helper method to populate the database with some entries.
372 * @return array the entry ids created
374 public function populate_database_with_entries() {
378 $DB->set_field('data', 'approval', 1, array('id' => $this->database->id));
379 $generator = $this->getDataGenerator()->get_plugin_generator('mod_data');
380 $fieldtypes = array('checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url');
383 // Creating test Fields with default parameter values.
384 foreach ($fieldtypes as $fieldtype) {
385 $fieldname = 'field-' . $count;
386 $record = new StdClass();
387 $record->name = $fieldname;
388 $record->type = $fieldtype;
389 $record->required = 1;
391 $generator->create_field($record, $this->database);
394 // Get all the fields created.
395 $fields = $DB->get_records('data_fields', array('dataid' => $this->database->id), 'id');
397 // Populate with contents, creating a new entry.
399 $contents[] = array('opt1', 'opt2', 'opt3', 'opt4');
400 $contents[] = '01-01-2037'; // It should be lower than 2038, to avoid failing on 32-bit windows.
401 $contents[] = 'menu1';
402 $contents[] = array('multimenu1', 'multimenu2', 'multimenu3', 'multimenu4');
403 $contents[] = '12345';
404 $contents[] = 'radioopt1';
405 $contents[] = 'text for testing';
406 $contents[] = '<p>text area testing<br /></p>';
407 $contents[] = array('example.url', 'sampleurl');
409 $fieldcontents = array();
410 foreach ($fields as $fieldrecord) {
411 $fieldcontents[$fieldrecord->id] = $contents[$count++];
414 $this->setUser($this->student1);
415 $entry11 = $generator->create_entry($this->database, $fieldcontents, $this->group1->id);
416 $this->setUser($this->student2);
417 $entry12 = $generator->create_entry($this->database, $fieldcontents, $this->group1->id);
418 $entry13 = $generator->create_entry($this->database, $fieldcontents, $this->group1->id);
419 // Entry not in group.
420 $entry14 = $generator->create_entry($this->database, $fieldcontents, 0);
422 $this->setUser($this->student3);
423 $entry21 = $generator->create_entry($this->database, $fieldcontents, $this->group2->id);
425 // Approve all except $entry13.
426 $DB->set_field('data_records', 'approved', 1, ['id' => $entry11]);
427 $DB->set_field('data_records', 'approved', 1, ['id' => $entry12]);
428 $DB->set_field('data_records', 'approved', 1, ['id' => $entry14]);
429 $DB->set_field('data_records', 'approved', 1, ['id' => $entry21]);
431 return [$entry11, $entry12, $entry13, $entry14, $entry21];
437 public function test_get_entries() {
439 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
441 // First of all, expect to see only my group entries (not other users in other groups ones).
442 // We may expect entries without group also.
443 $this->setUser($this->student1);
444 $result = mod_data_external::get_entries($this->database->id);
445 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
446 $this->assertCount(0, $result['warnings']);
447 $this->assertCount(3, $result['entries']);
448 $this->assertEquals(3, $result['totalcount']);
449 $this->assertEquals($entry11, $result['entries'][0]['id']);
450 $this->assertEquals($this->student1->id, $result['entries'][0]['userid']);
451 $this->assertEquals($this->group1->id, $result['entries'][0]['groupid']);
452 $this->assertEquals($this->database->id, $result['entries'][0]['dataid']);
453 $this->assertEquals($entry12, $result['entries'][1]['id']);
454 $this->assertEquals($this->student2->id, $result['entries'][1]['userid']);
455 $this->assertEquals($this->group1->id, $result['entries'][1]['groupid']);
456 $this->assertEquals($this->database->id, $result['entries'][1]['dataid']);
457 $this->assertEquals($entry14, $result['entries'][2]['id']);
458 $this->assertEquals($this->student2->id, $result['entries'][2]['userid']);
459 $this->assertEquals(0, $result['entries'][2]['groupid']);
460 $this->assertEquals($this->database->id, $result['entries'][2]['dataid']);
461 // Other user in same group.
462 $this->setUser($this->student2);
463 $result = mod_data_external::get_entries($this->database->id);
464 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
465 $this->assertCount(0, $result['warnings']);
466 $this->assertCount(4, $result['entries']); // I can see my entry not approved yet.
467 $this->assertEquals(4, $result['totalcount']);
469 // Now try with the user in the second group that must see only two entries (his group entry and the one without group).
470 $this->setUser($this->student3);
471 $result = mod_data_external::get_entries($this->database->id);
472 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
473 $this->assertCount(0, $result['warnings']);
474 $this->assertCount(2, $result['entries']);
475 $this->assertEquals(2, $result['totalcount']);
476 $this->assertEquals($entry14, $result['entries'][0]['id']);
477 $this->assertEquals($this->student2->id, $result['entries'][0]['userid']);
478 $this->assertEquals(0, $result['entries'][0]['groupid']);
479 $this->assertEquals($this->database->id, $result['entries'][0]['dataid']);
480 $this->assertEquals($entry21, $result['entries'][1]['id']);
481 $this->assertEquals($this->student3->id, $result['entries'][1]['userid']);
482 $this->assertEquals($this->group2->id, $result['entries'][1]['groupid']);
483 $this->assertEquals($this->database->id, $result['entries'][1]['dataid']);
485 // Now, as teacher we should see all (we have permissions to view all groups).
486 $this->setUser($this->teacher);
487 $result = mod_data_external::get_entries($this->database->id);
488 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
489 $this->assertCount(0, $result['warnings']);
490 $this->assertCount(5, $result['entries']); // I can see the not approved one.
491 $this->assertEquals(5, $result['totalcount']);
493 $entries = $DB->get_records('data_records', array('dataid' => $this->database->id), 'id');
494 $this->assertCount(5, $entries);
496 foreach ($entries as $entry) {
497 $this->assertEquals($entry->id, $result['entries'][$count]['id']);
501 // Basic test passing the parameter (instead having to calculate it).
502 $this->setUser($this->student1);
503 $result = mod_data_external::get_entries($this->database->id, $this->group1->id);
504 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
505 $this->assertCount(0, $result['warnings']);
506 $this->assertCount(3, $result['entries']);
507 $this->assertEquals(3, $result['totalcount']);
509 // Test ordering (reverse).
510 $this->setUser($this->student1);
511 $result = mod_data_external::get_entries($this->database->id, $this->group1->id, false, null, 'DESC');
512 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
513 $this->assertCount(0, $result['warnings']);
514 $this->assertCount(3, $result['entries']);
515 $this->assertEquals(3, $result['totalcount']);
516 $this->assertEquals($entry14, $result['entries'][0]['id']);
519 $this->setUser($this->student1);
520 $result = mod_data_external::get_entries($this->database->id, $this->group1->id, false, null, null, 0, 1);
521 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
522 $this->assertCount(0, $result['warnings']);
523 $this->assertCount(1, $result['entries']);
524 $this->assertEquals(3, $result['totalcount']);
525 $this->assertEquals($entry11, $result['entries'][0]['id']);
527 $result = mod_data_external::get_entries($this->database->id, $this->group1->id, false, null, null, 1, 1);
528 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
529 $this->assertCount(0, $result['warnings']);
530 $this->assertCount(1, $result['entries']);
531 $this->assertEquals(3, $result['totalcount']);
532 $this->assertEquals($entry12, $result['entries'][0]['id']);
534 // Now test the return contents.
535 data_generate_default_template($this->database, 'listtemplate', 0, false, true); // Generate a default list template.
536 $result = mod_data_external::get_entries($this->database->id, $this->group1->id, true, null, null, 0, 2);
537 $result = external_api::clean_returnvalue(mod_data_external::get_entries_returns(), $result);
538 $this->assertCount(0, $result['warnings']);
539 $this->assertCount(2, $result['entries']);
540 $this->assertEquals(3, $result['totalcount']);
541 $this->assertCount(9, $result['entries'][0]['contents']);
542 $this->assertCount(9, $result['entries'][1]['contents']);
543 // Search for some content.
544 $this->assertTrue(strpos($result['listviewcontents'], 'opt1') !== false);
545 $this->assertTrue(strpos($result['listviewcontents'], 'January') !== false);
546 $this->assertTrue(strpos($result['listviewcontents'], 'menu1') !== false);
547 $this->assertTrue(strpos($result['listviewcontents'], 'text for testing') !== false);
548 $this->assertTrue(strpos($result['listviewcontents'], 'sampleurl') !== false);
552 * Test get_entry_visible_groups.
554 public function test_get_entry_visible_groups() {
557 $DB->set_field('course', 'groupmode', VISIBLEGROUPS, ['id' => $this->course->id]);
558 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
560 // Check I can see my approved group entries.
561 $this->setUser($this->student1);
562 $result = mod_data_external::get_entry($entry11);
563 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
564 $this->assertCount(0, $result['warnings']);
565 $this->assertEquals($entry11, $result['entry']['id']);
566 $this->assertTrue($result['entry']['approved']);
567 $this->assertTrue($result['entry']['canmanageentry']); // Is mine, I can manage it.
569 // Entry from other group.
570 $result = mod_data_external::get_entry($entry21);
571 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
572 $this->assertCount(0, $result['warnings']);
573 $this->assertEquals($entry21, $result['entry']['id']);
577 * Test get_entry_separated_groups.
579 public function test_get_entry_separated_groups() {
581 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
583 // Check I can see my approved group entries.
584 $this->setUser($this->student1);
585 $result = mod_data_external::get_entry($entry11);
586 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
587 $this->assertCount(0, $result['warnings']);
588 $this->assertEquals($entry11, $result['entry']['id']);
589 $this->assertTrue($result['entry']['approved']);
590 $this->assertTrue($result['entry']['canmanageentry']); // Is mine, I can manage it.
592 // Retrieve contents.
593 data_generate_default_template($this->database, 'singletemplate', 0, false, true);
594 $result = mod_data_external::get_entry($entry11, true);
595 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
596 $this->assertCount(0, $result['warnings']);
597 $this->assertCount(9, $result['entry']['contents']);
598 $this->assertTrue(strpos($result['entryviewcontents'], 'opt1') !== false);
599 $this->assertTrue(strpos($result['entryviewcontents'], 'January') !== false);
600 $this->assertTrue(strpos($result['entryviewcontents'], 'menu1') !== false);
601 $this->assertTrue(strpos($result['entryviewcontents'], 'text for testing') !== false);
602 $this->assertTrue(strpos($result['entryviewcontents'], 'sampleurl') !== false);
604 // This is in my group but I'm not the author.
605 $result = mod_data_external::get_entry($entry12);
606 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
607 $this->assertCount(0, $result['warnings']);
608 $this->assertEquals($entry12, $result['entry']['id']);
609 $this->assertTrue($result['entry']['approved']);
610 $this->assertFalse($result['entry']['canmanageentry']); // Not mine.
612 $this->setUser($this->student3);
613 $result = mod_data_external::get_entry($entry21);
614 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
615 $this->assertCount(0, $result['warnings']);
616 $this->assertEquals($entry21, $result['entry']['id']);
617 $this->assertTrue($result['entry']['approved']);
618 $this->assertTrue($result['entry']['canmanageentry']); // Is mine, I can manage it.
620 // As teacher I should be able to see all the entries.
621 $this->setUser($this->teacher);
622 $result = mod_data_external::get_entry($entry11);
623 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
624 $this->assertEquals($entry11, $result['entry']['id']);
626 $result = mod_data_external::get_entry($entry12);
627 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
628 $this->assertEquals($entry12, $result['entry']['id']);
629 // This is the not approved one.
630 $result = mod_data_external::get_entry($entry13);
631 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
632 $this->assertEquals($entry13, $result['entry']['id']);
634 $result = mod_data_external::get_entry($entry21);
635 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
636 $this->assertEquals($entry21, $result['entry']['id']);
638 // Now, try to get an entry not approved yet.
639 $this->setUser($this->student1);
640 $this->expectException('moodle_exception');
641 $result = mod_data_external::get_entry($entry13);
645 * Test get_entry from other group in separated groups.
647 public function test_get_entry_other_group_separated_groups() {
648 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
650 // We should not be able to view other gropu entries (in separated groups).
651 $this->setUser($this->student1);
652 $this->expectException('moodle_exception');
653 $result = mod_data_external::get_entry($entry21);
659 public function test_get_fields() {
661 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
663 $this->setUser($this->student1);
664 $result = mod_data_external::get_fields($this->database->id);
665 $result = external_api::clean_returnvalue(mod_data_external::get_fields_returns(), $result);
667 // Basically compare we retrieve all the fields and the correct values.
668 $fields = $DB->get_records('data_fields', array('dataid' => $this->database->id), 'id');
669 foreach ($result['fields'] as $field) {
670 $this->assertEquals($field, (array) $fields[$field['id']]);
675 * Test get_fields_database_without_fields.
677 public function test_get_fields_database_without_fields() {
679 $this->setUser($this->student1);
680 $result = mod_data_external::get_fields($this->database->id);
681 $result = external_api::clean_returnvalue(mod_data_external::get_fields_returns(), $result);
683 $this->assertEmpty($result['fields']);
687 * Test search_entries.
689 public function test_search_entries() {
691 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
693 $this->setUser($this->student1);
694 // Empty search, it should return all the visible entries.
695 $result = mod_data_external::search_entries($this->database->id, 0, false);
696 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
697 $this->assertCount(3, $result['entries']);
698 $this->assertEquals(3, $result['totalcount']);
700 // Search for something that does not exists.
701 $result = mod_data_external::search_entries($this->database->id, 0, false, 'abc');
702 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
703 $this->assertCount(0, $result['entries']);
704 $this->assertEquals(0, $result['totalcount']);
706 // Search by text matching all the entries.
707 $result = mod_data_external::search_entries($this->database->id, 0, false, 'text');
708 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
709 $this->assertCount(3, $result['entries']);
710 $this->assertEquals(3, $result['totalcount']);
711 $this->assertEquals(3, $result['maxcount']);
713 // Now as the other student I should receive my not approved entry. Apply ordering here.
714 $this->setUser($this->student2);
715 $result = mod_data_external::search_entries($this->database->id, 0, false, 'text', [], DATA_APPROVED, 'ASC');
716 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
717 $this->assertCount(4, $result['entries']);
718 $this->assertEquals(4, $result['totalcount']);
719 $this->assertEquals(4, $result['maxcount']);
720 // The not approved one should be the first.
721 $this->assertEquals($entry13, $result['entries'][0]['id']);
723 // Now as the other group student.
724 $this->setUser($this->student3);
725 $result = mod_data_external::search_entries($this->database->id, 0, false, 'text');
726 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
727 $this->assertCount(2, $result['entries']);
728 $this->assertEquals(2, $result['totalcount']);
729 $this->assertEquals(2, $result['maxcount']);
730 $this->assertEquals($this->student2->id, $result['entries'][0]['userid']);
731 $this->assertEquals($this->student3->id, $result['entries'][1]['userid']);
733 // Same normal text search as teacher.
734 $this->setUser($this->teacher);
735 $result = mod_data_external::search_entries($this->database->id, 0, false, 'text');
736 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
737 $this->assertCount(5, $result['entries']); // I can see all groups and non approved.
738 $this->assertEquals(5, $result['totalcount']);
739 $this->assertEquals(5, $result['maxcount']);
742 $this->setUser($this->teacher);
743 $result = mod_data_external::search_entries($this->database->id, 0, false, 'text', [], DATA_TIMEADDED, 'ASC', 0, 2);
744 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
745 $this->assertCount(2, $result['entries']); // Only 2 per page.
746 $this->assertEquals(5, $result['totalcount']);
747 $this->assertEquals(5, $result['maxcount']);
749 // Now advanced search or not dinamic fields (user firstname for example).
750 $this->setUser($this->student1);
752 ['name' => 'fn', 'value' => json_encode($this->student2->firstname)]
754 $result = mod_data_external::search_entries($this->database->id, 0, false, '', $advsearch);
755 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
756 $this->assertCount(2, $result['entries']);
757 $this->assertEquals(2, $result['totalcount']);
758 $this->assertEquals(3, $result['maxcount']);
759 $this->assertEquals($this->student2->id, $result['entries'][0]['userid']); // I only found mine!
761 // Advanced search for fields.
762 $field = $DB->get_record('data_fields', array('type' => 'url'));
764 ['name' => 'f_' . $field->id , 'value' => 'sampleurl']
766 $result = mod_data_external::search_entries($this->database->id, 0, false, '', $advsearch);
767 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
768 $this->assertCount(3, $result['entries']); // Found two entries matching this.
769 $this->assertEquals(3, $result['totalcount']);
770 $this->assertEquals(3, $result['maxcount']);
773 $field2 = $DB->get_record('data_fields', array('type' => 'number'));
775 ['name' => 'f_' . $field->id , 'value' => 'sampleurl'],
776 ['name' => 'f_' . $field2->id , 'value' => '12345'],
777 ['name' => 'ln', 'value' => json_encode($this->student2->lastname)]
779 $result = mod_data_external::search_entries($this->database->id, 0, false, '', $advsearch);
780 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
781 $this->assertCount(2, $result['entries']); // Only one matching everything.
782 $this->assertEquals(2, $result['totalcount']);
783 $this->assertEquals(3, $result['maxcount']);
785 // Combined search (no results).
786 $field2 = $DB->get_record('data_fields', array('type' => 'number'));
788 ['name' => 'f_' . $field->id , 'value' => 'sampleurl'],
789 ['name' => 'f_' . $field2->id , 'value' => '98780333'], // Non existent number.
791 $result = mod_data_external::search_entries($this->database->id, 0, false, '', $advsearch);
792 $result = external_api::clean_returnvalue(mod_data_external::search_entries_returns(), $result);
793 $this->assertCount(0, $result['entries']); // Only one matching everything.
794 $this->assertEquals(0, $result['totalcount']);
795 $this->assertEquals(3, $result['maxcount']);
799 * Test approve_entry.
801 public function test_approve_entry() {
803 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
805 $this->setUser($this->teacher);
806 $this->assertEquals(0, $DB->get_field('data_records', 'approved', array('id' => $entry13)));
807 $result = mod_data_external::approve_entry($entry13);
808 $result = external_api::clean_returnvalue(mod_data_external::approve_entry_returns(), $result);
809 $this->assertEquals(1, $DB->get_field('data_records', 'approved', array('id' => $entry13)));
813 * Test unapprove_entry.
815 public function test_unapprove_entry() {
817 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
819 $this->setUser($this->teacher);
820 $this->assertEquals(1, $DB->get_field('data_records', 'approved', array('id' => $entry11)));
821 $result = mod_data_external::approve_entry($entry11, false);
822 $result = external_api::clean_returnvalue(mod_data_external::approve_entry_returns(), $result);
823 $this->assertEquals(0, $DB->get_field('data_records', 'approved', array('id' => $entry11)));
827 * Test approve_entry missing permissions.
829 public function test_approve_entry_missing_permissions() {
831 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
833 $this->setUser($this->student1);
834 $this->expectException('moodle_exception');
835 mod_data_external::approve_entry($entry13);
839 * Test delete_entry as teacher. Check I can delete any entry.
841 public function test_delete_entry_as_teacher() {
843 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
845 $this->setUser($this->teacher);
846 $result = mod_data_external::delete_entry($entry11);
847 $result = external_api::clean_returnvalue(mod_data_external::delete_entry_returns(), $result);
848 $this->assertEquals(0, $DB->count_records('data_records', array('id' => $entry11)));
850 // Entry in other group.
851 $result = mod_data_external::delete_entry($entry21);
852 $result = external_api::clean_returnvalue(mod_data_external::delete_entry_returns(), $result);
853 $this->assertEquals(0, $DB->count_records('data_records', array('id' => $entry21)));
857 * Test delete_entry as student. Check I can delete my own entries.
859 public function test_delete_entry_as_student() {
861 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
863 $this->setUser($this->student1);
864 $result = mod_data_external::delete_entry($entry11);
865 $result = external_api::clean_returnvalue(mod_data_external::delete_entry_returns(), $result);
866 $this->assertEquals(0, $DB->count_records('data_records', array('id' => $entry11)));
870 * Test delete_entry as student in read only mode period. Check I cannot delete my own entries in that period.
872 public function test_delete_entry_as_student_in_read_only_period() {
874 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
875 // Set a time period.
876 $this->database->timeviewfrom = time() - HOURSECS;
877 $this->database->timeviewto = time() + HOURSECS;
878 $DB->update_record('data', $this->database);
880 $this->setUser($this->student1);
881 $this->expectException('moodle_exception');
882 mod_data_external::delete_entry($entry11);
886 * Test delete_entry with an user missing permissions.
888 public function test_delete_entry_missing_permissions() {
890 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
892 $this->setUser($this->student1);
893 $this->expectException('moodle_exception');
894 mod_data_external::delete_entry($entry21);
900 public function test_add_entry() {
902 // First create the record structure and add some entries.
903 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
905 $this->setUser($this->student1);
907 $fields = $DB->get_records('data_fields', array('dataid' => $this->database->id), 'id');
908 // Prepare the new entry data.
909 foreach ($fields as $field) {
910 $subfield = $value = '';
912 switch ($field->type) {
914 $value = ['opt1', 'opt2'];
919 'fieldid' => $field->id,
921 'value' => json_encode('5')
924 'fieldid' => $field->id,
925 'subfield' => 'month',
926 'value' => json_encode('1')
935 $value = ['multimenu1', 'multimenu4'];
941 $value = 'radioopt1';
944 $value = 'some text';
948 'fieldid' => $field->id,
949 'subfield' => 'content1',
950 'value' => json_encode(FORMAT_MOODLE)
953 'fieldid' => $field->id,
954 'subfield' => 'itemid',
955 'value' => json_encode(0)
957 $value = 'more text';
960 $value = 'https://moodle.org';
966 'fieldid' => $field->id,
967 'subfield' => $subfield,
968 'value' => json_encode($value)
971 $result = mod_data_external::add_entry($this->database->id, 0, $newentrydata);
972 $result = external_api::clean_returnvalue(mod_data_external::add_entry_returns(), $result);
974 $newentryid = $result['newentryid'];
975 $result = mod_data_external::get_entry($newentryid, true);
976 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
977 $this->assertEquals($this->student1->id, $result['entry']['userid']);
978 $this->assertCount(9, $result['entry']['contents']);
979 foreach ($result['entry']['contents'] as $content) {
980 $field = $fields[$content['fieldid']];
981 // Stored content same that the one retrieved by WS.
982 $dbcontent = $DB->get_record('data_content', array('fieldid' => $field->id, 'recordid' => $newentryid));
983 $this->assertEquals($dbcontent->content, $content['content']);
985 // Now double check everything stored is correct.
986 if ($field->type == 'checkbox') {
987 $this->assertEquals('opt1##opt2', $content['content']);
990 if ($field->type == 'date') {
991 $this->assertEquals(347500800, $content['content']); // Date in gregorian format.
994 if ($field->type == 'menu') {
995 $this->assertEquals('menu1', $content['content']);
998 if ($field->type == 'multimenu') {
999 $this->assertEquals('multimenu1##multimenu4', $content['content']);
1002 if ($field->type == 'number') {
1003 $this->assertEquals(6, $content['content']);
1006 if ($field->type == 'radiobutton') {
1007 $this->assertEquals('radioopt1', $content['content']);
1010 if ($field->type == 'text') {
1011 $this->assertEquals('some text', $content['content']);
1014 if ($field->type == 'textarea') {
1015 $this->assertEquals('more text', $content['content']);
1016 $this->assertEquals(FORMAT_MOODLE, $content['content1']);
1019 if ($field->type == 'url') {
1020 $this->assertEquals('https://moodle.org', $content['content']);
1023 $this->assertEquals('multimenu1##multimenu4', $content['content']);
1026 // Now, try to add another entry but removing some required data.
1027 unset($newentrydata[0]);
1028 $result = mod_data_external::add_entry($this->database->id, 0, $newentrydata);
1029 $result = external_api::clean_returnvalue(mod_data_external::add_entry_returns(), $result);
1030 $this->assertEquals(0, $result['newentryid']);
1031 $this->assertCount(0, $result['generalnotifications']);
1032 $this->assertCount(1, $result['fieldnotifications']);
1033 $this->assertEquals('field-1', $result['fieldnotifications'][0]['fieldname']);
1034 $this->assertEquals(get_string('errormustsupplyvalue', 'data'), $result['fieldnotifications'][0]['notification']);
1038 * Test add_entry empty_form.
1040 public function test_add_entry_empty_form() {
1041 $result = mod_data_external::add_entry($this->database->id, 0, []);
1042 $result = external_api::clean_returnvalue(mod_data_external::add_entry_returns(), $result);
1043 $this->assertEquals(0, $result['newentryid']);
1044 $this->assertCount(1, $result['generalnotifications']);
1045 $this->assertCount(0, $result['fieldnotifications']);
1046 $this->assertEquals(get_string('emptyaddform', 'data'), $result['generalnotifications'][0]);
1050 * Test add_entry read_only_period.
1052 public function test_add_entry_read_only_period() {
1054 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1055 // Set a time period.
1056 $this->database->timeviewfrom = time() - HOURSECS;
1057 $this->database->timeviewto = time() + HOURSECS;
1058 $DB->update_record('data', $this->database);
1060 $this->setUser($this->student1);
1061 $this->expectExceptionMessage(get_string('noaccess', 'data'));
1062 $this->expectException('moodle_exception');
1063 mod_data_external::add_entry($this->database->id, 0, []);
1067 * Test add_entry max_num_entries.
1069 public function test_add_entry_max_num_entries() {
1071 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1072 // Set a time period.
1073 $this->database->maxentries = 1;
1074 $DB->update_record('data', $this->database);
1076 $this->setUser($this->student1);
1077 $this->expectExceptionMessage(get_string('noaccess', 'data'));
1078 $this->expectException('moodle_exception');
1079 mod_data_external::add_entry($this->database->id, 0, []);
1083 * Test update_entry.
1085 public function test_update_entry() {
1087 // First create the record structure and add some entries.
1088 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1090 $this->setUser($this->student1);
1092 $fields = $DB->get_records('data_fields', array('dataid' => $this->database->id), 'id');
1093 // Prepare the new entry data.
1094 foreach ($fields as $field) {
1095 $subfield = $value = '';
1097 switch ($field->type) {
1099 $value = ['opt1', 'opt2'];
1104 'fieldid' => $field->id,
1105 'subfield' => 'day',
1106 'value' => json_encode('5')
1109 'fieldid' => $field->id,
1110 'subfield' => 'month',
1111 'value' => json_encode('1')
1120 $value = ['multimenu1', 'multimenu4'];
1126 $value = 'radioopt2';
1129 $value = 'some text';
1133 'fieldid' => $field->id,
1134 'subfield' => 'content1',
1135 'value' => json_encode(FORMAT_MOODLE)
1138 'fieldid' => $field->id,
1139 'subfield' => 'itemid',
1140 'value' => json_encode(0)
1142 $value = 'more text';
1145 $value = 'https://moodle.org';
1151 'fieldid' => $field->id,
1152 'subfield' => $subfield,
1153 'value' => json_encode($value)
1156 $result = mod_data_external::update_entry($entry11, $newentrydata);
1157 $result = external_api::clean_returnvalue(mod_data_external::update_entry_returns(), $result);
1158 $this->assertTrue($result['updated']);
1159 $this->assertCount(0, $result['generalnotifications']);
1160 $this->assertCount(0, $result['fieldnotifications']);
1162 $result = mod_data_external::get_entry($entry11, true);
1163 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
1164 $this->assertEquals($this->student1->id, $result['entry']['userid']);
1165 $this->assertCount(9, $result['entry']['contents']);
1166 foreach ($result['entry']['contents'] as $content) {
1167 $field = $fields[$content['fieldid']];
1168 // Stored content same that the one retrieved by WS.
1169 $dbcontent = $DB->get_record('data_content', array('fieldid' => $field->id, 'recordid' => $entry11));
1170 $this->assertEquals($dbcontent->content, $content['content']);
1172 // Now double check everything stored is correct.
1173 if ($field->type == 'checkbox') {
1174 $this->assertEquals('opt1##opt2', $content['content']);
1177 if ($field->type == 'date') {
1178 $this->assertEquals(347500800, $content['content']); // Date in gregorian format.
1181 if ($field->type == 'menu') {
1182 $this->assertEquals('menu1', $content['content']);
1185 if ($field->type == 'multimenu') {
1186 $this->assertEquals('multimenu1##multimenu4', $content['content']);
1189 if ($field->type == 'number') {
1190 $this->assertEquals(6, $content['content']);
1193 if ($field->type == 'radiobutton') {
1194 $this->assertEquals('radioopt2', $content['content']);
1197 if ($field->type == 'text') {
1198 $this->assertEquals('some text', $content['content']);
1201 if ($field->type == 'textarea') {
1202 $this->assertEquals('more text', $content['content']);
1203 $this->assertEquals(FORMAT_MOODLE, $content['content1']);
1206 if ($field->type == 'url') {
1207 $this->assertEquals('https://moodle.org', $content['content']);
1210 $this->assertEquals('multimenu1##multimenu4', $content['content']);
1213 // Now, try to update the entry but removing some required data.
1214 unset($newentrydata[0]);
1215 $result = mod_data_external::update_entry($entry11, $newentrydata);
1216 $result = external_api::clean_returnvalue(mod_data_external::update_entry_returns(), $result);
1217 $this->assertFalse($result['updated']);
1218 $this->assertCount(0, $result['generalnotifications']);
1219 $this->assertCount(1, $result['fieldnotifications']);
1220 $this->assertEquals('field-1', $result['fieldnotifications'][0]['fieldname']);
1221 $this->assertEquals(get_string('errormustsupplyvalue', 'data'), $result['fieldnotifications'][0]['notification']);
1225 * Test update_entry sending empty data.
1227 public function test_update_entry_empty_data() {
1228 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1230 $this->setUser($this->student1);
1231 $result = mod_data_external::update_entry($entry11, []);
1232 $result = external_api::clean_returnvalue(mod_data_external::update_entry_returns(), $result);
1233 $this->assertFalse($result['updated']);
1234 $this->assertCount(1, $result['generalnotifications']);
1235 $this->assertCount(9, $result['fieldnotifications']);
1236 $this->assertEquals(get_string('emptyaddform', 'data'), $result['generalnotifications'][0]);
1240 * Test update_entry in read only period.
1242 public function test_update_entry_read_only_period() {
1244 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1245 // Set a time period.
1246 $this->database->timeviewfrom = time() - HOURSECS;
1247 $this->database->timeviewto = time() + HOURSECS;
1248 $DB->update_record('data', $this->database);
1250 $this->setUser($this->student1);
1251 $this->expectExceptionMessage(get_string('noaccess', 'data'));
1252 $this->expectException('moodle_exception');
1253 mod_data_external::update_entry($entry11, []);
1257 * Test update_entry other_user.
1259 public function test_update_entry_other_user() {
1260 // Try to update other user entry.
1261 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1262 $this->setUser($this->student2);
1263 $this->expectExceptionMessage(get_string('noaccess', 'data'));
1264 $this->expectException('moodle_exception');
1265 mod_data_external::update_entry($entry11, []);
1269 * Test get_entry_rating_information.
1271 public function test_get_entry_rating_information() {
1273 require_once($CFG->dirroot . '/rating/lib.php');
1275 $DB->set_field('data', 'assessed', RATING_AGGREGATE_SUM, array('id' => $this->database->id));
1276 $DB->set_field('data', 'scale', 100, array('id' => $this->database->id));
1277 list($entry11, $entry12, $entry13, $entry14, $entry21) = self::populate_database_with_entries();
1279 $user1 = self::getDataGenerator()->create_user();
1280 $user2 = self::getDataGenerator()->create_user();
1281 $this->getDataGenerator()->enrol_user($user1->id, $this->course->id, $this->studentrole->id, 'manual');
1282 $this->getDataGenerator()->enrol_user($user2->id, $this->course->id, $this->studentrole->id, 'manual');
1284 // Rate the entry as user1.
1285 $rating1 = new stdClass();
1286 $rating1->contextid = $this->context->id;
1287 $rating1->component = 'mod_data';
1288 $rating1->ratingarea = 'entry';
1289 $rating1->itemid = $entry11;
1290 $rating1->rating = 50;
1291 $rating1->scaleid = 100;
1292 $rating1->userid = $user1->id;
1293 $rating1->timecreated = time();
1294 $rating1->timemodified = time();
1295 $rating1->id = $DB->insert_record('rating', $rating1);
1297 // Rate the entry as user2.
1298 $rating2 = new stdClass();
1299 $rating2->contextid = $this->context->id;
1300 $rating2->component = 'mod_data';
1301 $rating2->ratingarea = 'entry';
1302 $rating2->itemid = $entry11;
1303 $rating2->rating = 100;
1304 $rating2->scaleid = 100;
1305 $rating2->userid = $user2->id;
1306 $rating2->timecreated = time() + 1;
1307 $rating2->timemodified = time() + 1;
1308 $rating2->id = $DB->insert_record('rating', $rating2);
1310 // As student, retrieve ratings information.
1311 $this->setUser($this->student2);
1312 $result = mod_data_external::get_entry($entry11);
1313 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
1314 $this->assertCount(1, $result['ratinginfo']['ratings']);
1315 $this->assertFalse($result['ratinginfo']['ratings'][0]['canviewaggregate']);
1316 $this->assertFalse($result['ratinginfo']['canviewall']);
1317 $this->assertFalse($result['ratinginfo']['ratings'][0]['canrate']);
1318 $this->assertTrue(!isset($result['ratinginfo']['ratings'][0]['count']));
1320 // Now, as teacher, I should see the info correctly.
1321 $this->setUser($this->teacher);
1322 $result = mod_data_external::get_entry($entry11);
1323 $result = external_api::clean_returnvalue(mod_data_external::get_entry_returns(), $result);
1324 $this->assertCount(1, $result['ratinginfo']['ratings']);
1325 $this->assertTrue($result['ratinginfo']['ratings'][0]['canviewaggregate']);
1326 $this->assertTrue($result['ratinginfo']['canviewall']);
1327 $this->assertTrue($result['ratinginfo']['ratings'][0]['canrate']);
1328 $this->assertEquals(2, $result['ratinginfo']['ratings'][0]['count']);
1329 $this->assertEquals(100, $result['ratinginfo']['ratings'][0]['aggregate']); // Expect maximium scale value.