You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
14 KiB

<?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);
$this->assertEventContextNotUsed($event);
// Test can_view() .
$this->setUser($this->eventuser);
$this->assertFalse($event->can_view());
$this->assertDebuggingCalled();
$this->setAdminUser();
$this->assertTrue($event->can_view());
$this->assertDebuggingCalled();
// 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->assertDebuggingCalled();
$this->setAdminUser();
$this->assertTrue($event->can_view());
$this->assertDebuggingCalled();
$this->assertEventContextNotUsed($event);
}
/**
* 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 other['anonymous'].
try {
\mod_feedback\event\response_submitted::create(array(
'context' => $context,
'objectid' => $this->eventfeedbackcompleted->id,
'relateduserid' => 2,
));
$this->fail("Event validation should not allow \\mod_feedback\\event\\response_deleted to be triggered without
other['anonymous']");
} catch (coding_exception $e) {
$this->assertContains("The 'anonymous' value must be set in other.", $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);
$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(1, $event->anonymous);
$this->assertEquals(FEEDBACK_ANONYMOUS_YES, $event->other['anonymous']);
$this->setUser($this->eventuser);
$this->assertFalse($event->can_view());
$this->assertDebuggingCalled();
$this->setAdminUser();
$this->assertTrue($event->can_view());
$this->assertDebuggingCalled();
// 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);
$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->eventcm->id, $this->eventuser->id);
$this->assertEventLegacyLogData($arr, $event);
// Test can_view().
$this->assertTrue($event->can_view());
$this->assertDebuggingCalled();
$this->setAdminUser();
$this->assertTrue($event->can_view());
$this->assertDebuggingCalled();
$this->assertEventContextNotUsed($event);
}
/**
* Tests for event validations related to feedback response submission.
*/
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,
'relateduserid' => 2,
'anonymous' => 0,
'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("The 'instanceid' value must be set in other.", $e->getMessage());
}
// Test not setting cmid.
try {
\mod_feedback\event\response_submitted::create(array(
'context' => $context,
'objectid' => $this->eventfeedbackcompleted->id,
'relateduserid' => 2,
'anonymous' => 0,
'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("The 'cmid' value must be set in other.", $e->getMessage());
}
// Test not setting anonymous.
try {
\mod_feedback\event\response_submitted::create(array(
'context' => $context,
'objectid' => $this->eventfeedbackcompleted->id,
'relateduserid' => 2,
'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("The 'anonymous' value must be set in other.", $e->getMessage());
}
}
/**
* Test that event observer is executed on course deletion and the templates are removed.
*/
public function test_delete_course() {
global $DB;
$this->resetAfterTest();
feedback_save_as_template($this->eventfeedback, 'my template', 0);
$courseid = $this->eventcourse->id;
$this->assertNotEmpty($DB->get_records('feedback_template', array('course' => $courseid)));
delete_course($this->eventcourse, false);
$this->assertEmpty($DB->get_records('feedback_template', array('course' => $courseid)));
}
}