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 * Unit tests for lib.php
22 * @copyright 2013 Adrian Greeve
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->dirroot . '/mod/data/lib.php');
32 * Unit tests for lib.php
35 * @copyright 2013 Adrian Greeve
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 class mod_data_lib_testcase extends advanced_testcase {
41 * @var moodle_database
46 * Tear Down to reset DB.
48 public function tearDown() {
51 if (isset($this->DB)) {
58 * Confirms that completionentries is working
59 * Sets it to 1, confirms that
60 * it is not complete. Inserts a record and
61 * confirms that it is complete.
63 public function test_data_completion() {
65 $this->resetAfterTest();
66 $this->setAdminUser();
67 $CFG->enablecompletion = 1;
68 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
69 $record = new stdClass();
70 $record->course = $course->id;
71 $record->name = "Mod data completion test";
72 $record->intro = "Some intro of some sort";
73 $record->completionentries = "1";
74 /* completion=2 means Show activity commplete when condition is met and completionentries means 1 record is
75 * required for the activity to be considered complete
77 $module = $this->getDataGenerator()->create_module('data', $record, array('completion' => 2, 'completionentries' => 1));
79 $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
80 $completion = new completion_info($course);
81 $completiondata = $completion->get_data($cm, true, 0);
82 /* Confirm it is not complete as there are no entries */
83 $this->assertNotEquals(1, $completiondata->completionstate);
85 $field = data_get_field_new('text', $module);
86 $fielddetail = new stdClass();
87 $fielddetail->d = $module->id;
88 $fielddetail->mode = 'add';
89 $fielddetail->type = 'text';
90 $fielddetail->sesskey = sesskey();
91 $fielddetail->name = 'Name';
92 $fielddetail->description = 'Some name';
94 $field->define_field($fielddetail);
95 $field->insert_field();
96 $recordid = data_add_record($module);
98 $datacontent = array();
99 $datacontent['fieldid'] = $field->field->id;
100 $datacontent['recordid'] = $recordid;
101 $datacontent['content'] = 'Asterix';
102 $contentid = $DB->insert_record('data_content', $datacontent);
104 $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
105 $completion = new completion_info($course);
106 $completiondata = $completion->get_data($cm);
107 /* Confirm it is complete because it has 1 entry */
108 $this->assertEquals(1, $completiondata->completionstate);
111 public function test_data_delete_record() {
114 $this->resetAfterTest();
116 // Create a record for deleting.
117 $this->setAdminUser();
118 $course = $this->getDataGenerator()->create_course();
119 $record = new stdClass();
120 $record->course = $course->id;
121 $record->name = "Mod data delete test";
122 $record->intro = "Some intro of some sort";
124 $module = $this->getDataGenerator()->create_module('data', $record);
126 $field = data_get_field_new('text', $module);
128 $fielddetail = new stdClass();
129 $fielddetail->d = $module->id;
130 $fielddetail->mode = 'add';
131 $fielddetail->type = 'text';
132 $fielddetail->sesskey = sesskey();
133 $fielddetail->name = 'Name';
134 $fielddetail->description = 'Some name';
136 $field->define_field($fielddetail);
137 $field->insert_field();
138 $recordid = data_add_record($module);
140 $datacontent = array();
141 $datacontent['fieldid'] = $field->field->id;
142 $datacontent['recordid'] = $recordid;
143 $datacontent['content'] = 'Asterix';
145 $contentid = $DB->insert_record('data_content', $datacontent);
146 $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
148 // Check to make sure that we have a database record.
149 $data = $DB->get_records('data', array('id' => $module->id));
150 $this->assertEquals(1, count($data));
152 $datacontent = $DB->get_records('data_content', array('id' => $contentid));
153 $this->assertEquals(1, count($datacontent));
155 $datafields = $DB->get_records('data_fields', array('id' => $field->field->id));
156 $this->assertEquals(1, count($datafields));
158 $datarecords = $DB->get_records('data_records', array('id' => $recordid));
159 $this->assertEquals(1, count($datarecords));
161 // Test to see if a failed delete returns false.
162 $result = data_delete_record(8798, $module, $course->id, $cm->id);
163 $this->assertFalse($result);
165 // Delete the record.
166 $result = data_delete_record($recordid, $module, $course->id, $cm->id);
168 // Check that all of the record is gone.
169 $datacontent = $DB->get_records('data_content', array('id' => $contentid));
170 $this->assertEquals(0, count($datacontent));
172 $datarecords = $DB->get_records('data_records', array('id' => $recordid));
173 $this->assertEquals(0, count($datarecords));
175 // Make sure the function returns true on a successful deletion.
176 $this->assertTrue($result);
180 * Test comment_created event.
182 public function test_data_comment_created_event() {
184 require_once($CFG->dirroot . '/comment/lib.php');
186 $this->resetAfterTest();
188 // Create a record for deleting.
189 $this->setAdminUser();
190 $course = $this->getDataGenerator()->create_course();
191 $record = new stdClass();
192 $record->course = $course->id;
193 $record->name = "Mod data delete test";
194 $record->intro = "Some intro of some sort";
195 $record->comments = 1;
197 $module = $this->getDataGenerator()->create_module('data', $record);
198 $field = data_get_field_new('text', $module);
200 $fielddetail = new stdClass();
201 $fielddetail->name = 'Name';
202 $fielddetail->description = 'Some name';
204 $field->define_field($fielddetail);
205 $field->insert_field();
206 $recordid = data_add_record($module);
208 $datacontent = array();
209 $datacontent['fieldid'] = $field->field->id;
210 $datacontent['recordid'] = $recordid;
211 $datacontent['content'] = 'Asterix';
213 $contentid = $DB->insert_record('data_content', $datacontent);
214 $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
216 $context = context_module::instance($module->cmid);
217 $cmt = new stdClass();
218 $cmt->context = $context;
219 $cmt->course = $course;
221 $cmt->area = 'database_entry';
222 $cmt->itemid = $recordid;
223 $cmt->showcount = true;
224 $cmt->component = 'mod_data';
225 $comment = new comment($cmt);
227 // Triggering and capturing the event.
228 $sink = $this->redirectEvents();
229 $comment->add('New comment');
230 $events = $sink->get_events();
231 $this->assertCount(1, $events);
232 $event = reset($events);
234 // Checking that the event contains the expected values.
235 $this->assertInstanceOf('\mod_data\event\comment_created', $event);
236 $this->assertEquals($context, $event->get_context());
237 $url = new moodle_url('/mod/data/view.php', array('id' => $cm->id));
238 $this->assertEquals($url, $event->get_url());
239 $this->assertEventContextNotUsed($event);
243 * Test comment_deleted event.
245 public function test_data_comment_deleted_event() {
247 require_once($CFG->dirroot . '/comment/lib.php');
249 $this->resetAfterTest();
251 // Create a record for deleting.
252 $this->setAdminUser();
253 $course = $this->getDataGenerator()->create_course();
254 $record = new stdClass();
255 $record->course = $course->id;
256 $record->name = "Mod data delete test";
257 $record->intro = "Some intro of some sort";
258 $record->comments = 1;
260 $module = $this->getDataGenerator()->create_module('data', $record);
261 $field = data_get_field_new('text', $module);
263 $fielddetail = new stdClass();
264 $fielddetail->name = 'Name';
265 $fielddetail->description = 'Some name';
267 $field->define_field($fielddetail);
268 $field->insert_field();
269 $recordid = data_add_record($module);
271 $datacontent = array();
272 $datacontent['fieldid'] = $field->field->id;
273 $datacontent['recordid'] = $recordid;
274 $datacontent['content'] = 'Asterix';
276 $contentid = $DB->insert_record('data_content', $datacontent);
277 $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
279 $context = context_module::instance($module->cmid);
280 $cmt = new stdClass();
281 $cmt->context = $context;
282 $cmt->course = $course;
284 $cmt->area = 'database_entry';
285 $cmt->itemid = $recordid;
286 $cmt->showcount = true;
287 $cmt->component = 'mod_data';
288 $comment = new comment($cmt);
289 $newcomment = $comment->add('New comment 1');
291 // Triggering and capturing the event.
292 $sink = $this->redirectEvents();
293 $comment->delete($newcomment->id);
294 $events = $sink->get_events();
295 $this->assertCount(1, $events);
296 $event = reset($events);
298 // Checking that the event contains the expected values.
299 $this->assertInstanceOf('\mod_data\event\comment_deleted', $event);
300 $this->assertEquals($context, $event->get_context());
301 $url = new moodle_url('/mod/data/view.php', array('id' => $module->cmid));
302 $this->assertEquals($url, $event->get_url());
303 $this->assertEventContextNotUsed($event);
307 * Checks that data_user_can_manage_entry will return true if the user
308 * has the mod/data:manageentries capability.
310 public function test_data_user_can_manage_entry_return_true_with_capability() {
312 $this->resetAfterTest();
313 $testdata = $this->create_user_test_data();
315 $user = $testdata['user'];
316 $course = $testdata['course'];
317 $roleid = $testdata['roleid'];
318 $context = $testdata['context'];
319 $record = $testdata['record'];
320 $data = new stdClass();
322 $this->setUser($user);
324 assign_capability('mod/data:manageentries', CAP_ALLOW, $roleid, $context);
326 $this->assertTrue(data_user_can_manage_entry($record, $data, $context),
327 'data_user_can_manage_entry() returns true if the user has mod/data:manageentries capability');
331 * Checks that data_user_can_manage_entry will return false if the data
332 * is set to readonly.
334 public function test_data_user_can_manage_entry_return_false_readonly() {
336 $this->resetAfterTest();
337 $testdata = $this->create_user_test_data();
339 $user = $testdata['user'];
340 $course = $testdata['course'];
341 $roleid = $testdata['roleid'];
342 $context = $testdata['context'];
343 $record = $testdata['record'];
345 $this->setUser($user);
347 // Need to make sure they don't have this capability in order to fall back to
349 assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
351 // Causes readonly mode to be enabled.
352 $data = new stdClass();
354 // Add a small margin around the periods to prevent errors with slow tests.
355 $data->timeviewfrom = $now - 1;
356 $data->timeviewto = $now + 5;
358 $this->assertFalse(data_user_can_manage_entry($record, $data, $context),
359 'data_user_can_manage_entry() returns false if the data is read only');
363 * Checks that data_user_can_manage_entry will return false if the record
364 * can't be found in the database.
366 public function test_data_user_can_manage_entry_return_false_no_record() {
368 $this->resetAfterTest();
369 $testdata = $this->create_user_test_data();
371 $user = $testdata['user'];
372 $course = $testdata['course'];
373 $roleid = $testdata['roleid'];
374 $context = $testdata['context'];
375 $record = $testdata['record'];
376 $data = new stdClass();
377 // Causes readonly mode to be disabled.
379 $data->timeviewfrom = $now + 100;
380 $data->timeviewto = $now - 100;
382 $this->setUser($user);
384 // Need to make sure they don't have this capability in order to fall back to
386 assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
388 // Pass record id instead of object to force DB lookup.
389 $this->assertFalse(data_user_can_manage_entry(1, $data, $context),
390 'data_user_can_manage_entry() returns false if the record cannot be found');
394 * Checks that data_user_can_manage_entry will return false if the record
395 * isn't owned by the user.
397 public function test_data_user_can_manage_entry_return_false_not_owned_record() {
399 $this->resetAfterTest();
400 $testdata = $this->create_user_test_data();
402 $user = $testdata['user'];
403 $course = $testdata['course'];
404 $roleid = $testdata['roleid'];
405 $context = $testdata['context'];
406 $record = $testdata['record'];
407 $data = new stdClass();
408 // Causes readonly mode to be disabled.
410 $data->timeviewfrom = $now + 100;
411 $data->timeviewto = $now - 100;
412 // Make sure the record isn't owned by this user.
413 $record->userid = $user->id + 1;
415 $this->setUser($user);
417 // Need to make sure they don't have this capability in order to fall back to
419 assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
421 $this->assertFalse(data_user_can_manage_entry($record, $data, $context),
422 'data_user_can_manage_entry() returns false if the record isnt owned by the user');
426 * Checks that data_user_can_manage_entry will return true if the data
427 * doesn't require approval.
429 public function test_data_user_can_manage_entry_return_true_data_no_approval() {
431 $this->resetAfterTest();
432 $testdata = $this->create_user_test_data();
434 $user = $testdata['user'];
435 $course = $testdata['course'];
436 $roleid = $testdata['roleid'];
437 $context = $testdata['context'];
438 $record = $testdata['record'];
439 $data = new stdClass();
440 // Causes readonly mode to be disabled.
442 $data->timeviewfrom = $now + 100;
443 $data->timeviewto = $now - 100;
444 // The record doesn't need approval.
445 $data->approval = false;
446 // Make sure the record is owned by this user.
447 $record->userid = $user->id;
449 $this->setUser($user);
451 // Need to make sure they don't have this capability in order to fall back to
453 assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
455 $this->assertTrue(data_user_can_manage_entry($record, $data, $context),
456 'data_user_can_manage_entry() returns true if the record doesnt require approval');
460 * Checks that data_user_can_manage_entry will return true if the record
461 * isn't yet approved.
463 public function test_data_user_can_manage_entry_return_true_record_unapproved() {
465 $this->resetAfterTest();
466 $testdata = $this->create_user_test_data();
468 $user = $testdata['user'];
469 $course = $testdata['course'];
470 $roleid = $testdata['roleid'];
471 $context = $testdata['context'];
472 $record = $testdata['record'];
473 $data = new stdClass();
474 // Causes readonly mode to be disabled.
476 $data->timeviewfrom = $now + 100;
477 $data->timeviewto = $now - 100;
478 // The record needs approval.
479 $data->approval = true;
480 // Make sure the record is owned by this user.
481 $record->userid = $user->id;
482 // The record hasn't yet been approved.
483 $record->approved = false;
485 $this->setUser($user);
487 // Need to make sure they don't have this capability in order to fall back to
489 assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
491 $this->assertTrue(data_user_can_manage_entry($record, $data, $context),
492 'data_user_can_manage_entry() returns true if the record is not yet approved');
496 * Checks that data_user_can_manage_entry will return the 'manageapproved'
497 * value if the record has already been approved.
499 public function test_data_user_can_manage_entry_return_manageapproved() {
501 $this->resetAfterTest();
502 $testdata = $this->create_user_test_data();
504 $user = $testdata['user'];
505 $course = $testdata['course'];
506 $roleid = $testdata['roleid'];
507 $context = $testdata['context'];
508 $record = $testdata['record'];
509 $data = new stdClass();
510 // Causes readonly mode to be disabled.
512 $data->timeviewfrom = $now + 100;
513 $data->timeviewto = $now - 100;
514 // The record needs approval.
515 $data->approval = true;
516 // Can the user managed approved records?
517 $data->manageapproved = false;
518 // Make sure the record is owned by this user.
519 $record->userid = $user->id;
520 // The record has been approved.
521 $record->approved = true;
523 $this->setUser($user);
525 // Need to make sure they don't have this capability in order to fall back to
527 assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
529 $canmanageentry = data_user_can_manage_entry($record, $data, $context);
531 // Make sure the result of the check is what ever the manageapproved setting
533 $this->assertEquals($data->manageapproved, $canmanageentry,
534 'data_user_can_manage_entry() returns the manageapproved setting on approved records');
538 * Helper method to create a set of test data for data_user_can_manage tests
540 * @return array contains user, course, roleid, module, context and record
542 private function create_user_test_data() {
543 $user = $this->getDataGenerator()->create_user();
544 $course = $this->getDataGenerator()->create_course();
545 $roleid = $this->getDataGenerator()->create_role();
546 $record = new stdClass();
547 $record->name = "test name";
548 $record->intro = "test intro";
549 $record->comments = 1;
550 $record->course = $course->id;
551 $record->userid = $user->id;
553 $module = $this->getDataGenerator()->create_module('data', $record);
554 $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
555 $context = context_module::instance($module->cmid);
557 $this->getDataGenerator()->role_assign($roleid, $user->id, $context->id);
564 'context' => $context,
570 * Tests for mod_data_rating_can_see_item_ratings().
572 * @throws coding_exception
573 * @throws rating_exception
575 public function test_mod_data_rating_can_see_item_ratings() {
578 $this->resetAfterTest();
581 $course = new stdClass();
582 $course->groupmode = SEPARATEGROUPS;
583 $course->groupmodeforce = true;
584 $course = $this->getDataGenerator()->create_course($course);
585 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id));
586 $cm = get_coursemodule_from_instance('data', $data->id);
587 $context = context_module::instance($cm->id);
590 $user1 = $this->getDataGenerator()->create_user();
591 $user2 = $this->getDataGenerator()->create_user();
592 $user3 = $this->getDataGenerator()->create_user();
593 $user4 = $this->getDataGenerator()->create_user();
596 $role = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST);
597 $this->getDataGenerator()->enrol_user($user1->id, $course->id, $role->id);
598 $this->getDataGenerator()->enrol_user($user2->id, $course->id, $role->id);
599 $this->getDataGenerator()->enrol_user($user3->id, $course->id, $role->id);
600 $this->getDataGenerator()->enrol_user($user4->id, $course->id, $role->id);
602 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
603 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
604 groups_add_member($group1, $user1);
605 groups_add_member($group1, $user2);
606 groups_add_member($group2, $user3);
607 groups_add_member($group2, $user4);
610 $field = data_get_field_new('text', $data);
612 $fielddetail = new stdClass();
613 $fielddetail->name = 'Name';
614 $fielddetail->description = 'Some name';
616 $field->define_field($fielddetail);
617 $field->insert_field();
619 // Add a record with a group id of zero (all participants).
620 $recordid1 = data_add_record($data, 0);
622 $datacontent = array();
623 $datacontent['fieldid'] = $field->field->id;
624 $datacontent['recordid'] = $recordid1;
625 $datacontent['content'] = 'Obelix';
626 $DB->insert_record('data_content', $datacontent);
628 $recordid = data_add_record($data, $group1->id);
630 $datacontent = array();
631 $datacontent['fieldid'] = $field->field->id;
632 $datacontent['recordid'] = $recordid;
633 $datacontent['content'] = 'Asterix';
634 $DB->insert_record('data_content', $datacontent);
636 // Now try to access it as various users.
637 unassign_capability('moodle/site:accessallgroups', $role->id);
638 // Eveyone should have access to the record with the group id of zero.
639 $params1 = array('contextid' => 2,
640 'component' => 'mod_data',
641 'ratingarea' => 'entry',
642 'itemid' => $recordid1,
645 $params = array('contextid' => 2,
646 'component' => 'mod_data',
647 'ratingarea' => 'entry',
648 'itemid' => $recordid,
651 $this->setUser($user1);
652 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
653 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
654 $this->setUser($user2);
655 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
656 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
657 $this->setUser($user3);
658 $this->assertFalse(mod_data_rating_can_see_item_ratings($params));
659 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
660 $this->setUser($user4);
661 $this->assertFalse(mod_data_rating_can_see_item_ratings($params));
662 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
664 // Now try with accessallgroups cap and make sure everything is visible.
665 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role->id, $context->id);
666 $this->setUser($user1);
667 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
668 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
669 $this->setUser($user2);
670 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
671 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
672 $this->setUser($user3);
673 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
674 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
675 $this->setUser($user4);
676 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
677 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
679 // Change group mode and verify visibility.
680 $course->groupmode = VISIBLEGROUPS;
681 $DB->update_record('course', $course);
682 unassign_capability('moodle/site:accessallgroups', $role->id);
683 $this->setUser($user1);
684 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
685 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
686 $this->setUser($user2);
687 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
688 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
689 $this->setUser($user3);
690 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
691 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
692 $this->setUser($user4);
693 $this->assertTrue(mod_data_rating_can_see_item_ratings($params));
694 $this->assertTrue(mod_data_rating_can_see_item_ratings($params1));
699 * Tests for mod_data_refresh_events.
701 public function test_data_refresh_events() {
703 $this->resetAfterTest();
704 $this->setAdminUser();
707 $timeclose = time() + 86400;
709 $course = $this->getDataGenerator()->create_course();
710 $generator = $this->getDataGenerator()->get_plugin_generator('mod_data');
711 $params['course'] = $course->id;
712 $params['timeavailablefrom'] = $timeopen;
713 $params['timeavailableto'] = $timeclose;
714 $data = $generator->create_instance($params);
716 // Normal case, with existing course.
717 $this->assertTrue(data_refresh_events($course->id));
718 $eventparams = array('modulename' => 'data', 'instance' => $data->id, 'eventtype' => 'open');
719 $openevent = $DB->get_record('event', $eventparams, '*', MUST_EXIST);
720 $this->assertEquals($openevent->timestart, $timeopen);
722 $eventparams = array('modulename' => 'data', 'instance' => $data->id, 'eventtype' => 'close');
723 $closeevent = $DB->get_record('event', $eventparams, '*', MUST_EXIST);
724 $this->assertEquals($closeevent->timestart, $timeclose);
725 // In case the course ID is passed as a numeric string.
726 $this->assertTrue(data_refresh_events('' . $course->id));
727 // Course ID not provided.
728 $this->assertTrue(data_refresh_events());
729 $eventparams = array('modulename' => 'data');
730 $events = $DB->get_records('event', $eventparams);
731 foreach ($events as $event) {
732 if ($event->modulename === 'data' && $event->instance === $data->id && $event->eventtype === 'open') {
733 $this->assertEquals($event->timestart, $timeopen);
735 if ($event->modulename === 'data' && $event->instance === $data->id && $event->eventtype === 'close') {
736 $this->assertEquals($event->timestart, $timeclose);
742 * Data provider for tests of data_get_config.
746 public function data_get_config_provider() {
747 $initialdata = (object) [
748 'template_foo' => true,
749 'template_bar' => false,
750 'template_baz' => null,
753 $database = (object) [
754 'config' => json_encode($initialdata),
758 'Return full dataset (no key/default)' => [
762 'Return full dataset (no default)' => [
766 'Return full dataset' => [
767 [$database, null, null],
770 'Return requested key only, value true, no default' => [
771 [$database, 'template_foo'],
774 'Return requested key only, value false, no default' => [
775 [$database, 'template_bar'],
778 'Return requested key only, value null, no default' => [
779 [$database, 'template_baz'],
782 'Return unknown key, value null, no default' => [
783 [$database, 'template_bum'],
786 'Return requested key only, value true, default null' => [
787 [$database, 'template_foo', null],
790 'Return requested key only, value false, default null' => [
791 [$database, 'template_bar', null],
794 'Return requested key only, value null, default null' => [
795 [$database, 'template_baz', null],
798 'Return unknown key, value null, default null' => [
799 [$database, 'template_bum', null],
802 'Return requested key only, value true, default 42' => [
803 [$database, 'template_foo', 42],
806 'Return requested key only, value false, default 42' => [
807 [$database, 'template_bar', 42],
810 'Return requested key only, value null, default 42' => [
811 [$database, 'template_baz', 42],
814 'Return unknown key, value null, default 42' => [
815 [$database, 'template_bum', 42],
822 * Tests for data_get_config.
824 * @dataProvider data_get_config_provider
825 * @param array $funcargs The args to pass to data_get_config
826 * @param mixed $expectation The expected value
828 public function test_data_get_config($funcargs, $expectation) {
829 $this->assertEquals($expectation, call_user_func_array('data_get_config', $funcargs));
833 * Data provider for tests of data_set_config.
837 public function data_set_config_provider() {
838 $basevalue = (object) ['id' => rand(1, 1000)];
840 'template_foo' => true,
841 'template_bar' => false,
844 $withvalues = clone $basevalue;
845 $withvalues->config = json_encode((object) $config);
848 'Empty config, New value' => [
853 json_encode((object) ['etc' => 'newvalue'])
855 'Has config, New value' => [
860 json_encode((object) array_merge($config, ['etc' => 'newvalue']))
862 'Has config, Update value, string' => [
867 json_encode((object) array_merge($config, ['template_foo' => 'newvalue']))
869 'Has config, Update value, true' => [
874 json_encode((object) array_merge($config, ['template_bar' => true]))
876 'Has config, Update value, false' => [
881 json_encode((object) array_merge($config, ['template_foo' => false]))
883 'Has config, Update value, null' => [
888 json_encode((object) array_merge($config, ['template_foo' => null]))
890 'Has config, No update, value true' => [
901 * Tests for data_set_config.
903 * @dataProvider data_set_config_provider
904 * @param object $database The example row for the entry
905 * @param string $key The config key to set
906 * @param mixed $value The value of the key
907 * @param bool $expectupdate Whether we expected an update
908 * @param mixed $newconfigvalue The expected value
910 public function test_data_set_config($database, $key, $value, $expectupdate, $newconfigvalue) {
913 // Mock the database.
914 // Note: Use the actual test class here rather than the abstract because are testing concrete methods.
916 $DB = $this->getMockBuilder(get_class($DB))
917 ->setMethods(['set_field'])
920 $DB->expects($this->exactly((int) $expectupdate))
921 ->method('set_field')
926 ['id' => $database->id]
929 // Perform the update.
930 data_set_config($database, $key, $value);
932 // Ensure that the value was updated by reference in $database.
933 $config = json_decode($database->config);
934 $this->assertEquals($value, $config->$key);
941 public function test_data_view() {
944 $CFG->enablecompletion = 1;
945 $this->resetAfterTest();
947 $this->setAdminUser();
949 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
950 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id),
951 array('completion' => 2, 'completionview' => 1));
952 $context = context_module::instance($data->cmid);
953 $cm = get_coursemodule_from_instance('data', $data->id);
955 // Trigger and capture the event.
956 $sink = $this->redirectEvents();
958 data_view($data, $course, $cm, $context);
960 $events = $sink->get_events();
961 // 2 additional events thanks to completion.
962 $this->assertCount(3, $events);
963 $event = array_shift($events);
965 // Checking that the event contains the expected values.
966 $this->assertInstanceOf('\mod_data\event\course_module_viewed', $event);
967 $this->assertEquals($context, $event->get_context());
968 $moodleurl = new \moodle_url('/mod/data/view.php', array('id' => $cm->id));
969 $this->assertEquals($moodleurl, $event->get_url());
970 $this->assertEventContextNotUsed($event);
971 $this->assertNotEmpty($event->get_name());
973 // Check completion status.
974 $completion = new completion_info($course);
975 $completiondata = $completion->get_data($cm);
976 $this->assertEquals(1, $completiondata->completionstate);
979 public function test_mod_data_get_tagged_records() {
980 $this->resetAfterTest();
981 $this->setAdminUser();
984 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
985 $course1 = $this->getDataGenerator()->create_course();
987 $fieldrecord = new StdClass();
988 $fieldrecord->name = 'field-1';
989 $fieldrecord->type = 'text';
991 $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course1->id, 'approval' => true));
992 $field1 = $datagenerator->create_field($fieldrecord, $data1);
994 $datagenerator->create_entry($data1, [$field1->field->id => 'value11'], 0, ['Cats', 'Dogs']);
995 $datagenerator->create_entry($data1, [$field1->field->id => 'value12'], 0, ['Cats', 'mice']);
996 $datagenerator->create_entry($data1, [$field1->field->id => 'value13'], 0, ['Cats']);
997 $datagenerator->create_entry($data1, [$field1->field->id => 'value14'], 0);
999 $tag = core_tag_tag::get_by_name(0, 'Cats');
1001 // Admin can see everything.
1002 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1003 $this->assertContains('value11', $res->content);
1004 $this->assertContains('value12', $res->content);
1005 $this->assertContains('value13', $res->content);
1006 $this->assertNotContains('value14', $res->content);
1009 public function test_mod_data_get_tagged_records_approval() {
1012 $this->resetAfterTest();
1013 $this->setAdminUser();
1016 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
1017 $course2 = $this->getDataGenerator()->create_course();
1018 $course1 = $this->getDataGenerator()->create_course();
1020 $fieldrecord = new StdClass();
1021 $fieldrecord->name = 'field-1';
1022 $fieldrecord->type = 'text';
1024 $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course1->id));
1025 $field1 = $datagenerator->create_field($fieldrecord, $data1);
1026 $data2 = $this->getDataGenerator()->create_module('data', array('course' => $course2->id, 'approval' => true));
1027 $field2 = $datagenerator->create_field($fieldrecord, $data2);
1029 $record11 = $datagenerator->create_entry($data1, [$field1->field->id => 'value11'], 0, ['Cats', 'Dogs']);
1030 $record21 = $datagenerator->create_entry($data2, [$field2->field->id => 'value21'], 0, ['Cats'], ['approved' => false]);
1031 $tag = core_tag_tag::get_by_name(0, 'Cats');
1033 // Admin can see everything.
1034 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1035 $this->assertContains('value11', $res->content);
1036 $this->assertContains('value21', $res->content);
1037 $this->assertEmpty($res->prevpageurl);
1038 $this->assertEmpty($res->nextpageurl);
1040 // Create and enrol a user.
1041 $student = self::getDataGenerator()->create_user();
1042 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
1043 $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
1044 $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
1045 $this->setUser($student);
1047 // User can search data records inside a course.
1048 core_tag_index_builder::reset_caches();
1049 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1051 $this->assertContains('value11', $res->content);
1052 $this->assertNotContains('value21', $res->content);
1054 $recordtoupdate = new stdClass();
1055 $recordtoupdate->id = $record21;
1056 $recordtoupdate->approved = true;
1057 $DB->update_record('data_records', $recordtoupdate);
1059 core_tag_index_builder::reset_caches();
1060 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1062 $this->assertContains('value11', $res->content);
1063 $this->assertContains('value21', $res->content);
1066 public function test_mod_data_get_tagged_records_time() {
1069 $this->resetAfterTest();
1070 $this->setAdminUser();
1073 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
1074 $course2 = $this->getDataGenerator()->create_course();
1075 $course1 = $this->getDataGenerator()->create_course();
1077 $fieldrecord = new StdClass();
1078 $fieldrecord->name = 'field-1';
1079 $fieldrecord->type = 'text';
1081 $timefrom = time() - YEARSECS;
1082 $timeto = time() - WEEKSECS;
1084 $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course1->id, 'approval' => true));
1085 $field1 = $datagenerator->create_field($fieldrecord, $data1);
1086 $data2 = $this->getDataGenerator()->create_module('data', array('course' => $course2->id,
1087 'timeviewfrom' => $timefrom,
1088 'timeviewto' => $timeto));
1089 $field2 = $datagenerator->create_field($fieldrecord, $data2);
1090 $record11 = $datagenerator->create_entry($data1, [$field1->field->id => 'value11'], 0, ['Cats', 'Dogs']);
1091 $record21 = $datagenerator->create_entry($data2, [$field2->field->id => 'value21'], 0, ['Cats']);
1092 $tag = core_tag_tag::get_by_name(0, 'Cats');
1094 // Admin can see everything.
1095 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1096 $this->assertContains('value11', $res->content);
1097 $this->assertContains('value21', $res->content);
1098 $this->assertEmpty($res->prevpageurl);
1099 $this->assertEmpty($res->nextpageurl);
1101 // Create and enrol a user.
1102 $student = self::getDataGenerator()->create_user();
1103 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
1104 $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
1105 $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
1106 $this->setUser($student);
1108 // User can search data records inside a course.
1109 core_tag_index_builder::reset_caches();
1110 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1112 $this->assertContains('value11', $res->content);
1113 $this->assertNotContains('value21', $res->content);
1115 $data2->timeviewto = time() + YEARSECS;
1116 $DB->update_record('data', $data2);
1118 core_tag_index_builder::reset_caches();
1119 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1121 $this->assertContains('value11', $res->content);
1122 $this->assertContains('value21', $res->content);
1125 public function test_mod_data_get_tagged_records_course_enrolment() {
1128 $this->resetAfterTest();
1129 $this->setAdminUser();
1132 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
1133 $course2 = $this->getDataGenerator()->create_course();
1134 $course1 = $this->getDataGenerator()->create_course();
1136 $fieldrecord = new StdClass();
1137 $fieldrecord->name = 'field-1';
1138 $fieldrecord->type = 'text';
1140 $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course1->id, 'approval' => true));
1141 $field1 = $datagenerator->create_field($fieldrecord, $data1);
1142 $data2 = $this->getDataGenerator()->create_module('data', array('course' => $course2->id));
1143 $field2 = $datagenerator->create_field($fieldrecord, $data2);
1145 $record11 = $datagenerator->create_entry($data1, [$field1->field->id => 'value11'], 0, ['Cats', 'Dogs']);
1146 $record21 = $datagenerator->create_entry($data2, [$field2->field->id => 'value21'], 0, ['Cats']);
1147 $tag = core_tag_tag::get_by_name(0, 'Cats');
1149 // Admin can see everything.
1150 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1151 $this->assertContains('value11', $res->content);
1152 $this->assertContains('value21', $res->content);
1153 $this->assertEmpty($res->prevpageurl);
1154 $this->assertEmpty($res->nextpageurl);
1156 // Create and enrol a user.
1157 $student = self::getDataGenerator()->create_user();
1158 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
1159 $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
1160 $this->setUser($student);
1161 core_tag_index_builder::reset_caches();
1163 // User can search data records inside a course.
1164 $coursecontext = context_course::instance($course1->id);
1165 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1167 $this->assertContains('value11', $res->content);
1168 $this->assertNotContains('value21', $res->content);
1170 $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
1172 core_tag_index_builder::reset_caches();
1173 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1175 $this->assertContains('value11', $res->content);
1176 $this->assertContains('value21', $res->content);
1179 public function test_mod_data_get_tagged_records_course_groups() {
1182 $this->resetAfterTest();
1183 $this->setAdminUser();
1186 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
1187 $course2 = $this->getDataGenerator()->create_course();
1188 $course1 = $this->getDataGenerator()->create_course();
1190 $groupa = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'name' => 'groupA'));
1191 $groupb = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'name' => 'groupB'));
1193 $fieldrecord = new StdClass();
1194 $fieldrecord->name = 'field-1';
1195 $fieldrecord->type = 'text';
1197 $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course1->id, 'approval' => true));
1198 $field1 = $datagenerator->create_field($fieldrecord, $data1);
1199 $data2 = $this->getDataGenerator()->create_module('data', array('course' => $course2->id));
1200 $field2 = $datagenerator->create_field($fieldrecord, $data2);
1201 set_coursemodule_groupmode($data2->cmid, SEPARATEGROUPS);
1203 $record11 = $datagenerator->create_entry($data1, [$field1->field->id => 'value11'],
1204 0, ['Cats', 'Dogs']);
1205 $record21 = $datagenerator->create_entry($data2, [$field2->field->id => 'value21'],
1206 $groupa->id, ['Cats']);
1207 $record22 = $datagenerator->create_entry($data2, [$field2->field->id => 'value22'],
1208 $groupb->id, ['Cats']);
1209 $tag = core_tag_tag::get_by_name(0, 'Cats');
1211 // Admin can see everything.
1212 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1213 $this->assertContains('value11', $res->content);
1214 $this->assertContains('value21', $res->content);
1215 $this->assertContains('value22', $res->content);
1216 $this->assertEmpty($res->prevpageurl);
1217 $this->assertEmpty($res->nextpageurl);
1219 // Create and enrol a user.
1220 $student = self::getDataGenerator()->create_user();
1221 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
1222 $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
1223 $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
1224 groups_add_member($groupa, $student);
1225 $this->setUser($student);
1226 core_tag_index_builder::reset_caches();
1228 // User can search data records inside a course.
1229 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1231 $this->assertContains('value11', $res->content);
1232 $this->assertContains('value21', $res->content);
1233 $this->assertNotContains('value22', $res->content);
1235 groups_add_member($groupb, $student);
1236 core_tag_index_builder::reset_caches();
1237 $res = mod_data_get_tagged_records($tag, false, 0, 0, 1, 0);
1239 $this->assertContains('value11', $res->content);
1240 $this->assertContains('value21', $res->content);
1241 $this->assertContains('value22', $res->content);
1245 * Test check_updates_since callback.
1247 public function test_check_updates_since() {
1249 $this->resetAfterTest();
1250 $this->setAdminUser();
1251 $course = $this->getDataGenerator()->create_course();
1253 $student = self::getDataGenerator()->create_user();
1255 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
1256 $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
1257 $this->setCurrentTimeStart();
1259 'course' => $course->id,
1261 $data = $this->getDataGenerator()->create_module('data', $record);
1262 $cm = get_coursemodule_from_instance('data', $data->id, $course->id);
1263 $cm = cm_info::create($cm);
1264 $this->setUser($student);
1266 // Check that upon creation, the updates are only about the new configuration created.
1267 $onehourago = time() - HOURSECS;
1268 $updates = data_check_updates_since($cm, $onehourago);
1269 foreach ($updates as $el => $val) {
1270 if ($el == 'configuration') {
1271 $this->assertTrue($val->updated);
1272 $this->assertTimeCurrent($val->timeupdated);
1274 $this->assertFalse($val->updated);
1278 // Add a couple of entries.
1279 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data');
1280 $fieldtypes = array('checkbox', 'date');
1283 // Creating test Fields with default parameter values.
1284 foreach ($fieldtypes as $fieldtype) {
1285 // Creating variables dynamically.
1286 $fieldname = 'field-' . $count;
1287 $record = new StdClass();
1288 $record->name = $fieldname;
1289 $record->type = $fieldtype;
1290 $record->required = 1;
1292 ${$fieldname} = $datagenerator->create_field($record, $data);
1296 $fields = $DB->get_records('data_fields', array('dataid' => $data->id), 'id');
1298 $contents = array();
1299 $contents[] = array('opt1', 'opt2', 'opt3', 'opt4');
1300 $contents[] = '01-01-2037'; // It should be lower than 2038, to avoid failing on 32-bit windows.
1302 $fieldcontents = array();
1303 foreach ($fields as $fieldrecord) {
1304 $fieldcontents[$fieldrecord->id] = $contents[$count++];
1307 $datarecor1did = $datagenerator->create_entry($data, $fieldcontents);
1308 $datarecor2did = $datagenerator->create_entry($data, $fieldcontents);
1309 $records = $DB->get_records('data_records', array('dataid' => $data->id));
1310 $this->assertCount(2, $records);
1311 // Check we received the entries updated.
1312 $updates = data_check_updates_since($cm, $onehourago);
1313 $this->assertTrue($updates->entries->updated);
1314 $this->assertEquals([$datarecor1did, $datarecor2did], $updates->entries->itemids, '', 0, 10, true);
1317 public function test_data_core_calendar_provide_event_action_open() {
1318 $this->resetAfterTest();
1320 $this->setAdminUser();
1323 $course = $this->getDataGenerator()->create_course();
1325 // Create a database activity.
1326 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id,
1327 'timeavailablefrom' => time() - DAYSECS, 'timeavailableto' => time() + DAYSECS));
1329 // Create a calendar event.
1330 $event = $this->create_action_event($course->id, $data->id, DATA_EVENT_TYPE_OPEN);
1332 // Create an action factory.
1333 $factory = new \core_calendar\action_factory();
1335 // Decorate action event.
1336 $actionevent = mod_data_core_calendar_provide_event_action($event, $factory);
1338 // Confirm the event was decorated.
1339 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
1340 $this->assertEquals(get_string('add', 'data'), $actionevent->get_name());
1341 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
1342 $this->assertEquals(1, $actionevent->get_item_count());
1343 $this->assertTrue($actionevent->is_actionable());
1346 public function test_data_core_calendar_provide_event_action_closed() {
1347 $this->resetAfterTest();
1349 $this->setAdminUser();
1352 $course = $this->getDataGenerator()->create_course();
1354 // Create a database activity.
1355 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id,
1356 'timeavailableto' => time() - DAYSECS));
1358 // Create a calendar event.
1359 $event = $this->create_action_event($course->id, $data->id, DATA_EVENT_TYPE_OPEN);
1361 // Create an action factory.
1362 $factory = new \core_calendar\action_factory();
1364 // Decorate action event.
1365 $actionevent = mod_data_core_calendar_provide_event_action($event, $factory);
1367 // No event on the dashboard if module is closed.
1368 $this->assertNull($actionevent);
1371 public function test_data_core_calendar_provide_event_action_open_in_future() {
1372 $this->resetAfterTest();
1374 $this->setAdminUser();
1377 $course = $this->getDataGenerator()->create_course();
1379 // Create a database activity.
1380 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id,
1381 'timeavailablefrom' => time() + DAYSECS));
1383 // Create a calendar event.
1384 $event = $this->create_action_event($course->id, $data->id, DATA_EVENT_TYPE_OPEN);
1386 // Create an action factory.
1387 $factory = new \core_calendar\action_factory();
1389 // Decorate action event.
1390 $actionevent = mod_data_core_calendar_provide_event_action($event, $factory);
1392 // Confirm the event was decorated.
1393 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
1394 $this->assertEquals(get_string('add', 'data'), $actionevent->get_name());
1395 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
1396 $this->assertEquals(1, $actionevent->get_item_count());
1397 $this->assertFalse($actionevent->is_actionable());
1400 public function test_data_core_calendar_provide_event_action_no_time_specified() {
1401 $this->resetAfterTest();
1403 $this->setAdminUser();
1406 $course = $this->getDataGenerator()->create_course();
1408 // Create a database activity.
1409 $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id));
1411 // Create a calendar event.
1412 $event = $this->create_action_event($course->id, $data->id, DATA_EVENT_TYPE_OPEN);
1414 // Create an action factory.
1415 $factory = new \core_calendar\action_factory();
1417 // Decorate action event.
1418 $actionevent = mod_data_core_calendar_provide_event_action($event, $factory);
1420 // Confirm the event was decorated.
1421 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
1422 $this->assertEquals(get_string('add', 'data'), $actionevent->get_name());
1423 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
1424 $this->assertEquals(1, $actionevent->get_item_count());
1425 $this->assertTrue($actionevent->is_actionable());
1429 * Creates an action event.
1431 * @param int $courseid
1432 * @param int $instanceid The data id.
1433 * @param string $eventtype The event type. eg. DATA_EVENT_TYPE_OPEN.
1434 * @return bool|calendar_event
1436 private function create_action_event($courseid, $instanceid, $eventtype) {
1437 $event = new stdClass();
1438 $event->name = 'Calendar event';
1439 $event->modulename = 'data';
1440 $event->courseid = $courseid;
1441 $event->instance = $instanceid;
1442 $event->type = CALENDAR_EVENT_TYPE_ACTION;
1443 $event->eventtype = $eventtype;
1444 $event->timestart = time();
1446 return calendar_event::create($event);
1450 * Test the callback responsible for returning the completion rule descriptions.
1451 * This function should work given either an instance of the module (cm_info), such as when checking the active rules,
1452 * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type.
1454 public function test_mod_data_completion_get_active_rule_descriptions() {
1455 $this->resetAfterTest();
1456 $this->setAdminUser();
1458 // Two activities, both with automatic completion. One has the 'completionentries' rule, one doesn't.
1459 $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]);
1460 $data1 = $this->getDataGenerator()->create_module('data', [
1461 'course' => $course->id,
1463 'completionentries' => 3
1465 $data2 = $this->getDataGenerator()->create_module('data', [
1466 'course' => $course->id,
1468 'completionentries' => 0
1470 $cm1 = cm_info::create(get_coursemodule_from_instance('data', $data1->id));
1471 $cm2 = cm_info::create(get_coursemodule_from_instance('data', $data2->id));
1473 // Data for the stdClass input type.
1474 // This type of input would occur when checking the default completion rules for an activity type, where we don't have
1475 // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info.
1476 $moddefaults = new stdClass();
1477 $moddefaults->customdata = ['customcompletionrules' => ['completionentries' => 3]];
1478 $moddefaults->completion = 2;
1480 $activeruledescriptions = [get_string('completionentriesdesc', 'data', 3)];
1481 $this->assertEquals(mod_data_get_completion_active_rule_descriptions($cm1), $activeruledescriptions);
1482 $this->assertEquals(mod_data_get_completion_active_rule_descriptions($cm2), []);
1483 $this->assertEquals(mod_data_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions);
1484 $this->assertEquals(mod_data_get_completion_active_rule_descriptions(new stdClass()), []);