MDL-59244 mod_workshop: New WS mod_workshop_delete_submission
authorJuan Leyva <juanleyvadelgado@gmail.com>
Wed, 21 Jun 2017 13:40:08 +0000 (14:40 +0100)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Wed, 6 Sep 2017 13:51:55 +0000 (15:51 +0200)
mod/workshop/classes/external.php
mod/workshop/db/services.php
mod/workshop/tests/external_test.php
mod/workshop/version.php

index 0756214..e37c49c 100644 (file)
@@ -637,4 +637,70 @@ class mod_workshop_external extends external_api {
             'warnings' => new external_warnings()
         ));
     }
+
+    /**
+     * Returns the description of the external function parameters.
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.4
+     */
+    public static function delete_submission_parameters() {
+        return new external_function_parameters(
+            array(
+                'submissionid' => new external_value(PARAM_INT, 'Submission id'),
+            )
+        );
+    }
+
+
+    /**
+     * Deletes the given submission.
+     *
+     * @param int $submissionid the submission id.
+     * @return array containing the result status and warnings.
+     * @since Moodle 3.4
+     * @throws moodle_exception
+     */
+    public static function delete_submission($submissionid) {
+        global $USER, $DB;
+
+        $params = self::validate_parameters(self::delete_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);
+
+        // Check if we can delete the submission.
+        if (!has_capability('mod/workshop:deletesubmissions', $context)) {
+            require_capability('mod/workshop:submit', $context);
+            // We can delete our own submission, on time and not yet assessed.
+            $candeletesubmission = $submission->authorid == $USER->id;
+            $candeletesubmission = $candeletesubmission && $workshop->modifying_submission_allowed($USER->id);
+            $candeletesubmission = $candeletesubmission && count($workshop->get_assessments_of_submission($submission->id)) == 0;
+            if (!$candeletesubmission) {
+                throw new moodle_exception('nopermissions', 'error', '', 'delete submission');
+            }
+        }
+
+        $workshop->delete_submission($submission);
+
+        return array(
+            'status' => true,
+            'warnings' => $warnings
+        );
+    }
+
+    /**
+     * Returns the description of the external function return value.
+     *
+     * @return external_description
+     * @since Moodle 3.4
+     */
+    public static function delete_submission_returns() {
+        return new external_single_structure(array(
+            'status' => new external_value(PARAM_BOOL, 'True if the submission was deleted.'),
+            'warnings' => new external_warnings()
+        ));
+    }
 }
index 7fc3ea7..416821a 100644 (file)
@@ -77,4 +77,12 @@ $functions = array(
         'capabilities'  => 'mod/workshop:submit',
         'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
     ),
+    'mod_workshop_delete_submission' => array(
+        'classname'     => 'mod_workshop_external',
+        'methodname'    => 'delete_submission',
+        'description'   => 'Deletes the given submission.',
+        'type'          => 'write',
+        'capabilities'  => 'mod/workshop:submit',
+        'services'      => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+    ),
 );
index 89b7284..071c139 100644 (file)
@@ -692,4 +692,100 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase {
         $this->expectException('moodle_exception');
         mod_workshop_external::update_submission($submissionid, '');
     }
+
+    /**
+     * Test test_delete_submission.
+     */
+    public function test_delete_submission() {
+
+        // Create the submission that will be deleted.
+        $submissionid = $this->create_test_submission($this->student);
+
+        $this->setUser($this->student);
+
+        // Trigger and capture the event.
+        $sink = $this->redirectEvents();
+
+        $result = mod_workshop_external::delete_submission($submissionid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::delete_submission_returns(), $result);
+        $this->assertEmpty($result['warnings']);
+        $this->assertTrue($result['status']);
+        $workshop = new workshop($this->workshop, $this->cm, $this->course);
+        $submission = $workshop->get_submission_by_author($this->student->id);
+        $this->assertFalse($submission);
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = array_shift($events);
+
+        // Checking event.
+        $this->assertInstanceOf('\mod_workshop\event\submission_deleted', $event);
+        $this->assertEquals($this->context, $event->get_context());
+    }
+
+    /**
+     * Test test_delete_submission_with_assessments.
+     */
+    public function test_delete_submission_with_assessments() {
+
+        // Create the submission that will be deleted.
+        $submissionid = $this->create_test_submission($this->student);
+
+        $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
+        $workshopgenerator->create_assessment($submissionid, $this->teacher->id, array(
+            'weight' => 3,
+            'grade' => 95.00000,
+        ));
+
+        $this->setUser($this->student);
+        $this->expectException('moodle_exception');
+        mod_workshop_external::delete_submission($submissionid);
+    }
+
+    /**
+     * Test test_delete_submission_invalid_phase.
+     */
+    public function test_delete_submission_invalid_phase() {
+
+        // Create the submission that will be deleted.
+        $submissionid = $this->create_test_submission($this->student);
+
+        // Switch to assessment phase.
+        $workshop = new workshop($this->workshop, $this->cm, $this->course);
+        $workshop->switch_phase(workshop::PHASE_ASSESSMENT);
+
+        $this->setUser($this->student);
+        $this->expectException('moodle_exception');
+        mod_workshop_external::delete_submission($submissionid);
+    }
+
+    /**
+     * Test test_delete_submission_as_teacher.
+     */
+    public function test_delete_submission_as_teacher() {
+
+        // Create the submission that will be deleted.
+        $submissionid = $this->create_test_submission($this->student);
+
+        $this->setUser($this->teacher);
+        $result = mod_workshop_external::delete_submission($submissionid);
+        $result = external_api::clean_returnvalue(mod_workshop_external::delete_submission_returns(), $result);
+        $this->assertEmpty($result['warnings']);
+        $this->assertTrue($result['status']);
+    }
+
+    /**
+     * Test test_delete_submission_other_user.
+     */
+    public function test_delete_submission_other_user() {
+
+        $anotheruser = self::getDataGenerator()->create_user();
+        $this->getDataGenerator()->enrol_user($anotheruser->id, $this->course->id, $this->studentrole->id, 'manual');
+        // Create the submission that will be deleted.
+        $submissionid = $this->create_test_submission($this->student);
+
+        $this->setUser($anotheruser);
+        $this->expectException('moodle_exception');
+        mod_workshop_external::delete_submission($submissionid);
+    }
 }
index f611a42..937d9b4 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2017051506;        // The current module version (YYYYMMDDXX)
+$plugin->version   = 2017051507;        // 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.