MDL-59244 mod_workshop: New WS mod_workshop_delete_submission
[moodle.git] / mod / workshop / tests / external_test.php
CommitLineData
9f1ab2db
JL
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/>.
16
17/**
18 * Workshop module external functions tests
19 *
20 * @package mod_workshop
21 * @category external
22 * @copyright 2017 Juan Leyva <juan@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @since Moodle 3.4
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30
31require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32require_once($CFG->dirroot . '/mod/workshop/lib.php');
33
34use mod_workshop\external\workshop_summary_exporter;
35
36/**
37 * Workshop module external functions tests
38 *
39 * @package mod_workshop
40 * @category external
41 * @copyright 2017 Juan Leyva <juan@moodle.com>
42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 * @since Moodle 3.4
44 */
45class mod_workshop_external_testcase extends externallib_advanced_testcase {
46
47 /** @var stdClass course object */
48 private $course;
49 /** @var stdClass workshop object */
50 private $workshop;
51 /** @var stdClass context object */
52 private $context;
53 /** @var stdClass cm object */
54 private $cm;
55 /** @var stdClass student object */
56 private $student;
57 /** @var stdClass teacher object */
58 private $teacher;
59 /** @var stdClass student role object */
60 private $studentrole;
61 /** @var stdClass teacher role object */
62 private $teacherrole;
63
64 /**
65 * Set up for every test
66 */
67 public function setUp() {
68 global $DB;
69 $this->resetAfterTest();
70 $this->setAdminUser();
71
72 // Setup test data.
73 $this->course = $this->getDataGenerator()->create_course();
74 $this->workshop = $this->getDataGenerator()->create_module('workshop', array('course' => $this->course->id));
75 $this->context = context_module::instance($this->workshop->cmid);
76 $this->cm = get_coursemodule_from_instance('workshop', $this->workshop->id);
77
78 // Create users.
79 $this->student = self::getDataGenerator()->create_user();
80 $this->teacher = self::getDataGenerator()->create_user();
81
82 // Users enrolments.
83 $this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
84 $this->teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
85 $this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->studentrole->id, 'manual');
86 $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, $this->teacherrole->id, 'manual');
87 }
88
89 /**
90 * Test test_mod_workshop_get_workshops_by_courses
91 */
92 public function test_mod_workshop_get_workshops_by_courses() {
93 global $DB;
94
95 // Create additional course.
96 $course2 = self::getDataGenerator()->create_course();
97
98 // Second workshop.
99 $record = new stdClass();
100 $record->course = $course2->id;
101 $workshop2 = self::getDataGenerator()->create_module('workshop', $record);
102
103 // Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
104 $enrol = enrol_get_plugin('manual');
105 $enrolinstances = enrol_get_instances($course2->id, true);
106 foreach ($enrolinstances as $courseenrolinstance) {
107 if ($courseenrolinstance->enrol == "manual") {
108 $instance2 = $courseenrolinstance;
109 break;
110 }
111 }
112 $enrol->enrol_user($instance2, $this->student->id, $this->studentrole->id);
113
114 self::setUser($this->student);
115
116 $returndescription = mod_workshop_external::get_workshops_by_courses_returns();
117
118 // Create what we expect to be returned when querying the two courses.
119 $properties = workshop_summary_exporter::read_properties_definition();
120 $expectedfields = array_keys($properties);
121
122 // Add expected coursemodule and data.
123 $workshop1 = $this->workshop;
124 $workshop1->coursemodule = $workshop1->cmid;
125 $workshop1->introformat = 1;
126 $workshop1->introfiles = [];
127 $workshop1->instructauthorsfiles = [];
128 $workshop1->instructauthorsformat = 1;
129 $workshop1->instructreviewersfiles = [];
130 $workshop1->instructreviewersformat = 1;
131 $workshop1->conclusionfiles = [];
132 $workshop1->conclusionformat = 1;
133
134 $workshop2->coursemodule = $workshop2->cmid;
135 $workshop2->introformat = 1;
136 $workshop2->introfiles = [];
137 $workshop2->instructauthorsfiles = [];
138 $workshop2->instructauthorsformat = 1;
139 $workshop2->instructreviewersfiles = [];
140 $workshop2->instructreviewersformat = 1;
141 $workshop2->conclusionfiles = [];
142 $workshop2->conclusionformat = 1;
143
144 foreach ($expectedfields as $field) {
145 if (!empty($properties[$field]) && $properties[$field]['type'] == PARAM_BOOL) {
146 $workshop1->{$field} = (bool) $workshop1->{$field};
147 $workshop2->{$field} = (bool) $workshop2->{$field};
148 }
149 $expected1[$field] = $workshop1->{$field};
150 $expected2[$field] = $workshop2->{$field};
151 }
152
153 $expectedworkshops = array($expected2, $expected1);
154
155 // Call the external function passing course ids.
156 $result = mod_workshop_external::get_workshops_by_courses(array($course2->id, $this->course->id));
157 $result = external_api::clean_returnvalue($returndescription, $result);
158
159 $this->assertEquals($expectedworkshops, $result['workshops']);
160 $this->assertCount(0, $result['warnings']);
161
162 // Call the external function without passing course id.
163 $result = mod_workshop_external::get_workshops_by_courses();
164 $result = external_api::clean_returnvalue($returndescription, $result);
165 $this->assertEquals($expectedworkshops, $result['workshops']);
166 $this->assertCount(0, $result['warnings']);
167
168 // Unenrol user from second course and alter expected workshops.
169 $enrol->unenrol_user($instance2, $this->student->id);
170 array_shift($expectedworkshops);
171
172 // Call the external function without passing course id.
173 $result = mod_workshop_external::get_workshops_by_courses();
174 $result = external_api::clean_returnvalue($returndescription, $result);
175 $this->assertEquals($expectedworkshops, $result['workshops']);
176
177 // Call for the second course we unenrolled the user from, expected warning.
178 $result = mod_workshop_external::get_workshops_by_courses(array($course2->id));
179 $this->assertCount(1, $result['warnings']);
180 $this->assertEquals('1', $result['warnings'][0]['warningcode']);
181 $this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
182 }
977fdfa3
JL
183
184 /**
185 * Test mod_workshop_get_workshop_access_information for students.
186 */
187 public function test_mod_workshop_get_workshop_access_information_student() {
188
189 self::setUser($this->student);
190 $result = mod_workshop_external::get_workshop_access_information($this->workshop->id);
191 $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result);
192 // Check default values for capabilities.
193 $enabledcaps = array('canpeerassess', 'cansubmit', 'canview', 'canviewauthornames', 'canviewauthorpublished',
194 'canviewpublishedsubmissions', 'canexportsubmissions');
195
196 foreach ($result as $capname => $capvalue) {
197 if (strpos($capname, 'can') !== 0) {
198 continue;
199 }
200 if (in_array($capname, $enabledcaps)) {
201 $this->assertTrue($capvalue);
202 } else {
203 $this->assertFalse($capvalue);
204 }
205 }
206 // Now, unassign some capabilities.
207 unassign_capability('mod/workshop:peerassess', $this->studentrole->id);
208 unassign_capability('mod/workshop:submit', $this->studentrole->id);
209 unset($enabledcaps[0]);
210 unset($enabledcaps[1]);
211 accesslib_clear_all_caches_for_unit_testing();
212
213 $result = mod_workshop_external::get_workshop_access_information($this->workshop->id);
214 $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result);
215 foreach ($result as $capname => $capvalue) {
216 if (strpos($capname, 'can') !== 0) {
217 continue;
218 }
219 if (in_array($capname, $enabledcaps)) {
220 $this->assertTrue($capvalue);
221 } else {
222 $this->assertFalse($capvalue);
223 }
224 }
225
226 // Now, specific functionalities.
227 $this->assertFalse($result['creatingsubmissionallowed']);
228 $this->assertFalse($result['modifyingsubmissionallowed']);
229 $this->assertFalse($result['assessingallowed']);
230 $this->assertFalse($result['assessingexamplesallowed']);
c2cf2450 231 $this->assertTrue($result['examplesassessed']);
977fdfa3
JL
232
233 // Switch phase.
234 $workshop = new workshop($this->workshop, $this->cm, $this->course);
235 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
236 $result = mod_workshop_external::get_workshop_access_information($this->workshop->id);
237 $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result);
238
239 $this->assertTrue($result['creatingsubmissionallowed']);
240 $this->assertTrue($result['modifyingsubmissionallowed']);
241 $this->assertFalse($result['assessingallowed']);
242 $this->assertFalse($result['assessingexamplesallowed']);
c2cf2450 243 $this->assertTrue($result['examplesassessed']);
977fdfa3
JL
244
245 // Switch to next (to assessment).
246 $workshop = new workshop($this->workshop, $this->cm, $this->course);
247 $workshop->switch_phase(workshop::PHASE_ASSESSMENT);
248 $result = mod_workshop_external::get_workshop_access_information($this->workshop->id);
249 $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result);
250
251 $this->assertFalse($result['creatingsubmissionallowed']);
252 $this->assertFalse($result['modifyingsubmissionallowed']);
253 $this->assertTrue($result['assessingallowed']);
254 $this->assertFalse($result['assessingexamplesallowed']);
c2cf2450 255 $this->assertTrue($result['examplesassessed']);
977fdfa3
JL
256 }
257
258 /**
259 * Test mod_workshop_get_workshop_access_information for teachers.
260 */
261 public function test_mod_workshop_get_workshop_access_information_teacher() {
262
263 self::setUser($this->teacher);
264 $result = mod_workshop_external::get_workshop_access_information($this->workshop->id);
265 $result = external_api::clean_returnvalue(mod_workshop_external::get_workshop_access_information_returns(), $result);
266 // Check default values.
267 $disabledcaps = array('canpeerassess', 'cansubmit');
268
269 foreach ($result as $capname => $capvalue) {
270 if (strpos($capname, 'can') !== 0) {
271 continue;
272 }
273 if (in_array($capname, $disabledcaps)) {
274 $this->assertFalse($capvalue);
275 } else {
276 $this->assertTrue($capvalue);
277 }
278 }
279
280 // Now, specific functionalities.
281 $this->assertFalse($result['creatingsubmissionallowed']);
282 $this->assertFalse($result['modifyingsubmissionallowed']);
283 $this->assertFalse($result['assessingallowed']);
284 $this->assertFalse($result['assessingexamplesallowed']);
285 }
cd495029
JL
286
287 /**
288 * Test mod_workshop_get_user_plan for students.
289 */
290 public function test_mod_workshop_get_user_plan_student() {
291
292 self::setUser($this->student);
293 $result = mod_workshop_external::get_user_plan($this->workshop->id);
294 $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
295
296 $this->assertCount(0, $result['userplan']['examples']); // No examples given.
297 $this->assertCount(5, $result['userplan']['phases']); // Always 5 phases.
298 $this->assertEquals(workshop::PHASE_SETUP, $result['userplan']['phases'][0]['code']); // First phase always setup.
299 $this->assertTrue($result['userplan']['phases'][0]['active']); // First phase "Setup" active in new workshops.
300
301 // Switch phase.
302 $workshop = new workshop($this->workshop, $this->cm, $this->course);
303 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
304
305 $result = mod_workshop_external::get_user_plan($this->workshop->id);
306 $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
307
308 $this->assertEquals(workshop::PHASE_SUBMISSION, $result['userplan']['phases'][1]['code']);
309 $this->assertTrue($result['userplan']['phases'][1]['active']); // We are now in submission phase.
310 }
311
312 /**
313 * Test mod_workshop_get_user_plan for teachers.
314 */
315 public function test_mod_workshop_get_user_plan_teacher() {
316 global $DB;
317
318 self::setUser($this->teacher);
319 $result = mod_workshop_external::get_user_plan($this->workshop->id);
320 $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
321
322 $this->assertCount(0, $result['userplan']['examples']); // No examples given.
323 $this->assertCount(5, $result['userplan']['phases']); // Always 5 phases.
324 $this->assertEquals(workshop::PHASE_SETUP, $result['userplan']['phases'][0]['code']); // First phase always setup.
325 $this->assertTrue($result['userplan']['phases'][0]['active']); // First phase "Setup" active in new workshops.
326 $this->assertCount(4, $result['userplan']['phases'][0]['tasks']); // For new empty workshops, always 4 tasks.
327
328 foreach ($result['userplan']['phases'][0]['tasks'] as $task) {
329 if ($task['code'] == 'intro' || $task['code'] == 'instructauthors') {
330 $this->assertEquals(1, $task['completed']);
331 } else {
332 $this->assertEmpty($task['completed']);
333 }
334 }
335
336 // Do some of the tasks asked - switch phase.
337 $workshop = new workshop($this->workshop, $this->cm, $this->course);
338 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
339
340 $result = mod_workshop_external::get_user_plan($this->workshop->id);
341 $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
342 foreach ($result['userplan']['phases'][0]['tasks'] as $task) {
343 if ($task['code'] == 'intro' || $task['code'] == 'instructauthors' || $task['code'] == 'switchtonextphase') {
344 $this->assertEquals(1, $task['completed']);
345 } else {
346 $this->assertEmpty($task['completed']);
347 }
348 }
349
350 $result = mod_workshop_external::get_user_plan($this->workshop->id);
351 $result = external_api::clean_returnvalue(mod_workshop_external::get_user_plan_returns(), $result);
352
353 $this->assertEquals(workshop::PHASE_SUBMISSION, $result['userplan']['phases'][1]['code']);
354 $this->assertTrue($result['userplan']['phases'][1]['active']); // We are now in submission phase.
355 }
291645f7
JL
356
357 /**
358 * Test test_view_workshop invalid id.
359 */
360 public function test_view_workshop_invalid_id() {
361 $this->expectException('moodle_exception');
362 mod_workshop_external::view_workshop(0);
363 }
364
365 /**
366 * Test test_view_workshop user not enrolled.
367 */
368 public function test_view_workshop_user_not_enrolled() {
369 // Test not-enrolled user.
370 $usernotenrolled = self::getDataGenerator()->create_user();
371 $this->setUser($usernotenrolled);
372 $this->expectException('moodle_exception');
373 mod_workshop_external::view_workshop($this->workshop->id);
374 }
375
376 /**
377 * Test test_view_workshop user student.
378 */
379 public function test_view_workshop_user_student() {
380 // Test user with full capabilities.
381 $this->setUser($this->student);
382
383 // Trigger and capture the event.
384 $sink = $this->redirectEvents();
385
386 $result = mod_workshop_external::view_workshop($this->workshop->id);
387 $result = external_api::clean_returnvalue(mod_workshop_external::view_workshop_returns(), $result);
388 $this->assertTrue($result['status']);
389
390 $events = $sink->get_events();
391 $this->assertCount(1, $events);
392 $event = array_shift($events);
393
394 // Checking that the event contains the expected values.
395 $this->assertInstanceOf('\mod_workshop\event\course_module_viewed', $event);
396 $this->assertEquals($this->context, $event->get_context());
397 $moodleworkshop = new \moodle_url('/mod/workshop/view.php', array('id' => $this->cm->id));
398 $this->assertEquals($moodleworkshop, $event->get_url());
399 $this->assertEventContextNotUsed($event);
400 $this->assertNotEmpty($event->get_name());
401 }
402
403 /**
404 * Test test_view_workshop user missing capabilities.
405 */
406 public function test_view_workshop_user_missing_capabilities() {
407 // Test user with no capabilities.
408 // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
409 assign_capability('mod/workshop:view', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
410 // Empty all the caches that may be affected by this change.
411 accesslib_clear_all_caches_for_unit_testing();
412 course_modinfo::clear_instance_cache();
413
414 $this->setUser($this->student);
415 $this->expectException('moodle_exception');
416 mod_workshop_external::view_workshop($this->workshop->id);
417 }
c2cf2450
JL
418
419 /**
420 * Test test_add_submission.
421 */
422 public function test_add_submission() {
423 $fs = get_file_storage();
424
425 // Test user with full capabilities.
426 $this->setUser($this->student);
427
428 $title = 'Submission title';
429 $content = 'Submission contents';
430
431 // Create a file in a draft area for inline attachments.
432 $draftidinlineattach = file_get_unused_draft_itemid();
433 $usercontext = context_user::instance($this->student->id);
434 $filenameimg = 'shouldbeanimage.txt';
435 $filerecordinline = array(
436 'contextid' => $usercontext->id,
437 'component' => 'user',
438 'filearea' => 'draft',
439 'itemid' => $draftidinlineattach,
440 'filepath' => '/',
441 'filename' => $filenameimg,
442 );
443 $fs->create_file_from_string($filerecordinline, 'image contents (not really)');
444
445 // Create a file in a draft area for regular attachments.
446 $draftidattach = file_get_unused_draft_itemid();
447 $filerecordattach = $filerecordinline;
448 $attachfilename = 'attachment.txt';
449 $filerecordattach['filename'] = $attachfilename;
450 $filerecordattach['itemid'] = $draftidattach;
451 $fs->create_file_from_string($filerecordattach, 'simple text attachment');
452
453 // Switch to submission phase.
454 $workshop = new workshop($this->workshop, $this->cm, $this->course);
455 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
456
457 $result = mod_workshop_external::add_submission($this->workshop->id, $title, $content, FORMAT_MOODLE, $draftidinlineattach,
458 $draftidattach);
459 $result = external_api::clean_returnvalue(mod_workshop_external::add_submission_returns(), $result);
460 $this->assertEmpty($result['warnings']);
461
462 // Check submission created.
463 $submission = $workshop->get_submission_by_author($this->student->id);
464 $this->assertEquals($result['submissionid'], $submission->id);
465 $this->assertEquals($title, $submission->title);
466 $this->assertEquals($content, $submission->content);
467
468 // Check files.
469 $contentfiles = $fs->get_area_files($this->context->id, 'mod_workshop', 'submission_content', $submission->id);
470 $this->assertCount(2, $contentfiles);
471 foreach ($contentfiles as $file) {
472 if ($file->is_directory()) {
473 continue;
474 } else {
475 $this->assertEquals($filenameimg, $file->get_filename());
476 }
477 }
478 $contentfiles = $fs->get_area_files($this->context->id, 'mod_workshop', 'submission_attachment', $submission->id);
479 $this->assertCount(2, $contentfiles);
480 foreach ($contentfiles as $file) {
481 if ($file->is_directory()) {
482 continue;
483 } else {
484 $this->assertEquals($attachfilename, $file->get_filename());
485 }
486 }
487 }
488
489 /**
490 * Test test_add_submission invalid phase.
491 */
492 public function test_add_submission_invalid_phase() {
493 $this->setUser($this->student);
494
495 $this->expectException('moodle_exception');
496 mod_workshop_external::add_submission($this->workshop->id, 'Test');
497 }
498
499 /**
500 * Test test_add_submission empty title.
501 */
502 public function test_add_submission_empty_title() {
503 $this->setUser($this->student);
504
505 // Switch to submission phase.
506 $workshop = new workshop($this->workshop, $this->cm, $this->course);
507 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
508
509 $this->expectException('moodle_exception');
510 mod_workshop_external::add_submission($this->workshop->id, '');
511 }
512
513 /**
514 * Test test_add_submission already added.
515 */
516 public function test_add_submission_already_added() {
517 $this->setUser($this->student);
518
519 // Switch to submission phase.
520 $workshop = new workshop($this->workshop, $this->cm, $this->course);
521 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
522
523 // Create the submission.
524 $result = mod_workshop_external::add_submission($this->workshop->id, 'My submission');
525 $result = external_api::clean_returnvalue(mod_workshop_external::add_submission_returns(), $result);
526
527 // Try to create it again.
528 $result = mod_workshop_external::add_submission($this->workshop->id, 'My submission');
529 $result = external_api::clean_returnvalue(mod_workshop_external::add_submission_returns(), $result);
530 $this->assertEquals(0, $result['submissionid']);
531 $this->assertCount(2, $result['warnings']);
532 $this->assertEquals('fielderror', $result['warnings'][0]['warningcode']);
533 $this->assertEquals('content_editor', $result['warnings'][0]['item']);
534 $this->assertEquals('fielderror', $result['warnings'][1]['warningcode']);
535 $this->assertEquals('attachment_filemanager', $result['warnings'][1]['item']);
536 }
c1698a37
JL
537
538 /**
539 * Helper method to create a submission for testing for the given user.
540 *
541 * @param int $user the submission will be created by this student.
542 * @return int the submission id
543 */
544 protected function create_test_submission($user) {
545 // Test user with full capabilities.
546 $this->setUser($user);
547
548 $title = 'Submission title';
549 $content = 'Submission contents';
550
551 // Create a file in a draft area for inline attachments.
552 $fs = get_file_storage();
553 $draftidinlineattach = file_get_unused_draft_itemid();
554 $usercontext = context_user::instance($this->student->id);
555 $filenameimg = 'shouldbeanimage.txt';
556 $filerecordinline = array(
557 'contextid' => $usercontext->id,
558 'component' => 'user',
559 'filearea' => 'draft',
560 'itemid' => $draftidinlineattach,
561 'filepath' => '/',
562 'filename' => $filenameimg,
563 );
564 $fs->create_file_from_string($filerecordinline, 'image contents (not really)');
565
566 // Create a file in a draft area for regular attachments.
567 $draftidattach = file_get_unused_draft_itemid();
568 $filerecordattach = $filerecordinline;
569 $attachfilename = 'attachment.txt';
570 $filerecordattach['filename'] = $attachfilename;
571 $filerecordattach['itemid'] = $draftidattach;
572 $fs->create_file_from_string($filerecordattach, 'simple text attachment');
573
574 // Switch to submission phase.
575 $workshop = new workshop($this->workshop, $this->cm, $this->course);
576 $workshop->switch_phase(workshop::PHASE_SUBMISSION);
577
578 $result = mod_workshop_external::add_submission($this->workshop->id, $title, $content, FORMAT_MOODLE, $draftidinlineattach,
579 $draftidattach);
580 return $result['submissionid'];
581 }
582
583 /**
584 * Test test_update_submission.
585 */
586 public function test_update_submission() {
587
588 // Create the submission that will be updated.
589 $submissionid = $this->create_test_submission($this->student);
590
591 // Test user with full capabilities.
592 $this->setUser($this->student);
593
594 $title = 'Submission new title';
595 $content = 'Submission new contents';
596
597 // Create a different file in a draft area for inline attachments.
598 $fs = get_file_storage();
599 $draftidinlineattach = file_get_unused_draft_itemid();
600 $usercontext = context_user::instance($this->student->id);
601 $filenameimg = 'shouldbeanimage_new.txt';
602 $filerecordinline = array(
603 'contextid' => $usercontext->id,
604 'component' => 'user',
605 'filearea' => 'draft',
606 'itemid' => $draftidinlineattach,
607 'filepath' => '/',
608 'filename' => $filenameimg,
609 );
610 $fs->create_file_from_string($filerecordinline, 'image contents (not really)');
611
612 // Create a different file in a draft area for regular attachments.
613 $draftidattach = file_get_unused_draft_itemid();
614 $filerecordattach = $filerecordinline;
615 $attachfilename = 'attachment_new.txt';
616 $filerecordattach['filename'] = $attachfilename;
617 $filerecordattach['itemid'] = $draftidattach;
618 $fs->create_file_from_string($filerecordattach, 'simple text attachment');
619
620 $result = mod_workshop_external::update_submission($submissionid, $title, $content, FORMAT_MOODLE, $draftidinlineattach,
621 $draftidattach);
622 $result = external_api::clean_returnvalue(mod_workshop_external::update_submission_returns(), $result);
623 $this->assertEmpty($result['warnings']);
624
625 // Check submission updated.
626 $workshop = new workshop($this->workshop, $this->cm, $this->course);
627 $submission = $workshop->get_submission_by_id($submissionid);
628 $this->assertTrue($result['status']);
629 $this->assertEquals($title, $submission->title);
630 $this->assertEquals($content, $submission->content);
631
632 // Check files.
633 $contentfiles = $fs->get_area_files($this->context->id, 'mod_workshop', 'submission_content', $submission->id);
634 $this->assertCount(2, $contentfiles);
635 foreach ($contentfiles as $file) {
636 if ($file->is_directory()) {
637 continue;
638 } else {
639 $this->assertEquals($filenameimg, $file->get_filename());
640 }
641 }
642 $contentfiles = $fs->get_area_files($this->context->id, 'mod_workshop', 'submission_attachment', $submission->id);
643 $this->assertCount(2, $contentfiles);
644 foreach ($contentfiles as $file) {
645 if ($file->is_directory()) {
646 continue;
647 } else {
648 $this->assertEquals($attachfilename, $file->get_filename());
649 }
650 }
651 }
652
653 /**
654 * Test test_update_submission belonging to other user.
655 */
656 public function test_update_submission_of_other_user() {
657 // Create the submission that will be updated.
658 $submissionid = $this->create_test_submission($this->student);
659
660 $this->setUser($this->teacher);
661
662 $this->expectException('moodle_exception');
663 mod_workshop_external::update_submission($submissionid, 'Test');
664 }
665
666 /**
667 * Test test_update_submission invalid phase.
668 */
669 public function test_update_submission_invalid_phase() {
670 // Create the submission that will be updated.
671 $submissionid = $this->create_test_submission($this->student);
672
673 $this->setUser($this->student);
674
675 // Switch to assessment phase.
676 $workshop = new workshop($this->workshop, $this->cm, $this->course);
677 $workshop->switch_phase(workshop::PHASE_ASSESSMENT);
678
679 $this->expectException('moodle_exception');
680 mod_workshop_external::update_submission($submissionid, 'Test');
681 }
682
683 /**
684 * Test test_update_submission empty title.
685 */
686 public function test_update_submission_empty_title() {
687 // Create the submission that will be updated.
688 $submissionid = $this->create_test_submission($this->student);
689
690 $this->setUser($this->student);
691
692 $this->expectException('moodle_exception');
693 mod_workshop_external::update_submission($submissionid, '');
694 }
bde5631d
JL
695
696 /**
697 * Test test_delete_submission.
698 */
699 public function test_delete_submission() {
700
701 // Create the submission that will be deleted.
702 $submissionid = $this->create_test_submission($this->student);
703
704 $this->setUser($this->student);
705
706 // Trigger and capture the event.
707 $sink = $this->redirectEvents();
708
709 $result = mod_workshop_external::delete_submission($submissionid);
710 $result = external_api::clean_returnvalue(mod_workshop_external::delete_submission_returns(), $result);
711 $this->assertEmpty($result['warnings']);
712 $this->assertTrue($result['status']);
713 $workshop = new workshop($this->workshop, $this->cm, $this->course);
714 $submission = $workshop->get_submission_by_author($this->student->id);
715 $this->assertFalse($submission);
716
717 $events = $sink->get_events();
718 $this->assertCount(1, $events);
719 $event = array_shift($events);
720
721 // Checking event.
722 $this->assertInstanceOf('\mod_workshop\event\submission_deleted', $event);
723 $this->assertEquals($this->context, $event->get_context());
724 }
725
726 /**
727 * Test test_delete_submission_with_assessments.
728 */
729 public function test_delete_submission_with_assessments() {
730
731 // Create the submission that will be deleted.
732 $submissionid = $this->create_test_submission($this->student);
733
734 $workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
735 $workshopgenerator->create_assessment($submissionid, $this->teacher->id, array(
736 'weight' => 3,
737 'grade' => 95.00000,
738 ));
739
740 $this->setUser($this->student);
741 $this->expectException('moodle_exception');
742 mod_workshop_external::delete_submission($submissionid);
743 }
744
745 /**
746 * Test test_delete_submission_invalid_phase.
747 */
748 public function test_delete_submission_invalid_phase() {
749
750 // Create the submission that will be deleted.
751 $submissionid = $this->create_test_submission($this->student);
752
753 // Switch to assessment phase.
754 $workshop = new workshop($this->workshop, $this->cm, $this->course);
755 $workshop->switch_phase(workshop::PHASE_ASSESSMENT);
756
757 $this->setUser($this->student);
758 $this->expectException('moodle_exception');
759 mod_workshop_external::delete_submission($submissionid);
760 }
761
762 /**
763 * Test test_delete_submission_as_teacher.
764 */
765 public function test_delete_submission_as_teacher() {
766
767 // Create the submission that will be deleted.
768 $submissionid = $this->create_test_submission($this->student);
769
770 $this->setUser($this->teacher);
771 $result = mod_workshop_external::delete_submission($submissionid);
772 $result = external_api::clean_returnvalue(mod_workshop_external::delete_submission_returns(), $result);
773 $this->assertEmpty($result['warnings']);
774 $this->assertTrue($result['status']);
775 }
776
777 /**
778 * Test test_delete_submission_other_user.
779 */
780 public function test_delete_submission_other_user() {
781
782 $anotheruser = self::getDataGenerator()->create_user();
783 $this->getDataGenerator()->enrol_user($anotheruser->id, $this->course->id, $this->studentrole->id, 'manual');
784 // Create the submission that will be deleted.
785 $submissionid = $this->create_test_submission($this->student);
786
787 $this->setUser($anotheruser);
788 $this->expectException('moodle_exception');
789 mod_workshop_external::delete_submission($submissionid);
790 }
9f1ab2db 791}