MDL-50664 mod_data: tests for 'manageapproved' setting.
authorRyan Wyllie <ryan@moodle.com>
Thu, 6 Aug 2015 04:08:16 +0000 (04:08 +0000)
committerRyan Wyllie <ryan@moodle.com>
Thu, 17 Sep 2015 06:18:26 +0000 (06:18 +0000)
Adding test coverage for the 'manageapproved' setting that
was added by Johannes Burk.

mod/data/tests/behat/manageapproved.feature [new file with mode: 0644]
mod/data/tests/externallib_test.php
mod/data/tests/lib_test.php

diff --git a/mod/data/tests/behat/manageapproved.feature b/mod/data/tests/behat/manageapproved.feature
new file mode 100644 (file)
index 0000000..70e4151
--- /dev/null
@@ -0,0 +1,91 @@
+@mod @mod_data
+Feature: Users can edit approved entries in database activities
+  In order to control whether approved database entries can be changed
+  As a teacher
+  I need to be able to enable or disable management of approved entries
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email |
+      | student1 | Student | 1 | student1@example.com |
+      | teacher1 | Teacher | 1 | teacher1@example.com |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exist:
+      | 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
+
+  @javascript
+  Scenario: Students can manage their approved entries to a database
+    # Create database activity and allow editing of
+    # approved entries.
+    And I add a "Database" to section "1" and I fill the form with:
+      | Name              | Test database name |
+      | Description       | Test               |
+      | id_approval       | Yes                |
+      | id_manageapproved | Yes                |
+    And I add a "Text input" field to "Test database name" database and I fill the form with:
+      | Field name | Test field name |
+      | Field description | Test field description |
+    # To generate the default templates.
+    And I follow "Templates"
+    And I log out
+    # Add an entry as a student.
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I add an entry to "Test database name" database with:
+      | Test field name | Student entry |
+    And I press "Save and view"
+    And I log out
+    # Approve the student's entry as a teacher.
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Test database name"
+    And I follow "Approve"
+    And I log out
+    # Make sure the student can still edit their entry after it's approved.
+    When I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test database name"
+    Then I should see "Student entry"
+    And "Edit" "link" should exist
+
+  @javascript
+  Scenario: Students can not manage their approved entries to a database
+    # Create database activity and don't allow editing of
+    # approved entries.
+    And I add a "Database" to section "1" and I fill the form with:
+      | Name              | Test database name |
+      | Description       | Test               |
+      | id_approval       | Yes                |
+      | id_manageapproved | No                 |
+    And I add a "Text input" field to "Test database name" database and I fill the form with:
+      | Field name | Test field name |
+      | Field description | Test field description |
+    # To generate the default templates.
+    And I follow "Templates"
+    And I log out
+    # Add an entry as a student.
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I add an entry to "Test database name" database with:
+      | Test field name | Student entry |
+    And I press "Save and view"
+    And I log out
+    # Approve the student's entry as a teacher.
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Test database name"
+    And I follow "Approve"
+    And I log out
+    # Make sure the student isn't able to edit their entry after it's approved.
+    When I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test database name"
+    Then I should see "Student entry"
+    And "Edit" "link" should not exist
index 1cc34c2..a0ecd29 100644 (file)
@@ -144,7 +144,7 @@ class mod_data_external_testcase extends externallib_advanced_testcase {
         $additionalfields = array('maxentries', 'rssarticles', 'singletemplate', 'listtemplate',
                                 'listtemplateheader', 'listtemplatefooter', 'addtemplate', 'rsstemplate', 'rsstitletemplate',
                                 'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', 'scale', 'assessed', 'assesstimestart',
-                                'assesstimefinish', 'defaultsort', 'defaultsortdir', 'editany', 'notification');
+                                'assesstimefinish', 'defaultsort', 'defaultsortdir', 'editany', 'notification', 'manageapproved');
 
         foreach ($additionalfields as $field) {
             if ($field == 'approval' or $field == 'editany') {
index fbd744c..7ea4ae5 100644 (file)
@@ -232,6 +232,267 @@ class mod_data_lib_testcase extends advanced_testcase {
         $this->assertEventContextNotUsed($event);
     }
 
+    /**
+     * Checks that data_user_can_manage_entry will return true if the user
+     * has the mod/data:manageentries capability.
+     */
+    public function test_data_user_can_manage_entry_return_true_with_capability() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+
+        $this->setUser($user);
+
+        assign_capability('mod/data:manageentries', CAP_ALLOW, $roleid, $context);
+
+        $this->assertTrue(data_user_can_manage_entry($record, $data, $context),
+            'data_user_can_manage_entry() returns true if the user has mod/data:manageentries capability');
+    }
+
+    /**
+     * Checks that data_user_can_manage_entry will return false if the data
+     * is set to readonly.
+     */
+    public function test_data_user_can_manage_entry_return_false_readonly() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+        // Causes readonly mode to be enable.
+        $now = time();
+        $data->timeviewfrom = $now;
+        $data->timeviewto = $now;
+
+        $this->setUser($user);
+
+        // Need to make sure they don't have this capability in order to fall back to
+        // the other checks.
+        assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
+
+        $this->assertFalse(data_user_can_manage_entry($record, $data, $context),
+            'data_user_can_manage_entry() returns false if the data is read only');
+    }
+
+    /**
+     * Checks that data_user_can_manage_entry will return false if the record
+     * can't be found in the database.
+     */
+    public function test_data_user_can_manage_entry_return_false_no_record() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+        // Causes readonly mode to be disabled.
+        $now = time();
+        $data->timeviewfrom = $now + 100;
+        $data->timeviewto = $now - 100;
+
+        $this->setUser($user);
+
+        // Need to make sure they don't have this capability in order to fall back to
+        // the other checks.
+        assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
+
+        // Pass record id instead of object to force DB lookup.
+        $this->assertFalse(data_user_can_manage_entry(1, $data, $context),
+            'data_user_can_manage_entry() returns false if the record cannot be found');
+    }
+
+    /**
+     * Checks that data_user_can_manage_entry will return false if the record
+     * isn't owned by the user.
+     */
+    public function test_data_user_can_manage_entry_return_false_not_owned_record() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+        // Causes readonly mode to be disabled.
+        $now = time();
+        $data->timeviewfrom = $now + 100;
+        $data->timeviewto = $now - 100;
+        // Make sure the record isn't owned by this user.
+        $record->userid = $user->id + 1;
+
+        $this->setUser($user);
+
+        // Need to make sure they don't have this capability in order to fall back to
+        // the other checks.
+        assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
+
+        $this->assertFalse(data_user_can_manage_entry($record, $data, $context),
+            'data_user_can_manage_entry() returns false if the record isnt owned by the user');
+    }
+
+    /**
+     * Checks that data_user_can_manage_entry will return true if the data
+     * doesn't require approval.
+     */
+    public function test_data_user_can_manage_entry_return_true_data_no_approval() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+        // Causes readonly mode to be disabled.
+        $now = time();
+        $data->timeviewfrom = $now + 100;
+        $data->timeviewto = $now - 100;
+        // The record doesn't need approval.
+        $data->approval = false;
+        // Make sure the record is owned by this user.
+        $record->userid = $user->id;
+
+        $this->setUser($user);
+
+        // Need to make sure they don't have this capability in order to fall back to
+        // the other checks.
+        assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
+
+        $this->assertTrue(data_user_can_manage_entry($record, $data, $context),
+            'data_user_can_manage_entry() returns true if the record doesnt require approval');
+    }
+
+    /**
+     * Checks that data_user_can_manage_entry will return true if the record
+     * isn't yet approved.
+     */
+    public function test_data_user_can_manage_entry_return_true_record_unapproved() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+        // Causes readonly mode to be disabled.
+        $now = time();
+        $data->timeviewfrom = $now + 100;
+        $data->timeviewto = $now - 100;
+        // The record needs approval.
+        $data->approval = true;
+        // Make sure the record is owned by this user.
+        $record->userid = $user->id;
+        // The record hasn't yet been approved.
+        $record->approved = false;
+
+        $this->setUser($user);
+
+        // Need to make sure they don't have this capability in order to fall back to
+        // the other checks.
+        assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
+
+        $this->assertTrue(data_user_can_manage_entry($record, $data, $context),
+            'data_user_can_manage_entry() returns true if the record is not yet approved');
+    }
+
+    /**
+     * Checks that data_user_can_manage_entry will return the 'manageapproved'
+     * value if the record has already been approved.
+     */
+    public function test_data_user_can_manage_entry_return_manageapproved() {
+
+        $this->resetAfterTest();
+        $testdata = $this->create_user_test_data();
+
+        $user = $testdata['user'];
+        $course = $testdata['course'];
+        $roleid = $testdata['roleid'];
+        $context = $testdata['context'];
+        $record = $testdata['record'];
+        $data = new stdClass();
+        // Causes readonly mode to be disabled.
+        $now = time();
+        $data->timeviewfrom = $now + 100;
+        $data->timeviewto = $now - 100;
+        // The record needs approval.
+        $data->approval = true;
+        // Can the user managed approved records?
+        $data->manageapproved = false;
+        // Make sure the record is owned by this user.
+        $record->userid = $user->id;
+        // The record has been approved.
+        $record->approved = true;
+
+        $this->setUser($user);
+
+        // Need to make sure they don't have this capability in order to fall back to
+        // the other checks.
+        assign_capability('mod/data:manageentries', CAP_PROHIBIT, $roleid, $context);
+
+        $canmanageentry = data_user_can_manage_entry($record, $data, $context);
+
+        // Make sure the result of the check is what ever the manageapproved setting
+        // is set to.
+        $this->assertEquals($data->manageapproved, $canmanageentry,
+            'data_user_can_manage_entry() returns the manageapproved setting on approved records');
+    }
+
+    /**
+     * Helper method to create a set of test data for data_user_can_manage tests
+     *
+     * @return array contains user, course, roleid, module, context and record
+     */
+    private function create_user_test_data() {
+        $user = $this->getDataGenerator()->create_user();
+        $course = $this->getDataGenerator()->create_course();
+        $roleid = $this->getDataGenerator()->create_role();
+        $record = new stdClass();
+        $record->name = "test name";
+        $record->intro = "test intro";
+        $record->comments = 1;
+        $record->course = $course->id;
+        $record->userid = $user->id;
+
+        $module = $this->getDataGenerator()->create_module('data', $record);
+        $cm = get_coursemodule_from_instance('data', $module->id, $course->id);
+        $context = context_module::instance($module->cmid);
+
+        $this->getDataGenerator()->role_assign($roleid, $user->id, $context->id);
+
+        return array(
+            'user' => $user,
+            'course' => $course,
+            'roleid' => $roleid,
+            'module' => $module,
+            'context' => $context,
+            'record' => $record
+        );
+    }
+
     /**
      * Tests for mod_data_rating_can_see_item_ratings().
      *