MDL-40047 events: Add unit tests for feedback events
[moodle.git] / mod / feedback / tests / events_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Tests for feedback events.
19  *
20  * @package    mod_feedback
21  * @copyright  2013 Ankit Agarwal
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
23  */
25 global $CFG;
27 /**
28  * Class mod_feedback_events_testcase
29  *
30  * Class for tests related to feedback events.
31  *
32  * @package    mod_feedback
33  * @copyright  2013 Ankit Agarwal
34  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
35  */
36 class mod_feedback_events_testcase extends advanced_testcase {
38     /** @var  stdClass A user who likes to interact with feedback activity. */
39     private $eventuser;
41     /** @var  stdClass A course used to hold feedback activities for testing. */
42     private $eventcourse;
44     /** @var  stdClass A feedback activity used for feedback event testing. */
45     private $eventfeedback;
47     /** @var  stdClass course module object . */
48     private $eventcm;
50     /** @var  stdClass A feedback item. */
51     private $eventfeedbackitem;
53     /** @var  stdClass A feedback activity response submitted by user. */
54     private $eventfeedbackcompleted;
56     /** @var  stdClass value associated with $eventfeedbackitem . */
57     private $eventfeedbackvalue;
59     public function setUp() {
60         global $DB;
62         $this->setAdminUser();
63         $gen = $this->getDataGenerator();
64         $this->eventuser = $gen->create_user(); // Create a user.
65         $course = $gen->create_course(); // Create a course.
66         // Assign manager role, so user can see reports.
67         role_assign(1, $this->eventuser->id, context_course::instance($course->id));
69         // Add a feedback activity to the created course.
70         $record = new stdClass();
71         $record->course = $course->id;
72         $feedback = $gen->create_module('feedback', $record);
73         $this->eventfeedback = $DB->get_record('feedback', array('id' => $feedback->id), '*', MUST_EXIST); // Get exact copy.
74         $this->eventcm = get_coursemodule_from_instance('feedback', $this->eventfeedback->id, false, MUST_EXIST);
76         // Create a feedback item.
77         $item = new stdClass();
78         $item->feedback = $this->eventfeedback->id;
79         $item->type = 'numeric';
80         $item->presentation = '0|0';
81         $itemid = $DB->insert_record('feedback_item', $item);
82         $this->eventfeedbackitem = $DB->get_record('feedback_item', array('id' => $itemid), '*', MUST_EXIST);
84         // Create a response from a user.
85         $response = new stdClass();
86         $response->feedback = $this->eventfeedback->id;
87         $response->userid = $this->eventuser->id;
88         $response->anonymous_response = FEEDBACK_ANONYMOUS_YES;
89         $completedid = $DB->insert_record('feedback_completed', $response);
90         $this->eventfeedbackcompleted = $DB->get_record('feedback_completed', array('id' => $completedid), '*', MUST_EXIST);
92         $value = new stdClass();
93         $value->course_id = $course->id;
94         $value->item = $this->eventfeedbackitem->id;
95         $value->completed = $this->eventfeedbackcompleted->id;
96         $value->value = 25; // User response value.
97         $valueid = $DB->insert_record('feedback_value', $value);
98         $this->eventfeedbackvalue = $DB->get_record('feedback_value', array('id' => $valueid), '*', MUST_EXIST);
99         // Do this in the end to get correct sortorder and cacherev values.
100         $this->eventcourse = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST);
102     }
104     /**
105      * Tests for event response_deleted.
106      */
107     public function test_response_deleted_event() {
108         global $USER, $DB;
109         $this->resetAfterTest();
111         // Create and delete a module.
112         $sink = $this->redirectEvents();
113         feedback_delete_completed($this->eventfeedbackcompleted->id);
114         $events = $sink->get_events();
115         $event = array_pop($events); // Delete feedback event.
116         $sink->close();
118         // Validate event data.
119         $this->assertInstanceOf('\mod_feedback\event\response_deleted', $event);
120         $this->assertEquals($this->eventfeedbackcompleted->id, $event->objectid);
121         $this->assertEquals($USER->id, $event->userid);
122         $this->assertEquals($this->eventuser->id, $event->relateduserid);
123         $this->assertEquals('feedback_completed', $event->objecttable);
124         $this->assertEquals(null, $event->get_url());
125         $this->assertEquals($this->eventfeedbackcompleted, $event->get_record_snapshot('feedback_completed', $event->objectid));
126         $this->assertEquals($this->eventcourse, $event->get_record_snapshot('course', $event->courseid));
127         $this->assertEquals($this->eventfeedback, $event->get_record_snapshot('feedback', $event->other['instanceid']));
129         // Test legacy data.
130         $arr = array($this->eventcourse->id, 'feedback', 'delete', 'view.php?id=' . $this->eventcm->id, $this->eventfeedback->id,
131                 $this->eventfeedback->id);
132         $this->assertEventLegacyLogData($arr, $event);
134         // Test can_view() .
135         $this->setUser($this->eventuser);
136         $this->assertFalse($event->can_view());
137         $this->setAdminUser();
138         $this->assertTrue($event->can_view());
140         // Create a response, with anonymous set to no and test can_view().
141         $response = new stdClass();
142         $response->feedback = $this->eventcm->instance;
143         $response->userid = $this->eventuser->id;
144         $response->anonymous_response = FEEDBACK_ANONYMOUS_NO;
145         $completedid = $DB->insert_record('feedback_completed', $response);
146         $DB->get_record('feedback_completed', array('id' => $completedid), '*', MUST_EXIST);
147         $value = new stdClass();
148         $value->course_id = $this->eventcourse->id;
149         $value->item = $this->eventfeedbackitem->id;
150         $value->completed = $completedid;
151         $value->value = 25; // User response value.
152         $DB->insert_record('feedback_valuetmp', $value);
154         // Save the feedback.
155         $sink = $this->redirectEvents();
156         feedback_delete_completed($completedid);
157         $events = $sink->get_events();
158         $event = array_pop($events); // Response submitted feedback event.
159         $sink->close();
161         // Test can_view() .
162         $this->setUser($this->eventuser);
163         $this->assertTrue($event->can_view());
164         $this->setAdminUser();
165         $this->assertTrue($event->can_view());
166     }
168     /**
169      * Tests for event validations related to feedback response deletion.
170      */
171     public function test_response_deleted_event_exceptions() {
173         $this->resetAfterTest();
175         $context = context_module::instance($this->eventcm->id);
177         // Test not setting instanceid.
178         try {
179             \mod_feedback\event\response_deleted::create(array(
180                 'context'  => $context,
181                 'objectid' => $this->eventfeedbackcompleted->id,
182                 'other'    => array('cmid' => $this->eventcm->id, 'anonymous' => 2)
183             ));
184             $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
185                     other['instanceid']");
186         } catch (coding_exception $e) {
187             $this->assertContains("Field other['instanceid'] cannot be empty", $e->getMessage());
188         }
190         // Test not setting cmid.
191         try {
192             \mod_feedback\event\response_deleted::create(array(
193                 'context'  => $context,
194                 'objectid' => $this->eventfeedbackcompleted->id,
195                 'other'    => array('instanceid' => $this->eventfeedback->id, 'anonymous' => 2)
196             ));
197             $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
198                     other['cmid']");
199         } catch (coding_exception $e) {
200             $this->assertContains("Field other['cmid'] cannot be empty", $e->getMessage());
201         }
203         // Test not setting anonymous.
204         try {
205             \mod_feedback\event\response_submitted::create(array(
206                 'context'  => $context,
207                 'objectid' => $this->eventfeedbackcompleted->id,
208                 'other'    => array('cmid' => $this->eventcm->id, 'instanceid' => $this->eventfeedback->id)
209             ));
210             $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
211                     other['anonymous']");
212         } catch (coding_exception $e) {
213             $this->assertContains("Field other['anonymous'] cannot be empty", $e->getMessage());
214         }
215     }
217     /**
218      * Tests for event response_submitted.
219      */
220     public function test_response_submitted_event() {
221         global $USER, $DB;
222         $this->resetAfterTest();
223         $this->setUser($this->eventuser);
225         // Create a temporary response, with anonymous set to yes.
226         $response = new stdClass();
227         $response->feedback = $this->eventcm->instance;
228         $response->userid = $this->eventuser->id;
229         $response->anonymous_response = FEEDBACK_ANONYMOUS_YES;
230         $completedid = $DB->insert_record('feedback_completedtmp', $response);
231         $completed = $DB->get_record('feedback_completedtmp', array('id' => $completedid), '*', MUST_EXIST);
232         $value = new stdClass();
233         $value->course_id = $this->eventcourse->id;
234         $value->item = $this->eventfeedbackitem->id;
235         $value->completed = $completedid;
236         $value->value = 25; // User response value.
237         $DB->insert_record('feedback_valuetmp', $value);
239         // Save the feedback.
240         $sink = $this->redirectEvents();
241         $id = feedback_save_tmp_values($completed, false, $USER->id);
242         $events = $sink->get_events();
243         $event = array_pop($events); // Response submitted feedback event.
244         $sink->close();
246         // Validate event data. Feedback is anonymous.
247         $this->assertInstanceOf('\mod_feedback\event\response_submitted', $event);
248         $this->assertEquals($id, $event->objectid);
249         $this->assertEquals($USER->id, $event->userid);
250         $this->assertEquals($USER->id, $event->relateduserid);
251         $this->assertEquals('feedback_completed', $event->objecttable);
252         $this->assertEquals($this->eventcm->id, $event->other['cmid']);
253         $this->assertEquals($this->eventcm->instance, $event->other['instanceid']);
254         $this->assertEquals(FEEDBACK_ANONYMOUS_YES, $event->other['anonymous']);
255         $this->setUser($this->eventuser);
256         $this->assertFalse($event->can_view());
257         $this->setAdminUser();
258         $this->assertTrue($event->can_view());
260         // Test legacy data.
261         $this->assertEventLegacyLogData(null, $event);
263         // Create a temporary response, with anonymous set to no.
264         $response = new stdClass();
265         $response->feedback = $this->eventcm->instance;
266         $response->userid = $this->eventuser->id;
267         $response->anonymous_response = FEEDBACK_ANONYMOUS_NO;
268         $completedid = $DB->insert_record('feedback_completedtmp', $response);
269         $completed = $DB->get_record('feedback_completedtmp', array('id' => $completedid), '*', MUST_EXIST);
270         $value = new stdClass();
271         $value->course_id = $this->eventcourse->id;
272         $value->item = $this->eventfeedbackitem->id;
273         $value->completed = $completedid;
274         $value->value = 25; // User response value.
275         $DB->insert_record('feedback_valuetmp', $value);
277         // Save the feedback.
278         $sink = $this->redirectEvents();
279         feedback_save_tmp_values($completed, false, $USER->id);
280         $events = $sink->get_events();
281         $event = array_pop($events); // Response submitted feedback event.
282         $sink->close();
284         // Test legacy data.
285         $arr = array($this->eventcourse->id, 'feedback', 'submit', 'view.php?id=' . $this->eventcm->id, $this->eventfeedback->id,
286                      $this->eventfeedback->id, $USER->id);
287         $this->assertEventLegacyLogData($arr, $event);
289         // Test can_view().
290         $this->assertTrue($event->can_view());
291         $this->setAdminUser();
292         $this->assertTrue($event->can_view());
294     }
296     /**
297      * Tests for event validations related to feedback response submittion.
298      */
299     public function test_response_submitted_event_exceptions() {
301         $this->resetAfterTest();
303         $context = context_module::instance($this->eventcm->id);
305         // Test not setting instanceid.
306         try {
307             \mod_feedback\event\response_submitted::create(array(
308                 'context'  => $context,
309                 'objectid' => $this->eventfeedbackcompleted->id,
310                 'other'    => array('cmid' => $this->eventcm->id, 'anonymous' => 2)
311             ));
312             $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
313                     other['instanceid']");
314         } catch (coding_exception $e) {
315             $this->assertContains("Field other['instanceid'] cannot be empty", $e->getMessage());
316         }
318         // Test not setting cmid.
319         try {
320             \mod_feedback\event\response_submitted::create(array(
321                 'context'  => $context,
322                 'objectid' => $this->eventfeedbackcompleted->id,
323                 'other'    => array('instanceid' => $this->eventfeedback->id, 'anonymous' => 2)
324             ));
325             $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
326                     other['cmid']");
327         } catch (coding_exception $e) {
328             $this->assertContains("Field other['cmid'] cannot be empty", $e->getMessage());
329         }
331         // Test not setting anonymous.
332         try {
333             \mod_feedback\event\response_submitted::create(array(
334                  'context'  => $context,
335                  'objectid' => $this->eventfeedbackcompleted->id,
336                  'other'    => array('cmid' => $this->eventcm->id, 'instanceid' => $this->eventfeedback->id)
337             ));
338             $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
339                     other['anonymous']");
340         } catch (coding_exception $e) {
341             $this->assertContains("Field other['anonymous'] cannot be empty", $e->getMessage());
342         }
343     }