diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_admin.php b/theme/classic/tests/behat/behat_theme_classic_behat_admin.php new file mode 100644 index 00000000000..94b81f2bd00 --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_admin.php @@ -0,0 +1,120 @@ +. + +/** + * Step definitions related to administration overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. +// For that reason, we can't even rely on $CFG->admin being available here. + +require_once(__DIR__ . '/../../../../admin/tests/behat/behat_admin.php'); + +use Behat\Gherkin\Node\TableNode as TableNode, + Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException; + +/** + * Site administration level steps definitions overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_admin extends behat_admin { + + /** + * Sets the specified site settings. A table with | Setting label | value | is expected. + * + * @param TableNode $table + */ + public function i_set_the_following_administration_settings_values(TableNode $table) { + + if (!$data = $table->getRowsHash()) { + return; + } + + foreach ($data as $label => $value) { + + // We expect admin block to be visible, otherwise go to homepage. + if (!$this->getSession()->getPage()->find('css', '.block_settings')) { + $this->getSession()->visit($this->locate_path('/')); + $this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS); + } + + // Search by label. + $searchbox = $this->find_field(get_string('searchinsettings', 'admin')); + $searchbox->setValue($label); + $submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]'); + $submitsearch->press(); + + $this->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS); + + // Admin settings does not use the same DOM structure than other moodle forms + // but we also need to use lib/behat/form_field/* to deal with the different moodle form elements. + $exception = new ElementNotFoundException($this->getSession(), '"' . $label . '" administration setting '); + + // The argument should be converted to an xpath literal. + $label = behat_context_helper::escape($label); + + // Single element settings. + try { + $fieldxpath = "//*[self::input | self::textarea | self::select]" . + "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" . + "[@id=//label[contains(normalize-space(.), $label)]/@for or " . + "@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]"; + $fieldnode = $this->find('xpath', $fieldxpath, $exception); + + $formfieldtypenode = $this->find('xpath', $fieldxpath . + "/ancestor::div[contains(concat(' ', @class, ' '), ' form-setting ')]" . + "/child::div[contains(concat(' ', @class, ' '), ' form-')]/child::*/parent::div"); + + } catch (ElementNotFoundException $e) { + + // Multi element settings, interacting only the first one. + $fieldxpath = "//*[label[contains(., $label)]|span[contains(., $label)]]" . + "/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" . + "/descendant::div[contains(concat(' ', @class, ' '), ' form-group ')]" . + "/descendant::*[self::input | self::textarea | self::select]" . + "[not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]"; + $fieldnode = $this->find('xpath', $fieldxpath); + + // It is the same one that contains the type. + $formfieldtypenode = $fieldnode; + } + + // Getting the class which contains the field type. + $classes = explode(' ', $formfieldtypenode->getAttribute('class')); + $type = false; + foreach ($classes as $class) { + if (substr($class, 0, 5) == 'form-') { + $type = substr($class, 5); + } + } + + // Instantiating the appropiate field type. + $field = behat_field_manager::get_field_instance($type, $fieldnode, $this->getSession()); + $field->set_value($value); + + $this->find_button(get_string('savechanges'))->press(); + } + } +} diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_blocks.php b/theme/classic/tests/behat/behat_theme_classic_behat_blocks.php new file mode 100644 index 00000000000..08a8543d710 --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_blocks.php @@ -0,0 +1,78 @@ +. + +/** + * Step definitions related to blocks overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../blocks/tests/behat/behat_blocks.php'); + +/** + * Blocks management step definitions for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_blocks extends behat_blocks { + + /** + * Adds the selected block. Editing mode must be previously enabled. + * + * @param string $blockname + * @return void + */ + public function i_add_the_block($blockname) { + $this->execute('behat_forms::i_set_the_field_to', + array("bui_addblock", $this->escape($blockname)) + ); + + // If we are running without javascript we need to submit the form. + if (!$this->running_javascript()) { + $this->execute('behat_general::i_click_on_in_the', + array(get_string('go'), "button", "#add_block", "css_element") + ); + } + } + + /** + * Ensures that block can be added to the page, but does not add it. + * + * @param string $blockname + * @return void + */ + public function the_add_block_selector_should_contain_block($blockname) { + $this->execute('behat_forms::the_select_box_should_contain', [get_string('addblock'), $blockname]); + } + + /** + * Ensures that block cannot be added to the page. + * + * @param string $blockname + * @return void + */ + public function the_add_block_selector_should_not_contain_block($blockname) { + $this->execute('behat_forms::the_select_box_should_not_contain', [get_string('addblock'), $blockname]); + } +} diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_course.php b/theme/classic/tests/behat/behat_theme_classic_behat_course.php new file mode 100644 index 00000000000..24dd714dd3e --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_course.php @@ -0,0 +1,49 @@ +. + +/** + * Behat course-related step definition overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../course/tests/behat/behat_course.php'); + +/** + * Course-related step definition overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_course extends behat_course { + + /** + * Go to the course participants. + */ + public function i_navigate_to_course_participants() { + $coursestr = behat_context_helper::escape(get_string('courses')); + $mycoursestr = behat_context_helper::escape(get_string('mycourses')); + $xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]"; + $this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']); + } +} diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_grade.php b/theme/classic/tests/behat/behat_theme_classic_behat_grade.php new file mode 100644 index 00000000000..336303dcbd1 --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_grade.php @@ -0,0 +1,57 @@ +. + +/** + * Behat grade related step definition overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../grade/tests/behat/behat_grade.php'); + +use Behat\Gherkin\Node\TableNode as TableNode; + +/** + * Behat grade overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_grade extends behat_grade { + + /** + * Navigates to the course gradebook and selects a specified item from the grade navigation tabs. + * + * @param string $gradepath + */ + public function i_navigate_to_in_the_course_gradebook($gradepath) { + // If we are not on one of the gradebook pages already, follow "Grades" link in the navigation block. + $xpath = '//div[contains(@class,\'grade-navigation\')]'; + if (!$this->getSession()->getPage()->findAll('xpath', $xpath)) { + $this->execute("behat_general::i_click_on_in_the", array(get_string('grades'), 'link', + get_string('pluginname', 'block_navigation'), 'block')); + } + + $this->select_in_gradebook_tabs($gradepath); + } +} diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_mod_quiz.php b/theme/classic/tests/behat/behat_theme_classic_behat_mod_quiz.php new file mode 100644 index 00000000000..ea366409a10 --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_mod_quiz.php @@ -0,0 +1,65 @@ +. + +/** + * Step definitions related to mod_quiz overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../mod/quiz/tests/behat/behat_mod_quiz.php'); + +use Behat\Gherkin\Node\TableNode as TableNode; + +/** + * Step definitions related to mod_quiz overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_mod_quiz extends behat_mod_quiz { + + /** + * Adds a question to the existing quiz with filling the form. + * The form for creating a question should be on one page. + * + * @param string $questiontype + * @param string $quizname + * @param TableNode $questiondata with data for filling the add question form + */ + public function i_add_question_to_the_quiz_with($questiontype, $quizname, TableNode $questiondata) { + $quizname = $this->escape($quizname); + $editquiz = $this->escape(get_string('editquiz', 'quiz')); + $menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' dropdown-toggle')]"; + $itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]"; + + $this->execute('behat_general::click_link', $quizname); + + $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", $editquiz); + + $this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element")); + $this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element")); + + $this->finish_adding_question($questiontype, $questiondata); + } +} diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_navigation.php b/theme/classic/tests/behat/behat_theme_classic_behat_navigation.php new file mode 100644 index 00000000000..4183bbad015 --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_navigation.php @@ -0,0 +1,229 @@ +. + +/** + * Navigation step definition overrides for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: No MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../lib/tests/behat/behat_navigation.php'); + +use Behat\Mink\Exception\ExpectationException as ExpectationException; +use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException; + +/** + * Step definitions and overrides to navigate through the navigation tree nodes in the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_navigation extends behat_navigation { + /** + * Navigate to an item in a current page administration menu. + * + * @throws ExpectationException + * @param string $nodetext The navigation node/path to follow, eg "Course administration > Edit settings" + * @return void + */ + public function i_navigate_to_in_current_page_administration($nodetext) { + $parentnodes = array_map('trim', explode('>', $nodetext)); + + // Find the name of the first category of the administration block tree. + $xpath = "//section[contains(@class,'block_settings')]//div[@id='settingsnav']/ul[1]/li[1]/p[1]/span"; + $node = $this->find('xpath', $xpath); + + array_unshift($parentnodes, $node->getText()); + $lastnode = array_pop($parentnodes); + $this->select_node_in_navigation($lastnode, $parentnodes); + } + + /** + * Navigate to an item within the site administration menu. + * + * @throws ExpectationException + * @param string $nodetext The navigation node/path to follow, excluding "Site administration" itself, eg "Grades > Scales" + * @return void + */ + public function i_navigate_to_in_site_administration($nodetext) { + $parentnodes = array_map('trim', explode('>', $nodetext)); + array_unshift($parentnodes, get_string('administrationsite')); + $lastnode = array_pop($parentnodes); + $this->select_node_in_navigation($lastnode, $parentnodes); + } + + /** + * Helper function to get top navigation node in the tree. + * + * @throws ExpectationException if node not found. + * @param string $nodetext name of top navigation node in tree. + * @return NodeElement + */ + protected function get_top_navigation_node($nodetext) { + // Avoid problems with quotes. + $nodetextliteral = behat_context_helper::escape($nodetext); + $exception = new ExpectationException('Top navigation node "' . $nodetext . '" not found', $this->getSession()); + + $xpath = // Navigation block. + "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]" . + "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . + "/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . + "/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . + "[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . + "[span[normalize-space(.)={$nodetextliteral}] or a[normalize-space(.)={$nodetextliteral}]]]" . + "|" . + // Administration block. + "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" . + "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . + "/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . + "/ul/li[contains(concat(' ', normalize-space(@class), ' '), ' contains_branch ')]" . + "[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . + "/span[normalize-space(.)={$nodetextliteral}]]" . + "|" . + "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" . + "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . + "/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . + "/span[normalize-space(.)={$nodetextliteral}]]" . + "|" . + "//div[contains(concat(' ', normalize-space(@class), ' '), ' content ')]/div" . + "/ul[contains(concat(' ', normalize-space(@class), ' '), ' block_tree ')]" . + "/li[p[contains(concat(' ', normalize-space(@class), ' '), ' branch ')]" . + "/a[normalize-space(.)={$nodetextliteral}]]"; + + $node = $this->find('xpath', $xpath, $exception); + + return $node; + } + + /** + * Check that current page administration contains an element. + * + * @throws ElementNotFoundException + * @param string $element The locator of the specified selector. + * This may be a path, for example "Subscription mode > Forced subscription" + * @param string $selectortype The selector type (link or text) + * @return void + */ + public function should_exist_in_current_page_administration($element, $selectortype) { + $nodes = array_map('trim', explode('>', $element)); + $nodetext = end($nodes); + + // Find administration menu. + $rootxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu(true); + $menuxpath = $rootxpath . '/p/../ul[1]'; + + for ($i = 0; $i < (count($nodes) - 1); $i++) { + $menuxpath .= "/li/p/span[contains(text(), '{$nodes[$i]}')]/../../ul[1]"; + } + + if ($selectortype == 'link') { + $menuxpath .= "/li/p[a[contains(text(), '{$nodetext}')]"; + $menuxpath .= "|a/span[contains(text(), '{$nodetext}')]]"; + } else { + $menuxpath .= "/li/p/span[contains(text(), '{$nodes[$i]}')]"; + } + + $exception = new ElementNotFoundException($this->getSession(), "\"{$element}\" \"{$selectortype}\""); + $this->find('xpath', $menuxpath, $exception); + } + + /** + * Check that current page administration does not contains an element. + * + * @throws ExpectationException + * @param string $element The locator of the specified selector. + * This may be a path, for example "Subscription mode > Forced subscription" + * @param string $selectortype The selector type (link or text) + * @return void + */ + public function should_not_exist_in_current_page_administration($element, $selectortype) { + try { + $menuxpath = $this->find_header_administration_menu() ?: $this->find_page_administration_menu(true); + } catch (Exception $e) { + // If an exception was thrown, it means the root note does not exist, so we can conclude the test is a success. + return; + } + + // Test if the element exists. + try { + $this->should_exist_in_current_page_administration($element, $selectortype); + } catch (ElementNotFoundException $e) { + + // If an exception was thrown, it means the element does not exist, so the test is successful. + return; + } + + // If the try block passed, the element exists, so throw an exception. + $exception = 'The "' . $element . '" "' . $selectortype . '" was found, but should not exist'; + throw new ExpectationException($exception, $this->getSession()); + } + + /** + * Check that the page administration menu exists on the page. + * + * This confirms the existence of the menu, which authorised users should have access to. + * @Given /^I should see the page administration menu$/ + * + * @throws ExpectationException + * @return void + */ + public function page_administration_exists() { + $menuxpath = "//section[contains(@class,'block_settings')]//div[@id='settingsnav']"; + $this->ensure_element_exists($menuxpath, 'xpath_element'); + } + + /** + * Check that the page administration menu does not exist on the page. + * + * This confirms the absence of the menu, which unauthorised users should not have access to. + * @Given /^I should not see the page administration menu$/ + * + * @throws ExpectationException + * @return void + */ + public function page_administration_does_not_exist() { + $menuxpath = "//section[contains(@class,'block_settings')]//div[@id='settingsnav']"; + $this->ensure_element_does_not_exist($menuxpath, 'xpath_element'); + } + + /** + * Locate the administration menu on the page (but not in the header) and return its xpath. + * + * @throws ElementNotFoundException + * @param bool $mustexist If true, throws an exception if menu is not found + * @return null|string + */ + protected function find_page_administration_menu($mustexist = false) { + $menuxpath = "//section[contains(@class,'block_settings')]//div[@id='settingsnav']/ul[1]/li[1]"; + + if ($mustexist) { + $exception = new ElementNotFoundException($this->getSession(), 'Page administration menu is not found'); + $this->find('xpath', $menuxpath, $exception); + + } else if (!$this->getSession()->getPage()->find('xpath', $menuxpath)) { + return null; + } + + return $menuxpath; + } +} diff --git a/theme/classic/tests/behat/behat_theme_classic_behat_repository_upload.php b/theme/classic/tests/behat/behat_theme_classic_behat_repository_upload.php new file mode 100644 index 00000000000..369b91e3909 --- /dev/null +++ b/theme/classic/tests/behat/behat_theme_classic_behat_repository_upload.php @@ -0,0 +1,74 @@ +. + +/** + * Override definitions for the upload repository type for the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../repository/upload/tests/behat/behat_repository_upload.php'); + +use Behat\Mink\Exception\ExpectationException as ExpectationException; + +/** + * Override step definitions to deal with the upload repository in the Classic theme. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_theme_classic_behat_repository_upload extends behat_repository_upload { + + /** + * Gets the NodeElement for filepicker of filemanager moodleform element. + * + * @throws ExpectationException + * @param string $filepickerelement The filepicker form field label + * @return NodeElement The hidden element node. + */ + protected function get_filepicker_node($filepickerelement) { + + // More info about the problem (in case there is a problem). + $exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession()); + + // If no file picker label is mentioned take the first file picker from the page. + if (empty($filepickerelement)) { + $filepickercontainer = $this->find( + 'xpath', + "//*[@class=\"form-filemanager\"]", + $exception + ); + } else { + // Gets the ffilemanager node specified by the locator which contains the filepicker container. + $filepickerelement = behat_context_helper::escape($filepickerelement); + $filepickercontainer = $this->find( + 'xpath', + "//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" . + "//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' felement ')]", + $exception + ); + } + + return $filepickercontainer; + } +} diff --git a/theme/classic/tests/behat/blacklist.json b/theme/classic/tests/behat/blacklist.json new file mode 100644 index 00000000000..1d0c8d840e2 --- /dev/null +++ b/theme/classic/tests/behat/blacklist.json @@ -0,0 +1,8 @@ +{ + "features": [ + "lib/tests/behat/action_menu.feature", + "course/tests/behat/activities_edit_with_block_dock.feature", + "blocks/tests/behat/hide_blocks.feature", + "blocks/tests/behat/move_blocks.feature" + ] +} diff --git a/theme/classic/tests/behat/courseadministrationmenu.feature b/theme/classic/tests/behat/courseadministrationmenu.feature new file mode 100644 index 00000000000..0f2aea62efc --- /dev/null +++ b/theme/classic/tests/behat/courseadministrationmenu.feature @@ -0,0 +1,27 @@ +@javascript @theme_classic +Feature: Course administration menu + To navigate in classic theme teachers need to use the course administration menu + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + | student1 | Student | 1 | student1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + Scenario: Teacher can use the course administration menu + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I should see the page administration menu + + Scenario: Student cannot see the course administration menu + And I log in as "student1" + And I am on "Course 1" course homepage + And I should not see the page administration menu + And I log out diff --git a/theme/classic/tests/behat/pageadministrationmenu.feature b/theme/classic/tests/behat/pageadministrationmenu.feature new file mode 100644 index 00000000000..bb5060ad08e --- /dev/null +++ b/theme/classic/tests/behat/pageadministrationmenu.feature @@ -0,0 +1,50 @@ +@javascript @theme_classic +Feature: Page administration menu + To navigate in classic theme I need to use the page administration menu + + Background: + Given the following "courses" exist: + | fullname | shortname | newsitems | + | Course 1 | C1 | 5 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + | student1 | Student | 1 | student1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + + Scenario: Teacher can access activity administration menus + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I follow "Choice name" + And I should see the page administration menu + And "Edit settings" "link" should exist in current page administration + And I navigate to "Edit settings" in current page administration + And I should see "Updating: Choice" + And I navigate to course participants + And I should see the page administration menu + And I navigate to "Users > Enrolment methods" in current page administration + And I should see "Enrolment methods" + And I log out + + Scenario: Student cannot access course and activity administration menus + And I log in as "student1" + And I am on "Course 1" course homepage + And I should not see the page administration menu + And I follow "Choice name" + And I should not see the page administration menu + And I log out + + Scenario: Administrator can access site administration menus and sub-menus + And I log in as "admin" + And I should see the page administration menu + And I navigate to "Advanced features" in site administration + And I should see "Enable comments" + And I navigate to "Users > Accounts > Add a new user" in site administration + And I should see "New password" + And I log out diff --git a/theme/classic/tests/scss_test.php b/theme/classic/tests/scss_test.php new file mode 100644 index 00000000000..565aaf03811 --- /dev/null +++ b/theme/classic/tests/scss_test.php @@ -0,0 +1,52 @@ +. + +/** + * This file contains the unittests for classic's scss compilation. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Unit tests for scss compilation. + * + * @package theme_classic + * @category test + * @copyright 2019 Michael Hawkins + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class theme_classic_scss_testcase extends advanced_testcase { + /** + * Test that classic can be compiled using SassC (the defacto implemention). + */ + public function test_scss_compilation_with_sassc() { + if (!defined('PHPUNIT_PATH_TO_SASSC')) { + $this->markTestSkipped('Path to SassC not provided'); + } + + $this->resetAfterTest(); + set_config('pathtosassc', PHPUNIT_PATH_TO_SASSC); + + $this->assertNotEmpty( + theme_config::load('classic')->get_css_content_debug('scss', null, null) + ); + } +}