MDL-40047 events: Add unit tests for feedback events
authorAnkit Agarwal <ankit@moodle.com>
Tue, 24 Sep 2013 09:47:31 +0000 (17:47 +0800)
committerAnkit Agarwal <ankit@moodle.com>
Tue, 1 Oct 2013 02:12:06 +0000 (10:12 +0800)
mod/feedback/lib.php
mod/feedback/tests/events_test.php [new file with mode: 0644]

index affb79e..e4ef19a 100644 (file)
@@ -27,6 +27,8 @@
 require_once($CFG->libdir.'/eventslib.php');
 /** Include calendar/lib.php */
 require_once($CFG->dirroot.'/calendar/lib.php');
+// Include forms lib.
+require_once($CFG->libdir.'/formslib.php');
 
 define('FEEDBACK_ANONYMOUS_YES', 1);
 define('FEEDBACK_ANONYMOUS_NO', 2);
diff --git a/mod/feedback/tests/events_test.php b/mod/feedback/tests/events_test.php
new file mode 100644 (file)
index 0000000..ff5dcbb
--- /dev/null
@@ -0,0 +1,345 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Tests for feedback events.
+ *
+ * @package    mod_feedback
+ * @copyright  2013 Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
+ */
+
+global $CFG;
+
+/**
+ * Class mod_feedback_events_testcase
+ *
+ * Class for tests related to feedback events.
+ *
+ * @package    mod_feedback
+ * @copyright  2013 Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
+ */
+class mod_feedback_events_testcase extends advanced_testcase {
+
+    /** @var  stdClass A user who likes to interact with feedback activity. */
+    private $eventuser;
+
+    /** @var  stdClass A course used to hold feedback activities for testing. */
+    private $eventcourse;
+
+    /** @var  stdClass A feedback activity used for feedback event testing. */
+    private $eventfeedback;
+
+    /** @var  stdClass course module object . */
+    private $eventcm;
+
+    /** @var  stdClass A feedback item. */
+    private $eventfeedbackitem;
+
+    /** @var  stdClass A feedback activity response submitted by user. */
+    private $eventfeedbackcompleted;
+
+    /** @var  stdClass value associated with $eventfeedbackitem . */
+    private $eventfeedbackvalue;
+
+    public function setUp() {
+        global $DB;
+
+        $this->setAdminUser();
+        $gen = $this->getDataGenerator();
+        $this->eventuser = $gen->create_user(); // Create a user.
+        $course = $gen->create_course(); // Create a course.
+        // Assign manager role, so user can see reports.
+        role_assign(1, $this->eventuser->id, context_course::instance($course->id));
+
+        // Add a feedback activity to the created course.
+        $record = new stdClass();
+        $record->course = $course->id;
+        $feedback = $gen->create_module('feedback', $record);
+        $this->eventfeedback = $DB->get_record('feedback', array('id' => $feedback->id), '*', MUST_EXIST); // Get exact copy.
+        $this->eventcm = get_coursemodule_from_instance('feedback', $this->eventfeedback->id, false, MUST_EXIST);
+
+        // Create a feedback item.
+        $item = new stdClass();
+        $item->feedback = $this->eventfeedback->id;
+        $item->type = 'numeric';
+        $item->presentation = '0|0';
+        $itemid = $DB->insert_record('feedback_item', $item);
+        $this->eventfeedbackitem = $DB->get_record('feedback_item', array('id' => $itemid), '*', MUST_EXIST);
+
+        // Create a response from a user.
+        $response = new stdClass();
+        $response->feedback = $this->eventfeedback->id;
+        $response->userid = $this->eventuser->id;
+        $response->anonymous_response = FEEDBACK_ANONYMOUS_YES;
+        $completedid = $DB->insert_record('feedback_completed', $response);
+        $this->eventfeedbackcompleted = $DB->get_record('feedback_completed', array('id' => $completedid), '*', MUST_EXIST);
+
+        $value = new stdClass();
+        $value->course_id = $course->id;
+        $value->item = $this->eventfeedbackitem->id;
+        $value->completed = $this->eventfeedbackcompleted->id;
+        $value->value = 25; // User response value.
+        $valueid = $DB->insert_record('feedback_value', $value);
+        $this->eventfeedbackvalue = $DB->get_record('feedback_value', array('id' => $valueid), '*', MUST_EXIST);
+        // Do this in the end to get correct sortorder and cacherev values.
+        $this->eventcourse = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST);
+
+    }
+
+    /**
+     * Tests for event response_deleted.
+     */
+    public function test_response_deleted_event() {
+        global $USER, $DB;
+        $this->resetAfterTest();
+
+        // Create and delete a module.
+        $sink = $this->redirectEvents();
+        feedback_delete_completed($this->eventfeedbackcompleted->id);
+        $events = $sink->get_events();
+        $event = array_pop($events); // Delete feedback event.
+        $sink->close();
+
+        // Validate event data.
+        $this->assertInstanceOf('\mod_feedback\event\response_deleted', $event);
+        $this->assertEquals($this->eventfeedbackcompleted->id, $event->objectid);
+        $this->assertEquals($USER->id, $event->userid);
+        $this->assertEquals($this->eventuser->id, $event->relateduserid);
+        $this->assertEquals('feedback_completed', $event->objecttable);
+        $this->assertEquals(null, $event->get_url());
+        $this->assertEquals($this->eventfeedbackcompleted, $event->get_record_snapshot('feedback_completed', $event->objectid));
+        $this->assertEquals($this->eventcourse, $event->get_record_snapshot('course', $event->courseid));
+        $this->assertEquals($this->eventfeedback, $event->get_record_snapshot('feedback', $event->other['instanceid']));
+
+        // Test legacy data.
+        $arr = array($this->eventcourse->id, 'feedback', 'delete', 'view.php?id=' . $this->eventcm->id, $this->eventfeedback->id,
+                $this->eventfeedback->id);
+        $this->assertEventLegacyLogData($arr, $event);
+
+        // Test can_view() .
+        $this->setUser($this->eventuser);
+        $this->assertFalse($event->can_view());
+        $this->setAdminUser();
+        $this->assertTrue($event->can_view());
+
+        // Create a response, with anonymous set to no and test can_view().
+        $response = new stdClass();
+        $response->feedback = $this->eventcm->instance;
+        $response->userid = $this->eventuser->id;
+        $response->anonymous_response = FEEDBACK_ANONYMOUS_NO;
+        $completedid = $DB->insert_record('feedback_completed', $response);
+        $DB->get_record('feedback_completed', array('id' => $completedid), '*', MUST_EXIST);
+        $value = new stdClass();
+        $value->course_id = $this->eventcourse->id;
+        $value->item = $this->eventfeedbackitem->id;
+        $value->completed = $completedid;
+        $value->value = 25; // User response value.
+        $DB->insert_record('feedback_valuetmp', $value);
+
+        // Save the feedback.
+        $sink = $this->redirectEvents();
+        feedback_delete_completed($completedid);
+        $events = $sink->get_events();
+        $event = array_pop($events); // Response submitted feedback event.
+        $sink->close();
+
+        // Test can_view() .
+        $this->setUser($this->eventuser);
+        $this->assertTrue($event->can_view());
+        $this->setAdminUser();
+        $this->assertTrue($event->can_view());
+    }
+
+    /**
+     * Tests for event validations related to feedback response deletion.
+     */
+    public function test_response_deleted_event_exceptions() {
+
+        $this->resetAfterTest();
+
+        $context = context_module::instance($this->eventcm->id);
+
+        // Test not setting instanceid.
+        try {
+            \mod_feedback\event\response_deleted::create(array(
+                'context'  => $context,
+                'objectid' => $this->eventfeedbackcompleted->id,
+                'other'    => array('cmid' => $this->eventcm->id, 'anonymous' => 2)
+            ));
+            $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
+                    other['instanceid']");
+        } catch (coding_exception $e) {
+            $this->assertContains("Field other['instanceid'] cannot be empty", $e->getMessage());
+        }
+
+        // Test not setting cmid.
+        try {
+            \mod_feedback\event\response_deleted::create(array(
+                'context'  => $context,
+                'objectid' => $this->eventfeedbackcompleted->id,
+                'other'    => array('instanceid' => $this->eventfeedback->id, 'anonymous' => 2)
+            ));
+            $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
+                    other['cmid']");
+        } catch (coding_exception $e) {
+            $this->assertContains("Field other['cmid'] cannot be empty", $e->getMessage());
+        }
+
+        // Test not setting anonymous.
+        try {
+            \mod_feedback\event\response_submitted::create(array(
+                'context'  => $context,
+                'objectid' => $this->eventfeedbackcompleted->id,
+                'other'    => array('cmid' => $this->eventcm->id, 'instanceid' => $this->eventfeedback->id)
+            ));
+            $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
+                    other['anonymous']");
+        } catch (coding_exception $e) {
+            $this->assertContains("Field other['anonymous'] cannot be empty", $e->getMessage());
+        }
+    }
+
+    /**
+     * Tests for event response_submitted.
+     */
+    public function test_response_submitted_event() {
+        global $USER, $DB;
+        $this->resetAfterTest();
+        $this->setUser($this->eventuser);
+
+        // Create a temporary response, with anonymous set to yes.
+        $response = new stdClass();
+        $response->feedback = $this->eventcm->instance;
+        $response->userid = $this->eventuser->id;
+        $response->anonymous_response = FEEDBACK_ANONYMOUS_YES;
+        $completedid = $DB->insert_record('feedback_completedtmp', $response);
+        $completed = $DB->get_record('feedback_completedtmp', array('id' => $completedid), '*', MUST_EXIST);
+        $value = new stdClass();
+        $value->course_id = $this->eventcourse->id;
+        $value->item = $this->eventfeedbackitem->id;
+        $value->completed = $completedid;
+        $value->value = 25; // User response value.
+        $DB->insert_record('feedback_valuetmp', $value);
+
+        // Save the feedback.
+        $sink = $this->redirectEvents();
+        $id = feedback_save_tmp_values($completed, false, $USER->id);
+        $events = $sink->get_events();
+        $event = array_pop($events); // Response submitted feedback event.
+        $sink->close();
+
+        // Validate event data. Feedback is anonymous.
+        $this->assertInstanceOf('\mod_feedback\event\response_submitted', $event);
+        $this->assertEquals($id, $event->objectid);
+        $this->assertEquals($USER->id, $event->userid);
+        $this->assertEquals($USER->id, $event->relateduserid);
+        $this->assertEquals('feedback_completed', $event->objecttable);
+        $this->assertEquals($this->eventcm->id, $event->other['cmid']);
+        $this->assertEquals($this->eventcm->instance, $event->other['instanceid']);
+        $this->assertEquals(FEEDBACK_ANONYMOUS_YES, $event->other['anonymous']);
+        $this->setUser($this->eventuser);
+        $this->assertFalse($event->can_view());
+        $this->setAdminUser();
+        $this->assertTrue($event->can_view());
+
+        // Test legacy data.
+        $this->assertEventLegacyLogData(null, $event);
+
+        // Create a temporary response, with anonymous set to no.
+        $response = new stdClass();
+        $response->feedback = $this->eventcm->instance;
+        $response->userid = $this->eventuser->id;
+        $response->anonymous_response = FEEDBACK_ANONYMOUS_NO;
+        $completedid = $DB->insert_record('feedback_completedtmp', $response);
+        $completed = $DB->get_record('feedback_completedtmp', array('id' => $completedid), '*', MUST_EXIST);
+        $value = new stdClass();
+        $value->course_id = $this->eventcourse->id;
+        $value->item = $this->eventfeedbackitem->id;
+        $value->completed = $completedid;
+        $value->value = 25; // User response value.
+        $DB->insert_record('feedback_valuetmp', $value);
+
+        // Save the feedback.
+        $sink = $this->redirectEvents();
+        feedback_save_tmp_values($completed, false, $USER->id);
+        $events = $sink->get_events();
+        $event = array_pop($events); // Response submitted feedback event.
+        $sink->close();
+
+        // Test legacy data.
+        $arr = array($this->eventcourse->id, 'feedback', 'submit', 'view.php?id=' . $this->eventcm->id, $this->eventfeedback->id,
+                     $this->eventfeedback->id, $USER->id);
+        $this->assertEventLegacyLogData($arr, $event);
+
+        // Test can_view().
+        $this->assertTrue($event->can_view());
+        $this->setAdminUser();
+        $this->assertTrue($event->can_view());
+
+    }
+
+    /**
+     * Tests for event validations related to feedback response submittion.
+     */
+    public function test_response_submitted_event_exceptions() {
+
+        $this->resetAfterTest();
+
+        $context = context_module::instance($this->eventcm->id);
+
+        // Test not setting instanceid.
+        try {
+            \mod_feedback\event\response_submitted::create(array(
+                'context'  => $context,
+                'objectid' => $this->eventfeedbackcompleted->id,
+                'other'    => array('cmid' => $this->eventcm->id, 'anonymous' => 2)
+            ));
+            $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
+                    other['instanceid']");
+        } catch (coding_exception $e) {
+            $this->assertContains("Field other['instanceid'] cannot be empty", $e->getMessage());
+        }
+
+        // Test not setting cmid.
+        try {
+            \mod_feedback\event\response_submitted::create(array(
+                'context'  => $context,
+                'objectid' => $this->eventfeedbackcompleted->id,
+                'other'    => array('instanceid' => $this->eventfeedback->id, 'anonymous' => 2)
+            ));
+            $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
+                    other['cmid']");
+        } catch (coding_exception $e) {
+            $this->assertContains("Field other['cmid'] cannot be empty", $e->getMessage());
+        }
+
+        // Test not setting anonymous.
+        try {
+            \mod_feedback\event\response_submitted::create(array(
+                 'context'  => $context,
+                 'objectid' => $this->eventfeedbackcompleted->id,
+                 'other'    => array('cmid' => $this->eventcm->id, 'instanceid' => $this->eventfeedback->id)
+            ));
+            $this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
+                    other['anonymous']");
+        } catch (coding_exception $e) {
+            $this->assertContains("Field other['anonymous'] cannot be empty", $e->getMessage());
+        }
+    }
+}
+