MDL-59242 mod_workshop: New WS mod_workshop_get_submission
authorJuan Leyva <juanleyvadelgado@gmail.com>
Thu, 22 Jun 2017 12:34:14 +0000 (13:34 +0100)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Mon, 2 Oct 2017 07:35:06 +0000 (09:35 +0200)
mod/workshop/classes/external.php
mod/workshop/db/services.php
mod/workshop/tests/external_test.php
mod/workshop/version.php

index bd24d27..2d6522a 100644 (file)
@@ -873,4 +873,79 @@ class mod_workshop_external extends external_api {
             )
         );
     }
+
+    /**
+     * Returns the description of the external function parameters.
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.4
+     */
+    public static function get_submission_parameters() {
+        return new external_function_parameters(
+            array(
+                'submissionid' => new external_value(PARAM_INT, 'Submission id'),
+            )
+        );
+    }
+
+
+    /**
+     * Retrieves the given submission.
+     *
+     * @param int $submissionid the submission id
+     * @return array containing the submission and warnings.
+     * @since Moodle 3.4
+     * @throws moodle_exception
+     */
+    public static function get_submission($submissionid) {
+        global $USER, $DB, $PAGE;
+
+        $params = self::validate_parameters(self::get_submission_parameters(), array('submissionid' => $submissionid));
+        $warnings = array();
+
+        // Get and validate the submission and workshop.
+        $submission = $DB->get_record('workshop_submissions', array('id' => $params['submissionid']), '*', MUST_EXIST);
+        list($workshop, $course, $cm, $context) = self::validate_workshop($submission->workshopid);
+
+        $workshopclosed = $workshop->phase == workshop::PHASE_CLOSED;
+        $canviewpublished = has_capability('mod/workshop:viewpublishedsubmissions', $context);
+
+        $canview = $submission->authorid == $USER->id;  // I did it.
+        $canview = $canview || !empty($workshop->get_assessment_of_submission_by_user($submission->id, $USER->id));  // I reviewed.
+        $canview = $canview || has_capability('mod/workshop:viewallsubmissions', $context); // I can view all.
+        $canview = $canview || ($submission->published && $workshopclosed && $canviewpublished);    // It has been published.
+
+        if ($canview) {
+            // Here we should check if the user share group.
+            if ($submission->authorid != $USER->id && !groups_user_groups_visible($course, $submission->authorid, $cm)) {
+                throw new moodle_exception('notingroup');
+            }
+        } else {
+            throw new moodle_exception('nopermissions', 'error', '', 'view submission');
+        }
+
+        $submission = self::prepare_submission_for_external($submission, $workshop);
+
+        $related = array('context' => $context);
+        $exporter = new submission_exporter($submission, $related);
+        return array(
+            'submission' => $exporter->export($PAGE->get_renderer('core')),
+            'warnings' => $warnings
+        );
+    }
+
+    /**
+     * Returns description of method result value
+     *
+     * @return external_description
+     * @since Moodle 3.4
+     */
+    public static function get_submission_returns() {
+        return new external_single_structure(
+            array(
+                'submission' => submission_exporter::get_read_structure(),
+                'warnings' => new external_warnings()
+            )
+        );
+    }
 }
