From 69ced43b54bbf08468862580e6f10cc7d64a9d95 Mon Sep 17 00:00:00 2001 From: ferishili Date: Thu, 14 Nov 2024 15:04:11 +0100 Subject: [PATCH] add behat test and its adjustments --- classes/local/apibridge.php | 4 + classes/local/massaction_helper.php | 16 +- deleteevent_massaction.php | 2 +- index.php | 18 ++- overview_videos.php | 8 +- tests/behat/behat_block_opencast.php | 36 +++++ .../behat/block_opencast_massactions.feature | 145 ++++++++++++++++++ 7 files changed, 211 insertions(+), 18 deletions(-) create mode 100644 tests/behat/block_opencast_massactions.feature diff --git a/classes/local/apibridge.php b/classes/local/apibridge.php index d2d1db3c..93ea8618 100644 --- a/classes/local/apibridge.php +++ b/classes/local/apibridge.php @@ -3083,6 +3083,7 @@ public function generate_studio_url_path($courseid, $seriesid) { /** * Checks if the user has the capability to update metadata for multiple events in a course. + * We use specific checker method, in case there would be more conditions later on. * * @param int $courseid The ID of the course. * @@ -3095,6 +3096,7 @@ public function can_update_metadata_massaction($courseid) { /** * Checks if the user has the capability to delete multiple events in a course. + * We use specific checker method, in case there would be more conditions later on. * * @param int $courseid The ID of the course. * @@ -3107,6 +3109,7 @@ public function can_delete_massaction($courseid) { /** * Checks if the user has the capability to change the visibility of multiple events in a course. + * We use specific checker method, in case there would be more conditions later on. * * @param int $courseid The ID of the course. * @@ -3119,6 +3122,7 @@ public function can_change_visibility_massaction($courseid) { /** * Checks if the user has the capability to start workflows for multiple events in a course. + * We use specific checker method, in case there would be more conditions later on. * * @param int $courseid The ID of the course. * diff --git a/classes/local/massaction_helper.php b/classes/local/massaction_helper.php index c49b72c0..32e6b922 100644 --- a/classes/local/massaction_helper.php +++ b/classes/local/massaction_helper.php @@ -148,8 +148,12 @@ public function render_master_checkbox() { 'classes' => self::CHECKBOX_SELECTALL_CLASSNAME, 'id' => self::CHECKBOX_SELECTALL_ID, 'name' => self::CHECKBOX_SELECTALL_ID, - 'label' => get_string('select'), - 'labelclasses' => 'accesshide', + 'label' => get_string('selectall'), + // Consistent label to prevent unwanted text change when we automatically uncheck. + 'selectall' => get_string('selectall'), + 'deselectall' => get_string('selectall'), + // We need the classes specially for behat test to pickup the checkbox. + 'labelclasses' => 'form-check-label d-block pe-2 sr-only', ]); return $OUTPUT->render($mastercheckbox); } @@ -191,8 +195,10 @@ public function render_item_checkbox(stdClass $video, bool $isselectable = true) 'id' => 'ocvideo' . $video->identifier, 'name' => 'ocvideo' . $video->title, 'checked' => false, - 'label' => get_string('select'), - 'labelclasses' => 'accesshide', + // For behat tests to pickup the checkbox easier, we provide the title as well. + 'label' => get_string('select') . ' ' . $video->title, + // We need the classes specially for behat test to pickup the checkbox. + 'labelclasses' => 'form-check-label d-block pe-2 sr-only', ]; $checkbox = new \core\output\checkbox_toggleall(self::TOGGLE_GROUP_NAME, false, $selectableattributes); $checkboxhtml = $OUTPUT->render($checkbox); @@ -292,7 +298,7 @@ public function add_massaction($name, $url, $enable = true) { * @param bool $enable Whether the mass action should be enabled (true) or disabled (false). Default is true. * */ - public function massaction_activation($item, $enable = true) { + public function massaction_action_activation($item, $enable = true) { if (isset($this->massactions[$item])) { $this->massactions[$item]['enable'] = $enable; } diff --git a/deleteevent_massaction.php b/deleteevent_massaction.php index e6d4d259..17c13926 100644 --- a/deleteevent_massaction.php +++ b/deleteevent_massaction.php @@ -38,7 +38,7 @@ $series = optional_param('series', null, PARAM_ALPHANUMEXT); $baseurl = new moodle_url('/blocks/opencast/deleteevent_massaction.php', - ['identifier' => $identifier, 'courseid' => $courseid, 'ocinstanceid' => $ocinstanceid, + ['courseid' => $courseid, 'ocinstanceid' => $ocinstanceid, 'redirectpage' => $redirectpage, 'series' => $series, ]); $PAGE->set_url($baseurl); diff --git a/index.php b/index.php index 53e525ff..af5a0954 100644 --- a/index.php +++ b/index.php @@ -175,22 +175,22 @@ // Mass-Action configuration for update metadata. if (!$apibridge->can_update_metadata_massaction($courseid)) { - $massaction->massaction_activation(massaction_helper::MASSACTION_UPDATEMETADATA, false); + $massaction->massaction_action_activation(massaction_helper::MASSACTION_UPDATEMETADATA, false); } // Mass-Action configuration for delete. if (!$apibridge->can_delete_massaction($courseid)) { - $massaction->massaction_activation(massaction_helper::MASSACTION_DELETE, false); + $massaction->massaction_action_activation(massaction_helper::MASSACTION_DELETE, false); } // Mass-Action configuration for change visibility. if (!$apibridge->can_change_visibility_massaction($courseid) || !$toggleaclroles) { - $massaction->massaction_activation(massaction_helper::MASSACTION_CHANGEVISIBILITY, false); + $massaction->massaction_action_activation(massaction_helper::MASSACTION_CHANGEVISIBILITY, false); } // Mass-Action configuration for start workflow. if (!$apibridge->can_start_workflow_massaction($courseid) || !$workflowsavailable) { - $massaction->massaction_activation(massaction_helper::MASSACTION_STARTWORKFLOW, false); + $massaction->massaction_action_activation(massaction_helper::MASSACTION_STARTWORKFLOW, false); } // We add the select columns and headers into the beginning of the headers and columns arrays, when mass actions are there! @@ -200,6 +200,12 @@ } foreach ($headers as $i => $header) { + // Take care of selectall at first. + if ($header == 'selectall') { + $headers[$i] = $massaction->render_master_checkbox(); + continue; + } + if (!empty($header)) { $headers[$i] = get_string('h' . $header, 'block_opencast'); } else { @@ -219,10 +225,6 @@ $legendicon = $renderer->render_from_template('block_opencast/table_legend_help_icon', $context); $headers[$i] .= $legendicon; } - - if ($header == 'selectall') { - $headers[$i] = $massaction->render_master_checkbox(); - } } $perpage = optional_param('perpage', 20, PARAM_INT); diff --git a/overview_videos.php b/overview_videos.php index 1997bcf5..06d08a51 100644 --- a/overview_videos.php +++ b/overview_videos.php @@ -166,7 +166,7 @@ $massaction = new massaction_helper(); // Mass-Action configuration for update metadata. if (!$hasaddvideopermission) { - $massaction->massaction_activation(massaction_helper::MASSACTION_UPDATEMETADATA, false); + $massaction->massaction_action_activation(massaction_helper::MASSACTION_UPDATEMETADATA, false); } else { // When it is offered, we add extra parameters. $massaction->set_action_path_parameter(massaction_helper::MASSACTION_UPDATEMETADATA, 'redirectpage', 'overviewvideos'); @@ -175,7 +175,7 @@ // Mass-Action configuration for delete. if (!$hasdeletepermission) { - $massaction->massaction_activation(massaction_helper::MASSACTION_DELETE, false); + $massaction->massaction_action_activation(massaction_helper::MASSACTION_DELETE, false); } else { // When it is offered, we add extra parameters. $massaction->set_action_path_parameter(massaction_helper::MASSACTION_DELETE, 'redirectpage', 'overviewvideos'); @@ -183,8 +183,8 @@ } // No visiblity change and no strat workflow is allowed from overview page! -$massaction->massaction_activation(massaction_helper::MASSACTION_CHANGEVISIBILITY, false); -$massaction->massaction_activation(massaction_helper::MASSACTION_STARTWORKFLOW, false); +$massaction->massaction_action_activation(massaction_helper::MASSACTION_CHANGEVISIBILITY, false); +$massaction->massaction_action_activation(massaction_helper::MASSACTION_STARTWORKFLOW, false); // We add the select columns and headers into the beginning of the headers and columns arrays, when mass actions are there! if ($massaction->has_massactions()) { diff --git a/tests/behat/behat_block_opencast.php b/tests/behat/behat_block_opencast.php index 9daca684..aca43bf1 100644 --- a/tests/behat/behat_block_opencast.php +++ b/tests/behat/behat_block_opencast.php @@ -225,4 +225,40 @@ public function the_lti_tool_in_the_course_should_have_the_custom_parameter($lti " instead of expected \"$customparameter\"", $this->getSession()); } } + + /** + * Checks whether the checkbox is checked, throws exception if it is not checked. + * + * @Then /^the "(?P(?:[^"]|\\")*)" checkbox should be checked$/ + * @throws ExpectationException Thrown by behat_base::find and isChecked + * @param string $element Element we look on + */ + public function the_element_checkbox_should_be_checked($element) { + $element = $this->find("checkbox", $element); + if (!$element) { + throw new ExpectationException('Checkbox not found with the provided XPath.', $this->getSession()); + } + + if (!$element->isChecked()) { + throw new ExpectationException('The checkbox is not checked.', $this->getSession()); + } + } + + /** + * Checks whether the checkbox is not checked, throws error if it is checked. + * + * @Then /^the "(?P(?:[^"]|\\")*)" checkbox should not be checked$/ + * @throws ExpectationException Thrown by behat_base::find and isChecked + * @param string $element Element we look on + */ + public function the_element_checkbox_should_not_be_checked($element) { + $element = $this->find("checkbox", $element); + if (!$element) { + throw new ExpectationException('Checkbox not found with the provided XPath.', $this->getSession()); + } + + if ($element->isChecked()) { + throw new ExpectationException('The checkbox is checked.', $this->getSession()); + } + } } diff --git a/tests/behat/block_opencast_massactions.feature b/tests/behat/block_opencast_massactions.feature new file mode 100644 index 00000000..110d023e --- /dev/null +++ b/tests/behat/block_opencast_massactions.feature @@ -0,0 +1,145 @@ +@block @block_opencast @block_opencast_massactions +Feature: Select all videos and perform mass actions in the Opencast Block Overview page + As a teacher, I want to be able to select all videos from the video list table + and perform mass actions so that I can manage multiple videos efficiently. + Background: + Given the following "users" exist: + | username | firstname | lastname | email | idnumber | + | teacher1 | Teacher | 1 | teacher1@example.com | T1 | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I setup the default settigns for opencast plugins + And the following config values are set as admin: + | config | value | plugin | + | apiurl_1 | http://testapi:8080 | tool_opencast | + | apipassword_1 | opencast | tool_opencast | + | apiusername_1 | admin | tool_opencast | + | ocinstances | [{"id":1,"name":"Default","isvisible":true,"isdefault":true}] | tool_opencast | + | limituploadjobs_1 | 0 | block_opencast | + | group_creation_1 | 0 | block_opencast | + | group_name_1 | Moodle_course_[COURSEID] | block_opencast | + | series_name_1 | Course_Series_[COURSEID] | block_opencast | + | enablechunkupload_1 | 0 | block_opencast | + | workflow_roles_1 | republish-metadata | block_opencast | + | metadata_1 | [{"name":"rightsHolder","datatype":"text","required":0,"readonly":0,"param_json":null}] | block_opencast | + | workflow_tags_1 | archive | block_opencast | + And I setup the opencast test api + And I upload a testvideo + And I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I add the "Opencast Videos" block + + @javascript + Scenario: Teachers should see the mass action elements and be able to select and deselect all or one video, select actions from dropdown only when videos are selected, see the confrimation dialog when selecting a mass action and the video selection should be reset when the confirmation dialogue is canceled. + Given I click on "Go to overview..." "link" + Then the "With Selected Videos..." "select" should be disabled + And the "Select all" checkbox should not be checked + # Testing basic video selection via select all. + When I click on "Select all" "checkbox" + Then the "With Selected Videos..." "select" should be enabled + And the "Select Test video" checkbox should be checked + When I click on "Select all" "checkbox" + Then the "With Selected Videos..." "select" should be disabled + And the "Select Test video" checkbox should not be checked + # Testing basic video selection via a video. + When I click on "Select Test video" "checkbox" + Then the "With Selected Videos..." "select" should be enabled + And the "Select all" checkbox should be checked + When I click on "Select Test video" "checkbox" + Then the "With Selected Videos..." "select" should be disabled + And the "Select all" checkbox should not be checked + # Testing actions dropdowns selection. + When I click on "Select all" "checkbox" + Then the "With Selected Videos..." "select" should be enabled + And the "Select Test video" checkbox should be checked + When I click on "With Selected Videos..." "select" + Then I should see "Delete" + And I should see "Update metadata" + And I should see "Change Visibility" + And I should see "Start workflow" + # Testing confirmation dialogue and reset video selection when confirmation is cancelled. + When I select "Update metadata" from the "With Selected Videos..." singleselect + Then I should see "Are you sure you want to update the metadata of the following selected videos:" + When I click on "Cancel" "button" in the "Update metadata of selected videos" "dialogue" + Then the "Select all" checkbox should not be checked + And the "Select Test video" checkbox should not be checked + And the "With Selected Videos..." "select" should be disabled + + @javascript + Scenario: The mass actions should not be provided when conditions are not met, such as permissions and configurations. + Given the following "permission overrides" exist: + | capability | permission | role | contextlevel | reference | + | block/opencast:deleteevent | Prevent | editingteacher | Course | C1 | + | block/opencast:startworkflow | Prevent | editingteacher | Course | C1 | + | block/opencast:addvideo | Prevent | editingteacher | Course | C1 | + When I click on "Go to overview..." "link" + Then I should not see "With Selected Videos..." + When the following "permission overrides" exist: + | capability | permission | role | contextlevel | reference | + | block/opencast:deleteevent | Allow | editingteacher | Course | C1 | + | block/opencast:startworkflow | Allow | editingteacher | Course | C1 | + | block/opencast:addvideo | Allow | editingteacher | Course | C1 | + And I reload the page + Then I should see "With Selected Videos..." + When the following config values are set as admin: + | workflow_tags_1 | | block_opencast | + | aclcontrolafter_1 | 0 | block_opencast | + And I reload the page + And I click on "With Selected Videos..." "select" + Then "Start workflow" "option" should not exist in the "With Selected Videos..." "select" + And "Change Visibility" "option" should not exist in the "With Selected Videos..." "select" + When the following config values are set as admin: + | workflow_tags_1 | archive | block_opencast | + | aclcontrolafter_1 | 1 | block_opencast | + And I reload the page + And I click on "With Selected Videos..." "select" + Then I should see "Delete" + And I should see "Update metadata" + And I should see "Change Visibility" + And I should see "Start workflow" + + @javascript + Scenario: Teachers should be able to perform the mass action after the confirmation + Given I click on "Go to overview..." "link" + # Testing start workflow. + When I click on "Select all" "checkbox" + And I select "Start workflow" from the "With Selected Videos..." singleselect + Then I should see "You have selected the following videos to start workflow for:" + And I wait "1" seconds + And I set the field "workflow" to "duplicate-event" + When I click on "Start workflow" "button" + And I wait "2" seconds + Then I should see "Workflow has been successfully started for the selected videos:" + # Testing start workflow. + When I click on "Select all" "checkbox" + And I select "Change Visibility" from the "With Selected Videos..." singleselect + Then I should see "Are you sure you want to perform visibility change on the following selected videos:" + When I click on "Change Visibility" "button" + And I wait "1" seconds + Then I should see "You have selected the following video(s):" + And I click on "#id_visibility_1" "css_element" + And I click on "Save changes" "button" + And I should see "The visibility of the selected video(s) has been successfully updated:" + # Testing Update metadata. + When I click on "Select all" "checkbox" + And I select "Update metadata" from the "With Selected Videos..." singleselect + Then I should see "Are you sure you want to update the metadata of the following selected videos:" + When I click on "Update metadata" "button" + And I wait "1" seconds + Then I should see "You have selected the following video(s):" + And I click on "#id_rightsHolder_enabled" "css_element" + And I set the field "Rights" to "TEST TEXT FOR RIGHTS" + When I click on "Save changes" "button" + And I wait "1" seconds + Then I should see "The metadata of the selected video(s) has been successfully updated:" + # Testing Delete. + When I click on "Select all" "checkbox" + And I select "Delete" from the "With Selected Videos..." singleselect + Then I should see "Are you sure you want to delete the following selected videos:" + When I click on "Delete" "button" in the ".modal" "css_element" + And I wait "1" seconds + Then I should see "The following selected video will be deleted shortly:"