MDL-51569 mod_choice: Validate the submitted optionid
[moodle.git] / mod / choice / tests / lib_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  * Choice module library functions tests
19  *
20  * @package    mod_choice
21  * @category   test
22  * @copyright  2015 Juan Leyva <juan@moodle.com>
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  * @since      Moodle 3.0
25  */
27 defined('MOODLE_INTERNAL') || die();
29 global $CFG;
31 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32 require_once($CFG->dirroot . '/mod/choice/lib.php');
34 /**
35  * Choice module library functions tests
36  *
37  * @package    mod_choice
38  * @category   test
39  * @copyright  2015 Juan Leyva <juan@moodle.com>
40  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  * @since      Moodle 3.0
42  */
43 class mod_choice_lib_testcase extends externallib_advanced_testcase {
45     /**
46      * Test choice_view
47      * @return void
48      */
49     public function test_choice_view() {
50         global $CFG;
52         $this->resetAfterTest();
54         $this->setAdminUser();
55         // Setup test data.
56         $course = $this->getDataGenerator()->create_course();
57         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
58         $context = context_module::instance($choice->cmid);
59         $cm = get_coursemodule_from_instance('choice', $choice->id);
61         // Trigger and capture the event.
62         $sink = $this->redirectEvents();
64         choice_view($choice, $course, $cm, $context);
66         $events = $sink->get_events();
67         $this->assertCount(1, $events);
68         $event = array_shift($events);
70         // Checking that the event contains the expected values.
71         $this->assertInstanceOf('\mod_choice\event\course_module_viewed', $event);
72         $this->assertEquals($context, $event->get_context());
73         $url = new \moodle_url('/mod/choice/view.php', array('id' => $cm->id));
74         $this->assertEquals($url, $event->get_url());
75         $this->assertEventContextNotUsed($event);
76         $this->assertNotEmpty($event->get_name());
77     }
79     /**
80      * Test choice_can_view_results
81      * @return void
82      */
83     public function test_choice_can_view_results() {
84         global $DB, $USER;
86         $this->resetAfterTest();
88         $this->setAdminUser();
89         // Setup test data.
90         $course = $this->getDataGenerator()->create_course();
91         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
92         $context = context_module::instance($choice->cmid);
93         $cm = get_coursemodule_from_instance('choice', $choice->id);
95         // Default values are false, user cannot view results.
96         $canview = choice_can_view_results($choice);
97         $this->assertFalse($canview);
99         // Show results forced.
100         $choice->showresults = CHOICE_SHOWRESULTS_ALWAYS;
101         $DB->update_record('choice', $choice);
102         $canview = choice_can_view_results($choice);
103         $this->assertTrue($canview);
105         // Show results after closing.
106         $choice->showresults = CHOICE_SHOWRESULTS_AFTER_CLOSE;
107         $DB->update_record('choice', $choice);
108         $canview = choice_can_view_results($choice);
109         $this->assertFalse($canview);
111         $choice->timeclose = time() - HOURSECS;
112         $DB->update_record('choice', $choice);
113         $canview = choice_can_view_results($choice);
114         $this->assertTrue($canview);
116         // Show results after answering.
117         $choice->timeclose = 0;
118         $choice->showresults = CHOICE_SHOWRESULTS_AFTER_ANSWER;
119         $DB->update_record('choice', $choice);
120         $canview = choice_can_view_results($choice);
121         $this->assertFalse($canview);
123         // Get the first option.
124         $choicewithoptions = choice_get_choice($choice->id);
125         $optionids = array_keys($choicewithoptions->option);
127         choice_user_submit_response($optionids[0], $choice, $USER->id, $course, $cm);
129         $canview = choice_can_view_results($choice);
130         $this->assertTrue($canview);
132     }
134     public function test_choice_user_submit_response_validation() {
135         global $USER;
137         $this->resetAfterTest();
139         $this->setAdminUser();
140         // Setup test data.
141         $course = $this->getDataGenerator()->create_course();
142         $choice1 = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
143         $choice2 = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
144         $cm = get_coursemodule_from_instance('choice', $choice1->id);
146         $choicewithoptions1 = choice_get_choice($choice1->id);
147         $choicewithoptions2 = choice_get_choice($choice2->id);
148         $optionids1 = array_keys($choicewithoptions1->option);
149         $optionids2 = array_keys($choicewithoptions2->option);
151         // Make sure we cannot submit options from a different choice instance.
152         $this->setExpectedException('moodle_exception');
153         choice_user_submit_response($optionids2[0], $choice1, $USER->id, $course, $cm);
154     }
156     /**
157      * Test choice_get_my_response
158      * @return void
159      */
160     public function test_choice_get_my_response() {
161         global $USER;
163         $this->resetAfterTest();
165         $this->setAdminUser();
166         // Setup test data.
167         $course = $this->getDataGenerator()->create_course();
168         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
169         $context = context_module::instance($choice->cmid);
170         $cm = get_coursemodule_from_instance('choice', $choice->id);
172         $choicewithoptions = choice_get_choice($choice->id);
173         $optionids = array_keys($choicewithoptions->option);
175         choice_user_submit_response($optionids[0], $choice, $USER->id, $course, $cm);
176         $responses = choice_get_my_response($choice, $course, $cm, $context);
177         $this->assertCount(1, $responses);
178         $response = array_shift($responses);
179         $this->assertEquals($optionids[0], $response->optionid);
181         // Multiple responses.
182         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id, 'allowmultiple' => 1));
183         $context = context_module::instance($choice->cmid);
184         $cm = get_coursemodule_from_instance('choice', $choice->id);
186         $choicewithoptions = choice_get_choice($choice->id);
187         $optionids = array_keys($choicewithoptions->option);
189         choice_user_submit_response($optionids, $choice, $USER->id, $course, $cm);
190         $responses = choice_get_my_response($choice, $course, $cm, $context);
191         $this->assertCount(count($optionids), $responses);
192         foreach ($responses as $resp) {
193             $this->assertContains($resp->optionid, $optionids);
194         }
195     }
197     /**
198      * Test choice_get_availability_status
199      * @return void
200      */
201     public function choice_get_availability_status() {
202         $this->resetAfterTest();
204         $this->setAdminUser();
205         // Setup test data.
206         $course = $this->getDataGenerator()->create_course();
207         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
209         // No time restrictions.
210         list($status, $warnings) = choice_get_availability_status($choice, false);
211         $this->assertEquals(true, $status);
212         $this->assertCount(0, $warnings);
214         // With time restrictions, still open.
215         $choice->timeopen = time() - DAYSECS;
216         $choice->timeclose = time() + DAYSECS;
217         list($status, $warnings) = choice_get_availability_status($choice, false);
218         $this->assertEquals(true, $status);
219         $this->assertCount(0, $warnings);
221         // Choice not open yet.
222         $choice->timeopen = time() + DAYSECS;
223         $choice->timeclose = $choice->timeopen + DAYSECS;
224         list($status, $warnings) = choice_get_availability_status($choice, false);
225         $this->assertEquals(false, $status);
226         $this->assertCount(1, $warnings);
227         $this->assertEquals('notopenyet', $warnings[0]);
229         // Choice closed.
230         $choice->timeopen = time() - DAYSECS;
231         $choice->timeclose = time() - 1;
232         list($status, $warnings) = choice_get_availability_status($choice, false);
233         $this->assertEquals(false, $status);
234         $this->assertCount(1, $warnings);
235         $this->assertEquals('expired', $warnings[0]);
237     }