Merge branch 'MDL-38637-master' of github.com:StudiUM/moodle
authorDan Poltawski <dan@moodle.com>
Fri, 12 Apr 2013 02:08:45 +0000 (10:08 +0800)
committerDan Poltawski <dan@moodle.com>
Fri, 12 Apr 2013 02:08:45 +0000 (10:08 +0800)
18 files changed:
admin/settings/top.php
badges/badge.php
badges/cron.php
badges/edit_form.php
badges/mybackpack.php
badges/mybadges.php
badges/renderer.php
lib/badgeslib.php
lib/navigationlib.php
lib/tests/behat/behat_general.php
lib/tests/behat/behat_hooks.php
mod/glossary/tests/behat/behat_mod_glossary.php
mod/glossary/tests/behat/search_entries.feature [new file with mode: 0644]
mod/wiki/tests/behat/collaborative_individual.feature [new file with mode: 0644]
mod/wiki/tests/behat/preview_page.feature [new file with mode: 0644]
question/tests/behat/behat_question.php [new file with mode: 0644]
question/tests/behat/edit_questions.feature [new file with mode: 0644]
question/tests/behat/sort_questions.feature [new file with mode: 0644]

index e855519..768d287 100644 (file)
@@ -30,7 +30,7 @@ if ($hassiteconfig) {
 $ADMIN->add('root', new admin_category('users', new lang_string('users','admin')));
 $ADMIN->add('root', new admin_category('courses', new lang_string('courses','admin')));
 $ADMIN->add('root', new admin_category('grades', new lang_string('grades')));
-$ADMIN->add('root', new admin_category('badges', new lang_string('badges'), (isset($CFG->enablebadges) && $CFG->enablebadges == 0)));
+$ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empty($CFG->enablebadges)));
 $ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
 $ADMIN->add('root', new admin_category('language', new lang_string('language')));
 $ADMIN->add('root', new admin_category('modules', new lang_string('plugins', 'admin')));
index 1061eb4..cd90239 100644 (file)
@@ -57,7 +57,7 @@ if (isloggedin()) {
 }
 
 // TODO: Better way of pushing badges to Mozilla backpack?
-if ($CFG->badges_allowexternalbackpack) {
+if (!empty($CFG->badges_allowexternalbackpack)) {
     $PAGE->requires->js(new moodle_url('http://backpack.openbadges.org/issuer.js'), true);
 }
 
index 833ee35..a1dcfcc 100644 (file)
@@ -30,7 +30,7 @@ require_once($CFG->libdir . '/badgeslib.php');
 function badge_cron() {
     global $CFG;
 
-    if ($CFG->enablebadges) {
+    if (!empty($CFG->enablebadges)) {
         badge_review_cron();
         badge_message_cron();
     }
@@ -159,4 +159,4 @@ function badge_assemble_notification(stdClass $badge) {
 
         message_send($eventdata);
     }
-}
\ No newline at end of file
+}
index 4011e05..768cc95 100644 (file)
@@ -74,11 +74,15 @@ class edit_details_form extends moodleform {
         $mform->addElement('text', 'issuername', get_string('name'), array('size' => '70'));
         $mform->setType('issuername', PARAM_NOTAGS);
         $mform->addRule('issuername', null, 'required');
-        $mform->setDefault('issuername', $CFG->badges_defaultissuername);
+        if (isset($CFG->badges_defaultissuername)) {
+            $mform->setDefault('issuername', $CFG->badges_defaultissuername);
+        }
         $mform->addHelpButton('issuername', 'issuername', 'badges');
 
         $mform->addElement('text', 'issuercontact', get_string('contact', 'badges'), array('size' => '70'));
-        $mform->setDefault('issuercontact', $CFG->badges_defaultissuercontact);
+        if (isset($CFG->badges_defaultissuercontact)) {
+            $mform->setDefault('issuercontact', $CFG->badges_defaultissuercontact);
+        }
         $mform->setType('issuercontact', PARAM_EMAIL);
         $mform->addRule('issuercontact', get_string('invalidemail', 'moodle'), 'email', null, 'client', true);
         $mform->addHelpButton('issuercontact', 'contact', 'badges');
@@ -238,4 +242,4 @@ class edit_message_form extends moodleform {
 
         return $errors;
     }
-}
\ No newline at end of file
+}
index 6797c7d..c5bee65 100644 (file)
@@ -40,7 +40,7 @@ require_capability('moodle/badges:manageownbadges', $context);
 
 $clear = optional_param('clear', false, PARAM_BOOL);
 
