From bde5631d667dc8abe3261988c2340e00ce4cea6b Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Wed, 21 Jun 2017 14:40:08 +0100 Subject: [PATCH] MDL-59244 mod_workshop: New WS mod_workshop_delete_submission --- mod/workshop/classes/external.php | 66 +++++++++++++++++++ mod/workshop/db/services.php | 8 +++ mod/workshop/tests/external_test.php | 96 ++++++++++++++++++++++++++++ mod/workshop/version.php | 2 +- 4 files changed, 171 insertions(+), 1 deletion(-) diff --git a/mod/workshop/classes/external.php b/mod/workshop/classes/external.php index 07562146d09..e37c49c6e89 100644 --- a/mod/workshop/classes/external.php +++ b/mod/workshop/classes/external.php @@ -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() + )); + } } diff --git a/mod/workshop/db/services.php b/mod/workshop/db/services.php index 7fc3ea7ce43..416821a3379 100644 --- a/mod/workshop/db/services.php +++ b/mod/workshop/db/services.php @@ -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) + ), ); diff --git a/mod/workshop/tests/external_test.php b/mod/workshop/tests/external_test.php index 89b7284111b..071c139d860 100644 --- a/mod/workshop/tests/external_test.php +++ b/mod/workshop/tests/external_test.php @@ -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); + } } diff --git a/mod/workshop/version.php b/mod/workshop/version.php index f611a42aafe..937d9b4a195 100644 --- a/mod/workshop/version.php +++ b/mod/workshop/version.php @@ -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. -- 2.43.0