index 6cdb621..9f0bd6b 100644 (file)
@@ -92,4 +92,11 @@ $functions = array(
         'type'          => 'read',
         'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     ),
+    'mod_workshop_get_submission' => array(
+        'classname'     => 'mod_workshop_external',
+        'methodname'    => 'get_submission',
+        'description'   => 'Retrieves the given submission.',
+        'type'          => 'read',
+        'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+    ),
 );
index 903bebb..f546179 100644 (file)
@@ -930,4 +930,139 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase {
         $this->assertEquals(1, $result['totalcount']);
         $this->assertEquals($submissionid2, $result['submissions'][0]['id']);
     }
+
+    /**
+     * Test test_get_submission_student.
+     */
+    public function test_get_submission_student() {
+
+        // Create a couple of submissions with files.
+        $firstsubmissionid = $this->create_test_submission($this->student);  // Create submission with files.
+
+        $this->setUser($this->student);
+        $result = mod_workshop_external::get_submission($firstsubmissionid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_submission_returns(), $result);
+        $this->assertEquals($firstsubmissionid, $result['submission']['id']);
+        $this->assertCount(1, $result['submission']['contentfiles']); // Check we retrieve submission text files.
+        $this->assertCount(1, $result['submission']['attachmentfiles']); // Check we retrieve attachment files.
+    }
+
+    /**
+     * Test test_get_submission_i_reviewed.
+     */
+    public function test_get_submission_i_reviewed() {
+
+        // Create a couple of submissions with files.
+        $firstsubmissionid = $this->create_test_submission($this->student);  // Create submission with files.
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $workshopgenerator->create_assessment($firstsubmissionid, $this->anotherstudentg1->id, array(
+            'weight' => 3,
+            'grade' => 95,
+        ));
+        // Now try to get the submission I just reviewed.
+        $this->setUser($this->anotherstudentg1);
+        $result = mod_workshop_external::get_submission($firstsubmissionid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_submission_returns(), $result);
+        $this->assertEquals($firstsubmissionid, $result['submission']['id']);
+        $this->assertCount(1, $result['submission']['contentfiles']); // Check we retrieve submission text files.
+        $this->assertCount(1, $result['submission']['attachmentfiles']); // Check we retrieve attachment files.
+    }
+
+    /**
+     * Test test_get_submission_other_student.
+     */
+    public function test_get_submission_other_student() {
+
+        // Create a couple of submissions with files.
+        $firstsubmissionid = $this->create_test_submission($this->student);  // Create submission with files.
+        // Expect failure.
+        $this->setUser($this->anotherstudentg1);
+        $this->expectException('moodle_exception');
+        $result = mod_workshop_external::get_submission($firstsubmissionid);
+    }
+
+    /**
+     * Test test_get_submission_published_student.
+     */
+    public function test_get_submission_published_student() {
+        global $DB;
+
+        $DB->set_field('workshop', 'phase', workshop::PHASE_CLOSED, array('id' => $this->workshop->id));
+        // Create a couple of submissions with files.
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submission = array('published' => 1);
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->anotherstudentg1->id, $submission);
+
+        $this->setUser($this->student);
+        $result = mod_workshop_external::get_submission($submissionid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_submission_returns(), $result);
+        $this->assertEquals($submissionid, $result['submission']['id']);
+        // Check that the student don't see the other student grade/feedback data even if is published.
+        // We shoul not see the grade or feedback information.
+        $properties = submission_exporter::properties_definition();
+        foreach ($properties as $attribute => $settings) {
+            if (!empty($settings['optional'])) {
+                if (isset($result['submission'][$attribute])) {
+                    echo "error $attribute";
+                }
+                $this->assertFalse(isset($result['submission'][$attribute]));
+            }
+        }
+
+        // Check with group restrictions.
+        $this->setUser($this->anotherstudentg2);
+        $this->expectException('moodle_exception');
+        mod_workshop_external::get_submission($submissionid);
+    }
+
+    /**
+     * Test test_get_submission_from_student_with_feedback_from_teacher.
+     */
+    public function test_get_submission_from_student_with_feedback_from_teacher() {
+        global $DB;
+
+        // Create a couple of submissions with files.
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+        // Create teacher feedback for submission.
+        $record = new stdclass();
+        $record->id = $submissionid;
+        $record->gradeover = 9;
+        $record->gradeoverby = $this->teacher->id;
+        $record->feedbackauthor = 'Hey';
+        $record->feedbackauthorformat = FORMAT_MOODLE;
+        $record->published = 1;
+        $DB->update_record('workshop_submissions', $record);
+
+        // Remove teacher caps.
+        assign_capability('mod/workshop:viewallsubmissions', CAP_PROHIBIT, $this->teacher->id, $this->context->id);
+        // Empty all the caches that may be affected  by this change.
+        accesslib_clear_all_caches_for_unit_testing();
+        course_modinfo::clear_instance_cache();
+
+        $this->setUser($this->teacher);
+        $result = mod_workshop_external::get_submission($submissionid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_submission_returns(), $result);
+        $this->assertEquals($submissionid, $result['submission']['id']);
+    }
+
+    /**
+     * Test test_get_submission_from_students_as_teacher.
+     */
+    public function test_get_submission_from_students_as_teacher() {
+        // Create a couple of submissions with files.
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $submissionid1 = $workshopgenerator->create_submission($this->workshop->id, $this->student->id);
+        $submissionid2 = $workshopgenerator->create_submission($this->workshop->id, $this->anotherstudentg1->id);
+        $submissionid3 = $workshopgenerator->create_submission($this->workshop->id, $this->anotherstudentg2->id);
+
+        $this->setUser($this->teacher);
+        $result = mod_workshop_external::get_submission($submissionid1); // Get all.
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_submission_returns(), $result);
+        $this->assertEquals($submissionid1, $result['submission']['id']);
+
+        $result = mod_workshop_external::get_submission($submissionid3); // Get group 2.
+        $result = external_api::clean_returnvalue(mod_workshop_external::get_submission_returns(), $result);
+        $this->assertEquals($submissionid3, $result['submission']['id']);
+    }
 }
index 43d1635..c319cc2 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2017051508;        // The current module version (YYYYMMDDXX)
+$plugin->version   = 2017051509;        // The current module version (YYYYMMDDXX)
 $plugin->requires  = 2017050500;        // Requires this Moodle version.
 $plugin->component = 'mod_workshop';
 $plugin->cron      = 60;                // Give as a chance every minute.