-if (!$CFG->badges_allowexternalbackpack) {
+if (empty($CFG->badges_allowexternalbackpack)) {
     redirect($CFG->wwwroot);
 }
 
@@ -161,4 +161,4 @@ if ($backpack) {
     echo $OUTPUT->header();
     $form->display();
     echo $OUTPUT->footer();
-}
\ No newline at end of file
+}
index bf18a7f..46f4c1d 100644 (file)
@@ -91,7 +91,7 @@ $PAGE->set_heading($title);
 $PAGE->set_pagelayout('mydashboard');
 
 // TODO: Better way of pushing badges to Mozilla backpack?
-if ($CFG->badges_allowexternalbackpack) {
+if (!empty($CFG->badges_allowexternalbackpack)) {
     $PAGE->requires->js(new moodle_url('http://backpack.openbadges.org/issuer.js'), true);
     $PAGE->requires->js('/badges/backpack.js', true);
 }
@@ -113,4 +113,4 @@ $userbadges->search     = $search;
 
 echo $output->render($userbadges);
 
-echo $OUTPUT->footer();
\ No newline at end of file
+echo $OUTPUT->footer();
index 6c7dc92..8f517ab 100644 (file)
@@ -60,7 +60,7 @@ class core_badges_renderer extends plugin_renderer_base {
             $download = $status = $push = '';
             if (($userid == $USER->id) && !$profile) {
                 $url = new moodle_url('mybadges.php', array('download' => $badge->id, 'hash' => $badge->uniquehash, 'sesskey' => sesskey()));
-                if ($CFG->badges_allowexternalbackpack && (empty($badge->dateexpire) || $badge->dateexpire > time())) {
+                if (!empty($CFG->badges_allowexternalbackpack) && (empty($badge->dateexpire) || $badge->dateexpire > time())) {
                     $assertion = new moodle_url('/badges/assertion.php', array('b' => $badge->uniquehash));
                     $action = new component_action('click', 'addtobackpack', array('assertion' => $assertion->out(false)));
                     $push = $this->output->action_icon(new moodle_url('#'), new pix_icon('t/backpack', get_string('addtobackpack', 'badges')), $action);
@@ -293,7 +293,7 @@ class core_badges_renderer extends plugin_renderer_base {
                             get_string('download'),
                             'POST'));
                 $expiration = isset($issued['expires']) ? strtotime($issued['expires']) : $today + 1;
-                if ($CFG->badges_allowexternalbackpack && ($expiration > $today)) {
+                if (!empty($CFG->badges_allowexternalbackpack) && ($expiration > $today)) {
                     $assertion = new moodle_url('/badges/assertion.php', array('b' => $ibadge->hash));
                     $attributes = array(
                             'type' => 'button',
@@ -474,7 +474,7 @@ class core_badges_renderer extends plugin_renderer_base {
         // External badges.
         $backpack = $badges->backpack;
         $externalhtml = "";
-        if ($CFG->badges_allowexternalbackpack) {
+        if (!empty($CFG->badges_allowexternalbackpack)) {
             $externalhtml .= html_writer::start_tag('fieldset', array('class' => 'generalbox'));
             $externalhtml .= html_writer::tag('legend', $this->output->heading_with_help(get_string('externalbadges', 'badges'), 'externalbadges', 'badges'));
             if (!is_null($backpack)) {
index 35b5a4b..e5e4c3e 100644 (file)
@@ -855,8 +855,9 @@ function badges_get_issued_badge_info($hash) {
         $url = new moodle_url('/badges/badge.php', array('hash' => $hash));
 
         // Recipient's email is hashed: <algorithm>$<hash(email + salt)>.
-        $a['recipient'] = 'sha256$' . hash('sha256', $record->email . $CFG->badges_badgesalt);
-        $a['salt'] = $CFG->badges_badgesalt;
+        $badgesalt = isset($CFG->badgesalt) ? $CFG->badgesalt : '';
+        $a['recipient'] = 'sha256$' . hash('sha256', $record->email . $badgesalt);
+        $a['salt'] = $badgesalt;
 
         if ($record->dateexpire) {
             $a['expires'] = date('Y-m-d', $record->dateexpire);
@@ -891,7 +892,7 @@ function badges_add_course_navigation(navigation_node $coursenode, stdClass $cou
     $coursecontext = context_course::instance($course->id);
     $isfrontpage = (!$coursecontext || $course->id == $SITE->id);
 
-    if ($CFG->enablebadges && $CFG->badges_allowcoursebadges && !$isfrontpage) {
+    if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges) && !$isfrontpage) {
         if (has_capability('moodle/badges:configuredetails', $coursecontext)) {
             $coursenode->add(get_string('coursebadges', 'badges'), null,
                     navigation_node::TYPE_CONTAINER, null, 'coursebadges',
@@ -1228,7 +1229,7 @@ function profile_display_badges($userid, $courseid = 0) {
         }
 
         // Print external badges.
-        if ($courseid == 0 && $CFG->badges_allowexternalbackpack) {
+        if ($courseid == 0 && !empty($CFG->badges_allowexternalbackpack)) {
             $backpack = get_backpack_settings($userid);
             if (isset($backpack->totalbadges) && $backpack->totalbadges !== 0) {
                 $left = get_string('externalbadgesp', 'badges');
index eab4bd3..8e5fe7d 100644 (file)
@@ -2445,7 +2445,7 @@ class global_navigation extends navigation_node {
         }
 
         // Badges.
-        if ($CFG->enablebadges && has_capability('moodle/badges:viewbadges', $this->page->context)) {
+        if (!empty($CFG->enablebadges) && has_capability('moodle/badges:viewbadges', $this->page->context)) {
             $url = new moodle_url($CFG->wwwroot . '/badges/view.php',
                     array('type' => 2, 'id' => $course->id));
 
index 76fbdc3..02e890c 100644 (file)
@@ -63,6 +63,25 @@ class behat_general extends behat_base {
         $this->getSession()->reload();
     }
 
+    /**
+     * Switches to the specified window. Useful when interacting with popup windows.
+     *
+     * @Given /^I switch to "(?P<window_name_string>(?:[^"]|\\")*)" window$/
+     * @param string $windowname
+     */
+    public function switch_to_window($windowname) {
+        $this->getSession()->switchToWindow($windowname);
+    }
+
+    /**
+     * Switches to the main Moodle window. Useful when you finish interacting with popup windows.
+     *
+     * @Given /^I switch to the main window$/
+     */
+    public function switch_to_the_main_window() {
+        $this->getSession()->switchToWindow();
+    }
+
     /**
      * Clicks link with specified id|title|alt|text.
      *
index 60b6768..a889348 100644 (file)
 
 require_once(__DIR__ . '/../../behat/behat_base.php');
 
-use Behat\Behat\Event\SuiteEvent as SuiteEvent;
-use Behat\Behat\Event\ScenarioEvent as ScenarioEvent;
-use Behat\Behat\Event\StepEvent as StepEvent;
+use Behat\Behat\Event\SuiteEvent as SuiteEvent,
+    Behat\Behat\Event\ScenarioEvent as ScenarioEvent,
+    Behat\Behat\Event\StepEvent as StepEvent,
+    WebDriver\Exception\NoSuchWindow as NoSuchWindow;
 
 /**
  * Hooks to the behat process.
@@ -116,6 +117,9 @@ class behat_hooks extends behat_base {
             throw new coding_exception('Behat only can modify the test database and the test dataroot!');
         }
 
+        // Avoid some notices / warnings.
+        $SESSION = new stdClass();
+
         behat_util::reset_database();
         behat_util::reset_dataroot();
 
@@ -128,9 +132,6 @@ class behat_hooks extends behat_base {
         // Assing valid data to admin user (some generator-related code needs a valid user).
         $user = $DB->get_record('user', array('username' => 'admin'));
         session_set_user($user);
-
-        // Avoid some notices / warnings.
-        $SESSION = new stdClass();
     }
 
     /**
@@ -170,7 +171,11 @@ class behat_hooks extends behat_base {
         }
 
         // Wait until the page is ready.
-        $this->getSession()->wait(self::TIMEOUT, '(document.readyState === "complete")');
+        try {
+            $this->getSession()->wait(self::TIMEOUT, '(document.readyState === "complete")');
+        } catch (NoSuchWindow $e) {
+            // If we were interacting with a popup window it will not exists after closing it.
+        }
     }
 
 }
index 4d27268..a692634 100644 (file)
@@ -28,8 +28,7 @@
 require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
 
 use Behat\Behat\Context\Step\Given as Given,
-    Behat\Gherkin\Node\TableNode as TableNode,
-    Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
+    Behat\Gherkin\Node\TableNode as TableNode;
 
 /**
  * Glossary-related steps definitions.
@@ -55,4 +54,21 @@ class behat_mod_glossary extends behat_base {
         );
     }
 
+    /**
+     * Adds a category with the specified name to the current glossary. You need to be in the glossary page.
+     *
+     * @Given /^I add a glossary entries category named "(?P<category_name_string>(?:[^"]|\\")*)"$/
+     * @param string $categoryname Category name
+     */
+    public function i_add_a_glossary_entries_category_named($categoryname) {
+
+        return array(
+            new Given('I follow "' . get_string('categoryview', 'mod_glossary') . '"'),
+            new Given('I press "' . get_string('editcategories', 'mod_glossary') . '"'),
+            new Given('I press "Add Category"'),
+            new Given('I fill in "name" with "' . $categoryname . '"'),
+            new Given('I press "' . get_string('savechanges') . '"'),
+            new Given('I press "' . get_string('back', 'mod_glossary') . '"')
+        );
+    }
 }
diff --git a/mod/glossary/tests/behat/search_entries.feature b/mod/glossary/tests/behat/search_entries.feature
new file mode 100644 (file)
index 0000000..2f6cd44
--- /dev/null
@@ -0,0 +1,88 @@
+@mod_glossary @mod
+Feature: Glossary entries can be searched or browsed by alphabet, category, date or author
+  In order to find entries in a glossary
+  As a moodle user
+  I need to search the entries list by keyword, alphabet, category, date and author
+
+  Background:
+    Given the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+      | student1 | Student | 1 | student1@asd.com |
+    And the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Glossary" to section "1" and I fill the form with:
+      | Name | Test glossary name |
+      | Description | Test glossary description |
+    And I follow "Test glossary name"
+    And I add a glossary entries category named "The ones I like"
+    And I add a glossary entries category named "All for you"
+    And I add a glossary entry with the following data:
+      | Concept | Eggplant |
+      | Definition | Sour eggplants |
+      | Categories | All for you |
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test glossary name"
+    And I add a glossary entry with the following data:
+      | Concept | Cucumber |
+      | Definition | Sweet cucumber |
+      | Categories | The ones I like |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Test glossary name"
+
+  @javascript
+  Scenario: Search by keyword and browse by alphabet
+    When I fill in "hook" with "cucumber"
+    And I press "Search"
+    Then I should see "Sweet cucumber"
+    And I should see "Search: cucumber"
+    And I follow "Browse by alphabet"
+    And I click on "E" "link" in the ".entrybox" "css_element"
+    And I should see "Sour eggplants"
+    And I should not see "Sweet cucumber"
+    And I click on "X" "link" in the ".entrybox" "css_element"
+    And I should not see "Sweet cucumber"
+    And I should see "No entries found in this section"
+
+  @javascript
+  Scenario: Browse by category
+    When I follow "Browse by category"
+    And I select "The ones I like" from "Categories"
+    Then I should see "Sweet cucumber"
+    And I should not see "Sour eggplants"
+    And I select "All for you" from "Categories"
+    And I should see "Sour eggplants"
+    And I should not see "Sweet cucumber"
+
+  @javascript
+  Scenario: Browse by date
+    When I follow "Browse by date"
+    And I follow "By creation date"
+    Then "Delete: Eggplant" "link" should appear before "Delete: Cucumber" "link"
+    And I follow "By last update"
+    And I follow "By last update change to descending"
+    And "Delete: Cucumber" "link" should appear before "Delete: Eggplant" "link"
+
+  @javascript
+  Scenario: Browse by author
+    When I follow "Browse by Author"
+    And I click on "T" "link" in the ".entrybox" "css_element"
+    Then I should see "Teacher 1"
+    And I should see "Sour eggplants"
+    And I should not see "Sweet cucumber"
+    And I click on "S" "link" in the ".entrybox" "css_element"
+    And I should see "Student 1"
+    And I should see "Sweet cucumber"
+    And I should not see "Sour eggplants"
diff --git a/mod/wiki/tests/behat/collaborative_individual.feature b/mod/wiki/tests/behat/collaborative_individual.feature
new file mode 100644 (file)
index 0000000..d48375f
--- /dev/null
@@ -0,0 +1,90 @@
+@mod_wiki @mod
+Feature: A teacher can set a wiki to be collaborative or individual
+  In order to allow both collaborative wikis and individual journals with history register
+  As a teacher
+  I need to select whether the wiki is collaborative or individual
+
+  @javascript
+  Scenario: Collaborative and individual wikis
+    Given the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+      | student1 | Student | 1 | student1@asd.com |
+      | student2 | Student | 2 | student2@asd.com |
+    And the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Wiki" to section "1" and I fill the form with:
+      | Wiki name | Collaborative wiki name |
+      | Description | Collaborative wiki description |
+      | First page name | Collaborative index |
+      | Wiki mode | Collaborative wiki |
+    And I follow "Collaborative wiki name"
+    And I press "Create page"
+    And I fill the moodle form with:
+      | HTML format | Collaborative teacher1 edition |
+    And I press "Save"
+    And I follow "Course 1"
+    And I add a "Wiki" to section "1" and I fill the form with:
+      | Wiki name | Individual wiki name |
+      | Description | Individual wiki description |
+      | First page name | Individual index |
+      | Wiki mode | Individual wiki |
+    And I follow "Individual wiki name"
+    And I press "Create page"
+    And I fill the moodle form with:
+      | HTML format | Individual teacher1 edition |
+    And I press "Save"
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    When I follow "Collaborative wiki name"
+    Then I should see "Collaborative teacher1 edition"
+    And I follow "Edit"
+    And I fill the moodle form with:
+      | HTML format | Collaborative student1 edition |
+    And I press "Save"
+    And I should not see "Collaborative teacher1 edition"
+    And I should see "Collaborative student1 edition"
+    And I follow "Course 1"
+    And I follow "Individual wiki name"
+    And I should not see "Individual teacher1 edition"
+    And I press "Create page"
+    And I fill the moodle form with:
+      | HTML format | Individual student1 edition |
+    And I press "Save"
+    And I log out
+    And I log in as "student2"
+    And I follow "Course 1"
+    And I follow "Individual wiki name"
+    And I should not see "Individual teacher1 edition"
+    And I should not see "Individual student1 edition"
+    And I press "Create page"
+    And I fill the moodle form with:
+      | HTML format | Individual student2 edition |
+    And I press "Save"
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Collaborative wiki name"
+    And I should see "Collaborative student1 edition"
+    And I follow "Course 1"
+    And I follow "Individual wiki name"
+    And I should see "Individual teacher1 edition"
+    And I should not see "Individual student1 edition"
+    And I select "Student 1" from "uid"
+    And I should see "Individual student1 edition"
+    And I should not see "Individual teacher1 edition"
+    And I select "Student 2" from "uid"
+    And I should see "Individual student2 edition"
+    And I should not see "Individual teacher1 edition"
+
+
diff --git a/mod/wiki/tests/behat/preview_page.feature b/mod/wiki/tests/behat/preview_page.feature
new file mode 100644 (file)
index 0000000..3cd1288
--- /dev/null
@@ -0,0 +1,45 @@
+@mod_wiki @mod
+Feature: Edited wiki pages may be previewed before saving
+
+  Background:
+    Given the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+      | student1 | Student | 1 | student1@asd.com |
+    And the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Wiki" to section "1" and I fill the form with:
+      | Wiki name | Test wiki name |
+      | Description | Test wiki description |
+      | First page name | First page |
+      | Wiki mode | Collaborative wiki |
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test wiki name"
+    When I press "Create page"
+    And I fill the moodle form with:
+      | HTML format | Student page contents to be previewed |
+    And I press "Preview"
+    Then I should see "This is a preview. Changes have not been saved yet"
+    And I should see "Student page contents to be previewed"
+    And I press "Save"
+    And I should see "Student page contents to be previewed"
+    And I follow "Edit"
+
+  @javascript
+  Scenario: Page contents preview before saving with Javascript enabled
+    Then the "HTML format" field should match "<p>Student page contents to be previewed</p>" value
+    And I press "Cancel"
+
+  Scenario: Page contents preview before saving with Javascript disabled
+    Then the "HTML format" field should match "Student page contents to be previewed" value
+    And I press "Cancel"
diff --git a/question/tests/behat/behat_question.php b/question/tests/behat/behat_question.php
new file mode 100644 (file)
index 0000000..cb1e423
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Behat question-related steps definitions.
+ *
+ * @package    core_question
+ * @category   test
+ * @copyright  2013 David MonllaĆ³
+ * @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/behat/behat_base.php');
+
+use Behat\Behat\Context\Step\Given as Given,
+    Behat\Gherkin\Node\TableNode as TableNode;
+
+/**
+ * Steps definitions related with the question bank management.
+ *
+ * @package    core_question
+ * @category   test
+ * @copyright  2013 David MonllaĆ³
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class behat_question extends behat_base {
+
+    /**
+     * Creates a question in the current course questions bank with the provided data. This step can only be used when creating question types composed by a single form.
+     *
+     * @Given /^I add a "(?P<question_type_name_string>(?:[^"]|\\")*)" question filling the form with:$/
+     * @param string $questiontypename The question type name
+     * @param TableNode $questiondata The data to fill the question type form
+     */
+    public function i_add_a_question_filling_the_form_with($questiontypename, TableNode $questiondata) {
+
+        $questiontypexpath = "//span[@class='qtypename'][.='" . $questiontypename . "']
+/ancestor::div[@class='qtypeoption']/descendant::input";
+
+        return array(
+            new Given('I follow "' . get_string('questionbank', 'question') . '"'),
+            new Given('I press "' . get_string('createnewquestion', 'question') . '"'),
+            new Given('I click on "' . $questiontypexpath . '" "xpath_element"'),
+            new Given('I click on "Next" "button" in the "#qtypechoicecontainer" "css_element"'),
+            new Given('I fill the moodle form with:', $questiondata),
+            new Given('I press "Save changes"')
+        );
+    }
+
+}
diff --git a/question/tests/behat/edit_questions.feature b/question/tests/behat/edit_questions.feature
new file mode 100644 (file)
index 0000000..124b86e
--- /dev/null
@@ -0,0 +1,44 @@
+@core_question
+Feature: A teacher can edit questions in the question bank
+  In order to refine questions contents
+  As a teacher
+  I need to edit questions
+
+  @javascript
+  Scenario: Edit a previously created question
+    Given the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+    And the following "courses" exists:
+      | fullname | shortname | format |
+      | Course 1 | C1 | weeks |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+    And I log in as "admin"
+    And I follow "Course 1"
+    And I add a "Essay" question filling the form with:
+      | Question name | Test question name |
+      | Question text | Write about whatever you want |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Question bank"
+    When I click on "Edit" "link" in the "Test question name" table row
+    And I fill the moodle form with:
+      | Question name | Edited question name |
+      | Question text | Write a lot about what you want |
+    And I press "Save changes"
+    Then I should see "Edited question name"
+    And I should not see "Test question name"
+    And I should see "Admin User" in the ".categoryquestionscontainer tbody .creatorname" "css_element"
+    And I should see "Teacher 1" in the ".categoryquestionscontainer tbody .modifiername" "css_element"
+    And I click on "Edit" "link" in the "Edited question name" table row
+    And the "Question name" field should match "Edited question name" value
+    And I press "Cancel"
+    And I click on "Preview" "link" in the "Edited question name" table row
+    And I switch to "questionpreview" window
+    And I should see "Edited question name"
+    And I should see "Write a lot about what you want"
+    And I press "Close preview"
+    And I switch to the main window
diff --git a/question/tests/behat/sort_questions.feature b/question/tests/behat/sort_questions.feature
new file mode 100644 (file)
index 0000000..ee7cedd
--- /dev/null
@@ -0,0 +1,53 @@
+@core_question
+Feature: A teacher can sort questions in the question bank
+  In order to order the question bank's questions
+  As a teacher
+  I need to sort the questions list using different sort orders
+
+  @javascript
+  Scenario: Sort using question name, question type and created by sort order links
+    Given the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+    And the following "courses" exists:
+      | fullname | shortname | format |
+      | Course 1 | C1 | weeks |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+    And I log in as "admin"
+    And I follow "Course 1"
+    And I add a "Essay" question filling the form with:
+      | Question name | A question 1 name |
+      | Question text | A question 1 text |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I add a "Essay" question filling the form with:
+      | Question name | B question 2 name |
+      | Question text | B question 2 text |
+    And I add a "Numerical" question filling the form with:
+      | Question name | C question 3 name |
+      | Question text | C question 3 text |
+      | answer[0] | 2 |
+      | fraction[0] | 100% |
+      | answer[1] | 1 |
+      | fraction[1] | None |
+    When I follow "Sort by Question ascending"
+    Then "A question 1 name" "checkbox" should appear before "B question 2 name" "checkbox"
+    And "B question 2 name" "checkbox" should appear before "C question 3 name" "checkbox"
+    And I follow "Sort by Question descending"
+    And "C question 3 name" "checkbox" should appear before "B question 2 name" "checkbox"
+    And "B question 2 name" "checkbox" should appear before "A question 1 name" "checkbox"
+    And I follow "Sort by Question type ascending"
+    And "A question 1 name" "checkbox" should appear before "C question 3 name" "checkbox"
+    And I follow "Sort by Question type descending"
+    And "C question 3 name" "checkbox" should appear before "A question 1 name" "checkbox"
+    And I follow "Sort by First name ascending"
+    And "A question 1 name" "checkbox" should appear before "B question 2 name" "checkbox"
+    And I follow "Sort by First name descending"
+    And "B question 2 name" "checkbox" should appear before "A question 1 name" "checkbox"
+    And I click on "Show question text in the question list" "checkbox"
+    And I should see "A question 1 text"
+    And I should see "B question 2 text"
+    And I should see "C question 3 text"