MDL-51566 mod_choice: New WS mod_choice_delete_choice_responses
[moodle.git] / mod / choice / tests / externallib_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * External choice functions unit tests
19  *
20  * @package    mod_choice
21  * @category   external
22  * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
30 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
31 require_once($CFG->dirroot . '/mod/choice/lib.php');
33 /**
34  * External choice functions unit tests
35  *
36  * @package    mod_choice
37  * @category   external
38  * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
39  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  */
41 class mod_choice_externallib_testcase extends externallib_advanced_testcase {
43     /**
44      * Test get_choice_results
45      */
46     public function test_get_choice_results() {
47         global $DB;
49         $this->resetAfterTest(true);
51         $course = self::getDataGenerator()->create_course();
52         $params = new stdClass();
53         $params->course = $course->id;
54         $params->option = array('fried rice', 'spring rolls', 'sweet and sour pork', 'satay beef', 'gyouza');
55         $params->name = 'First Choice Activity';
56         $params->showresults = CHOICE_SHOWRESULTS_AFTER_ANSWER;
57         $params->publish = 1;
58         $params->allowmultiple = 1;
59         $params->showunanswered = 1;
60         $choice = self::getDataGenerator()->create_module('choice', $params);
62         $cm = get_coursemodule_from_id('choice', $choice->cmid);
63         $choiceinstance = choice_get_choice($cm->instance);
64         $options = array_keys($choiceinstance->option);
65         $student1 = $this->getDataGenerator()->create_user();
66         $student2 = $this->getDataGenerator()->create_user();
67         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
69         // Enroll Students in Course1.
70         self::getDataGenerator()->enrol_user($student1->id,  $course->id, $studentrole->id);
71         self::getDataGenerator()->enrol_user($student2->id,  $course->id, $studentrole->id);
73         $this->setUser($student1);
74         $myanswer = $options[2];
75         choice_user_submit_response($myanswer, $choice, $student1->id, $course, $cm);
76         $results = mod_choice_external::get_choice_results($choice->id);
77         // We need to execute the return values cleaning process to simulate the web service server.
78         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_results_returns(), $results);
80         // Create an array with optionID as Key.
81         $resultsarr = array();
82         foreach ($results['options'] as $option) {
83             $resultsarr[$option['id']] = $option['userresponses'];
84         }
85         // The stundent1 is the userid who choosed the myanswer(option 3).
86         $this->assertEquals($resultsarr[$myanswer][0]['userid'], $student1->id);
87         // The stundent2 is the userid who didn't answered yet.
88         $this->assertEquals($resultsarr[0][0]['userid'], $student2->id);
90         // As Stundent2 we cannot see results (until we answered).
91         $this->setUser($student2);
92         $results = mod_choice_external::get_choice_results($choice->id);
93         // We need to execute the return values cleaning process to simulate the web service server.
94         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_results_returns(), $results);
95         // We do not retrieve any response!
96         foreach ($results['options'] as $option) {
97             $this->assertCount(0, $option['userresponses']);
98         }
100         $timenow = time();
101         // We can see results only after activity close (even if we didn't answered).
102         $choice->showresults = CHOICE_SHOWRESULTS_AFTER_CLOSE;
103         // Set timeopen and timeclose in the past.
104         $choice->timeopen = $timenow - (60 * 60 * 24 * 3);
105         $choice->timeclose = $timenow + (60 * 60 * 24 * 2);
106         $DB->update_record('choice', $choice);
108         $results = mod_choice_external::get_choice_results($choice->id);
109         // We need to execute the return values cleaning process to simulate the web service server.
110         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_results_returns(), $results);
111         // We do not retrieve any response (activity is still open).
112         foreach ($results['options'] as $option) {
113             $this->assertCount(0, $option['userresponses']);
114         }
116         // We close the activity (setting timeclose in the past).
117         $choice->timeclose = $timenow - (60 * 60 * 24 * 2);
118         $DB->update_record('choice', $choice);
119         // Now as Stundent2 we will see results!
120         $results = mod_choice_external::get_choice_results($choice->id);
121         // We need to execute the return values cleaning process to simulate the web service server.
122         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_results_returns(), $results);
123         // Create an array with optionID as Key.
124         $resultsarr = array();
125         foreach ($results['options'] as $option) {
126             $resultsarr[$option['id']] = $option['userresponses'];
127         }
128         // The stundent1 is the userid who choosed the myanswer(option 3).
129         $this->assertEquals($resultsarr[$myanswer][0]['userid'], $student1->id);
130         // The stundent2 is the userid who didn't answered yet.
131         $this->assertEquals($resultsarr[0][0]['userid'], $student2->id);
133         // Do not publish user names!
134         $choice->publish = 0;
135         $DB->update_record('choice', $choice);
136         $results = mod_choice_external::get_choice_results($choice->id);
137         // We need to execute the return values cleaning process to simulate the web service server.
138         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_results_returns(), $results);
139         // Create an array with optionID as Key.
140         $resultsarr = array();
141         // Does not show any user response!
142         foreach ($results['options'] as $option) {
143             $this->assertCount(0, $option['userresponses']);
144             $resultsarr[$option['id']] = $option;
145         }
146         // But we can see totals and percentages.
147         $this->assertEquals(1, $resultsarr[$myanswer]['numberofuser']);
148     }
150     /**
151      * Test get_choice_options
152      */
153     public function test_get_choice_options() {
154         global $DB;
156         // Warningcodes.
157         $notopenyet = 1;
158         $previewonly = 2;
159         $expired = 3;
161         $this->resetAfterTest(true);
162         $timenow = time();
163         $timeopen = $timenow + (60 * 60 * 24 * 2);
164         $timeclose = $timenow + (60 * 60 * 24 * 7);
165         $course = self::getDataGenerator()->create_course();
166         $possibleoptions = array('fried rice', 'spring rolls', 'sweet and sour pork', 'satay beef', 'gyouza');
167         $params = array();
168         $params['course'] = $course->id;
169         $params['option'] = $possibleoptions;
170         $params['name'] = 'First Choice Activity';
171         $params['showpreview'] = 0;
173         $generator = $this->getDataGenerator()->get_plugin_generator('mod_choice');
174         $choice = $generator->create_instance($params);
176         $student1 = $this->getDataGenerator()->create_user();
177         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
178         // Enroll Students in Course.
179         self::getDataGenerator()->enrol_user($student1->id,  $course->id, $studentrole->id);
180         $this->setUser($student1);
182         $results = mod_choice_external::get_choice_options($choice->id);
183         // We need to execute the return values cleaning process to simulate the web service server.
184         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_options_returns(), $results);
185         // We should retrieve all options.
186         $this->assertCount(count($possibleoptions), $results['options']);
188         // Here we force timeopen/close in the future.
189         $choice->timeopen = $timeopen;
190         $choice->timeclose = $timeclose;
191         $DB->update_record('choice', $choice);
193         $results = mod_choice_external::get_choice_options($choice->id);
194         // We need to execute the return values cleaning process to simulate the web service server.
195         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_options_returns(), $results);
196         // We should retrieve no options.
197         $this->assertCount(0, $results['options']);
198         $this->assertEquals($notopenyet, $results['warnings'][0]['warningcode']);
200         // Here we see the options because of preview!
201         $choice->showpreview = 1;
202         $DB->update_record('choice', $choice);
203         $results = mod_choice_external::get_choice_options($choice->id);
204         // We need to execute the return values cleaning process to simulate the web service server.
205         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_options_returns(), $results);
206         // We should retrieve all options.
207         $this->assertCount(count($possibleoptions), $results['options']);
209         foreach ($results['options'] as $option) {
210             // Each option is disabled as this is only the preview!
211             $this->assertEquals(1, $option['disabled']);
212         }
213         $warnings = array();
214         foreach ($results['warnings'] as $warning) {
215             $warnings[$warning['warningcode']] = $warning['message'];
216         }
217         $this->assertTrue(isset($warnings[$previewonly]));
218         $this->assertTrue(isset($warnings[$notopenyet]));
220         // Simulate activity as opened!
221         $choice->timeopen = $timenow - (60 * 60 * 24 * 3);
222         $choice->timeclose = $timenow + (60 * 60 * 24 * 2);
223         $DB->update_record('choice', $choice);
224         $cm = get_coursemodule_from_id('choice', $choice->cmid);
225         $choiceinstance = choice_get_choice($cm->instance);
226         $optionsids = array_keys($choiceinstance->option);
227         $myanswerid = $optionsids[2];
228         choice_user_submit_response($myanswerid, $choice, $student1->id, $course, $cm);
230         $results = mod_choice_external::get_choice_options($choice->id);
231         // We need to execute the return values cleaning process to simulate the web service server.
232         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_options_returns(), $results);
233         // We should retrieve all options.
234         $this->assertCount(count($possibleoptions), $results['options']);
235         foreach ($results['options'] as $option) {
236             // When we answered and we cannot update our choice.
237             if ($option['id'] == $myanswerid and !$choice->allowupdate) {
238                 $this->assertEquals(1, $option['disabled']);
239                 $this->assertEquals(1, $option['checked']);
240             } else {
241                 $this->assertEquals(0, $option['disabled']);
242             }
243         }
245         // Set timeopen and timeclose as older than today!
246         // We simulate what happens when the activity is closed.
247         $choice->timeopen = $timenow - (60 * 60 * 24 * 3);
248         $choice->timeclose = $timenow - (60 * 60 * 24 * 2);
249         $DB->update_record('choice', $choice);
250         $results = mod_choice_external::get_choice_options($choice->id);
251         // We need to execute the return values cleaning process to simulate the web service server.
252         $results = external_api::clean_returnvalue(mod_choice_external::get_choice_options_returns(), $results);
253         // We should retrieve no options.
254         $this->assertCount(0, $results['options']);
255         $this->assertEquals($expired, $results['warnings'][0]['warningcode']);
257     }
259     /**
260      * Test submit_choice_response
261      */
262     public function test_submit_choice_response() {
263         global $DB;
265         $this->resetAfterTest(true);
267         $course = self::getDataGenerator()->create_course();
268         $params = new stdClass();
269         $params->course = $course->id;
270         $params->option = array('fried rice', 'spring rolls', 'sweet and sour pork', 'satay beef', 'gyouza');
271         $params->name = 'First Choice Activity';
272         $params->showresults = CHOICE_SHOWRESULTS_ALWAYS;
273         $params->allowmultiple = 1;
274         $params->showunanswered = 1;
275         $choice = self::getDataGenerator()->create_module('choice', $params);
276         $cm = get_coursemodule_from_id('choice', $choice->cmid);
277         $choiceinstance = choice_get_choice($cm->instance);
278         $options = array_keys($choiceinstance->option);
279         $student1 = $this->getDataGenerator()->create_user();
280         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
282         // Enroll Students in Course1.
283         self::getDataGenerator()->enrol_user($student1->id,  $course->id, $studentrole->id);
285         $this->setUser($student1);
286         $myresponse = $options[2];
287         $results = mod_choice_external::submit_choice_response($choice->id, array($myresponse));
288         // We need to execute the return values cleaning process to simulate the web service server.
289         $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
290         $myanswers = $DB->get_records('choice_answers', array('choiceid' => $choice->id, 'userid' => $student1->id));
291         $myanswer = reset($myanswers);
292         $this->assertEquals($results['answers'][0]['id'], $myanswer->id);
293         $this->assertEquals($results['answers'][0]['choiceid'], $myanswer->choiceid);
294         $this->assertEquals($results['answers'][0]['userid'], $myanswer->userid);
295         $this->assertEquals($results['answers'][0]['timemodified'], $myanswer->timemodified);
296     }
298     /**
299      * Test view_choice
300      */
301     public function test_view_choice() {
302         global $DB;
304         $this->resetAfterTest(true);
306         // Setup test data.
307         $course = $this->getDataGenerator()->create_course();
308         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
309         $context = context_module::instance($choice->cmid);
310         $cm = get_coursemodule_from_instance('choice', $choice->id);
312         // Test invalid instance id.
313         try {
314             mod_choice_external::view_choice(0);
315             $this->fail('Exception expected due to invalid mod_choice instance id.');
316         } catch (moodle_exception $e) {
317             $this->assertEquals('invalidcoursemodule', $e->errorcode);
318         }
320         // Test not-enrolled user.
321         $user = self::getDataGenerator()->create_user();
322         $this->setUser($user);
323         try {
324             mod_choice_external::view_choice($choice->id);
325             $this->fail('Exception expected due to not enrolled user.');
326         } catch (moodle_exception $e) {
327             $this->assertEquals('requireloginerror', $e->errorcode);
328         }
330         // Test user with full capabilities.
331         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
332         $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
334         // Trigger and capture the event.
335         $sink = $this->redirectEvents();
337         $result = mod_choice_external::view_choice($choice->id);
338         $result = external_api::clean_returnvalue(mod_choice_external::view_choice_returns(), $result);
340         $events = $sink->get_events();
341         $this->assertCount(1, $events);
342         $event = array_shift($events);
344         // Checking that the event contains the expected values.
345         $this->assertInstanceOf('\mod_choice\event\course_module_viewed', $event);
346         $this->assertEquals($context, $event->get_context());
347         $moodlechoice = new \moodle_url('/mod/choice/view.php', array('id' => $cm->id));
348         $this->assertEquals($moodlechoice, $event->get_url());
349         $this->assertEventContextNotUsed($event);
350         $this->assertNotEmpty($event->get_name());
352     }
354     /**
355      * Test get_choices_by_courses
356      */
357     public function test_get_choices_by_courses() {
358         global $DB;
359         $this->resetAfterTest(true);
360         // As admin.
361         $this->setAdminUser();
362         $course1 = self::getDataGenerator()->create_course();
363         $choiceoptions1 = array(
364           'course' => $course1->id,
365           'name' => 'First IMSCP'
366         );
367         $choice1 = self::getDataGenerator()->create_module('choice', $choiceoptions1);
368         $course2 = self::getDataGenerator()->create_course();
370         $choiceoptions2 = array(
371           'course' => $course2->id,
372           'name' => 'Second IMSCP'
373         );
374         $choice2 = self::getDataGenerator()->create_module('choice', $choiceoptions2);
375         $student1 = $this->getDataGenerator()->create_user();
377         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
379         // Enroll Student1 in Course1.
380         self::getDataGenerator()->enrol_user($student1->id,  $course1->id, $studentrole->id);
382         $this->setUser($student1);
383         $choices = mod_choice_external::get_choices_by_courses(array());
384         $choices = external_api::clean_returnvalue(mod_choice_external::get_choices_by_courses_returns(), $choices);
385         $this->assertCount(1, $choices['choices']);
386         $this->assertEquals('First IMSCP', $choices['choices'][0]['name']);
387         // As Student you cannot see some IMSCP properties like 'section'.
388         $this->assertFalse(isset($choices['choices'][0]['section']));
390         // Student1 is not enrolled in this Course.
391         // The webservice will give a warning!
392         $choices = mod_choice_external::get_choices_by_courses(array($course2->id));
393         $choices = external_api::clean_returnvalue(mod_choice_external::get_choices_by_courses_returns(), $choices);
394         $this->assertCount(0, $choices['choices']);
395         $this->assertEquals(1, $choices['warnings'][0]['warningcode']);
397         // Now as admin.
398         $this->setAdminUser();
399         // As Admin we can see this IMSCP.
400         $choices = mod_choice_external::get_choices_by_courses(array($course2->id));
401         $choices = external_api::clean_returnvalue(mod_choice_external::get_choices_by_courses_returns(), $choices);
402         $this->assertCount(1, $choices['choices']);
403         $this->assertEquals('Second IMSCP', $choices['choices'][0]['name']);
404         // As an Admin you can see some IMSCP properties like 'section'.
405         $this->assertEquals(0, $choices['choices'][0]['section']);
407         // Now, prohibit capabilities.
408         $this->setUser($student1);
409         $contextcourse1 = context_course::instance($course1->id);
410         // Prohibit capability = mod:choice:choose on Course1 for students.
411         assign_capability('mod/choice:choose', CAP_PROHIBIT, $studentrole->id, $contextcourse1->id);
412         accesslib_clear_all_caches_for_unit_testing();
414         $choices = mod_choice_external::get_choices_by_courses(array($course1->id));
415         $choices = external_api::clean_returnvalue(mod_choice_external::get_choices_by_courses_returns(), $choices);
416         $this->assertFalse(isset($choices['choices'][0]['timeopen']));
417     }
419     /**
420      * Test delete_choice_responses
421      */
422     public function test_delete_choice_responses() {
423         global $DB;
425         $this->resetAfterTest(true);
427         $course = self::getDataGenerator()->create_course();
428         $params = new stdClass();
429         $params->course = $course->id;
430         $params->option = array('fried rice', 'spring rolls', 'sweet and sour pork', 'satay beef', 'gyouza');
431         $params->name = 'First Choice Activity';
432         $params->showresults = CHOICE_SHOWRESULTS_ALWAYS;
433         $params->allowmultiple = 1;
434         $params->showunanswered = 1;
435         $choice = self::getDataGenerator()->create_module('choice', $params);
436         $cm = get_coursemodule_from_id('choice', $choice->cmid);
438         $choiceinstance = choice_get_choice($cm->instance);
439         $options = array_keys($choiceinstance->option);
441         $student = $this->getDataGenerator()->create_user();
442         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
444         // Enroll student in Course1.
445         self::getDataGenerator()->enrol_user($student->id,  $course->id, $studentrole->id);
447         $this->setUser($student);
448         $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2]));
449         $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
451         $myresponses = array_keys(choice_get_my_response($choice));
453         // Try to delete responses when allow update is false.
454         try {
455             mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0], $myresponses[0]));
456             $this->fail('Exception expected due to missing permissions.');
457         } catch (required_capability_exception $e) {
458             $this->assertEquals('nopermissions', $e->errorcode);
459         }
461         // Set allow update to true, and a passed time close.
462         $DB->set_field('choice', 'allowupdate', 1, array('id' => $choice->id));
463         $DB->set_field('choice', 'timeclose', time() - DAYSECS, array('id' => $choice->id));
464         try {
465             mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0], $myresponses[1]));
466             $this->fail('Exception expected due to expired choice.');
467         } catch (moodle_exception $e) {
468             $this->assertEquals('expired', $e->errorcode);
469         }
471         // Reset time close. We should be able now to delete all the responses.
472         $DB->set_field('choice', 'timeclose', 0, array('id' => $choice->id));
473         $results = mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0], $myresponses[1]));
474         $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results);
476         $this->assertTrue($results['status']);
477         $this->assertCount(0, $results['warnings']);
478         // Now, in the DB 0 responses.
479         $this->assertCount(0, choice_get_my_response($choice));
481         // Submit again the responses.
482         $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2]));
483         $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
485         $myresponses = array_keys(choice_get_my_response($choice));
486         // Delete only one response.
487         $results = mod_choice_external::delete_choice_responses($choice->id, array($myresponses[0]));
488         $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results);
489         $this->assertTrue($results['status']);
490         $this->assertCount(0, $results['warnings']);
491         // Now, in the DB 1 response still.
492         $this->assertCount(1, choice_get_my_response($choice));
494         // Delete the remaining response, passing 2 invalid responses ids.
495         $results = mod_choice_external::delete_choice_responses($choice->id, array($myresponses[1], $myresponses[0] + 2,
496                                                                 $myresponses[0] + 3));
497         $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results);
498         $this->assertTrue($results['status']);
499         // 2 warnings, 2 invalid responses.
500         $this->assertCount(2, $results['warnings']);
501         // Now, in the DB 0 responses.
502         $this->assertCount(0, choice_get_my_response($choice));
504         // Now, as an admin we must be able to delete all the responses under any condition.
505         // Submit again the responses.
506         $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2]));
507         $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
508         $studentresponses = array_keys(choice_get_my_response($choice));
510         $this->setAdminUser();
511         $DB->set_field('choice', 'allowupdate', 0, array('id' => $choice->id));
512         $DB->set_field('choice', 'timeclose', time() - DAYSECS, array('id' => $choice->id));
514         $results = mod_choice_external::delete_choice_responses($choice->id, array($studentresponses[0], $studentresponses[1]));
515         $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results);
517         $this->assertTrue($results['status']);
518         $this->assertCount(0, $results['warnings']);
520         // Submit again the responses.
521         $DB->set_field('choice', 'timeclose', 0, array('id' => $choice->id));
522         $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2]));
523         $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
524         // With other user account too, so we can test all the responses are deleted.
525         choice_user_submit_response( array($options[1], $options[2]), $choice, $student->id, $course, $cm);
527         // Test deleting all (not passing the answers ids), event not only mine.
528         $results = mod_choice_external::delete_choice_responses($choice->id);
529         $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results);
531         $this->assertTrue($results['status']);
532         $this->assertCount(0, $results['warnings']);
533         $this->assertCount(0, choice_get_all_responses($choice));
535         // Now, in the DB 0 responses.
536         $this->setUser($student);
538         // Submit again respones.
539         $DB->set_field('choice', 'allowupdate', 1, array('id' => $choice->id));
540         $DB->set_field('choice', 'timeclose', 0, array('id' => $choice->id));
541         $results = mod_choice_external::submit_choice_response($choice->id, array($options[1], $options[2]));
542         $results = external_api::clean_returnvalue(mod_choice_external::submit_choice_response_returns(), $results);
544         // Delete all responses.
545         $results = mod_choice_external::delete_choice_responses($choice->id);
546         $results = external_api::clean_returnvalue(mod_choice_external::delete_choice_responses_returns(), $results);
548         $this->assertTrue($results['status']);
549         $this->assertCount(0, $results['warnings']);
550         $this->assertCount(0, choice_get_my_response($choice));
552     }