diff --git a/calendar/classes/external/event_exporter_base.php b/calendar/classes/external/event_exporter_base.php index 0f17777b4e8..fb9a62d2286 100644 --- a/calendar/classes/external/event_exporter_base.php +++ b/calendar/classes/external/event_exporter_base.php @@ -247,6 +247,9 @@ class event_exporter_base extends exporter { $values['iscourseevent'] = false; $values['iscategoryevent'] = false; if ($moduleproxy = $event->get_course_module()) { + // We need a separate property to flag if an event is action event. + // That's required because canedit return true but action action events cannot be edited on the calendar UI. + // But they are considered editable because you can drag and drop the event on the month view. $values['isactionevent'] = true; } else if ($event->get_type() == 'course') { $values['iscourseevent'] = true; diff --git a/calendar/templates/event_item.mustache b/calendar/templates/event_item.mustache index 91d07519887..721d681b714 100644 --- a/calendar/templates/event_item.mustache +++ b/calendar/templates/event_item.mustache @@ -49,9 +49,11 @@ {{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}} {{/candelete}} - - {{#pix}}t/edit, core, {{#str}}edit{{/str}}{{/pix}} - + {{^isactionevent}} + + {{#pix}}t/edit, core, {{#str}}edit{{/str}}{{/pix}} + + {{/isactionevent}} {{/canedit}} {{#icon}}{{#pix}} {{key}}, {{component}}, {{alttext}} {{/pix}}{{/icon}} diff --git a/completion/classes/api.php b/completion/classes/api.php index f8040c5864c..b569e3791d1 100644 --- a/completion/classes/api.php +++ b/completion/classes/api.php @@ -94,7 +94,7 @@ class api { $event->timeduration = 0; $calendarevent = \calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is no longer needed. $calendarevent = \calendar_event::load($event->id); @@ -115,7 +115,7 @@ class api { $event->visible = instance_is_visible($modulename, $instance); $event->timeduration = 0; - \calendar_event::create($event); + \calendar_event::create($event, false); } } diff --git a/completion/tests/behat/completion_no_calendar_capabilities.feature b/completion/tests/behat/completion_no_calendar_capabilities.feature new file mode 100644 index 00000000000..f690f76e556 --- /dev/null +++ b/completion/tests/behat/completion_no_calendar_capabilities.feature @@ -0,0 +1,44 @@ +@core @core_completion +Feature: Completion with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create activities with completion enabled without calendar capabilities + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | enablecompletion | + | Course 1 | C1 | 0 | 1 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing completion date + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Forum" to section "1" and I fill the form with: + | Forum name | Test forum name | + | Description | Test forum description | + | Completion tracking | Show activity as complete when conditions are met | + | id_completionexpected_enabled | 1 | + | id_completionexpected_day | 1 | + | id_completionexpected_month | 1 | + | id_completionexpected_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test forum name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_completionexpected_year | 2018 | + And I press "Save and return to course" + Then I should see "Test forum name" diff --git a/completion/tests/capabilities_test.php b/completion/tests/capabilities_test.php new file mode 100644 index 00000000000..5dd4239e955 --- /dev/null +++ b/completion/tests/capabilities_test.php @@ -0,0 +1,57 @@ +. + +/** + * Tests that completion works without requiring unnecessary capabilities. + * + * @package core_completion + * @copyright 2018 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Tests that completion works without requiring unnecessary capabilities. + * + * @package core_completion + * @copyright 2018 University of Nottingham + * @author Neill Magill + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_completion_capabilities_testcase extends advanced_testcase { + /** + * A user who does not have capabilities to add events to the calendar should be able to create activities. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(['enablecompletion' => 1]); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_forum'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $params = array( + 'course' => $course->id, + 'completionexpected' => time() + 2000, + ); + $generator->create_instance($params); + } +} diff --git a/mod/assign/lib.php b/mod/assign/lib.php index ee787849bc4..edc5c50a323 100644 --- a/mod/assign/lib.php +++ b/mod/assign/lib.php @@ -345,7 +345,7 @@ function assign_update_events($assign, $override = null) { unset($event->id); } $event->name = $eventname.' ('.get_string('duedate', 'assign').')'; - calendar_event::create($event); + calendar_event::create($event, false); } } diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 601cc21c33d..5ae989675b4 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -1332,9 +1332,9 @@ class assign { // Now process the event. if ($event->id) { $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { - calendar_event::create($event); + calendar_event::create($event, false); } } else { $DB->delete_records('event', array('modulename' => 'assign', 'instance' => $instance->id, @@ -1353,9 +1353,9 @@ class assign { // Now process the event. if ($event->id) { $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { - calendar_event::create($event); + calendar_event::create($event, false); } } else { $DB->delete_records('event', array('modulename' => 'assign', 'instance' => $instance->id, diff --git a/mod/assign/tests/behat/assign_no_calendar_capabilities.feature b/mod/assign/tests/behat/assign_no_calendar_capabilities.feature new file mode 100644 index 00000000000..e97a77db693 --- /dev/null +++ b/mod/assign/tests/behat/assign_no_calendar_capabilities.feature @@ -0,0 +1,58 @@ +@mod @mod_assign +Feature: Assignment with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create assignments even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing an assignment + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Assignment" to section "1" and I fill the form with: + | Assignment name | Test assignment name | + | Description | Test assignment description | + | id_allowsubmissionsfromdate_enabled | 1 | + | id_allowsubmissionsfromdate_day | 1 | + | id_allowsubmissionsfromdate_month | 1 | + | id_allowsubmissionsfromdate_year | 2017 | + | id_duedate_enabled | 1 | + | id_duedate_day | 1 | + | id_duedate_month | 2 | + | id_duedate_year | 2017 | + | id_cutoffdate_enabled | 1 | + | id_cutoffdate_day | 2 | + | id_cutoffdate_month | 2 | + | id_cutoffdate_year | 2017 | + | id_gradingduedate_enabled | 1 | + | id_gradingduedate_day | 1 | + | id_gradingduedate_month | 3 | + | id_gradingduedate_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test assignment name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_allowsubmissionsfromdate_year | 2018 | + | id_duedate_year | 2018 | + | id_cutoffdate_year | 2018 | + | id_gradingduedate_year | 2018 | + And I press "Save and return to course" + Then I should see "Test assignment name" diff --git a/mod/assign/tests/lib_test.php b/mod/assign/tests/lib_test.php index 54054b3f256..759f534818a 100644 --- a/mod/assign/tests/lib_test.php +++ b/mod/assign/tests/lib_test.php @@ -1472,4 +1472,29 @@ class mod_assign_lib_testcase extends advanced_testcase { // is changed. $this->assertNotEmpty($moduleupdatedevents); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create an assignment. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_assign'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'allowsubmissionsfromdate' => $time, + 'duedate' => $time + 500, + 'cutoffdate' => $time + 600, + 'gradingduedate' => $time + 700, + ); + $generator->create_instance($params); + } } diff --git a/mod/chat/lib.php b/mod/chat/lib.php index be20199bbba..128924e9e73 100644 --- a/mod/chat/lib.php +++ b/mod/chat/lib.php @@ -131,7 +131,7 @@ function chat_add_instance($chat) { $event->timesort = $chat->chattime; $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } if (!empty($chat->completionexpected)) { @@ -171,7 +171,7 @@ function chat_update_instance($chat) { $event->timesort = $chat->chattime; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Do not publish this event, so delete it. $calendarevent = calendar_event::load($event->id); @@ -194,7 +194,7 @@ function chat_update_instance($chat) { $event->timesort = $chat->chattime; $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } @@ -498,7 +498,7 @@ function chat_prepare_update_events($chat, $cm = null) { if ($event->id = $DB->get_field('event', 'id', array('modulename' => 'chat', 'instance' => $chat->id, 'eventtype' => CHAT_EVENT_TYPE_CHATTIME))) { $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else if ($chat->schedule > 0) { // The chat is scheduled and the event should be published. $event->courseid = $chat->course; @@ -509,7 +509,7 @@ function chat_prepare_update_events($chat, $cm = null) { $event->eventtype = CHAT_EVENT_TYPE_CHATTIME; $event->timeduration = 0; $event->visible = $cm->visible; - calendar_event::create($event); + calendar_event::create($event, false); } } diff --git a/mod/chat/tests/behat/chat_no_calendar_capabilities.feature b/mod/chat/tests/behat/chat_no_calendar_capabilities.feature new file mode 100644 index 00000000000..a9903493b4c --- /dev/null +++ b/mod/chat/tests/behat/chat_no_calendar_capabilities.feature @@ -0,0 +1,43 @@ +@mod @mod_chat +Feature: Chat with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create chats even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing a chat + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Chat" to section "1" and I fill the form with: + | Name of this chat room | Test chat name | + | Description | Test chat description | + | Repeat/publish session times | No repeats - publish the specified time only | + | id_chattime_day | 1 | + | id_chattime_month | 1 | + | id_chattime_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test chat name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_chattime_year | 2018 | + And I press "Save and return to course" + Then I should see "Test chat name" diff --git a/mod/chat/tests/lib_test.php b/mod/chat/tests/lib_test.php index 4edef1aea5a..6de2379f7eb 100644 --- a/mod/chat/tests/lib_test.php +++ b/mod/chat/tests/lib_test.php @@ -163,4 +163,25 @@ class mod_chat_lib_testcase extends advanced_testcase { return calendar_event::create($event); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create an chat. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_chat'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $params = array( + 'course' => $course->id, + 'chattime' => time() + 500, + ); + $generator->create_instance($params); + } } diff --git a/mod/choice/locallib.php b/mod/choice/locallib.php index ab33373c14e..b5cb29b8213 100644 --- a/mod/choice/locallib.php +++ b/mod/choice/locallib.php @@ -58,7 +58,7 @@ function choice_set_events($choice) { $event->visible = instance_is_visible('choice', $choice); $event->timeduration = 0; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is on longer needed. $calendarevent = calendar_event::load($event->id); @@ -78,7 +78,7 @@ function choice_set_events($choice) { $event->timesort = $choice->timeopen; $event->visible = instance_is_visible('choice', $choice); $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } @@ -97,7 +97,7 @@ function choice_set_events($choice) { $event->visible = instance_is_visible('choice', $choice); $event->timeduration = 0; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is on longer needed. $calendarevent = calendar_event::load($event->id); @@ -117,7 +117,7 @@ function choice_set_events($choice) { $event->timesort = $choice->timeclose; $event->visible = instance_is_visible('choice', $choice); $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } } diff --git a/mod/choice/tests/behat/choice_no_calendar_capabilities.feature b/mod/choice/tests/behat/choice_no_calendar_capabilities.feature new file mode 100644 index 00000000000..0f4554c7c78 --- /dev/null +++ b/mod/choice/tests/behat/choice_no_calendar_capabilities.feature @@ -0,0 +1,50 @@ +@mod @mod_choice +Feature: Choice with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create choices even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing a choice + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Choice" to section "1" and I fill the form with: + | Choice name | Test choice name | + | Description | Test choice description | + | option[0] | Option 1 | + | option[1] | Option 2 | + | id_timeopen_enabled | 1 | + | id_timeopen_day | 1 | + | id_timeopen_month | 1 | + | id_timeopen_year | 2017 | + | id_timeclose_enabled | 1 | + | id_timeclose_day | 1 | + | id_timeclose_month | 2 | + | id_timeclose_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test choice name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_timeopen_year | 2018 | + | id_timeclose_year | 2018 | + And I press "Save and return to course" + Then I should see "Test choice name" diff --git a/mod/choice/tests/lib_test.php b/mod/choice/tests/lib_test.php index eb452e16dc1..72a32fe3a97 100644 --- a/mod/choice/tests/lib_test.php +++ b/mod/choice/tests/lib_test.php @@ -979,4 +979,27 @@ class mod_choice_lib_testcase extends externallib_advanced_testcase { $this->expectException('moodle_exception'); choice_user_submit_response($optionids[1], $choicewithoptions, $user2->id, $course, $cm); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create an choice. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_choice'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'timeopen' => $time + 200, + 'timeclose' => $time + 500, + ); + $generator->create_instance($params); + } } diff --git a/mod/data/edit.php b/mod/data/edit.php index 5c6a6bf944c..d7ec1dbc1ad 100644 --- a/mod/data/edit.php +++ b/mod/data/edit.php @@ -156,6 +156,7 @@ if ($rid) { $PAGE->set_title($data->name); $PAGE->set_heading($course->fullname); +$PAGE->force_settings_menu(true); // Process incoming data for adding/updating records. diff --git a/mod/data/export.php b/mod/data/export.php index b2444f35ebd..e6d6e50213c 100644 --- a/mod/data/export.php +++ b/mod/data/export.php @@ -84,6 +84,7 @@ if($mform->is_cancelled()) { // build header to match the rest of the UI $PAGE->set_title($data->name); $PAGE->set_heading($course->fullname); + $PAGE->force_settings_menu(true); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($data->name), 2); echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro'); diff --git a/mod/data/field.php b/mod/data/field.php index d5040afc690..f014bb13cff 100644 --- a/mod/data/field.php +++ b/mod/data/field.php @@ -241,6 +241,7 @@ foreach ($plugins as $plugin=>$fulldir){ asort($menufield); //sort in alphabetical order $PAGE->set_title(get_string('course') . ': ' . $course->fullname); $PAGE->set_heading($course->fullname); +$PAGE->force_settings_menu(true); $PAGE->set_pagetype('mod-data-field-' . $newtype); if (($mode == 'new') && (!empty($newtype)) && confirm_sesskey()) { /// Adding a new field diff --git a/mod/data/locallib.php b/mod/data/locallib.php index e2f6442ea14..db8a7791c1c 100644 --- a/mod/data/locallib.php +++ b/mod/data/locallib.php @@ -613,7 +613,7 @@ function data_set_events($data) { $event->visible = instance_is_visible('data', $data); $event->timeduration = 0; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is on longer needed. $calendarevent = calendar_event::load($event->id); @@ -633,7 +633,7 @@ function data_set_events($data) { $event->timesort = $data->timeavailablefrom; $event->visible = instance_is_visible('data', $data); $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } @@ -652,7 +652,7 @@ function data_set_events($data) { $event->visible = instance_is_visible('data', $data); $event->timeduration = 0; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is on longer needed. $calendarevent = calendar_event::load($event->id); @@ -672,7 +672,7 @@ function data_set_events($data) { $event->timesort = $data->timeavailableto; $event->visible = instance_is_visible('data', $data); $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } } diff --git a/mod/data/preset.php b/mod/data/preset.php index 5cb45e95090..9a166b2d37d 100644 --- a/mod/data/preset.php +++ b/mod/data/preset.php @@ -51,6 +51,7 @@ require_capability('mod/data:managetemplates', $context); $PAGE->set_url(new moodle_url('/mod/data/preset.php', array('d'=>$data->id))); $PAGE->set_title(get_string('course') . ': ' . $course->fullname); $PAGE->set_heading($course->fullname); +$PAGE->force_settings_menu(true); // fill in missing properties needed for updating of instance $data->course = $cm->course; diff --git a/mod/data/templates.php b/mod/data/templates.php index 8fa48c53518..ce5af6c782a 100644 --- a/mod/data/templates.php +++ b/mod/data/templates.php @@ -103,6 +103,7 @@ $PAGE->requires->js('/mod/data/data.js'); $PAGE->set_title($data->name); $PAGE->set_heading($course->fullname); $PAGE->set_pagelayout('admin'); +$PAGE->force_settings_menu(true); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($data->name), 2); echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro'); diff --git a/mod/data/tests/behat/data_no_calendar_capabilities.feature b/mod/data/tests/behat/data_no_calendar_capabilities.feature new file mode 100644 index 00000000000..98d7d490311 --- /dev/null +++ b/mod/data/tests/behat/data_no_calendar_capabilities.feature @@ -0,0 +1,58 @@ +@mod @mod_data +Feature: Database with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create databases even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing a database + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Database" to section "1" and I fill the form with: + | Name | Test database name | + | Description | Test database description | + | id_timeavailablefrom_enabled | 1 | + | id_timeavailablefrom_day | 1 | + | id_timeavailablefrom_month | 1 | + | id_timeavailablefrom_year | 2017 | + | id_timeavailableto_enabled | 1 | + | id_timeavailableto_day | 1 | + | id_timeavailableto_month | 4 | + | id_timeavailableto_year | 2017 | + | id_timeviewfrom_enabled | 1 | + | id_timeviewfrom_day | 1 | + | id_timeviewfrom_month | 3 | + | id_timeviewfrom_year | 2017 | + | id_timeviewto_enabled | 1 | + | id_timeviewto_day | 1 | + | id_timeviewto_month | 4 | + | id_timeviewto_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test database name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_timeavailablefrom_year | 2018 | + | id_timeavailableto_year | 2018 | + | id_timeviewfrom_year | 2018 | + | id_timeviewto_year | 2018 | + And I press "Save and return to course" + Then I should see "Test database name" diff --git a/mod/data/tests/lib_test.php b/mod/data/tests/lib_test.php index 351879bb5cf..0117f8b01fd 100644 --- a/mod/data/tests/lib_test.php +++ b/mod/data/tests/lib_test.php @@ -1483,4 +1483,29 @@ class mod_data_lib_testcase extends advanced_testcase { $this->assertEquals(mod_data_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); $this->assertEquals(mod_data_get_completion_active_rule_descriptions(new stdClass()), []); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create an database. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_data'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'timeavailablefrom' => $time + 200, + 'timeavailableto' => $time + 2000, + 'timeviewfrom' => $time + 400, + 'timeviewto' => $time + 2000, + ); + $generator->create_instance($params); + } } diff --git a/mod/feedback/lib.php b/mod/feedback/lib.php index 724647a51ec..d3302e05f4c 100644 --- a/mod/feedback/lib.php +++ b/mod/feedback/lib.php @@ -828,7 +828,7 @@ function feedback_set_events($feedback) { // Calendar event exists so update it. $event->id = $eventid; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Event doesn't exist so create one. $event->courseid = $feedback->course; @@ -837,7 +837,7 @@ function feedback_set_events($feedback) { $event->modulename = 'feedback'; $event->instance = $feedback->id; $event->eventtype = FEEDBACK_EVENT_TYPE_OPEN; - calendar_event::create($event); + calendar_event::create($event, false); } } else if ($eventid) { // Calendar event is on longer needed. @@ -863,7 +863,7 @@ function feedback_set_events($feedback) { // Calendar event exists so update it. $event->id = $eventid; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Event doesn't exist so create one. $event->courseid = $feedback->course; @@ -871,7 +871,7 @@ function feedback_set_events($feedback) { $event->userid = 0; $event->modulename = 'feedback'; $event->instance = $feedback->id; - calendar_event::create($event); + calendar_event::create($event, false); } } else if ($eventid) { // Calendar event is on longer needed. diff --git a/mod/feedback/tests/behat/feedback_no_calendar_capabilities.feature b/mod/feedback/tests/behat/feedback_no_calendar_capabilities.feature new file mode 100644 index 00000000000..bf348ad2c7a --- /dev/null +++ b/mod/feedback/tests/behat/feedback_no_calendar_capabilities.feature @@ -0,0 +1,48 @@ +@mod @mod_feedback +Feature: Feedback with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create feedbacks even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing a feedback + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Feedback" to section "1" and I fill the form with: + | Name | Test feedback name | + | Description | Test feedback description | + | id_timeopen_enabled | 1 | + | id_timeopen_day | 1 | + | id_timeopen_month | 1 | + | id_timeopen_year | 2017 | + | id_timeclose_enabled | 1 | + | id_timeclose_day | 1 | + | id_timeclose_month | 2 | + | id_timeclose_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test feedback name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_timeopen_year | 2018 | + | id_timeclose_year | 2018 | + And I press "Save and return to course" + Then I should see "Test feedback name" diff --git a/mod/feedback/tests/lib_test.php b/mod/feedback/tests/lib_test.php index 37cbf30e7b2..0990f403be6 100644 --- a/mod/feedback/tests/lib_test.php +++ b/mod/feedback/tests/lib_test.php @@ -852,4 +852,27 @@ class mod_feedback_lib_testcase extends advanced_testcase { // was successfully modified. $this->assertNotEmpty($moduleupdatedevents); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create an feedback. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_feedback'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'timeopen' => $time + 200, + 'timeclose' => $time + 2000, + ); + $generator->create_instance($params); + } } diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index 96931c527b3..5526c72a64e 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -213,7 +213,7 @@ function lesson_update_events($lesson, $override = null) { } $event->name = get_string('lessoneventopens', 'lesson', $eventname); // The method calendar_event::create will reuse a db record if the id field is set. - calendar_event::create($event); + calendar_event::create($event, false); } if ($deadline && $addclose) { if ($oldevent = array_shift($oldevents)) { @@ -232,7 +232,7 @@ function lesson_update_events($lesson, $override = null) { $event->priority = $closepriorities[$deadline]; } } - calendar_event::create($event); + calendar_event::create($event, false); } } } diff --git a/mod/lesson/tests/behat/lesson_no_calendar_capabilities.feature b/mod/lesson/tests/behat/lesson_no_calendar_capabilities.feature new file mode 100644 index 00000000000..80e5cf8f381 --- /dev/null +++ b/mod/lesson/tests/behat/lesson_no_calendar_capabilities.feature @@ -0,0 +1,48 @@ +@mod @mod_lesson +Feature: Lesson with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create lessons even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing a lesson + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Lesson" to section "1" and I fill the form with: + | Name | Test lesson name | + | Description | Test lesson description | + | id_available_enabled | 1 | + | id_available_day | 1 | + | id_available_month | 1 | + | id_available_year | 2017 | + | id_deadline_enabled | 1 | + | id_deadline_day | 1 | + | id_deadline_month | 2 | + | id_deadline_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test lesson name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_available_year | 2018 | + | id_deadline_year | 2018 | + And I press "Save and return to course" + Then I should see "Test lesson name" diff --git a/mod/lesson/tests/lib_test.php b/mod/lesson/tests/lib_test.php index 5cd91a22856..0d1005c97c2 100644 --- a/mod/lesson/tests/lib_test.php +++ b/mod/lesson/tests/lib_test.php @@ -441,4 +441,27 @@ class mod_lesson_lib_testcase extends advanced_testcase { $this->assertEquals(mod_lesson_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); $this->assertEquals(mod_lesson_get_completion_active_rule_descriptions(new stdClass()), []); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create an lesson. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_lesson'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'available' => $time + 200, + 'deadline' => $time + 2000, + ); + $generator->create_instance($params); + } } diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index f92f5e1d635..65c9f5c5e31 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -1339,7 +1339,7 @@ function quiz_update_events($quiz, $override = null) { } $event->name = get_string('quizeventopens', 'quiz', $eventname); // The method calendar_event::create will reuse a db record if the id field is set. - calendar_event::create($event); + calendar_event::create($event, false); } if ($timeclose && $addclose) { if ($oldevent = array_shift($oldevents)) { @@ -1358,7 +1358,7 @@ function quiz_update_events($quiz, $override = null) { $event->priority = $closepriorities[$timeclose]; } } - calendar_event::create($event); + calendar_event::create($event, false); } } } diff --git a/mod/quiz/tests/behat/quiz_no_calendar_capabilities.feature b/mod/quiz/tests/behat/quiz_no_calendar_capabilities.feature new file mode 100644 index 00000000000..52b1f216b70 --- /dev/null +++ b/mod/quiz/tests/behat/quiz_no_calendar_capabilities.feature @@ -0,0 +1,48 @@ +@mod @mod_quiz +Feature: Quiz with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create quiz even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + Scenario: Editing a quiz + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "Quiz" to section "1" and I fill the form with: + | Name | Test quiz name | + | Description | Test quiz description | + | id_timeopen_enabled | 1 | + | id_timeopen_day | 1 | + | id_timeopen_month | 1 | + | id_timeopen_year | 2017 | + | id_timeclose_enabled | 1 | + | id_timeclose_day | 1 | + | id_timeclose_month | 2 | + | id_timeclose_year | 2017 | + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test quiz name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_timeopen_year | 2018 | + | id_timeclose_year | 2018 | + And I press "Save and return to course" + Then I should see "Test quiz name" diff --git a/mod/quiz/tests/lib_test.php b/mod/quiz/tests/lib_test.php index 8a54c36eb93..65d8b56b111 100644 --- a/mod/quiz/tests/lib_test.php +++ b/mod/quiz/tests/lib_test.php @@ -736,4 +736,27 @@ class mod_quiz_lib_testcase extends advanced_testcase { $this->assertEquals(mod_quiz_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); $this->assertEquals(mod_quiz_get_completion_active_rule_descriptions(new stdClass()), []); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create a quiz. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_quiz'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'timeopen' => $time + 200, + 'timeclose' => $time + 2000, + ); + $generator->create_instance($params); + } } diff --git a/mod/scorm/locallib.php b/mod/scorm/locallib.php index 869de923df9..8ba8322618e 100644 --- a/mod/scorm/locallib.php +++ b/mod/scorm/locallib.php @@ -2385,7 +2385,7 @@ function scorm_update_calendar(stdClass $scorm, $cmid) { $event->timeduration = 0; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is on longer needed. $calendarevent = calendar_event::load($event->id); @@ -2406,7 +2406,7 @@ function scorm_update_calendar(stdClass $scorm, $cmid) { $event->visible = instance_is_visible('scorm', $scorm); $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } @@ -2426,7 +2426,7 @@ function scorm_update_calendar(stdClass $scorm, $cmid) { $event->timeduration = 0; $calendarevent = calendar_event::load($event->id); - $calendarevent->update($event); + $calendarevent->update($event, false); } else { // Calendar event is on longer needed. $calendarevent = calendar_event::load($event->id); @@ -2447,7 +2447,7 @@ function scorm_update_calendar(stdClass $scorm, $cmid) { $event->visible = instance_is_visible('scorm', $scorm); $event->timeduration = 0; - calendar_event::create($event); + calendar_event::create($event, false); } } diff --git a/mod/scorm/tests/behat/scorm_no_calendar_capabilities.feature b/mod/scorm/tests/behat/scorm_no_calendar_capabilities.feature new file mode 100644 index 00000000000..77cd7a036c5 --- /dev/null +++ b/mod/scorm/tests/behat/scorm_no_calendar_capabilities.feature @@ -0,0 +1,52 @@ +@mod @mod_scorm +Feature: Scorm with no calendar capabilites + In order to allow work effectively + As a teacher + I need to be able to create SCORM activities even when I cannot edit calendar events + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "admin" + And I am on "Course 1" course homepage + And I navigate to "Users > Permissions" in current page administration + And I override the system permissions of "Teacher" role with: + | capability | permission | + | moodle/calendar:manageentries | Prohibit | + And I log out + + @javascript @_file_upload @_switch_iframe + Scenario: Editing a chat + Given I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + When I add a "SCORM package" to section "1" + And I set the following fields to these values: + | Name | Test scorm name | + | Description | Test scorm description | + | id_timeopen_enabled | 1 | + | id_timeopen_day | 1 | + | id_timeopen_month | 1 | + | id_timeopen_year | 2017 | + | id_timeclose_enabled | 1 | + | id_timeclose_day | 1 | + | id_timeclose_month | 2 | + | id_timeclose_year | 2017 | + And I upload "mod/scorm/tests/packages/singlesco_scorm12.zip" file to "Package file" filemanager + And I click on "Save and display" "button" + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Test scorm name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | id_timeopen_year | 2018 | + | id_timeclose_year | 2018 | + And I press "Save and return to course" + Then I should see "Test scorm name" diff --git a/mod/scorm/tests/lib_test.php b/mod/scorm/tests/lib_test.php index 9440e24d63d..094027b9e11 100644 --- a/mod/scorm/tests/lib_test.php +++ b/mod/scorm/tests/lib_test.php @@ -433,4 +433,27 @@ class mod_scorm_lib_testcase extends externallib_advanced_testcase { $this->assertEquals(mod_scorm_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions); $this->assertEquals(mod_scorm_get_completion_active_rule_descriptions(new stdClass()), []); } + + /** + * A user who does not have capabilities to add events to the calendar should be able to create a SCORM. + */ + public function test_creation_with_no_calendar_capabilities() { + $this->resetAfterTest(); + $course = self::getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $roleid = self::getDataGenerator()->create_role(); + self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); + assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); + $generator = self::getDataGenerator()->get_plugin_generator('mod_scorm'); + // Create an instance as a user without the calendar capabilities. + $this->setUser($user); + $time = time(); + $params = array( + 'course' => $course->id, + 'timeopen' => $time + 200, + 'timeclose' => $time + 2000, + ); + $generator->create_instance($params); + } }