]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - tests/ActivityGenerationTests.php
Merge branch 'cas-user-whitelist' into 'nightly'
[quix0rs-gnu-social.git] / tests / ActivityGenerationTests.php
1 <?php
2
3 if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
4     print "This script must be run from the command line\n";
5     exit();
6 }
7
8 // XXX: we should probably have some common source for this stuff
9
10 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
11 define('GNUSOCIAL', true);
12 define('STATUSNET', true);  // compatibility
13
14 require_once INSTALLDIR . '/lib/common.php';
15
16 class ActivityGenerationTests extends PHPUnit_Framework_TestCase
17 {
18     static $author1 = null;
19     static $author2 = null;
20
21     static $targetUser1 = null;
22     static $targetUser2 = null;
23
24     static $targetGroup1 = null;
25     static $targetGroup2 = null;
26
27     public static function setUpBeforeClass()
28     {
29         $authorNick1 = 'activitygenerationtestsuser' . common_random_hexstr(4);
30         $authorNick2 = 'activitygenerationtestsuser' . common_random_hexstr(4);
31
32         $targetNick1 = 'activitygenerationteststarget' . common_random_hexstr(4);
33         $targetNick2 = 'activitygenerationteststarget' . common_random_hexstr(4);
34
35         $groupNick1 = 'activitygenerationtestsgroup' . common_random_hexstr(4);
36         $groupNick2 = 'activitygenerationtestsgroup' . common_random_hexstr(4);
37
38         try{
39                 self::$author1 = User::register(array('nickname' => $authorNick1,
40                                               'email' => $authorNick1 . '@example.net',
41                                               'email_confirmed' => true));
42
43                 self::$author2 = User::register(array('nickname' => $authorNick2,
44                                               'email' => $authorNick2 . '@example.net',
45                                               'email_confirmed' => true));
46
47                 self::$targetUser1 = User::register(array('nickname' => $targetNick1,
48                                                   'email' => $targetNick1 . '@example.net',
49                                                   'email_confirmed' => true));
50
51                 self::$targetUser2 = User::register(array('nickname' => $targetNick2,
52                                                   'email' => $targetNick2 . '@example.net',
53                                                   'email_confirmed' => true));
54
55                 self::$targetGroup1 = User_group::register(array('nickname' => $groupNick1,
56                                                          'userid' => self::$author1->id,
57                                                          'aliases' => array(),
58                                                          'local' => true,
59                                                          'location' => null,
60                                                          'description' => null,
61                                                          'fullname' => null,
62                                                          'homepage' => null,
63                                                          'mainpage' => null));
64                 self::$targetGroup2 = User_group::register(array('nickname' => $groupNick2,
65                                                          'userid' => self::$author1->id,
66                                                          'aliases' => array(),
67                                                          'local' => true,
68                                                          'location' => null,
69                                                          'description' => null,
70                                                          'fullname' => null,
71                                                          'homepage' => null,
72                                                          'mainpage' => null));
73         } catch (Exception $e) {
74                 self::tearDownAfterClass();
75                 throw $e;
76         }
77     }
78
79     public function testBasicNoticeActivity()
80     {
81         $notice = $this->_fakeNotice();
82
83         $entry = $notice->asAtomEntry(true);
84
85         $element = $this->_entryToElement($entry, false);
86
87         $this->assertEquals($notice->getUri(), ActivityUtils::childContent($element, 'id'));
88         $this->assertEquals('New note by '. self::$author1->nickname, ActivityUtils::childContent($element, 'title'));
89         $this->assertEquals($notice->rendered, ActivityUtils::childContent($element, 'content'));
90         $this->assertEquals(strtotime($notice->created), strtotime(ActivityUtils::childContent($element, 'published')));
91         $this->assertEquals(strtotime($notice->created), strtotime(ActivityUtils::childContent($element, 'updated')));
92         $this->assertEquals(ActivityVerb::POST, ActivityUtils::childContent($element, 'verb', Activity::SPEC));
93         $this->assertEquals(ActivityObject::NOTE, ActivityUtils::childContent($element, 'object-type', Activity::SPEC));
94     }
95
96     public function testNamespaceFlag()
97     {
98         $notice = $this->_fakeNotice();
99
100         $entry = $notice->asAtomEntry(true);
101
102         $element = $this->_entryToElement($entry, false);
103
104         $this->assertTrue($element->hasAttribute('xmlns'));
105         $this->assertTrue($element->hasAttribute('xmlns:thr'));
106         $this->assertTrue($element->hasAttribute('xmlns:georss'));
107         $this->assertTrue($element->hasAttribute('xmlns:activity'));
108         $this->assertTrue($element->hasAttribute('xmlns:media'));
109         $this->assertTrue($element->hasAttribute('xmlns:poco'));
110         $this->assertTrue($element->hasAttribute('xmlns:ostatus'));
111         $this->assertTrue($element->hasAttribute('xmlns:statusnet'));
112
113         $entry = $notice->asAtomEntry(false);
114
115         $element = $this->_entryToElement($entry, true);
116
117         $this->assertFalse($element->hasAttribute('xmlns'));
118         $this->assertFalse($element->hasAttribute('xmlns:thr'));
119         $this->assertFalse($element->hasAttribute('xmlns:georss'));
120         $this->assertFalse($element->hasAttribute('xmlns:activity'));
121         $this->assertFalse($element->hasAttribute('xmlns:media'));
122         $this->assertFalse($element->hasAttribute('xmlns:poco'));
123         $this->assertFalse($element->hasAttribute('xmlns:ostatus'));
124         $this->assertFalse($element->hasAttribute('xmlns:statusnet'));
125     }
126
127     public function testSourceFlag()
128     {
129         $notice = $this->_fakeNotice();
130
131         // Test with no source
132
133         $entry = $notice->asAtomEntry(false, false);
134
135         $element = $this->_entryToElement($entry, true);
136
137         $source = ActivityUtils::child($element, 'source');
138
139         $this->assertNull($source);
140
141         // Test with source
142
143         $entry = $notice->asAtomEntry(false, true);
144
145         $element = $this->_entryToElement($entry, true);
146
147         $source = ActivityUtils::child($element, 'source');
148
149         $this->assertNotNull($source);
150     }
151
152     public function testSourceContent()
153     {
154         $notice = $this->_fakeNotice();
155         // make a time difference!
156         sleep(2);
157         $notice2 = $this->_fakeNotice();
158
159         $entry = $notice->asAtomEntry(false, true);
160
161         $element = $this->_entryToElement($entry, true);
162
163         $source = ActivityUtils::child($element, 'source');
164
165         $atomUrl = common_local_url('ApiTimelineUser', array('id' => self::$author1->id, 'format' => 'atom'));
166
167         $profile = self::$author1->getProfile();
168
169         $this->assertEquals($atomUrl, ActivityUtils::childContent($source, 'id'));
170         $this->assertEquals($atomUrl, ActivityUtils::getLink($source, 'self', 'application/atom+xml'));
171         $this->assertEquals($profile->profileurl, ActivityUtils::getPermalink($source));
172         $this->assertEquals(strtotime($notice2->created), strtotime(ActivityUtils::childContent($source, 'updated')));
173         // XXX: do we care here?
174         $this->assertFalse(is_null(ActivityUtils::childContent($source, 'title')));
175         $this->assertEquals(common_config('license', 'url'), ActivityUtils::getLink($source, 'license'));
176     }
177
178     public function testAuthorFlag()
179     {
180         $notice = $this->_fakeNotice();
181
182         // Test with no author
183
184         $entry = $notice->asAtomEntry(false, false, false);
185
186         $element = $this->_entryToElement($entry, true);
187
188         $this->assertNull(ActivityUtils::child($element, 'author'));
189         $this->assertNull(ActivityUtils::child($element, 'actor', Activity::SPEC));
190
191         // Test with source
192
193         $entry = $notice->asAtomEntry(false, false, true);
194
195         $element = $this->_entryToElement($entry, true);
196
197         $author = ActivityUtils::child($element, 'author');
198         $actor  = ActivityUtils::child($element, 'actor', Activity::SPEC);
199
200         $this->assertFalse(is_null($author));
201         $this->assertTrue(is_null($actor)); // <activity:actor> is obsolete, no longer added
202     }
203
204     public function testAuthorContent()
205     {
206         $notice = $this->_fakeNotice();
207
208         // Test with author
209
210         $entry = $notice->asAtomEntry(false, false, true);
211
212         $element = $this->_entryToElement($entry, true);
213
214         $author = ActivityUtils::child($element, 'author');
215
216         $this->assertEquals(self::$author1->getNickname(), ActivityUtils::childContent($author, 'name'));
217         $this->assertEquals(self::$author1->getUri(), ActivityUtils::childContent($author, 'uri'));
218     }
219
220     /**
221      * We no longer create <activity:actor> entries, they have merged to <atom:author>
222      */
223     public function testActorContent()
224     {
225         $notice = $this->_fakeNotice();
226
227         // Test with author
228
229         $entry = $notice->asAtomEntry(false, false, true);
230
231         $element = $this->_entryToElement($entry, true);
232
233         $actor = ActivityUtils::child($element, 'actor', Activity::SPEC);
234
235         $this->assertEquals($actor, null);
236     }
237
238     public function testReplyLink()
239     {
240         $orig = $this->_fakeNotice(self::$targetUser1);
241
242         $text = "@" . self::$targetUser1->nickname . " reply text " . common_random_hexstr(4);
243
244         $reply = Notice::saveNew(self::$author1->id, $text, 'test', array('uri' => null, 'reply_to' => $orig->id));
245
246         $entry = $reply->asAtomEntry();
247
248         $element = $this->_entryToElement($entry, true);
249
250         $irt = ActivityUtils::child($element, 'in-reply-to', 'http://purl.org/syndication/thread/1.0');
251
252         $this->assertNotNull($irt);
253         $this->assertEquals($orig->getUri(), $irt->getAttribute('ref'));
254         $this->assertEquals($orig->getUrl(), $irt->getAttribute('href'));
255     }
256
257     public function testReplyAttention()
258     {
259         $orig = $this->_fakeNotice(self::$targetUser1);
260
261         $text = "@" . self::$targetUser1->nickname . " reply text " . common_random_hexstr(4);
262
263         $reply = Notice::saveNew(self::$author1->id, $text, 'test', array('uri' => null, 'reply_to' => $orig->id));
264
265         $entry = $reply->asAtomEntry();
266
267         $element = $this->_entryToElement($entry, true);
268
269         $this->assertEquals(self::$targetUser1->getUri(), ActivityUtils::getLink($element, 'mentioned'));
270     }
271
272     public function testMultipleReplyAttention()
273     {
274         $orig = $this->_fakeNotice(self::$targetUser1);
275
276         $text = "@" . self::$targetUser1->nickname . " reply text " . common_random_hexstr(4);
277
278         $reply = Notice::saveNew(self::$targetUser2->id, $text, 'test', array('uri' => null, 'reply_to' => $orig->id));
279
280         $text = "@" . self::$targetUser1->nickname . " @" . self::$targetUser2->nickname . " reply text " . common_random_hexstr(4);
281
282         $reply2 = Notice::saveNew(self::$author1->id, $text, 'test', array('uri' => null, 'reply_to' => $reply->id));
283
284         $entry = $reply2->asAtomEntry();
285
286         $element = $this->_entryToElement($entry, true);
287
288         $links = ActivityUtils::getLinks($element, 'mentioned');
289
290         $hrefs = array();
291
292         foreach ($links as $link) {
293             $hrefs[] = $link->getAttribute('href');
294         }
295
296         $this->assertTrue(in_array(self::$targetUser1->getUri(), $hrefs));
297         $this->assertTrue(in_array(self::$targetUser2->getUri(), $hrefs));
298     }
299
300     public function testGroupPostAttention()
301     {
302         $text = "!" . self::$targetGroup1->nickname . " reply text " . common_random_hexstr(4);
303
304         $notice = Notice::saveNew(self::$author1->id, $text, 'test', array('uri' => null));
305
306         $entry = $notice->asAtomEntry();
307
308         $element = $this->_entryToElement($entry, true);
309
310         $this->assertEquals(self::$targetGroup1->getUri(), ActivityUtils::getLink($element, 'mentioned'));
311     }
312
313     public function testMultipleGroupPostAttention()
314     {
315         $text = "!" . self::$targetGroup1->nickname . " !" . self::$targetGroup2->nickname . " reply text " . common_random_hexstr(4);
316
317         $notice = Notice::saveNew(self::$author1->id, $text, 'test', array('uri' => null));
318
319         $entry = $notice->asAtomEntry();
320
321         $element = $this->_entryToElement($entry, true);
322
323         $links = ActivityUtils::getLinks($element, 'mentioned');
324
325         $hrefs = array();
326
327         foreach ($links as $link) {
328             $hrefs[] = $link->getAttribute('href');
329         }
330
331         $this->assertTrue(in_array(self::$targetGroup1->getUri(), $hrefs));
332         $this->assertTrue(in_array(self::$targetGroup2->getUri(), $hrefs));
333
334     }
335
336     public function testRepeatLink()
337     {
338         $notice = $this->_fakeNotice(self::$author1);
339         $repeat = $notice->repeat(self::$author2->getProfile(), 'test');
340
341         $entry = $repeat->asAtomEntry();
342
343         $element = $this->_entryToElement($entry, true);
344
345         $noticeInfo = ActivityUtils::child($element, 'notice_info', 'http://status.net/schema/api/1/');
346
347         $this->assertNotNull($noticeInfo);
348         $this->assertEquals($notice->id, $noticeInfo->getAttribute('repeat_of'));
349         $this->assertEquals($repeat->id, $noticeInfo->getAttribute('local_id'));
350     }
351
352     public function testTag()
353     {
354         $tag1 = common_random_hexstr(4);
355
356         $notice = $this->_fakeNotice(self::$author1, '#' . $tag1);
357
358         $entry = $notice->asAtomEntry();
359
360         $element = $this->_entryToElement($entry, true);
361
362         $category = ActivityUtils::child($element, 'category');
363
364         $this->assertNotNull($category);
365         $this->assertEquals($tag1, $category->getAttribute('term'));
366     }
367
368     public function testMultiTag()
369     {
370         $tag1 = common_random_hexstr(4);
371         $tag2 = common_random_hexstr(4);
372
373         $notice = $this->_fakeNotice(self::$author1, '#' . $tag1 . ' #' . $tag2);
374
375         $entry = $notice->asAtomEntry();
376
377         $element = $this->_entryToElement($entry, true);
378
379         $categories = $element->getElementsByTagName('category');
380
381         $this->assertNotNull($categories);
382         $this->assertEquals(2, $categories->length);
383
384         $terms = array();
385
386         for ($i = 0; $i < $categories->length; $i++) {
387             $cat = $categories->item($i);
388             $terms[] = $cat->getAttribute('term');
389         }
390
391         $this->assertTrue(in_array($tag1, $terms));
392         $this->assertTrue(in_array($tag2, $terms));
393     }
394
395     public function testGeotaggedActivity()
396     {
397         $notice = Notice::saveNew(self::$author1->id, common_random_hexstr(4), 'test', array('uri' => null, 'lat' => 45.5, 'lon' => -73.6));
398
399         $entry = $notice->asAtomEntry();
400
401         $element = $this->_entryToElement($entry, true);
402
403         $this->assertEquals('45.5000000 -73.6000000', ActivityUtils::childContent($element, 'point', "http://www.georss.org/georss"));
404     }
405
406     public function testNoticeInfo()
407     {
408         $notice = $this->_fakeNotice();
409
410         $entry = $notice->asAtomEntry();
411
412         $element = $this->_entryToElement($entry, true);
413
414         $noticeInfo = ActivityUtils::child($element, 'notice_info', "http://status.net/schema/api/1/");
415
416         $this->assertEquals($notice->id, $noticeInfo->getAttribute('local_id'));
417         $this->assertEquals($notice->source, $noticeInfo->getAttribute('source'));
418         $this->assertEquals('', $noticeInfo->getAttribute('repeat_of'));
419         $this->assertEquals('', $noticeInfo->getAttribute('repeated'));
420 //        $this->assertEquals('', $noticeInfo->getAttribute('favorite'));
421         $this->assertEquals('', $noticeInfo->getAttribute('source_link'));
422     }
423
424     public function testNoticeInfoRepeatOf()
425     {
426         $notice = $this->_fakeNotice();
427
428         $repeat = $notice->repeat(self::$author2->getProfile(), 'test');
429
430         $entry = $repeat->asAtomEntry();
431
432         $element = $this->_entryToElement($entry, true);
433
434         $noticeInfo = ActivityUtils::child($element, 'notice_info', "http://status.net/schema/api/1/");
435
436         $this->assertEquals($notice->id, $noticeInfo->getAttribute('repeat_of'));
437     }
438
439     public function testNoticeInfoRepeated()
440     {
441         $notice = $this->_fakeNotice();
442
443         $repeat = $notice->repeat(self::$author2->getProfile(), 'test');
444
445         $entry = $notice->asAtomEntry(false, false, false, self::$author2->getProfile());
446
447         $element = $this->_entryToElement($entry, true);
448
449         $noticeInfo = ActivityUtils::child($element, 'notice_info', "http://status.net/schema/api/1/");
450
451         $this->assertEquals('true', $noticeInfo->getAttribute('repeated'));
452
453         $entry = $notice->asAtomEntry(false, false, false, self::$targetUser1->getProfile());
454
455         $element = $this->_entryToElement($entry, true);
456
457         $noticeInfo = ActivityUtils::child($element, 'notice_info', "http://status.net/schema/api/1/");
458
459         $this->assertEquals('false', $noticeInfo->getAttribute('repeated'));
460     }
461
462 /*    public function testNoticeInfoFave()
463     {
464         $notice = $this->_fakeNotice();
465
466         $fave = Fave::addNew(self::$author2->getProfile(), $notice);
467
468         // Should be set if user has faved
469
470         $entry = $notice->asAtomEntry(false, false, false, self::$author2);
471
472         $element = $this->_entryToElement($entry, true);
473
474         $noticeInfo = ActivityUtils::child($element, 'notice_info', "http://status.net/schema/api/1/");
475
476         $this->assertEquals('true', $noticeInfo->getAttribute('favorite'));
477
478         // Shouldn't be set if user has not faved
479
480         $entry = $notice->asAtomEntry(false, false, false, self::$targetUser1);
481
482         $element = $this->_entryToElement($entry, true);
483
484         $noticeInfo = ActivityUtils::child($element, 'notice_info', "http://status.net/schema/api/1/");
485
486         $this->assertEquals('false', $noticeInfo->getAttribute('favorite'));
487     }*/
488
489     public function testConversationLink()
490     {
491         $orig = $this->_fakeNotice(self::$targetUser1);
492
493         $text = "@" . self::$targetUser1->nickname . " reply text " . common_random_hexstr(4);
494
495         $reply = Notice::saveNew(self::$author1->id, $text, 'test', array('uri' => null, 'reply_to' => $orig->id));
496
497         $conv = Conversation::getKV('id', $reply->conversation);
498
499         $entry = $reply->asAtomEntry();
500
501         $element = $this->_entryToElement($entry, true);
502
503         $this->assertEquals($conv->getUrl(), ActivityUtils::getLink($element, 'ostatus:conversation'));
504     }
505
506     public static function tearDownAfterClass()
507     {
508         if (!is_null(self::$author1)) {
509             self::$author1->getProfile()->delete();
510         }
511
512         if (!is_null(self::$author2)) {
513             self::$author2->getProfile()->delete();
514         }
515
516         if (!is_null(self::$targetUser1)) {
517             self::$targetUser1->getProfile()->delete();
518         }
519
520         if (!is_null(self::$targetUser2)) {
521             self::$targetUser2->getProfile()->delete();
522         }
523
524         if (!is_null(self::$targetGroup1)) {
525             self::$targetGroup1->delete();
526         }
527
528         if (!is_null(self::$targetGroup2)) {
529             self::$targetGroup2->delete();
530         }
531     }
532
533     private function _fakeNotice($user = null, $text = null)
534     {
535         if (empty($user)) {
536             $user = self::$author1;
537         }
538
539         if (empty($text)) {
540             $text = "fake-o text-o " . common_random_hexstr(32);
541         }
542
543         return Notice::saveNew($user->id, $text, 'test', array('uri' => null));
544     }
545
546     private function _entryToElement($entry, $namespace = false)
547     {
548         $xml = '<?xml version="1.0" encoding="utf-8"?>'."\n\n";
549         $xml .= '<feed';
550         if ($namespace) {
551             $xml .= ' xmlns="http://www.w3.org/2005/Atom"';
552             $xml .= ' xmlns:thr="http://purl.org/syndication/thread/1.0"';
553             $xml .= ' xmlns:georss="http://www.georss.org/georss"';
554             $xml .= ' xmlns:activity="http://activitystrea.ms/spec/1.0/"';
555             $xml .= ' xmlns:media="http://purl.org/syndication/atommedia"';
556             $xml .= ' xmlns:poco="http://portablecontacts.net/spec/1.0"';
557             $xml .= ' xmlns:ostatus="http://ostatus.org/schema/1.0"';
558             $xml .= ' xmlns:statusnet="http://status.net/schema/api/1/"';
559         }
560         $xml .= '>' . "\n" . $entry . "\n" . '</feed>' . "\n";
561         $doc = DOMDocument::loadXML($xml);
562         $feed = $doc->documentElement;
563         $entries = $feed->getElementsByTagName('entry');
564
565         return $entries->item(0);
566     }
567 }