MDL-49504 notes: Unit tests for core_notes_view_notes
[moodle.git] / notes / 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 notes functions unit tests
19  *
20  * @package    core_notes
21  * @category   external
22  * @copyright  2012 Jerome Mouneyrac
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 . '/notes/externallib.php');
33 class core_notes_externallib_testcase extends externallib_advanced_testcase {
35     /**
36      * Test create_notes
37      */
38     public function test_create_notes() {
40         global $DB, $USER;
42         $this->resetAfterTest(true);
44         $course = self::getDataGenerator()->create_course();
46         // Set the required capabilities by the external function.
47         $contextid = context_course::instance($course->id)->id;
48         $roleid = $this->assignUserCapability('moodle/notes:manage', $contextid);
49         $this->assignUserCapability('moodle/course:view', $contextid, $roleid);
51         // Create test note data.
52         $note1 = array();
53         $note1['userid'] = $USER->id;
54         $note1['publishstate'] = 'personal';
55         $note1['courseid'] = $course->id;
56         $note1['text'] = 'the text';
57         $note1['clientnoteid'] = 4;
58         $notes = array($note1);
60         $creatednotes = core_notes_external::create_notes($notes);
61         // We need to execute the return values cleaning process to simulate the web service server.
62         $creatednotes = external_api::clean_returnvalue(core_notes_external::create_notes_returns(), $creatednotes);
64         $thenote = $DB->get_record('post', array('id' => $creatednotes[0]['noteid']));
66         // Confirm that base note data was inserted correctly.
67         $this->assertEquals($thenote->userid, $note1['userid']);
68         $this->assertEquals($thenote->courseid, $note1['courseid']);
69         $this->assertEquals($thenote->publishstate, NOTES_STATE_DRAFT);
70         $this->assertEquals($thenote->content, $note1['text']);
71         $this->assertEquals($creatednotes[0]['clientnoteid'], $note1['clientnoteid']);
73         // Call without required capability.
74         $this->unassignUserCapability('moodle/notes:manage', $contextid, $roleid);
75         $this->setExpectedException('required_capability_exception');
76         $creatednotes = core_notes_external::create_notes($notes);
77     }
79     public function test_delete_notes() {
81         global $DB, $USER;
83         $this->resetAfterTest(true);
85         $course = self::getDataGenerator()->create_course();
87         // Set the required capabilities by the external function.
88         $contextid = context_course::instance($course->id)->id;
89         $roleid = $this->assignUserCapability('moodle/notes:manage', $contextid);
90         $this->assignUserCapability('moodle/course:view', $contextid, $roleid);
92         // Create test note data.
93         $cnote = array();
94         $cnote['userid'] = $USER->id;
95         $cnote['publishstate'] = 'personal';
96         $cnote['courseid'] = $course->id;
97         $cnote['text'] = 'the text';
98         $cnote['clientnoteid'] = 4;
99         $cnotes = array($cnote);
100         $creatednotes = core_notes_external::create_notes($cnotes);
101         $creatednotes = external_api::clean_returnvalue(core_notes_external::create_notes_returns(), $creatednotes);
103         $dnotes1 = array($creatednotes[0]['noteid']);
104         $deletednotes1 = core_notes_external::delete_notes($dnotes1);
105         $deletednotes1 = external_api::clean_returnvalue(core_notes_external::delete_notes_returns(), $deletednotes1);
107         // Confirm that base note data was deleted correctly.
108         $notdeletedcount = $DB->count_records_select('post', 'id = ' . $creatednotes[0]['noteid']);
109         $this->assertEquals(0, $notdeletedcount);
111         $dnotes2 = array(33); // This note does not exist.
112         $deletednotes2 = core_notes_external::delete_notes($dnotes2);
113         $deletednotes2 = external_api::clean_returnvalue(core_notes_external::delete_notes_returns(), $deletednotes2);
115         $this->assertEquals("note", $deletednotes2[0]["item"]);
116         $this->assertEquals(33, $deletednotes2[0]["itemid"]);
117         $this->assertEquals("badid", $deletednotes2[0]["warningcode"]);
118         $this->assertEquals("Note does not exist", $deletednotes2[0]["message"]);
120         // Call without required capability.
121         $creatednotes = core_notes_external::create_notes($cnotes);
122         $dnotes3 = array($creatednotes[0]['noteid']);
124         $this->unassignUserCapability('moodle/notes:manage', $contextid, $roleid);
125         $this->setExpectedException('required_capability_exception');
126         $deletednotes = core_notes_external::delete_notes($dnotes3);
127     }
129     public function test_get_notes() {
131         global $DB, $USER;
133         $this->resetAfterTest(true);
135         $course = self::getDataGenerator()->create_course();
137         // Set the required capabilities by the external function.
138         $contextid = context_course::instance($course->id)->id;
139         $roleid = $this->assignUserCapability('moodle/notes:manage', $contextid);
140         $this->assignUserCapability('moodle/notes:view', $contextid, $roleid);
141         $this->assignUserCapability('moodle/course:view', $contextid, $roleid);
143         // Create test note data.
144         $cnote = array();
145         $cnote['userid'] = $USER->id;
146         $cnote['publishstate'] = 'personal';
147         $cnote['courseid'] = $course->id;
148         $cnote['text'] = 'the text';
149         $cnotes = array($cnote);
151         $creatednotes1 = core_notes_external::create_notes($cnotes);
152         $creatednotes2 = core_notes_external::create_notes($cnotes);
153         $creatednotes3 = core_notes_external::create_notes($cnotes);
155         $creatednotes1 = external_api::clean_returnvalue(core_notes_external::create_notes_returns(), $creatednotes1);
156         $creatednotes2 = external_api::clean_returnvalue(core_notes_external::create_notes_returns(), $creatednotes2);
157         $creatednotes3 = external_api::clean_returnvalue(core_notes_external::create_notes_returns(), $creatednotes3);
159         // Note 33 does not exist.
160         $gnotes = array($creatednotes1[0]['noteid'], $creatednotes2[0]['noteid'], $creatednotes3[0]['noteid'], 33);
161         $getnotes = core_notes_external::get_notes($gnotes);
162         $getnotes = external_api::clean_returnvalue(core_notes_external::get_notes_returns(), $getnotes);
164         $this->unassignUserCapability('moodle/notes:manage', $contextid, $roleid);
165         // Confirm that base note data was retrieved correctly.
166         $this->assertEquals($cnote['userid'], $getnotes["notes"][0]["userid"]);
167         $this->assertEquals($cnote['text'], $getnotes["notes"][0]["text"]);
168         $this->assertEquals($cnote['userid'], $getnotes["notes"][1]["userid"]);
169         $this->assertEquals($cnote['text'], $getnotes["notes"][1]["text"]);
170         $this->assertEquals($cnote['userid'], $getnotes["notes"][2]["userid"]);
171         $this->assertEquals($cnote['text'], $getnotes["notes"][2]["text"]);
172         $this->assertEquals("note", $getnotes["warnings"][0]["item"]);
173         $this->assertEquals(33, $getnotes["warnings"][0]["itemid"]);
174         $this->assertEquals("badid", $getnotes["warnings"][0]["warningcode"]);
175         $this->assertEquals("Note does not exist", $getnotes["warnings"][0]["message"]);
177         // Call without required capability.
178         $this->unassignUserCapability('moodle/notes:view', $contextid, $roleid);
179         $this->setExpectedException('required_capability_exception');
180         $creatednotes = core_notes_external::get_notes($gnotes);
181     }
183     public function test_update_notes() {
185         global $DB, $USER;
187         $this->resetAfterTest(true);
189         $course = self::getDataGenerator()->create_course();
191         // Set the required capabilities by the external function.
192         $contextid = context_course::instance($course->id)->id;
193         $roleid = $this->assignUserCapability('moodle/notes:manage', $contextid);
194         $this->assignUserCapability('moodle/course:view', $contextid, $roleid);
196         // Create test note data.
197         $note1 = array();
198         $note1['userid'] = $USER->id;
199         $note1['publishstate'] = 'personal';
200         $note1['courseid'] = $course->id;
201         $note1['text'] = 'the text';
202         $note2['userid'] = $USER->id;
203         $note2['publishstate'] = 'course';
204         $note2['courseid'] = $course->id;
205         $note2['text'] = 'the text';
206         $note3['userid'] = $USER->id;
207         $note3['publishstate'] = 'site';
208         $note3['courseid'] = $course->id;
209         $note3['text'] = 'the text';
210         $notes1 = array($note1, $note2, $note3);
212         $creatednotes = core_notes_external::create_notes($notes1);
213         $creatednotes = external_api::clean_returnvalue(core_notes_external::create_notes_returns(), $creatednotes);
215         $note2 = array();
216         $note2["id"] = $creatednotes[0]['noteid'];
217         $note2['publishstate'] = 'personal';
218         $note2['text'] = 'the new text';
219         $note2['format'] = FORMAT_HTML;
220         $notes2 = array($note2);
222         $updatednotes = core_notes_external::update_notes($notes2);
224         $updatednotes = external_api::clean_returnvalue(core_notes_external::update_notes_returns(), $updatednotes);
225         $thenote = $DB->get_record('post', array('id' => $creatednotes[0]['noteid']));
227         // Confirm that base note data was updated correctly.
228         $this->assertEquals($thenote->publishstate, NOTES_STATE_DRAFT);
229         $this->assertEquals($note2['text'], $thenote->content);
231         // Call without required capability.
232         $creatednotes = core_notes_external::create_notes($notes1);
233         $this->unassignUserCapability('moodle/notes:manage', $contextid, $roleid);
234         $this->setExpectedException('required_capability_exception');
235         $note2 = array();
236         $note2["id"] = $creatednotes[0]['noteid'];
237         $note2['publishstate'] = 'personal';
238         $note2['text'] = 'the new text';
239         $note2['format'] = FORMAT_HTML;
240         $notes2 = array($note2);
241         $updatednotes = core_notes_external::update_notes($notes2);
242     }
244     /**
245      * Test get_course_notes
246      */
247     public function test_get_course_notes() {
248         global $DB, $CFG;
250         $this->resetAfterTest(true);
251         $CFG->enablenotes = true;
253         // Take role definitions.
254         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
255         $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
257         // Create students and teachers.
258         $student1 = $this->getDataGenerator()->create_user();
259         $student2 = $this->getDataGenerator()->create_user();
260         $teacher1 = $this->getDataGenerator()->create_user();
261         $teacher2 = $this->getDataGenerator()->create_user();
262         $course1 = $this->getDataGenerator()->create_course();
263         $course2 = $this->getDataGenerator()->create_course();
265         // Enroll students and teachers to COURSE-1.
266         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, $studentrole->id);
267         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, $studentrole->id);
268         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, $teacherrole->id);
269         $this->getDataGenerator()->enrol_user($teacher2->id, $course1->id, $teacherrole->id);
270         // Enroll students and teachers to COURSE-2 (teacher1 is not enrolled in Course 2).
271         $this->getDataGenerator()->enrol_user($student1->id, $course2->id, $studentrole->id);
272         $this->getDataGenerator()->enrol_user($student2->id, $course2->id, $studentrole->id);
274         $this->getDataGenerator()->enrol_user($teacher2->id, $course2->id, $teacherrole->id);
276         // Generate notes.
277         $gen = $this->getDataGenerator()->get_plugin_generator('core_notes');
279         $this->setUser($teacher1);
281         // NoteA1: on student1 (Course1) by Teacher1.
282         $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_PUBLIC,
283             'usermodified' => $teacher1->id);
284         $notea1 = $gen->create_instance($params);
285         // NoteA2: on student1 (Course1) by Teacher1.
286         $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_PUBLIC,
287             'usermodified' => $teacher1->id);
288         $notea2 = $gen->create_instance($params);
289         // NoteS1: on student1 SITE-LEVEL by teacher1.
290         $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_SITE,
291             'usermodified' => $teacher1->id);
292         $notes1 = $gen->create_instance($params);
293         // NoteP1: on student1 PERSONAL by teacher1.
294         $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_DRAFT,
295             'usermodified' => $teacher1->id);
296         $notep1 = $gen->create_instance($params);
297         // NoteB1: on student1 (Course2) by teacher1.
298         $params = array('courseid' => $course2->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_PUBLIC,
299             'usermodified' => $teacher1->id);
300         $noteb1 = $gen->create_instance($params);
302         // Retrieve notes, normal case.
303         $result = core_notes_external::get_course_notes($course1->id, $student1->id);
304         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
305         $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']);
306         $this->assertCount(2, $result['coursenotes']);
308         foreach ($result['coursenotes'] as $coursenote) {
309             if ($coursenote['id'] != $notea1->id and $coursenote['id'] != $notea2->id) {
310                 $this->fail('the returned notes ids does not match with the created ones');
311             }
312         }
314         $this->assertEquals($notep1->id, $result['personalnotes'][0]['id']);
316         // Try to get notes from a course the user is not enrolled.
317         try {
318             $result = core_notes_external::get_course_notes($course2->id, $student1->id);
319             $this->fail('the user is not enrolled in the course');
320         } catch (require_login_exception $e) {
321             $this->assertEquals('requireloginerror', $e->errorcode);
322         }
324         $result = core_notes_external::get_course_notes(0, $student1->id);
325         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
326         $this->assertEmpty($result['sitenotes']);
328         foreach ($result['coursenotes'] as $coursenote) {
329             if ($coursenote['id'] != $notea1->id and $coursenote['id'] != $notea2->id) {
330                 $this->fail('the returned notes ids does not match with the created ones');
331             }
332         }
334         $this->assertCount(2, $result['coursenotes']);
336         $this->setAdminUser();
337         $result = core_notes_external::get_course_notes(0, $student1->id);
338         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
339         $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']);
340         $this->assertCount(1, $result['sitenotes']);
342         $this->setUser($teacher1);
343         $result = core_notes_external::get_course_notes(0, 0);
344         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
345         $this->assertEmpty($result['sitenotes']);
346         $this->assertEmpty($result['coursenotes']);
347         $this->assertEmpty($result['personalnotes']);
349         $this->setUser($teacher2);
350         $result = core_notes_external::get_course_notes($course1->id, $student1->id);
351         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
352         $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']);
354         foreach ($result['coursenotes'] as $coursenote) {
355             if ($coursenote['id'] != $notea1->id and $coursenote['id'] != $notea2->id) {
356                 $this->fail('the returned notes ids does not match with the created ones');
357             }
358         }
360         $this->assertCount(1, $result['sitenotes']);
361         $this->assertCount(2, $result['coursenotes']);
363         $result = core_notes_external::get_course_notes($course1->id, 0);
364         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
365         $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']);
367         foreach ($result['coursenotes'] as $coursenote) {
368             if ($coursenote['id'] != $notea1->id and $coursenote['id'] != $notea2->id) {
369                 $this->fail('the returned notes ids does not match with the created ones');
370             }
371         }
373         $this->assertCount(1, $result['sitenotes']);
374         $this->assertCount(2, $result['coursenotes']);
376         $this->setUser($teacher1);
377         $result = core_notes_external::get_course_notes($course1->id, 0);
378         $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result);
379         $this->assertEquals($notep1->id, $result['personalnotes'][0]['id']);
380         $this->assertCount(1, $result['personalnotes']);
382     }
384     /**
385      * Test view_notes
386      */
387     public function test_view_notes() {
388         global $DB, $CFG;
390         $this->resetAfterTest(true);
391         $CFG->enablenotes = true;
393         // Take role definitions.
394         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
395         $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
397         // Create students and teachers.
398         $student = $this->getDataGenerator()->create_user();
399         $teacher = $this->getDataGenerator()->create_user();
400         $course = $this->getDataGenerator()->create_course();
401         $coursecontext = context_course::instance($course->id);
403         // Enroll students and teachers to course.
404         $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id);
405         $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id);
407         // Generate notes.
408         $gen = $this->getDataGenerator()->get_plugin_generator('core_notes');
409         $this->setUser($teacher);
411         // NoteA1: on student (Course) by Teacher.
412         $params = array('courseid' => $course->id, 'userid' => $student->id, 'publishstate' => NOTES_STATE_PUBLIC,
413             'usermodified' => $teacher->id);
414         $notea1 = $gen->create_instance($params);
416         $sink = $this->redirectEvents();
418         $result = core_notes_external::view_notes($course->id, $student->id);
419         $result = external_api::clean_returnvalue(core_notes_external::view_notes_returns(), $result);
421         $result = core_notes_external::view_notes($course->id);
422         $result = external_api::clean_returnvalue(core_notes_external::view_notes_returns(), $result);
424         $events = $sink->get_events();
426         $this->assertCount(2, $events);
428         $this->assertInstanceOf('\core\event\notes_viewed', $events[0]);
429         $this->assertEquals($coursecontext, $events[0]->get_context());
430         $this->assertEquals($student->id, $events[0]->relateduserid);
432         $this->assertInstanceOf('\core\event\notes_viewed', $events[1]);
433         $this->assertEquals($coursecontext, $events[1]->get_context());
434         $this->assertEquals(0, $events[1]->relateduserid);
436         try {
437             core_notes_external::view_notes(0);
438             $this->fail('Exception expected due to invalid permissions at system level.');
439         } catch (moodle_exception $e) {
440             $this->assertEquals('nopermissions', $e->errorcode);
441         }
443         try {
444             core_notes_external::view_notes($course->id, $student->id + 100);
445             $this->fail('Exception expected due to invalid user id.');
446         } catch (moodle_exception $e) {
447             $this->assertEquals('invaliduser', $e->errorcode);
448         }
449     }