diff --git a/grade/grading/classes/privacy/gradingform_legacy_polyfill.php b/grade/grading/classes/privacy/gradingform_legacy_polyfill.php index 799e8277192..59738572c20 100644 --- a/grade/grading/classes/privacy/gradingform_legacy_polyfill.php +++ b/grade/grading/classes/privacy/gradingform_legacy_polyfill.php @@ -58,7 +58,7 @@ trait gradingform_legacy_polyfill { * This method is used to export any user data this sub-plugin has using the object to get the context and userid. * * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. - * @todo MDL-63137 remove this method. + * @todo MDL-63167 remove this method. * * @param context $context Context owner of the data. * @param stdClass $definition Grading definition entry to export. @@ -75,7 +75,7 @@ trait gradingform_legacy_polyfill { * Any call to this method should delete all user data for the context defined. * * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. - * @todo MDL-63137 remove this method. + * @todo MDL-63167 remove this method. * * @param context $context Context owner of the data. */ @@ -88,7 +88,7 @@ trait gradingform_legacy_polyfill { * A call to this method should delete user data (where practicle) from the userid and context. * * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. - * @todo MDL-63137 remove this method. + * @todo MDL-63167 remove this method. * * @param int $userid The user whose information is to be deleted. * @param context $context Context owner of the data. diff --git a/grade/grading/tests/privacy_legacy_polyfill_test.php b/grade/grading/tests/privacy_legacy_polyfill_test.php index 241224a9314..63465c84f80 100644 --- a/grade/grading/tests/privacy_legacy_polyfill_test.php +++ b/grade/grading/tests/privacy_legacy_polyfill_test.php @@ -174,7 +174,7 @@ class test_legacy_polyfill_gradingform_provider implements * This method is used to export any user data this sub-plugin has using the object to get the context and userid. * * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. - * @todo MDL-63137 remove this method. + * @todo MDL-63167 remove this method. * * @param context $context Context owner of the data. * @param stdClass $definition Grading definition entry to export. @@ -190,7 +190,7 @@ class test_legacy_polyfill_gradingform_provider implements * Any call to this method should delete all user data for the context defined. * * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. - * @todo MDL-63137 remove this method. + * @todo MDL-63167 remove this method. * * @param context $context Context owner of the data. */ @@ -202,7 +202,7 @@ class test_legacy_polyfill_gradingform_provider implements * A call to this method should delete user data (where practicle) from the userid and context. * * @deprecated Since Moodle 3.6 MDL-62535 Please use the methods in the gradingform_provider_v2 interface. - * @todo MDL-63137 remove this method. + * @todo MDL-63167 remove this method. * * @param int $userid The user whose information is to be deleted. * @param context $context Context owner of the data. diff --git a/mod/feedback/classes/completion.php b/mod/feedback/classes/completion.php index 22898408152..b439afefcf1 100644 --- a/mod/feedback/classes/completion.php +++ b/mod/feedback/classes/completion.php @@ -61,12 +61,16 @@ class mod_feedback_completion extends mod_feedback_structure { * @param int $completedid id in the table feedback_completed, may be omitted if userid is specified * but it is highly recommended because the same user may have multiple responses to the same feedback * for different courses - * @param int $userid id of the user - if specified only non-anonymous replies will be returned. If not - * specified only anonymous replies will be returned and the $completedid is mandatory. + * @param int $nonanonymouseuserid - Return only anonymous results or specified user's results. + * If null only anonymous replies will be returned and the $completedid is mandatory. + * If specified only non-anonymous replies of $nonanonymouseuserid will be returned. + * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default). */ - public function __construct($feedback, $cm, $courseid, $iscompleted = false, $completedid = null, $userid = null) { + public function __construct($feedback, $cm, $courseid, $iscompleted = false, $completedid = null, + $nonanonymouseuserid = null, $userid = 0) { global $DB; - parent::__construct($feedback, $cm, $courseid, 0); + + parent::__construct($feedback, $cm, $courseid, 0, $userid); // Make sure courseid is always set for site feedback. if ($this->feedback->course == SITEID && !$this->courseid) { $this->courseid = SITEID; @@ -75,17 +79,17 @@ class mod_feedback_completion extends mod_feedback_structure { // Retrieve information about the completion. $this->iscompleted = true; $params = array('feedback' => $this->feedback->id); - if (!$userid && !$completedid) { - throw new coding_exception('Either $completedid or $userid must be specified for completed feedbacks'); + if (!$nonanonymouseuserid && !$completedid) { + throw new coding_exception('Either $completedid or $nonanonymouseuserid must be specified for completed feedbacks'); } if ($completedid) { $params['id'] = $completedid; } - if ($userid) { + if ($nonanonymouseuserid) { // We must respect the anonymousity of the reply that the user saw when they were completing the feedback, // not the current state that may have been changed later by the teacher. $params['anonymous_response'] = FEEDBACK_ANONYMOUS_NO; - $params['userid'] = $userid; + $params['userid'] = $nonanonymouseuserid; } $this->completed = $DB->get_record('feedback_completed', $params, '*', MUST_EXIST); $this->courseid = $this->completed->courseid; @@ -126,14 +130,14 @@ class mod_feedback_completion extends mod_feedback_structure { * @return stdClass|false record from feedback_completedtmp or false if not found */ public function get_current_completed_tmp() { - global $USER, $DB; + global $DB, $USER; if ($this->completedtmp === null) { $params = array('feedback' => $this->get_feedback()->id); if ($courseid = $this->get_courseid()) { $params['courseid'] = $courseid; } - if (isloggedin() && !isguestuser()) { - $params['userid'] = $USER->id; + if ((isloggedin() || $USER->id != $this->userid) && !isguestuser($this->userid)) { + $params['userid'] = $this->userid; } else { $params['guestid'] = sesskey(); } @@ -437,13 +441,13 @@ class mod_feedback_completion extends mod_feedback_structure { * @return stdClass record from feedback_completedtmp or false if not found */ protected function create_current_completed_tmp() { - global $USER, $DB; + global $DB, $USER; $record = (object)['feedback' => $this->feedback->id]; if ($this->get_courseid()) { $record->courseid = $this->get_courseid(); } - if (isloggedin() && !isguestuser()) { - $record->userid = $USER->id; + if ((isloggedin() || $USER->id != $this->userid) && !isguestuser($this->userid)) { + $record->userid = $this->userid; } else { $record->guestid = sesskey(); } @@ -535,7 +539,7 @@ class mod_feedback_completion extends mod_feedback_structure { * It is also responsible for sending email notifications when applicable. */ public function save_response() { - global $USER, $SESSION, $DB; + global $SESSION, $DB, $USER; $feedbackcompleted = $this->find_last_completed(); $feedbackcompletedtmp = $this->get_current_completed_tmp(); @@ -552,7 +556,7 @@ class mod_feedback_completion extends mod_feedback_structure { // Send email. if ($this->feedback->anonymous == FEEDBACK_ANONYMOUS_NO) { - feedback_send_email($this->cm, $this->feedback, $this->cm->get_course(), $USER, $this->completed); + feedback_send_email($this->cm, $this->feedback, $this->cm->get_course(), $this->userid, $this->completed); } else { feedback_send_email_anonym($this->cm, $this->feedback, $this->cm->get_course()); } @@ -561,9 +565,9 @@ class mod_feedback_completion extends mod_feedback_structure { // Update completion state. $completion = new completion_info($this->cm->get_course()); - if (isloggedin() && !isguestuser() && $completion->is_enabled($this->cm) && + if ((isloggedin() || $USER->id != $this->userid) && $completion->is_enabled($this->cm) && $this->cm->completion == COMPLETION_TRACKING_AUTOMATIC && $this->feedback->completionsubmit) { - $completion->update_state($this->cm, COMPLETION_COMPLETE); + $completion->update_state($this->cm, COMPLETION_COMPLETE, $this->userid); } } @@ -586,8 +590,8 @@ class mod_feedback_completion extends mod_feedback_structure { * @return stdClass record from feedback_completed or false if not found */ public function find_last_completed() { - global $USER, $DB; - if (!isloggedin() || isguestuser()) { + global $DB, $USER; + if ((!isloggedin() && $USER->id == $this->userid) || isguestuser($this->userid)) { // Not possible to retrieve completed feedback for guests. return false; } @@ -595,7 +599,10 @@ class mod_feedback_completion extends mod_feedback_structure { // Not possible to retrieve completed anonymous feedback. return false; } - $params = array('feedback' => $this->feedback->id, 'userid' => $USER->id, 'anonymous_response' => FEEDBACK_ANONYMOUS_NO); + $params = array('feedback' => $this->feedback->id, + 'userid' => $this->userid, + 'anonymous_response' => FEEDBACK_ANONYMOUS_NO + ); if ($this->get_courseid()) { $params['courseid'] = $this->get_courseid(); } @@ -604,7 +611,7 @@ class mod_feedback_completion extends mod_feedback_structure { } /** - * Checks if current user has capability to submit the feedback + * Checks if user has capability to submit the feedback * * There is an exception for fully anonymous feedbacks when guests can complete * feedback without the proper capability. @@ -616,17 +623,17 @@ class mod_feedback_completion extends mod_feedback_structure { * @return bool */ public function can_complete() { - global $CFG; + global $CFG, $USER; $context = context_module::instance($this->cm->id); - if (has_capability('mod/feedback:complete', $context)) { + if (has_capability('mod/feedback:complete', $context, $this->userid)) { return true; } if (!empty($CFG->feedback_allowfullanonymous) AND $this->feedback->course == SITEID AND $this->feedback->anonymous == FEEDBACK_ANONYMOUS_YES - AND (!isloggedin() OR isguestuser())) { + AND ((!isloggedin() && $USER->id == $this->userid) || isguestuser($this->userid))) { // Guests are allowed to complete fully anonymous feedback without having 'mod/feedback:complete' capability. return true; } @@ -670,7 +677,7 @@ class mod_feedback_completion extends mod_feedback_structure { require_once($CFG->libdir . '/completionlib.php'); $completion = new completion_info($this->cm->get_course()); - $completion->set_module_viewed($this->cm); + $completion->set_module_viewed($this->cm, $this->userid); } /** diff --git a/mod/feedback/classes/structure.php b/mod/feedback/classes/structure.php index 2dedb67a0df..826190163d1 100644 --- a/mod/feedback/classes/structure.php +++ b/mod/feedback/classes/structure.php @@ -47,6 +47,8 @@ class mod_feedback_structure { protected $allitems; /** @var array */ protected $allcourses; + /** @var int */ + protected $userid; /** * Constructor @@ -57,8 +59,11 @@ class mod_feedback_structure { * (at least one of $feedback or $cm is required) * @param int $courseid current course (for site feedbacks only) * @param int $templateid template id if this class represents the template structure + * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default). */ - public function __construct($feedback, $cm, $courseid = 0, $templateid = null) { + public function __construct($feedback, $cm, $courseid = 0, $templateid = null, $userid = 0) { + global $USER; + if ((empty($feedback->id) || empty($feedback->course)) && (empty($cm->instance) || empty($cm->course))) { throw new coding_exception('Either $feedback or $cm must be passed to constructor'); } @@ -68,6 +73,12 @@ class mod_feedback_structure { $this->templateid = $templateid; $this->courseid = ($this->feedback->course == SITEID) ? $courseid : 0; + if (empty($userid)) { + $this->userid = $USER->id; + } else { + $this->userid = $userid; + } + if (!$feedback) { // If feedback object was not specified, populate object with fields required for the most of methods. // These fields were added to course module cache in feedback_get_coursemodule_info(). @@ -201,17 +212,19 @@ class mod_feedback_structure { * @return bool */ public function can_view_analysis() { + global $USER; + $context = context_module::instance($this->cm->id); - if (has_capability('mod/feedback:viewreports', $context)) { + if (has_capability('mod/feedback:viewreports', $context, $this->userid)) { return true; } if (intval($this->get_feedback()->publish_stats) != 1 || - !has_capability('mod/feedback:viewanalysepage', $context)) { + !has_capability('mod/feedback:viewanalysepage', $context, $this->userid)) { return false; } - if (!isloggedin() || isguestuser()) { + if ((!isloggedin() && $USER->id == $this->userid) || isguestuser($this->userid)) { // There is no tracking for the guests, assume that they can view analysis if condition above is satisfied. return $this->feedback->course == SITEID; } @@ -228,13 +241,13 @@ class mod_feedback_structure { * @return bool true if the feedback already is submitted otherwise false */ public function is_already_submitted($anycourseid = false) { - global $USER, $DB; + global $DB, $USER; - if (!isloggedin() || isguestuser()) { + if ((!isloggedin() && $USER->id == $this->userid) || isguestuser($this->userid)) { return false; } - $params = array('userid' => $USER->id, 'feedback' => $this->feedback->id); + $params = array('userid' => $this->userid, 'feedback' => $this->feedback->id); if (!$anycourseid && $this->courseid) { $params['courseid'] = $this->courseid; } @@ -341,7 +354,8 @@ class mod_feedback_structure { $this->allcourses = array(); foreach ($list as $course) { context_helper::preload_from_record($course); - if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) { + if (!$course->visible && + !has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id), $this->userid)) { // Do not return courses that current user can not see. continue; } diff --git a/mod/feedback/lib.php b/mod/feedback/lib.php index 28ad191882e..c0eaf56a40a 100644 --- a/mod/feedback/lib.php +++ b/mod/feedback/lib.php @@ -3439,13 +3439,27 @@ function feedback_check_updates_since(cm_info $cm, $from, $filter = array()) { * * @param calendar_event $event * @param \core_calendar\action_factory $factory + * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default). * @return \core_calendar\local\event\entities\action_interface|null */ function mod_feedback_core_calendar_provide_event_action(calendar_event $event, - \core_calendar\action_factory $factory) { + \core_calendar\action_factory $factory, + int $userid = 0) { - $cm = get_fast_modinfo($event->courseid)->instances['feedback'][$event->instance]; - $feedbackcompletion = new mod_feedback_completion(null, $cm, 0); + global $USER; + + if (empty($userid)) { + $userid = $USER->id; + } + + $cm = get_fast_modinfo($event->courseid, $userid)->instances['feedback'][$event->instance]; + + if (!$cm->uservisible) { + // The module is not visible to the user for any reason. + return null; + } + + $feedbackcompletion = new mod_feedback_completion(null, $cm, 0, false, null, null, $userid); if (!empty($cm->customdata['timeclose']) && $cm->customdata['timeclose'] < time()) { // Feedback is already closed, do not display it even if it was never submitted. @@ -3460,7 +3474,7 @@ function mod_feedback_core_calendar_provide_event_action(calendar_event $event, // The feedback is actionable if it does not have timeopen or timeopen is in the past. $actionable = $feedbackcompletion->is_open(); - if ($actionable && $feedbackcompletion->is_already_submitted()) { + if ($actionable && $feedbackcompletion->is_already_submitted(false)) { // There is no need to display anything if the user has already submitted the feedback. return null; } diff --git a/mod/feedback/tests/lib_test.php b/mod/feedback/tests/lib_test.php index 0990f403be6..bcd46ac5eac 100644 --- a/mod/feedback/tests/lib_test.php +++ b/mod/feedback/tests/lib_test.php @@ -193,6 +193,42 @@ class mod_feedback_lib_testcase extends advanced_testcase { $this->assertTrue($actionevent->is_actionable()); } + /** + * Test calendar event provide action open, viewed by a different user. + */ + public function test_feedback_core_calendar_provide_event_action_open_for_user() { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $now = time(); + $user = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $course = $this->getDataGenerator()->create_course(); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id, 'manual'); + + $feedback = $this->getDataGenerator()->create_module('feedback', ['course' => $course->id, + 'timeopen' => $now - DAYSECS, 'timeclose' => $now + DAYSECS]); + $event = $this->create_action_event($course->id, $feedback->id, FEEDBACK_EVENT_TYPE_OPEN); + $factory = new \core_calendar\action_factory(); + + $this->setUser($user2); + + // User2 checking their events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user2->id); + $this->assertNull($actionevent); + + // User2 checking $user's events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user->id); + $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); + $this->assertEquals(get_string('answerquestions', 'feedback'), $actionevent->get_name()); + $this->assertInstanceOf('moodle_url', $actionevent->get_url()); + $this->assertEquals(1, $actionevent->get_item_count()); + $this->assertTrue($actionevent->is_actionable()); + } + /** * Test calendar event provide action closed. */ @@ -212,6 +248,38 @@ class mod_feedback_lib_testcase extends advanced_testcase { $this->assertNull($actionevent); } + /** + * Test calendar event provide action closed, viewed by a different user. + */ + public function test_feedback_core_calendar_provide_event_action_closed_for_user() { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $user = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id, 'manual'); + + $feedback = $this->getDataGenerator()->create_module('feedback', array('course' => $course->id, + 'timeclose' => time() - DAYSECS)); + $event = $this->create_action_event($course->id, $feedback->id, FEEDBACK_EVENT_TYPE_OPEN); + $factory = new \core_calendar\action_factory(); + $this->setUser($user2); + + // User2 checking their events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user2->id); + $this->assertNull($actionevent); + + // User2 checking $user's events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user->id); + + // No event on the dashboard if feedback is closed. + $this->assertNull($actionevent); + } + /** * Test calendar event action open in future. * @@ -236,6 +304,44 @@ class mod_feedback_lib_testcase extends advanced_testcase { $this->assertFalse($actionevent->is_actionable()); } + /** + * Test calendar event action open in future, viewed by a different user. + * + * @throws coding_exception + */ + public function test_feedback_core_calendar_provide_event_action_open_in_future_for_user() { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $user = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id, 'manual'); + + $feedback = $this->getDataGenerator()->create_module('feedback', ['course' => $course->id, + 'timeopen' => time() + DAYSECS]); + $event = $this->create_action_event($course->id, $feedback->id, FEEDBACK_EVENT_TYPE_OPEN); + + $factory = new \core_calendar\action_factory(); + $this->setUser($user2); + + // User2 checking their events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user2->id); + $this->assertNull($actionevent); + + // User2 checking $user's events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user->id); + + $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); + $this->assertEquals(get_string('answerquestions', 'feedback'), $actionevent->get_name()); + $this->assertInstanceOf('moodle_url', $actionevent->get_url()); + $this->assertEquals(1, $actionevent->get_item_count()); + $this->assertFalse($actionevent->is_actionable()); + } + /** * Test calendar event with no time specified. * @@ -259,6 +365,43 @@ class mod_feedback_lib_testcase extends advanced_testcase { $this->assertTrue($actionevent->is_actionable()); } + /** + * Test calendar event with no time specified, viewed by a different user. + * + * @throws coding_exception + */ + public function test_feedback_core_calendar_provide_event_action_no_time_specified_for_user() { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $user = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id, 'manual'); + + $feedback = $this->getDataGenerator()->create_module('feedback', ['course' => $course->id]); + $event = $this->create_action_event($course->id, $feedback->id, FEEDBACK_EVENT_TYPE_OPEN); + + $factory = new \core_calendar\action_factory(); + $this->setUser($user2); + + // User2 checking their events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user2->id); + $this->assertNull($actionevent); + + // User2 checking $user's events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user->id); + + $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); + $this->assertEquals(get_string('answerquestions', 'feedback'), $actionevent->get_name()); + $this->assertInstanceOf('moodle_url', $actionevent->get_url()); + $this->assertEquals(1, $actionevent->get_item_count()); + $this->assertTrue($actionevent->is_actionable()); + } + /** * A user that can not submit feedback should not have an action. */ @@ -287,6 +430,40 @@ class mod_feedback_lib_testcase extends advanced_testcase { $this->assertNull($action); } + /** + * A user that can not submit feedback should not have an action, viewed by a different user. + */ + public function test_feedback_core_calendar_provide_event_action_can_not_submit_for_user() { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $user = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', ['course' => $course->id]); + $event = $this->create_action_event($course->id, $feedback->id, FEEDBACK_EVENT_TYPE_OPEN); + $cm = get_coursemodule_from_instance('feedback', $feedback->id); + $context = context_module::instance($cm->id); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id, 'manual'); + + assign_capability('mod/feedback:complete', CAP_PROHIBIT, $studentrole->id, $context); + $factory = new \core_calendar\action_factory(); + $this->setUser($user2); + + // User2 checking their events. + + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user2->id); + $this->assertNull($actionevent); + + // User2 checking $user's events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user->id); + + $this->assertNull($actionevent); + } + /** * A user that has already submitted feedback should not have an action. */ @@ -322,6 +499,49 @@ class mod_feedback_lib_testcase extends advanced_testcase { $this->assertNull($action); } + /** + * A user that has already submitted feedback should not have an action, viewed by a different user. + */ + public function test_feedback_core_calendar_provide_event_action_already_submitted_for_user() { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $user = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $course = $this->getDataGenerator()->create_course(); + $feedback = $this->getDataGenerator()->create_module('feedback', ['course' => $course->id]); + $event = $this->create_action_event($course->id, $feedback->id, FEEDBACK_EVENT_TYPE_OPEN); + $cm = get_coursemodule_from_instance('feedback', $feedback->id); + $context = context_module::instance($cm->id); + + $this->setUser($user); + + $record = [ + 'feedback' => $feedback->id, + 'userid' => $user->id, + 'timemodified' => time(), + 'random_response' => 0, + 'anonymous_response' => FEEDBACK_ANONYMOUS_NO, + 'courseid' => 0, + ]; + $DB->insert_record('feedback_completed', (object) $record); + + $factory = new \core_calendar\action_factory(); + $this->setUser($user2); + + // User2 checking their events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user2->id); + $this->assertNull($actionevent); + + // User2 checking $user's events. + $actionevent = mod_feedback_core_calendar_provide_event_action($event, $factory, $user->id); + + $this->assertNull($actionevent); + } + /** * Creates an action event. * diff --git a/mod/feedback/tests/privacy_test.php b/mod/feedback/tests/privacy_test.php index f983481538c..248eef8d640 100644 --- a/mod/feedback/tests/privacy_test.php +++ b/mod/feedback/tests/privacy_test.php @@ -524,22 +524,18 @@ class mod_feedback_privacy_testcase extends provider_testcase { * @return void */ protected function create_submission_with_answers($feedback, $user, $answers, $submissioncount = 1) { - global $DB, $USER; - $origuser = $USER; - $this->setUser($user); + global $DB; $modinfo = get_fast_modinfo($feedback->course); $cm = $modinfo->get_cm($feedback->cmid); - $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $feedback->course); + $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $feedback->course, false, null, null, $user->id); $feedbackcompletion->save_response_tmp((object) $answers); $feedbackcompletion->save_response(); $this->assertEquals($submissioncount, $DB->count_records('feedback_completed', ['feedback' => $feedback->id, 'userid' => $user->id])); $this->assertEquals(count($answers), $DB->count_records('feedback_value', [ 'completed' => $feedbackcompletion->get_completed()->id])); - - $this->setUser($origuser); } /** @@ -551,19 +547,15 @@ class mod_feedback_privacy_testcase extends provider_testcase { * @return void */ protected function create_tmp_submission_with_answers($feedback, $user, $answers) { - global $DB, $USER; - $origuser = $USER; - $this->setUser($user); + global $DB; $modinfo = get_fast_modinfo($feedback->course); $cm = $modinfo->get_cm($feedback->cmid); - $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $feedback->course); + $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $feedback->course, false, null, null, $user->id); $feedbackcompletion->save_response_tmp((object) $answers); $this->assertEquals(1, $DB->count_records('feedback_completedtmp', ['feedback' => $feedback->id, 'userid' => $user->id])); $this->assertEquals(2, $DB->count_records('feedback_valuetmp', [ 'completed' => $feedbackcompletion->get_current_completed_tmp()->id])); - - $this->setUser($origuser); } }