From 71cd51b8ffb8dbc5a3a5d65b182dbb67225b36b9 Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Fri, 21 Apr 2017 02:07:39 +0000 Subject: [PATCH] MDL-58557 mod_choice: change action event callback logic --- mod/choice/lib.php | 21 ++++++++----- mod/choice/tests/lib_test.php | 55 ++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/mod/choice/lib.php b/mod/choice/lib.php index 6211721c947..5b3f07cc22d 100644 --- a/mod/choice/lib.php +++ b/mod/choice/lib.php @@ -1198,17 +1198,22 @@ function mod_choice_core_calendar_provide_event_action(calendar_event $event, $cm = get_fast_modinfo($event->courseid)->instances['choice'][$event->instance]; $choice = $DB->get_record('choice', array('id' => $event->instance), 'id, timeopen, timeclose'); + $now = time(); - if ($choice->timeopen && $choice->timeclose) { - $actionable = (time() >= $choice->timeopen) && (time() <= $choice->timeclose); - } else if ($choice->timeclose) { - $actionable = time() < $choice->timeclose; - } else if ($choice->timeopen) { - $actionable = time() >= $choice->timeopen; - } else { - $actionable = true; + if ($choice->timeclose && $choice->timeclose < $now) { + // The choice has closed so the user can no longer submit anything. + return null; } + if (choice_get_my_response($choice)) { + // There is no action if the user has already submitted their choice. + return null; + } + + // The choice is actionable if we don't have a start time or the start time is + // in the past. + $actionable = (!$choice->timeopen || $choice->timeopen <= $now); + return $factory->create_instance( get_string('viewchoices', 'choice'), new \moodle_url('/mod/choice/view.php', array('id' => $cm->id)), diff --git a/mod/choice/tests/lib_test.php b/mod/choice/tests/lib_test.php index 540671c9400..118a7d7db61 100644 --- a/mod/choice/tests/lib_test.php +++ b/mod/choice/tests/lib_test.php @@ -293,6 +293,51 @@ class mod_choice_lib_testcase extends externallib_advanced_testcase { $this->assertTrue($actionevent->is_actionable()); } + /** + * An event should not have an action if the user has already submitted a response + * to the choice activity. + */ + public function test_choice_core_calendar_provide_event_action_already_submitted() { + global $DB; + + $this->resetAfterTest(); + + $this->setAdminUser(); + + // Create a course. + $course = $this->getDataGenerator()->create_course(); + // Create user. + $student = $this->getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual'); + + // Create a choice. + $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id, + 'timeopen' => time() - DAYSECS, 'timeclose' => time() + DAYSECS)); + $context = context_module::instance($choice->cmid); + $cm = get_coursemodule_from_instance('choice', $choice->id); + + $choicewithoptions = choice_get_choice($choice->id); + $optionids = array_keys($choicewithoptions->option); + + choice_user_submit_response($optionids[0], $choice, $student->id, $course, $cm); + + // Create a calendar event. + $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN); + + // Create an action factory. + $factory = new \core_calendar\action_factory(); + + $this->setUser($student); + + // Decorate action event. + $action = mod_choice_core_calendar_provide_event_action($event, $factory); + + // Confirm no action was returned if the user has already submitted the + // choice activity. + $this->assertNull($action); + } + public function test_choice_core_calendar_provide_event_action_closed() { $this->resetAfterTest(); @@ -312,14 +357,10 @@ class mod_choice_lib_testcase extends externallib_advanced_testcase { $factory = new \core_calendar\action_factory(); // Decorate action event. - $actionevent = mod_choice_core_calendar_provide_event_action($event, $factory); + $action = mod_choice_core_calendar_provide_event_action($event, $factory); - // Confirm the event was decorated. - $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); - $this->assertEquals(get_string('viewchoices', 'choice'), $actionevent->get_name()); - $this->assertInstanceOf('moodle_url', $actionevent->get_url()); - $this->assertEquals(1, $actionevent->get_item_count()); - $this->assertFalse($actionevent->is_actionable()); + // Confirm not action was provided for a closed activity. + $this->assertNull($action); } public function test_choice_core_calendar_provide_event_action_open_in_future() { -- 2.43.0