80c3be50e7ac0d739582e769bda02df2f90f5816
[moodle.git] / blog / 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  * Unit tests for blog
19  *
20  * @package    core_blog
21  * @category   phpunit
22  * @copyright  2009 Nicolas Connault
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 global $CFG;
27 require_once($CFG->dirroot . '/blog/locallib.php');
28 require_once($CFG->dirroot . '/blog/lib.php');
30 /**
31  * Test functions that rely on the DB tables
32  */
33 class core_blog_lib_testcase extends advanced_testcase {
35     private $courseid;
36     private $cmid;
37     private $groupid;
38     private $userid;
39     private $tagid;
40     private $postid;
42     protected function setUp() {
43         global $DB;
44         parent::setUp();
46         $this->resetAfterTest();
48         // Create default course.
49         $course = $this->getDataGenerator()->create_course(array('category' => 1, 'shortname' => 'ANON'));
50         $this->assertNotEmpty($course);
51         $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
52         $this->assertNotEmpty($page);
54         // Create default group.
55         $group = new stdClass();
56         $group->courseid = $course->id;
57         $group->name = 'ANON';
58         $group->id = $DB->insert_record('groups', $group);
60         // Create default user.
61         $user = $this->getDataGenerator()->create_user(array(
62                 'username' => 'testuser',
63                 'firstname' => 'Jimmy',
64                 'lastname' => 'Kinnon'
65         ));
67         // Create default tag.
68         $tag = $this->getDataGenerator()->create_tag(array('userid' => $user->id,
69             'rawname' => 'Testtagname', 'isstandard' => 1));
71         // Create default post.
72         $post = new stdClass();
73         $post->userid = $user->id;
74         $post->groupid = $group->id;
75         $post->content = 'test post content text';
76         $post->module = 'blog';
77         $post->id = $DB->insert_record('post', $post);
79         // Grab important ids.
80         $this->courseid = $course->id;
81         $this->cmid = $page->cmid;
82         $this->groupid  = $group->id;
83         $this->userid  = $user->id;
84         $this->tagid  = $tag->id;
85         $this->postid = $post->id;
86     }
89     public function test_overrides() {
90         global $SITE;
92         // Try all the filters at once: Only the entry filter is active.
93         $filters = array('site' => $SITE->id, 'course' => $this->courseid, 'module' => $this->cmid,
94             'group' => $this->groupid, 'user' => $this->userid, 'tag' => $this->tagid, 'entry' => $this->postid);
95         $bloglisting = new blog_listing($filters);
96         $this->assertFalse(array_key_exists('site', $bloglisting->filters));
97         $this->assertFalse(array_key_exists('course', $bloglisting->filters));
98         $this->assertFalse(array_key_exists('module', $bloglisting->filters));
99         $this->assertFalse(array_key_exists('group', $bloglisting->filters));
100         $this->assertFalse(array_key_exists('user', $bloglisting->filters));
101         $this->assertFalse(array_key_exists('tag', $bloglisting->filters));
102         $this->assertTrue(array_key_exists('entry', $bloglisting->filters));
104         // Again, but without the entry filter: This time, the tag, user and module filters are active.
105         $filters = array('site' => $SITE->id, 'course' => $this->courseid, 'module' => $this->cmid,
106             'group' => $this->groupid, 'user' => $this->userid, 'tag' => $this->postid);
107         $bloglisting = new blog_listing($filters);
108         $this->assertFalse(array_key_exists('site', $bloglisting->filters));
109         $this->assertFalse(array_key_exists('course', $bloglisting->filters));
110         $this->assertFalse(array_key_exists('group', $bloglisting->filters));
111         $this->assertTrue(array_key_exists('module', $bloglisting->filters));
112         $this->assertTrue(array_key_exists('user', $bloglisting->filters));
113         $this->assertTrue(array_key_exists('tag', $bloglisting->filters));
115         // We should get the same result by removing the 3 inactive filters: site, course and group.
116         $filters = array('module' => $this->cmid, 'user' => $this->userid, 'tag' => $this->tagid);
117         $bloglisting = new blog_listing($filters);
118         $this->assertFalse(array_key_exists('site', $bloglisting->filters));
119         $this->assertFalse(array_key_exists('course', $bloglisting->filters));
120         $this->assertFalse(array_key_exists('group', $bloglisting->filters));
121         $this->assertTrue(array_key_exists('module', $bloglisting->filters));
122         $this->assertTrue(array_key_exists('user', $bloglisting->filters));
123         $this->assertTrue(array_key_exists('tag', $bloglisting->filters));
125     }
127     // The following series of 'test_blog..' functions correspond to the blog_get_headers() function within blog/lib.php.
128     // Some cases are omitted due to the optional_param variables used.
130     public function test_blog_get_headers_case_1() {
131         global $CFG, $PAGE, $OUTPUT;
132         $blogheaders = blog_get_headers();
133         $this->assertEquals($blogheaders['heading'], get_string('siteblogheading', 'blog'));
134     }
136     public function test_blog_get_headers_case_6() {
137         global $CFG, $PAGE, $OUTPUT;
138         $blogheaders = blog_get_headers($this->courseid, null, $this->userid);
139         $this->assertNotEquals($blogheaders['heading'], '');
140     }
142     public function test_blog_get_headers_case_7() {
143         global $CFG, $PAGE, $OUTPUT;
144         $blogheaders = blog_get_headers(null, $this->groupid);
145         $this->assertNotEquals($blogheaders['heading'], '');
146     }
148     public function test_blog_get_headers_case_10() {
149         global $CFG, $PAGE, $OUTPUT;
150         $blogheaders = blog_get_headers($this->courseid);
151         $this->assertNotEquals($blogheaders['heading'], '');
152     }
154     /**
155      * Test various blog related events.
156      */
157     public function test_blog_entry_created_event() {
158         global $USER;
160         $this->setAdminUser();
161         $this->resetAfterTest();
163         // Create a blog entry for another user as Admin.
164         $sink = $this->redirectEvents();
165         $blog = new blog_entry();
166         $blog->subject = "Subject of blog";
167         $blog->userid = $this->userid;
168         $states = blog_entry::get_applicable_publish_states();
169         $blog->publishstate = reset($states);
170         $blog->add();
171         $events = $sink->get_events();
172         $sink->close();
173         $event = reset($events);
174         $sitecontext = context_system::instance();
176         // Validate event data.
177         $this->assertInstanceOf('\core\event\blog_entry_created', $event);
178         $url = new moodle_url('/blog/index.php', array('entryid' => $event->objectid));
179         $this->assertEquals($url, $event->get_url());
180         $this->assertEquals($sitecontext->id, $event->contextid);
181         $this->assertEquals($blog->id, $event->objectid);
182         $this->assertEquals($USER->id, $event->userid);
183         $this->assertEquals($this->userid, $event->relateduserid);
184         $this->assertEquals("post", $event->objecttable);
185         $arr = array(SITEID, 'blog', 'add', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id, $blog->subject);
186         $this->assertEventLegacyLogData($arr, $event);
187         $this->assertEquals("blog_entry_added", $event->get_legacy_eventname());
188         $this->assertEventLegacyData($blog, $event);
189         $this->assertEventContextNotUsed($event);
190     }
192     /**
193      * Tests for event blog_entry_updated.
194      */
195     public function test_blog_entry_updated_event() {
196         global $USER;
198         $this->setAdminUser();
199         $this->resetAfterTest();
200         $sitecontext = context_system::instance();
202         // Edit a blog entry as Admin.
203         $blog = new blog_entry($this->postid);
204         $sink = $this->redirectEvents();
205         $blog->summary_editor = array('text' => 'Something', 'format' => FORMAT_MOODLE);
206         $blog->edit(array(), null, array(), array());
207         $events = $sink->get_events();
208         $event = array_pop($events);
209         $sink->close();
211         // Validate event data.
212         $this->assertInstanceOf('\core\event\blog_entry_updated', $event);
213         $url = new moodle_url('/blog/index.php', array('entryid' => $event->objectid));
214         $this->assertEquals($url, $event->get_url());
215         $this->assertEquals($sitecontext->id, $event->contextid);
216         $this->assertEquals($blog->id, $event->objectid);
217         $this->assertEquals($USER->id, $event->userid);
218         $this->assertEquals($this->userid, $event->relateduserid);
219         $this->assertEquals("post", $event->objecttable);
220         $this->assertEquals("blog_entry_edited", $event->get_legacy_eventname());
221         $this->assertEventLegacyData($blog, $event);
222         $arr = array (SITEID, 'blog', 'update', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id, $blog->subject);
223         $this->assertEventLegacyLogData($arr, $event);
224         $this->assertEventContextNotUsed($event);
225     }
227     /**
228      * Tests for event blog_entry_deleted.
229      */
230     public function test_blog_entry_deleted_event() {
231         global $USER, $DB;
233         $this->setAdminUser();
234         $this->resetAfterTest();
235         $sitecontext = context_system::instance();
237         // Delete a user blog entry as Admin.
238         $blog = new blog_entry($this->postid);
239         $sink = $this->redirectEvents();
240         $record = $DB->get_record('post', array('id' => $blog->id));
241         $blog->delete();
242         $events = $sink->get_events();
243         $event = array_pop($events);
244         $sink->close();
246         // Validate event data.
247         $this->assertInstanceOf('\core\event\blog_entry_deleted', $event);
248         $this->assertEquals(null, $event->get_url());
249         $this->assertEquals($sitecontext->id, $event->contextid);
250         $this->assertEquals($blog->id, $event->objectid);
251         $this->assertEquals($USER->id, $event->userid);
252         $this->assertEquals($this->userid, $event->relateduserid);
253         $this->assertEquals("post", $event->objecttable);
254         $this->assertEquals($record, $event->get_record_snapshot("post", $blog->id));
255         $this->assertSame('blog_entry_deleted', $event->get_legacy_eventname());
256         $arr = array(SITEID, 'blog', 'delete', 'index.php?userid=' . $blog->userid, 'deleted blog entry with entry id# ' .
257                 $blog->id);
258         $this->assertEventLegacyLogData($arr, $event);
259         $this->assertEventLegacyData($blog, $event);
260         $this->assertEventContextNotUsed($event);
261     }
264     /**
265      * Tests for event blog_association_created.
266      */
267     public function test_blog_association_created_event() {
268         global $USER;
270         $this->setAdminUser();
271         $this->resetAfterTest();
272         $sitecontext = context_system::instance();
273         $coursecontext = context_course::instance($this->courseid);
274         $contextmodule = context_module::instance($this->cmid);
276         // Add blog associations with a course.
277         $blog = new blog_entry($this->postid);
278         $sink = $this->redirectEvents();
279         $blog->add_association($coursecontext->id);
280         $events = $sink->get_events();
281         $event = reset($events);
282         $sink->close();
284         // Validate event data.
285         $this->assertInstanceOf('\core\event\blog_association_created', $event);
286         $this->assertEquals($sitecontext->id, $event->contextid);
287         $url = new moodle_url('/blog/index.php', array('entryid' => $event->other['blogid']));
288         $this->assertEquals($url, $event->get_url());
289         $this->assertEquals($blog->id, $event->other['blogid']);
290         $this->assertEquals($this->courseid, $event->other['associateid']);
291         $this->assertEquals('course', $event->other['associatetype']);
292         $this->assertEquals($blog->subject, $event->other['subject']);
293         $this->assertEquals($USER->id, $event->userid);
294         $this->assertEquals($this->userid, $event->relateduserid);
295         $this->assertEquals('blog_association', $event->objecttable);
296         $arr = array(SITEID, 'blog', 'add association', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id,
297                      $blog->subject, 0, $this->userid);
298         $this->assertEventLegacyLogData($arr, $event);
300         // Add blog associations with a module.
301         $blog = new blog_entry($this->postid);
302         $sink = $this->redirectEvents();
303         $blog->add_association($contextmodule->id);
304         $events = $sink->get_events();
305         $event = reset($events);
306         $sink->close();
308         // Validate event data.
309         $this->assertEquals($blog->id, $event->other['blogid']);
310         $this->assertEquals($this->cmid, $event->other['associateid']);
311         $this->assertEquals('coursemodule', $event->other['associatetype']);
312         $arr = array(SITEID, 'blog', 'add association', 'index.php?userid=' . $this->userid . '&entryid=' . $blog->id,
313                      $blog->subject, $this->cmid, $this->userid);
314         $this->assertEventLegacyLogData($arr, $event);
315         $this->assertEventContextNotUsed($event);
316     }
318     /**
319      * Tests for event blog_association_created validations.
320      */
321     public function test_blog_association_created_event_validations() {
323         $this->resetAfterTest();
325          // Make sure associatetype validations work.
326         try {
327             \core\event\blog_association_created::create(array(
328                 'contextid' => 1,
329                 'objectid' => 3,
330                 'relateduserid' => 2,
331                 'other' => array('associateid' => 2 , 'blogid' => 3, 'subject' => 'blog subject')));
332         } catch (coding_exception $e) {
333             $this->assertContains('The \'associatetype\' value must be set in other and be a valid type.', $e->getMessage());
334         }
335         try {
336             \core\event\blog_association_created::create(array(
337                 'contextid' => 1,
338                 'objectid' => 3,
339                 'relateduserid' => 2,
340                 'other' => array('associateid' => 2 , 'blogid' => 3, 'associatetype' => 'random', 'subject' => 'blog subject')));
341         } catch (coding_exception $e) {
342             $this->assertContains('The \'associatetype\' value must be set in other and be a valid type.', $e->getMessage());
343         }
344         // Make sure associateid validations work.
345         try {
346             \core\event\blog_association_created::create(array(
347                 'contextid' => 1,
348                 'objectid' => 3,
349                 'relateduserid' => 2,
350                 'other' => array('blogid' => 3, 'associatetype' => 'course', 'subject' => 'blog subject')));
351         } catch (coding_exception $e) {
352             $this->assertContains('The \'associateid\' value must be set in other.', $e->getMessage());
353         }
354         // Make sure blogid validations work.
355         try {
356             \core\event\blog_association_created::create(array(
357                 'contextid' => 1,
358                 'objectid' => 3,
359                 'relateduserid' => 2,
360                 'other' => array('associateid' => 3, 'associatetype' => 'course', 'subject' => 'blog subject')));
361         } catch (coding_exception $e) {
362             $this->assertContains('The \'blogid\' value must be set in other.', $e->getMessage());
363         }
364         // Make sure blogid validations work.
365         try {
366             \core\event\blog_association_created::create(array(
367                 'contextid' => 1,
368                 'objectid' => 3,
369                 'relateduserid' => 2,
370                 'other' => array('blogid' => 3, 'associateid' => 3, 'associatetype' => 'course')));
371         } catch (coding_exception $e) {
372             $this->assertContains('The \'subject\' value must be set in other.', $e->getMessage());
373         }
374     }
376     /**
377      * Tests for event blog_entries_viewed.
378      */
379     public function test_blog_entries_viewed_event() {
381         $this->setAdminUser();
383         $other = array('entryid' => $this->postid, 'tagid' => $this->tagid, 'userid' => $this->userid, 'modid' => $this->cmid,
384                        'groupid' => $this->groupid, 'courseid' => $this->courseid, 'search' => 'search', 'fromstart' => 2);
386         // Trigger event.
387         $sink = $this->redirectEvents();
388         $eventparams = array('other' => $other);
389         $eventinst = \core\event\blog_entries_viewed::create($eventparams);
390         $eventinst->trigger();
391         $events = $sink->get_events();
392         $event = reset($events);
393         $sink->close();
395         // Validate event data.
396         $url = new moodle_url('/blog/index.php', $other);
397         $url2 = new moodle_url('index.php', $other);
398         $this->assertEquals($url, $event->get_url());
399         $arr = array(SITEID, 'blog', 'view', $url2->out(), 'view blog entry');
400         $this->assertEventLegacyLogData($arr, $event);
401         $this->assertEventContextNotUsed($event);
402     }
404     /**
405      * Test comment_created event.
406      */
407     public function test_blog_comment_created_event() {
408         global $USER, $CFG;
410         $this->setAdminUser();
412         require_once($CFG->dirroot . '/comment/lib.php');
413         $context = context_user::instance($USER->id);
415         $cmt = new stdClass();
416         $cmt->context = $context;
417         $cmt->courseid = $this->courseid;
418         $cmt->area = 'format_blog';
419         $cmt->itemid = $this->postid;
420         $cmt->showcount = 1;
421         $cmt->component = 'blog';
422         $manager = new comment($cmt);
424         // Triggering and capturing the event.
425         $sink = $this->redirectEvents();
426         $manager->add("New comment");
427         $events = $sink->get_events();
428         $this->assertCount(1, $events);
429         $event = reset($events);
431         // Checking that the event contains the expected values.
432         $this->assertInstanceOf('\core\event\blog_comment_created', $event);
433         $this->assertEquals($context, $event->get_context());
434         $this->assertEquals($this->postid, $event->other['itemid']);
435         $url = new moodle_url('/blog/index.php', array('entryid' => $this->postid));
436         $this->assertEquals($url, $event->get_url());
437         $this->assertEventContextNotUsed($event);
438     }
440     /**
441      * Test comment_deleted event.
442      */
443     public function test_blog_comment_deleted_event() {
444         global $USER, $CFG;
446         $this->setAdminUser();
448         require_once($CFG->dirroot . '/comment/lib.php');
449         $context = context_user::instance($USER->id);
451         $cmt = new stdClass();
452         $cmt->context = $context;
453         $cmt->courseid = $this->courseid;
454         $cmt->area = 'format_blog';
455         $cmt->itemid = $this->postid;
456         $cmt->showcount = 1;
457         $cmt->component = 'blog';
458         $manager = new comment($cmt);
459         $newcomment = $manager->add("New comment");
461         // Triggering and capturing the event.
462         $sink = $this->redirectEvents();
463         $manager->delete($newcomment->id);
464         $events = $sink->get_events();
465         $this->assertCount(1, $events);
466         $event = reset($events);
468         // Checking that the event contains the expected values.
469         $this->assertInstanceOf('\core\event\blog_comment_deleted', $event);
470         $this->assertEquals($context, $event->get_context());
471         $this->assertEquals($this->postid, $event->other['itemid']);
472         $url = new moodle_url('/blog/index.php', array('entryid' => $this->postid));
473         $this->assertEquals($url, $event->get_url());
474         $this->assertEventContextNotUsed($event);
475     }
477     /**
478      * Tests the core_blog_myprofile_navigation() function.
479      */
480     public function test_core_blog_myprofile_navigation() {
481         global $USER;
483         // Set up the test.
484         $tree = new \core_user\output\myprofile\tree();
485         $this->setAdminUser();
486         $iscurrentuser = true;
487         $course = null;
489         // Enable blogs.
490         set_config('enableblogs', true);
492         // Check the node tree is correct.
493         core_blog_myprofile_navigation($tree, $USER, $iscurrentuser, $course);
494         $reflector = new ReflectionObject($tree);
495         $nodes = $reflector->getProperty('nodes');
496         $nodes->setAccessible(true);
497         $this->assertArrayHasKey('blogs', $nodes->getValue($tree));
498     }
500     /**
501      * Tests the core_blog_myprofile_navigation() function as a guest.
502      */
503     public function test_core_blog_myprofile_navigation_as_guest() {
504         global $USER;
506         // Set up the test.
507         $tree = new \core_user\output\myprofile\tree();
508         $iscurrentuser = false;
509         $course = null;
511         // Set user as guest.
512         $this->setGuestUser();
514         // Check the node tree is correct.
515         core_blog_myprofile_navigation($tree, $USER, $iscurrentuser, $course);
516         $reflector = new ReflectionObject($tree);
517         $nodes = $reflector->getProperty('nodes');
518         $nodes->setAccessible(true);
519         $this->assertArrayNotHasKey('blogs', $nodes->getValue($tree));
520     }
522     /**
523      * Tests the core_blog_myprofile_navigation() function when blogs are disabled.
524      */
525     public function test_core_blog_myprofile_navigation_blogs_disabled() {
526         global $USER;
528         // Set up the test.
529         $tree = new \core_user\output\myprofile\tree();
530         $this->setAdminUser();
531         $iscurrentuser = false;
532         $course = null;
534         // Disable blogs.
535         set_config('enableblogs', false);
537         // Check the node tree is correct.
538         core_blog_myprofile_navigation($tree, $USER, $iscurrentuser, $course);
539         $reflector = new ReflectionObject($tree);
540         $nodes = $reflector->getProperty('nodes');
541         $nodes->setAccessible(true);
542         $this->assertArrayNotHasKey('blogs', $nodes->getValue($tree));
543     }
545     public function test_blog_get_listing_course() {
546         $this->setAdminUser();
547         $coursecontext = context_course::instance($this->courseid);
548         $anothercourse = $this->getDataGenerator()->create_course();
550         // Add blog associations with a course.
551         $blog = new blog_entry($this->postid);
552         $blog->add_association($coursecontext->id);
554         // There is one entry associated with a course.
555         $bloglisting = new blog_listing(array('course' => $this->courseid));
556         $this->assertCount(1, $bloglisting->get_entries());
558         // There is no entry associated with a wrong course.
559         $bloglisting = new blog_listing(array('course' => $anothercourse->id));
560         $this->assertCount(0, $bloglisting->get_entries());
562         // There is no entry associated with a module.
563         $bloglisting = new blog_listing(array('module' => $this->cmid));
564         $this->assertCount(0, $bloglisting->get_entries());
566         // There is one entry associated with a site (id is ignored).
567         $bloglisting = new blog_listing(array('site' => 12345));
568         $this->assertCount(1, $bloglisting->get_entries());
570         // There is one entry associated with course context.
571         $bloglisting = new blog_listing(array('context' => $coursecontext->id));
572         $this->assertCount(1, $bloglisting->get_entries());
573     }
575     public function test_blog_get_listing_module() {
576         $this->setAdminUser();
577         $coursecontext = context_course::instance($this->courseid);
578         $contextmodule = context_module::instance($this->cmid);
579         $anothermodule = $this->getDataGenerator()->create_module('page', array('course' => $this->courseid));
581         // Add blog associations with a course.
582         $blog = new blog_entry($this->postid);
583         $blog->add_association($contextmodule->id);
585         // There is no entry associated with a course.
586         $bloglisting = new blog_listing(array('course' => $this->courseid));
587         $this->assertCount(0, $bloglisting->get_entries());
589         // There is one entry associated with a module.
590         $bloglisting = new blog_listing(array('module' => $this->cmid));
591         $this->assertCount(1, $bloglisting->get_entries());
593         // There is no entry associated with a wrong module.
594         $bloglisting = new blog_listing(array('module' => $anothermodule->cmid));
595         $this->assertCount(0, $bloglisting->get_entries());
597         // There is one entry associated with a site (id is ignored).
598         $bloglisting = new blog_listing(array('site' => 12345));
599         $this->assertCount(1, $bloglisting->get_entries());
601         // There is one entry associated with course context (module is a subcontext of a course).
602         $bloglisting = new blog_listing(array('context' => $coursecontext->id));
603         $this->assertCount(1, $bloglisting->get_entries());
604     }