Merge branch 'MDL-66226-master-2' of https://github.com/snake/moodle
[moodle.git] / blog / tests / events_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  * Events tests.
19  *
20  * @package    core
21  * @category   test
22  * @copyright  2016 Stephen Bourget
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot . '/blog/locallib.php');
30 require_once($CFG->dirroot . '/blog/lib.php');
32 /**
33  * Unit tests for the blog events.
34  *
35  * @copyright  2016 Stephen Bourget
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class core_blog_events_testcase extends advanced_testcase {
40     /** @var $courseid */
41     private $courseid;
43     /** @var $cmid */
44     private $cmid;
46     /** @var $groupid */
47     private $groupid;
49     /** @var $userid */
50     private $userid;
52     /** @var $tagid */
53     private $tagid;
55     /** @var $postid */
56     private $postid;
58     /**
59      * Setup the tests.
60      */
61     protected function setUp() {
62         global $DB;
63         parent::setUp();
65         $this->resetAfterTest();
67         // Create default course.
68         $course = $this->getDataGenerator()->create_course(array('category' => 1, 'shortname' => 'ANON'));
69         $this->assertNotEmpty($course);
70         $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
71         $this->assertNotEmpty($page);
73         // Create default group.
74         $group = new stdClass();
75         $group->courseid = $course->id;
76         $group->name = 'ANON';
77         $group->id = $DB->insert_record('groups', $group);
79         // Create default user.
80         $user = $this->getDataGenerator()->create_user(array(
81                 'username' => 'testuser',
82                 'firstname' => 'Jimmy',
83                 'lastname' => 'Kinnon'
84         ));
86         // Create default tag.
87         $tag = $this->getDataGenerator()->create_tag(array('userid' => $user->id,
88             'rawname' => 'Testtagname', 'isstandard' => 1));
90         // Create default post.
91         $post = new stdClass();
92         $post->userid = $user->id;
93         $post->groupid = $group->id;
94         $post->content = 'test post content text';
95         $post->module = 'blog';
96         $post->id = $DB->insert_record('post', $post);
98         // Grab important ids.
99         $this->courseid = $course->id;
100         $this->cmid = $page->cmid;
101         $this->groupid  = $group->id;
102         $this->userid  = $user->id;
103         $this->tagid  = $tag->id;
104         $this->postid = $post->id;
105     }
107     /**
108      * Test various blog related events.
109      */
110     public function test_blog_entry_created_event() {
111         global $USER;
113         $this->setAdminUser();
114         $this->resetAfterTest();
116         // Create a blog entry for another user as Admin.
117         $sink = $this->redirectEvents();
118         $blog = new blog_entry();
119         $blog->subject = "Subject of blog";
120         $blog->userid = $this->userid;
121         $states = blog_entry::get_applicable_publish_states();
122         $blog->publishstate = reset($states);
123         $blog->add();
124         $events = $sink->get_events();
125         $sink->close();
126         $event = reset($events);
127         $sitecontext = context_system::instance();
129         // Validate event data.
130         $this->assertInstanceOf('\core\event\blog_entry_created', $event);
131         $url = new moodle_url('/blog/index.php', array('entryid' => $event->objectid));
132         $this->assertEquals($url, $event->get_url());
133         $this->assertEquals($sitecontext->id, $event->contextid);
134         $this->assertEquals($blog->id, $event->objectid);
135         $this->assertEquals($USER->id, $event->userid);
136         $this->assertEquals($this->userid, $event->relateduserid);
137         $this->assertEquals("post", $event->objecttable);
138         $arr = array(SITEID, 'blog', 'add', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id, $blog->subject);
139         $this->assertEventLegacyLogData($arr, $event);
140         $this->assertEquals("blog_entry_added", $event->get_legacy_eventname());
141         $this->assertEventLegacyData($blog, $event);
142         $this->assertEventContextNotUsed($event);
143     }
145     /**
146      * Tests for event blog_entry_updated.
147      */
148     public function test_blog_entry_updated_event() {
149         global $USER;
151         $this->setAdminUser();
152         $this->resetAfterTest();
153         $sitecontext = context_system::instance();
155         // Edit a blog entry as Admin.
156         $blog = new blog_entry($this->postid);
157         $sink = $this->redirectEvents();
158         $blog->summary_editor = array('text' => 'Something', 'format' => FORMAT_MOODLE);
159         $blog->edit(array(), null, array(), array());
160         $events = $sink->get_events();
161         $event = array_pop($events);
162         $sink->close();
164         // Validate event data.
165         $this->assertInstanceOf('\core\event\blog_entry_updated', $event);
166         $url = new moodle_url('/blog/index.php', array('entryid' => $event->objectid));
167         $this->assertEquals($url, $event->get_url());
168         $this->assertEquals($sitecontext->id, $event->contextid);
169         $this->assertEquals($blog->id, $event->objectid);
170         $this->assertEquals($USER->id, $event->userid);
171         $this->assertEquals($this->userid, $event->relateduserid);
172         $this->assertEquals("post", $event->objecttable);
173         $this->assertEquals("blog_entry_edited", $event->get_legacy_eventname());
174         $this->assertEventLegacyData($blog, $event);
175         $arr = array (SITEID, 'blog', 'update', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id, $blog->subject);
176         $this->assertEventLegacyLogData($arr, $event);
177         $this->assertEventContextNotUsed($event);
178     }
180     /**
181      * Tests for event blog_entry_deleted.
182      */
183     public function test_blog_entry_deleted_event() {
184         global $USER, $DB;
186         $this->setAdminUser();
187         $this->resetAfterTest();
188         $sitecontext = context_system::instance();
190         // Delete a user blog entry as Admin.
191         $blog = new blog_entry($this->postid);
192         $sink = $this->redirectEvents();
193         $record = $DB->get_record('post', array('id' => $blog->id));
194         $blog->delete();
195         $events = $sink->get_events();
196         $event = array_pop($events);
197         $sink->close();
199         // Validate event data.
200         $this->assertInstanceOf('\core\event\blog_entry_deleted', $event);
201         $this->assertEquals(null, $event->get_url());
202         $this->assertEquals($sitecontext->id, $event->contextid);
203         $this->assertEquals($blog->id, $event->objectid);
204         $this->assertEquals($USER->id, $event->userid);
205         $this->assertEquals($this->userid, $event->relateduserid);
206         $this->assertEquals("post", $event->objecttable);
207         $this->assertEquals($record, $event->get_record_snapshot("post", $blog->id));
208         $this->assertSame('blog_entry_deleted', $event->get_legacy_eventname());
209         $arr = array(SITEID, 'blog', 'delete', 'index.php?userid=' . $blog->userid, 'deleted blog entry with entry id# ' .
210                 $blog->id);
211         $this->assertEventLegacyLogData($arr, $event);
212         $this->assertEventLegacyData($blog, $event);
213         $this->assertEventContextNotUsed($event);
214     }
216     /**
217      * Tests for event blog_association_deleted.
218      */
219     public function test_blog_association_deleted_event() {
220         global $USER;
222         $this->setAdminUser();
223         $this->resetAfterTest();
224         $sitecontext = context_system::instance();
225         $coursecontext = context_course::instance($this->courseid);
226         $contextmodule = context_module::instance($this->cmid);
228         // Add blog associations with a course.
229         $blog = new blog_entry($this->postid);
230         $blog->add_association($coursecontext->id);
232         $sink = $this->redirectEvents();
233         $blog->remove_associations();
234         $events = $sink->get_events();
235         $event = reset($events);
236         $sink->close();
238         // Validate event data.
239         $this->assertInstanceOf('\core\event\blog_association_deleted', $event);
240         $this->assertEquals($sitecontext->id, $event->contextid);
241         $this->assertEquals($blog->id, $event->other['blogid']);
242         $this->assertEquals($USER->id, $event->userid);
243         $this->assertEquals($this->userid, $event->relateduserid);
244         $this->assertEquals('blog_association', $event->objecttable);
246         // Add blog associations with a module.
247         $blog = new blog_entry($this->postid);
248         $blog->add_association($contextmodule->id);
249         $sink = $this->redirectEvents();
250         $blog->remove_associations();
251         $events = $sink->get_events();
252         $event = reset($events);
253         $sink->close();
255         // Validate event data.
256         $this->assertEquals($blog->id, $event->other['blogid']);
257         $this->assertEquals($USER->id, $event->userid);
258         $this->assertEventContextNotUsed($event);
259     }
261     /**
262      * Tests for event blog_association_created.
263      */
264     public function test_blog_association_created_event() {
265         global $USER;
267         $this->setAdminUser();
268         $this->resetAfterTest();
269         $sitecontext = context_system::instance();
270         $coursecontext = context_course::instance($this->courseid);
271         $contextmodule = context_module::instance($this->cmid);
273         // Add blog associations with a course.
274         $blog = new blog_entry($this->postid);
275         $sink = $this->redirectEvents();
276         $blog->add_association($coursecontext->id);
277         $events = $sink->get_events();
278         $event = reset($events);
279         $sink->close();
281         // Validate event data.
282         $this->assertInstanceOf('\core\event\blog_association_created', $event);
283         $this->assertEquals($sitecontext->id, $event->contextid);
284         $url = new moodle_url('/blog/index.php', array('entryid' => $event->other['blogid']));
285         $this->assertEquals($url, $event->get_url());
286         $this->assertEquals($blog->id, $event->other['blogid']);
287         $this->assertEquals($this->courseid, $event->other['associateid']);
288         $this->assertEquals('course', $event->other['associatetype']);
289         $this->assertEquals($blog->subject, $event->other['subject']);
290         $this->assertEquals($USER->id, $event->userid);
291         $this->assertEquals($this->userid, $event->relateduserid);
292         $this->assertEquals('blog_association', $event->objecttable);
293         $arr = array(SITEID, 'blog', 'add association', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id,
294                      $blog->subject, 0, $this->userid);
295         $this->assertEventLegacyLogData($arr, $event);
297         // Add blog associations with a module.
298         $blog = new blog_entry($this->postid);
299         $sink = $this->redirectEvents();
300         $blog->add_association($contextmodule->id);
301         $events = $sink->get_events();
302         $event = reset($events);
303         $sink->close();
305         // Validate event data.
306         $this->assertEquals($blog->id, $event->other['blogid']);
307         $this->assertEquals($this->cmid, $event->other['associateid']);
308         $this->assertEquals('coursemodule', $event->other['associatetype']);
309         $arr = array(SITEID, 'blog', 'add association', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id,
310                      $blog->subject, $this->cmid, $this->userid);
311         $this->assertEventLegacyLogData($arr, $event);
312         $this->assertEventContextNotUsed($event);
313     }
315     /**
316      * Tests for event blog_association_created validations.
317      */
318     public function test_blog_association_created_event_validations() {
320         $this->resetAfterTest();
322          // Make sure associatetype validations work.
323         try {
324             \core\event\blog_association_created::create(array(
325                 'contextid' => 1,
326                 'objectid' => 3,
327                 'relateduserid' => 2,
328                 'other' => array('associateid' => 2 , 'blogid' => 3, 'subject' => 'blog subject')));
329         } catch (coding_exception $e) {
330             $this->assertContains('The \'associatetype\' value must be set in other and be a valid type.', $e->getMessage());
331         }
332         try {
333             \core\event\blog_association_created::create(array(
334                 'contextid' => 1,
335                 'objectid' => 3,
336                 'relateduserid' => 2,
337                 'other' => array('associateid' => 2 , 'blogid' => 3, 'associatetype' => 'random', 'subject' => 'blog subject')));
338         } catch (coding_exception $e) {
339             $this->assertContains('The \'associatetype\' value must be set in other and be a valid type.', $e->getMessage());
340         }
341         // Make sure associateid validations work.
342         try {
343             \core\event\blog_association_created::create(array(
344                 'contextid' => 1,
345                 'objectid' => 3,
346                 'relateduserid' => 2,
347                 'other' => array('blogid' => 3, 'associatetype' => 'course', 'subject' => 'blog subject')));
348         } catch (coding_exception $e) {
349             $this->assertContains('The \'associateid\' value must be set in other.', $e->getMessage());
350         }
351         // Make sure blogid validations work.
352         try {
353             \core\event\blog_association_created::create(array(
354                 'contextid' => 1,
355                 'objectid' => 3,
356                 'relateduserid' => 2,
357                 'other' => array('associateid' => 3, 'associatetype' => 'course', 'subject' => 'blog subject')));
358         } catch (coding_exception $e) {
359             $this->assertContains('The \'blogid\' value must be set in other.', $e->getMessage());
360         }
361         // Make sure blogid validations work.
362         try {
363             \core\event\blog_association_created::create(array(
364                 'contextid' => 1,
365                 'objectid' => 3,
366                 'relateduserid' => 2,
367                 'other' => array('blogid' => 3, 'associateid' => 3, 'associatetype' => 'course')));
368         } catch (coding_exception $e) {
369             $this->assertContains('The \'subject\' value must be set in other.', $e->getMessage());
370         }
371     }
373     /**
374      * Tests for event blog_entries_viewed.
375      */
376     public function test_blog_entries_viewed_event() {
378         $this->setAdminUser();
380         $other = array('entryid' => $this->postid, 'tagid' => $this->tagid, 'userid' => $this->userid, 'modid' => $this->cmid,
381                        'groupid' => $this->groupid, 'courseid' => $this->courseid, 'search' => 'search', 'fromstart' => 2);
383         // Trigger event.
384         $sink = $this->redirectEvents();
385         $eventparams = array('other' => $other);
386         $eventinst = \core\event\blog_entries_viewed::create($eventparams);
387         $eventinst->trigger();
388         $events = $sink->get_events();
389         $event = reset($events);
390         $sink->close();
392         // Validate event data.
393         $url = new moodle_url('/blog/index.php', $other);
394         $url2 = new moodle_url('index.php', $other);
395         $this->assertEquals($url, $event->get_url());
396         $arr = array(SITEID, 'blog', 'view', $url2->out(), 'view blog entry');
397         $this->assertEventLegacyLogData($arr, $event);
398         $this->assertEventContextNotUsed($event);
399     }
401     /**
402      * Test comment_created event.
403      */
404     public function test_blog_comment_created_event() {
405         global $USER, $CFG;
407         $this->setAdminUser();
409         require_once($CFG->dirroot . '/comment/lib.php');
410         $context = context_user::instance($USER->id);
412         $cmt = new stdClass();
413         $cmt->context = $context;
414         $cmt->courseid = $this->courseid;
415         $cmt->area = 'format_blog';
416         $cmt->itemid = $this->postid;
417         $cmt->showcount = 1;
418         $cmt->component = 'blog';
419         $manager = new comment($cmt);
421         // Triggering and capturing the event.
422         $sink = $this->redirectEvents();
423         $manager->add("New comment");
424         $events = $sink->get_events();
425         $this->assertCount(1, $events);
426         $event = reset($events);
428         // Checking that the event contains the expected values.
429         $this->assertInstanceOf('\core\event\blog_comment_created', $event);
430         $this->assertEquals($context, $event->get_context());
431         $this->assertEquals($this->postid, $event->other['itemid']);
432         $url = new moodle_url('/blog/index.php', array('entryid' => $this->postid));
433         $this->assertEquals($url, $event->get_url());
434         $this->assertEventContextNotUsed($event);
435     }
437     /**
438      * Test comment_deleted event.
439      */
440     public function test_blog_comment_deleted_event() {
441         global $USER, $CFG;
443         $this->setAdminUser();
445         require_once($CFG->dirroot . '/comment/lib.php');
446         $context = context_user::instance($USER->id);
448         $cmt = new stdClass();
449         $cmt->context = $context;
450         $cmt->courseid = $this->courseid;
451         $cmt->area = 'format_blog';
452         $cmt->itemid = $this->postid;
453         $cmt->showcount = 1;
454         $cmt->component = 'blog';
455         $manager = new comment($cmt);
456         $newcomment = $manager->add("New comment");
458         // Triggering and capturing the event.
459         $sink = $this->redirectEvents();
460         $manager->delete($newcomment->id);
461         $events = $sink->get_events();
462         $this->assertCount(1, $events);
463         $event = reset($events);
465         // Checking that the event contains the expected values.
466         $this->assertInstanceOf('\core\event\blog_comment_deleted', $event);
467         $this->assertEquals($context, $event->get_context());
468         $this->assertEquals($this->postid, $event->other['itemid']);
469         $url = new moodle_url('/blog/index.php', array('entryid' => $this->postid));
470         $this->assertEquals($url, $event->get_url());
471         $this->assertEventContextNotUsed($event);
472     }
474     /**
475      * Test external blog added event.
476      *
477      * There is no external API for this, so the unit test will simply
478      * create and trigger the event and ensure data is returned as expected.
479      */
480     public function test_external_blog_added_event() {
482         // Trigger an event: external blog added.
483         $eventparams = array(
484             'context' => $context = context_system::instance(),
485             'objectid' => 1001,
486             'other' => array('url' => 'http://moodle.org')
487         );
489         $event = \core\event\blog_external_added::create($eventparams);
490         // Trigger and capture the event.
491         $sink = $this->redirectEvents();
492         $event->trigger();
493         $events = $sink->get_events();
494         $event = reset($events);
496         // Check that the event data is valid.
497         $this->assertInstanceOf('\core\event\blog_external_added', $event);
498         $this->assertEquals(1001, $event->objectid);
499         $this->assertEquals('http://moodle.org', $event->other['url']);
500         $this->assertDebuggingNotCalled();
501     }
503     /**
504      * Test external blog updated event.
505      *
506      * There is no external API for this, so the unit test will simply
507      * create and trigger the event and ensure data is returned as expected.
508      */
509     public function test_external_blog_updated_event() {
511         // Trigger an event: external blog updated.
512         $eventparams = array(
513             'context' => $context = context_system::instance(),
514             'objectid' => 1001,
515             'other' => array('url' => 'http://moodle.org')
516         );
518         $event = \core\event\blog_external_updated::create($eventparams);
519         // Trigger and capture the event.
520         $sink = $this->redirectEvents();
521         $event->trigger();
522         $events = $sink->get_events();
523         $event = reset($events);
525         // Check that the event data is valid.
526         $this->assertInstanceOf('\core\event\blog_external_updated', $event);
527         $this->assertEquals(1001, $event->objectid);
528         $this->assertEquals('http://moodle.org', $event->other['url']);
529         $this->assertDebuggingNotCalled();
530     }
532     /**
533      * Test external blog removed event.
534      *
535      * There is no external API for this, so the unit test will simply
536      * create and trigger the event and ensure data is returned as expected.
537      */
538     public function test_external_blog_removed_event() {
540         // Trigger an event: external blog removed.
541         $eventparams = array(
542             'context' => $context = context_system::instance(),
543             'objectid' => 1001,
544         );
546         $event = \core\event\blog_external_removed::create($eventparams);
547         // Trigger and capture the event.
548         $sink = $this->redirectEvents();
549         $event->trigger();
550         $events = $sink->get_events();
551         $event = reset($events);
553         // Check that the event data is valid.
554         $this->assertInstanceOf('\core\event\blog_external_removed', $event);
555         $this->assertEquals(1001, $event->objectid);
556         $this->assertDebuggingNotCalled();
557     }
559     /**
560      * Test external blogs viewed event.
561      *
562      * There is no external API for this, so the unit test will simply
563      * create and trigger the event and ensure data is returned as expected.
564      */
565     public function test_external_blogs_viewed_event() {
567         // Trigger an event: external blogs viewed.
568         $eventparams = array(
569             'context' => $context = context_system::instance(),
570         );
572         $event = \core\event\blog_external_viewed::create($eventparams);
573         // Trigger and capture the event.
574         $sink = $this->redirectEvents();
575         $event->trigger();
576         $events = $sink->get_events();
577         $event = reset($events);
579         // Check that the event data is valid.
580         $this->assertInstanceOf('\core\event\blog_external_viewed', $event);
581         $this->assertDebuggingNotCalled();
582     }