diff options
Diffstat (limited to 'tests')
54 files changed, 2313 insertions, 278 deletions
diff --git a/tests/ApplicationUtilsTest.php b/tests/ApplicationUtilsTest.php index ff4c9e17..fe5f84ce 100644 --- a/tests/ApplicationUtilsTest.php +++ b/tests/ApplicationUtilsTest.php | |||
@@ -17,7 +17,7 @@ class FakeApplicationUtils extends ApplicationUtils | |||
17 | /** | 17 | /** |
18 | * Toggle HTTP requests, allow overriding the version code | 18 | * Toggle HTTP requests, allow overriding the version code |
19 | */ | 19 | */ |
20 | public static function getVersion($url, $timeout=0) | 20 | public static function getVersion($url, $timeout = 0) |
21 | { | 21 | { |
22 | return self::$VERSION_CODE; | 22 | return self::$VERSION_CODE; |
23 | } | 23 | } |
@@ -67,7 +67,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase | |||
67 | '0.5.4', | 67 | '0.5.4', |
68 | ApplicationUtils::getVersion( | 68 | ApplicationUtils::getVersion( |
69 | 'https://raw.githubusercontent.com/shaarli/Shaarli/' | 69 | 'https://raw.githubusercontent.com/shaarli/Shaarli/' |
70 | .'v0.5.4/shaarli_version.php', | 70 | .'v0.5.4/shaarli_version.php', |
71 | $testTimeout | 71 | $testTimeout |
72 | ) | 72 | ) |
73 | ); | 73 | ); |
@@ -75,7 +75,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase | |||
75 | self::$versionPattern, | 75 | self::$versionPattern, |
76 | ApplicationUtils::getVersion( | 76 | ApplicationUtils::getVersion( |
77 | 'https://raw.githubusercontent.com/shaarli/Shaarli/' | 77 | 'https://raw.githubusercontent.com/shaarli/Shaarli/' |
78 | .'latest/shaarli_version.php', | 78 | .'latest/shaarli_version.php', |
79 | $testTimeout | 79 | $testTimeout |
80 | ) | 80 | ) |
81 | ); | 81 | ); |
diff --git a/tests/CacheTest.php b/tests/CacheTest.php index 992e26a5..f60fad91 100644 --- a/tests/CacheTest.php +++ b/tests/CacheTest.php | |||
@@ -84,7 +84,7 @@ class CacheTest extends PHPUnit_Framework_TestCase | |||
84 | invalidateCaches(self::$testCacheDir); | 84 | invalidateCaches(self::$testCacheDir); |
85 | foreach (self::$pages as $page) { | 85 | foreach (self::$pages as $page) { |
86 | $this->assertFileNotExists(self::$testCacheDir.'/'.$page.'.cache'); | 86 | $this->assertFileNotExists(self::$testCacheDir.'/'.$page.'.cache'); |
87 | } | 87 | } |
88 | 88 | ||
89 | $this->assertArrayNotHasKey('tags', $_SESSION); | 89 | $this->assertArrayNotHasKey('tags', $_SESSION); |
90 | } | 90 | } |
diff --git a/tests/FeedBuilderTest.php b/tests/FeedBuilderTest.php index a590306d..4ca58e5a 100644 --- a/tests/FeedBuilderTest.php +++ b/tests/FeedBuilderTest.php | |||
@@ -82,8 +82,8 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
82 | $this->assertFalse($data['usepermalinks']); | 82 | $this->assertFalse($data['usepermalinks']); |
83 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); | 83 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); |
84 | 84 | ||
85 | // Test first link (note link) | 85 | // Test first not pinned link (note link) |
86 | $link = reset($data['links']); | 86 | $link = $data['links'][array_keys($data['links'])[2]]; |
87 | $this->assertEquals(41, $link['id']); | 87 | $this->assertEquals(41, $link['id']); |
88 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); | 88 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); |
89 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); | 89 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); |
@@ -119,7 +119,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
119 | $data = $feedBuilder->buildData(); | 119 | $data = $feedBuilder->buildData(); |
120 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); | 120 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); |
121 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']); | 121 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']); |
122 | $link = reset($data['links']); | 122 | $link = $data['links'][array_keys($data['links'])[2]]; |
123 | $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']); | 123 | $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']); |
124 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']); | 124 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']); |
125 | } | 125 | } |
@@ -148,13 +148,13 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
148 | public function testBuildDataCount() | 148 | public function testBuildDataCount() |
149 | { | 149 | { |
150 | $criteria = array( | 150 | $criteria = array( |
151 | 'nb' => '1', | 151 | 'nb' => '3', |
152 | ); | 152 | ); |
153 | $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false); | 153 | $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false); |
154 | $feedBuilder->setLocale(self::$LOCALE); | 154 | $feedBuilder->setLocale(self::$LOCALE); |
155 | $data = $feedBuilder->buildData(); | 155 | $data = $feedBuilder->buildData(); |
156 | $this->assertEquals(1, count($data['links'])); | 156 | $this->assertEquals(3, count($data['links'])); |
157 | $link = array_shift($data['links']); | 157 | $link = $data['links'][array_keys($data['links'])[2]]; |
158 | $this->assertEquals(41, $link['id']); | 158 | $this->assertEquals(41, $link['id']); |
159 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); | 159 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); |
160 | } | 160 | } |
@@ -171,7 +171,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
171 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); | 171 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); |
172 | $this->assertTrue($data['usepermalinks']); | 172 | $this->assertTrue($data['usepermalinks']); |
173 | // First link is a permalink | 173 | // First link is a permalink |
174 | $link = array_shift($data['links']); | 174 | $link = $data['links'][array_keys($data['links'])[2]]; |
175 | $this->assertEquals(41, $link['id']); | 175 | $this->assertEquals(41, $link['id']); |
176 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); | 176 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); |
177 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); | 177 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); |
@@ -179,7 +179,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
179 | $this->assertContains('Direct link', $link['description']); | 179 | $this->assertContains('Direct link', $link['description']); |
180 | $this->assertContains('http://host.tld/?WDWyig', $link['description']); | 180 | $this->assertContains('http://host.tld/?WDWyig', $link['description']); |
181 | // Second link is a direct link | 181 | // Second link is a direct link |
182 | $link = array_shift($data['links']); | 182 | $link = $data['links'][array_keys($data['links'])[3]]; |
183 | $this->assertEquals(8, $link['id']); | 183 | $this->assertEquals(8, $link['id']); |
184 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']); | 184 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']); |
185 | $this->assertEquals('http://host.tld/?RttfEw', $link['guid']); | 185 | $this->assertEquals('http://host.tld/?RttfEw', $link['guid']); |
@@ -237,7 +237,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
237 | ); | 237 | ); |
238 | 238 | ||
239 | // Test first link (note link) | 239 | // Test first link (note link) |
240 | $link = array_shift($data['links']); | 240 | $link = $data['links'][array_keys($data['links'])[2]]; |
241 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']); | 241 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']); |
242 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']); | 242 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']); |
243 | $this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']); | 243 | $this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']); |
diff --git a/tests/HttpUtils/ClientIpIdTest.php b/tests/HttpUtils/ClientIpIdTest.php new file mode 100644 index 00000000..c15ac5cc --- /dev/null +++ b/tests/HttpUtils/ClientIpIdTest.php | |||
@@ -0,0 +1,52 @@ | |||
1 | <?php | ||
2 | /** | ||
3 | * HttpUtils' tests | ||
4 | */ | ||
5 | |||
6 | require_once 'application/HttpUtils.php'; | ||
7 | |||
8 | /** | ||
9 | * Unitary tests for client_ip_id() | ||
10 | */ | ||
11 | class ClientIpIdTest extends PHPUnit_Framework_TestCase | ||
12 | { | ||
13 | /** | ||
14 | * Get a remote client ID based on its IP | ||
15 | */ | ||
16 | public function testClientIpIdRemote() | ||
17 | { | ||
18 | $this->assertEquals( | ||
19 | '10.1.167.42', | ||
20 | client_ip_id(['REMOTE_ADDR' => '10.1.167.42']) | ||
21 | ); | ||
22 | } | ||
23 | |||
24 | /** | ||
25 | * Get a remote client ID based on its IP and proxy information (1) | ||
26 | */ | ||
27 | public function testClientIpIdRemoteForwarded() | ||
28 | { | ||
29 | $this->assertEquals( | ||
30 | '10.1.167.42_127.0.1.47', | ||
31 | client_ip_id([ | ||
32 | 'REMOTE_ADDR' => '10.1.167.42', | ||
33 | 'HTTP_X_FORWARDED_FOR' => '127.0.1.47' | ||
34 | ]) | ||
35 | ); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * Get a remote client ID based on its IP and proxy information (2) | ||
40 | */ | ||
41 | public function testClientIpIdRemoteForwardedClient() | ||
42 | { | ||
43 | $this->assertEquals( | ||
44 | '10.1.167.42_10.1.167.56_127.0.1.47', | ||
45 | client_ip_id([ | ||
46 | 'REMOTE_ADDR' => '10.1.167.42', | ||
47 | 'HTTP_X_FORWARDED_FOR' => '10.1.167.56', | ||
48 | 'HTTP_CLIENT_IP' => '127.0.1.47' | ||
49 | ]) | ||
50 | ); | ||
51 | } | ||
52 | } | ||
diff --git a/tests/HttpUtils/GetIpAdressFromProxyTest.php b/tests/HttpUtils/GetIpAdressFromProxyTest.php index 6a74a45a..7af5bd9d 100644 --- a/tests/HttpUtils/GetIpAdressFromProxyTest.php +++ b/tests/HttpUtils/GetIpAdressFromProxyTest.php | |||
@@ -5,7 +5,8 @@ require_once 'application/HttpUtils.php'; | |||
5 | /** | 5 | /** |
6 | * Unitary tests for getIpAddressFromProxy() | 6 | * Unitary tests for getIpAddressFromProxy() |
7 | */ | 7 | */ |
8 | class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase { | 8 | class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase |
9 | { | ||
9 | 10 | ||
10 | /** | 11 | /** |
11 | * Test without proxy | 12 | * Test without proxy |
diff --git a/tests/LanguagesTest.php b/tests/LanguagesTest.php index 864ce630..4951e09a 100644 --- a/tests/LanguagesTest.php +++ b/tests/LanguagesTest.php | |||
@@ -176,6 +176,32 @@ class LanguagesTest extends \PHPUnit_Framework_TestCase | |||
176 | } | 176 | } |
177 | 177 | ||
178 | /** | 178 | /** |
179 | * Test t() with an extension language file coming from the theme in gettext mode | ||
180 | */ | ||
181 | public function testTranslationThemeExtensionGettext() | ||
182 | { | ||
183 | $this->conf->set('translation.mode', 'gettext'); | ||
184 | $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); | ||
185 | $this->conf->set('theme', 'dummy'); | ||
186 | new Languages('en', $this->conf); | ||
187 | $txt = 'rooster'; // ignore me poedit | ||
188 | $this->assertEquals('rooster', t($txt, $txt, 1, 'dummy')); | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * Test t() with an extension language file coming from the theme in PHP mode | ||
193 | */ | ||
194 | public function testTranslationThemeExtensionPhp() | ||
195 | { | ||
196 | $this->conf->set('translation.mode', 'php'); | ||
197 | $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); | ||
198 | $this->conf->set('theme', 'dummy'); | ||
199 | new Languages('en', $this->conf); | ||
200 | $txt = 'rooster'; // ignore me poedit | ||
201 | $this->assertEquals('rooster', t($txt, $txt, 1, 'dummy')); | ||
202 | } | ||
203 | |||
204 | /** | ||
179 | * Test t() with an extension language file in gettext mode | 205 | * Test t() with an extension language file in gettext mode |
180 | */ | 206 | */ |
181 | public function testTranslationExtensionGettext() | 207 | public function testTranslationExtensionGettext() |
diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index 5b2f3667..c763c0cb 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php | |||
@@ -239,12 +239,12 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
239 | public function testDays() | 239 | public function testDays() |
240 | { | 240 | { |
241 | $this->assertEquals( | 241 | $this->assertEquals( |
242 | array('20100310', '20121206', '20130614', '20150310'), | 242 | array('20100309', '20100310', '20121206', '20121207', '20130614', '20150310'), |
243 | self::$publicLinkDB->days() | 243 | self::$publicLinkDB->days() |
244 | ); | 244 | ); |
245 | 245 | ||
246 | $this->assertEquals( | 246 | $this->assertEquals( |
247 | array('20100310', '20121206', '20130614', '20141125', '20150310'), | 247 | array('20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'), |
248 | self::$privateLinkDB->days() | 248 | self::$privateLinkDB->days() |
249 | ); | 249 | ); |
250 | } | 250 | } |
@@ -362,7 +362,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
362 | public function testLinkRealUrlWithoutRedirector() | 362 | public function testLinkRealUrlWithoutRedirector() |
363 | { | 363 | { |
364 | $db = new LinkDB(self::$testDatastore, false, false); | 364 | $db = new LinkDB(self::$testDatastore, false, false); |
365 | foreach($db as $link) { | 365 | foreach ($db as $link) { |
366 | $this->assertEquals($link['url'], $link['real_url']); | 366 | $this->assertEquals($link['url'], $link['real_url']); |
367 | } | 367 | } |
368 | } | 368 | } |
@@ -374,13 +374,13 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
374 | { | 374 | { |
375 | $redirector = 'http://redirector.to?'; | 375 | $redirector = 'http://redirector.to?'; |
376 | $db = new LinkDB(self::$testDatastore, false, false, $redirector); | 376 | $db = new LinkDB(self::$testDatastore, false, false, $redirector); |
377 | foreach($db as $link) { | 377 | foreach ($db as $link) { |
378 | $this->assertStringStartsWith($redirector, $link['real_url']); | 378 | $this->assertStringStartsWith($redirector, $link['real_url']); |
379 | $this->assertNotFalse(strpos($link['real_url'], urlencode('://'))); | 379 | $this->assertNotFalse(strpos($link['real_url'], urlencode('://'))); |
380 | } | 380 | } |
381 | 381 | ||
382 | $db = new LinkDB(self::$testDatastore, false, false, $redirector, false); | 382 | $db = new LinkDB(self::$testDatastore, false, false, $redirector, false); |
383 | foreach($db as $link) { | 383 | foreach ($db as $link) { |
384 | $this->assertStringStartsWith($redirector, $link['real_url']); | 384 | $this->assertStringStartsWith($redirector, $link['real_url']); |
385 | $this->assertFalse(strpos($link['real_url'], urlencode('://'))); | 385 | $this->assertFalse(strpos($link['real_url'], urlencode('://'))); |
386 | } | 386 | } |
@@ -475,13 +475,15 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
475 | public function testReorderLinksDesc() | 475 | public function testReorderLinksDesc() |
476 | { | 476 | { |
477 | self::$privateLinkDB->reorder('ASC'); | 477 | self::$privateLinkDB->reorder('ASC'); |
478 | $linkIds = array(42, 4, 9, 1, 0, 7, 6, 8, 41); | 478 | $stickyIds = [11, 10]; |
479 | $standardIds = [42, 4, 9, 1, 0, 7, 6, 8, 41]; | ||
480 | $linkIds = array_merge($stickyIds, $standardIds); | ||
479 | $cpt = 0; | 481 | $cpt = 0; |
480 | foreach (self::$privateLinkDB as $key => $value) { | 482 | foreach (self::$privateLinkDB as $key => $value) { |
481 | $this->assertEquals($linkIds[$cpt++], $key); | 483 | $this->assertEquals($linkIds[$cpt++], $key); |
482 | } | 484 | } |
483 | self::$privateLinkDB->reorder('DESC'); | 485 | self::$privateLinkDB->reorder('DESC'); |
484 | $linkIds = array_reverse($linkIds); | 486 | $linkIds = array_merge(array_reverse($stickyIds), array_reverse($standardIds)); |
485 | $cpt = 0; | 487 | $cpt = 0; |
486 | foreach (self::$privateLinkDB as $key => $value) { | 488 | foreach (self::$privateLinkDB as $key => $value) { |
487 | $this->assertEquals($linkIds[$cpt++], $key); | 489 | $this->assertEquals($linkIds[$cpt++], $key); |
@@ -542,4 +544,104 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
542 | $this->assertEquals(3, count($res)); | 544 | $this->assertEquals(3, count($res)); |
543 | $this->assertNotContains('cartoon', $linkDB[4]['tags']); | 545 | $this->assertNotContains('cartoon', $linkDB[4]['tags']); |
544 | } | 546 | } |
547 | |||
548 | /** | ||
549 | * Test linksCountPerTag all tags without filter. | ||
550 | * Equal occurrences should be sorted alphabetically. | ||
551 | */ | ||
552 | public function testCountLinkPerTagAllNoFilter() | ||
553 | { | ||
554 | $expected = [ | ||
555 | 'web' => 4, | ||
556 | 'cartoon' => 3, | ||
557 | 'dev' => 2, | ||
558 | 'gnu' => 2, | ||
559 | 'hashtag' => 2, | ||
560 | 'sTuff' => 2, | ||
561 | '-exclude' => 1, | ||
562 | '.hidden' => 1, | ||
563 | 'Mercurial' => 1, | ||
564 | 'css' => 1, | ||
565 | 'free' => 1, | ||
566 | 'html' => 1, | ||
567 | 'media' => 1, | ||
568 | 'samba' => 1, | ||
569 | 'software' => 1, | ||
570 | 'stallman' => 1, | ||
571 | 'tag1' => 1, | ||
572 | 'tag2' => 1, | ||
573 | 'tag3' => 1, | ||
574 | 'tag4' => 1, | ||
575 | 'ut' => 1, | ||
576 | 'w3c' => 1, | ||
577 | ]; | ||
578 | $tags = self::$privateLinkDB->linksCountPerTag(); | ||
579 | |||
580 | $this->assertEquals($expected, $tags, var_export($tags, true)); | ||
581 | } | ||
582 | |||
583 | /** | ||
584 | * Test linksCountPerTag all tags with filter. | ||
585 | * Equal occurrences should be sorted alphabetically. | ||
586 | */ | ||
587 | public function testCountLinkPerTagAllWithFilter() | ||
588 | { | ||
589 | $expected = [ | ||
590 | 'gnu' => 2, | ||
591 | 'hashtag' => 2, | ||
592 | '-exclude' => 1, | ||
593 | '.hidden' => 1, | ||
594 | 'free' => 1, | ||
595 | 'media' => 1, | ||
596 | 'software' => 1, | ||
597 | 'stallman' => 1, | ||
598 | 'stuff' => 1, | ||
599 | 'web' => 1, | ||
600 | ]; | ||
601 | $tags = self::$privateLinkDB->linksCountPerTag(['gnu']); | ||
602 | |||
603 | $this->assertEquals($expected, $tags, var_export($tags, true)); | ||
604 | } | ||
605 | |||
606 | /** | ||
607 | * Test linksCountPerTag public tags with filter. | ||
608 | * Equal occurrences should be sorted alphabetically. | ||
609 | */ | ||
610 | public function testCountLinkPerTagPublicWithFilter() | ||
611 | { | ||
612 | $expected = [ | ||
613 | 'gnu' => 2, | ||
614 | 'hashtag' => 2, | ||
615 | '-exclude' => 1, | ||
616 | '.hidden' => 1, | ||
617 | 'free' => 1, | ||
618 | 'media' => 1, | ||
619 | 'software' => 1, | ||
620 | 'stallman' => 1, | ||
621 | 'stuff' => 1, | ||
622 | 'web' => 1, | ||
623 | ]; | ||
624 | $tags = self::$privateLinkDB->linksCountPerTag(['gnu'], 'public'); | ||
625 | |||
626 | $this->assertEquals($expected, $tags, var_export($tags, true)); | ||
627 | } | ||
628 | |||
629 | /** | ||
630 | * Test linksCountPerTag public tags with filter. | ||
631 | * Equal occurrences should be sorted alphabetically. | ||
632 | */ | ||
633 | public function testCountLinkPerTagPrivateWithFilter() | ||
634 | { | ||
635 | $expected = [ | ||
636 | 'cartoon' => 1, | ||
637 | 'dev' => 1, | ||
638 | 'tag1' => 1, | ||
639 | 'tag2' => 1, | ||
640 | 'tag3' => 1, | ||
641 | 'tag4' => 1, | ||
642 | ]; | ||
643 | $tags = self::$privateLinkDB->linksCountPerTag(['dev'], 'private'); | ||
644 | |||
645 | $this->assertEquals($expected, $tags, var_export($tags, true)); | ||
646 | } | ||
545 | } | 647 | } |
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php index 9cd6dbd4..eb54c359 100644 --- a/tests/LinkFilterTest.php +++ b/tests/LinkFilterTest.php | |||
@@ -76,7 +76,15 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
76 | 76 | ||
77 | $this->assertEquals( | 77 | $this->assertEquals( |
78 | self::$refDB->countUntaggedLinks(), | 78 | self::$refDB->countUntaggedLinks(), |
79 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, /*$request=*/'', /*$casesensitive=*/false, /*$visibility=*/'all', /*$untaggedonly=*/true)) | 79 | count( |
80 | self::$linkFilter->filter( | ||
81 | LinkFilter::$FILTER_TAG, | ||
82 | /*$request=*/'', | ||
83 | /*$casesensitive=*/false, | ||
84 | /*$visibility=*/'all', | ||
85 | /*$untaggedonly=*/true | ||
86 | ) | ||
87 | ) | ||
80 | ); | 88 | ); |
81 | 89 | ||
82 | $this->assertEquals( | 90 | $this->assertEquals( |
@@ -246,7 +254,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
246 | 2, | 254 | 2, |
247 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org')) | 255 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org')) |
248 | ); | 256 | ); |
249 | 257 | ||
250 | $this->assertEquals( | 258 | $this->assertEquals( |
251 | 2, | 259 | 2, |
252 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org')) | 260 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org')) |
@@ -288,16 +296,16 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
288 | 1, | 296 | 1, |
289 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media')) | 297 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media')) |
290 | ); | 298 | ); |
291 | 299 | ||
292 | $this->assertEquals( | 300 | $this->assertEquals( |
293 | 1, | 301 | 1, |
294 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c')) | 302 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c')) |
295 | ); | 303 | ); |
296 | 304 | ||
297 | $this->assertEquals( | 305 | $this->assertEquals( |
298 | 3, | 306 | 3, |
299 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"')) | 307 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"')) |
300 | ); | 308 | ); |
301 | } | 309 | } |
302 | 310 | ||
303 | /** | 311 | /** |
diff --git a/tests/LinkUtilsTest.php b/tests/LinkUtilsTest.php index 7fbd59b0..5407159a 100644 --- a/tests/LinkUtilsTest.php +++ b/tests/LinkUtilsTest.php | |||
@@ -83,7 +83,9 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase | |||
83 | 'Date: Sat, 28 Oct 2017 12:01:33 GMT', | 83 | 'Date: Sat, 28 Oct 2017 12:01:33 GMT', |
84 | 'Content-Type: text/html; charset=utf-8', | 84 | 'Content-Type: text/html; charset=utf-8', |
85 | 'Status: 200 OK', | 85 | 'Status: 200 OK', |
86 | 'end' => 'th=device-width"><title>Refactoring · GitHub</title><link rel="search" type="application/opensea', | 86 | 'end' => 'th=device-width">' |
87 | .'<title>Refactoring · GitHub</title>' | ||
88 | .'<link rel="search" type="application/opensea', | ||
87 | '<title>ignored</title>', | 89 | '<title>ignored</title>', |
88 | ]; | 90 | ]; |
89 | foreach ($data as $key => $line) { | 91 | foreach ($data as $key => $line) { |
@@ -106,7 +108,9 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase | |||
106 | $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_no_charset'); | 108 | $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_no_charset'); |
107 | $data = [ | 109 | $data = [ |
108 | 'HTTP/1.1 200 OK', | 110 | 'HTTP/1.1 200 OK', |
109 | 'end' => 'th=device-width"><title>Refactoring · GitHub</title><link rel="search" type="application/opensea', | 111 | 'end' => 'th=device-width">' |
112 | .'<title>Refactoring · GitHub</title>' | ||
113 | .'<link rel="search" type="application/opensea', | ||
110 | '<title>ignored</title>', | 114 | '<title>ignored</title>', |
111 | ]; | 115 | ]; |
112 | foreach ($data as $key => $line) { | 116 | foreach ($data as $key => $line) { |
@@ -126,7 +130,9 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase | |||
126 | $data = [ | 130 | $data = [ |
127 | 'HTTP/1.1 200 OK', | 131 | 'HTTP/1.1 200 OK', |
128 | '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', | 132 | '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', |
129 | 'end' => 'th=device-width"><title>Refactoring · GitHub</title><link rel="search" type="application/opensea', | 133 | 'end' => 'th=device-width">' |
134 | .'<title>Refactoring · GitHub</title>' | ||
135 | .'<link rel="search" type="application/opensea', | ||
130 | '<title>ignored</title>', | 136 | '<title>ignored</title>', |
131 | ]; | 137 | ]; |
132 | foreach ($data as $key => $line) { | 138 | foreach ($data as $key => $line) { |
@@ -211,23 +217,26 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase | |||
211 | public function testText2clickableWithoutRedirector() | 217 | public function testText2clickableWithoutRedirector() |
212 | { | 218 | { |
213 | $text = 'stuff http://hello.there/is=someone#here otherstuff'; | 219 | $text = 'stuff http://hello.there/is=someone#here otherstuff'; |
214 | $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff'; | 220 | $expectedText = 'stuff <a href="http://hello.there/is=someone#here">' |
221 | .'http://hello.there/is=someone#here</a> otherstuff'; | ||
215 | $processedText = text2clickable($text, ''); | 222 | $processedText = text2clickable($text, ''); |
216 | $this->assertEquals($expectedText, $processedText); | 223 | $this->assertEquals($expectedText, $processedText); |
217 | 224 | ||
218 | $text = 'stuff http://hello.there/is=someone#here(please) otherstuff'; | 225 | $text = 'stuff http://hello.there/is=someone#here(please) otherstuff'; |
219 | $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)">http://hello.there/is=someone#here(please)</a> otherstuff'; | 226 | $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)">' |
227 | .'http://hello.there/is=someone#here(please)</a> otherstuff'; | ||
220 | $processedText = text2clickable($text, ''); | 228 | $processedText = text2clickable($text, ''); |
221 | $this->assertEquals($expectedText, $processedText); | 229 | $this->assertEquals($expectedText, $processedText); |
222 | 230 | ||
223 | $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff'; | 231 | $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff'; |
224 | $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)&no">http://hello.there/is=someone#here(please)&no</a> otherstuff'; | 232 | $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)&no">' |
233 | .'http://hello.there/is=someone#here(please)&no</a> otherstuff'; | ||
225 | $processedText = text2clickable($text, ''); | 234 | $processedText = text2clickable($text, ''); |
226 | $this->assertEquals($expectedText, $processedText); | 235 | $this->assertEquals($expectedText, $processedText); |
227 | } | 236 | } |
228 | 237 | ||
229 | /** | 238 | /** |
230 | * Test text2clickable a redirector set. | 239 | * Test text2clickable with a redirector set. |
231 | */ | 240 | */ |
232 | public function testText2clickableWithRedirector() | 241 | public function testText2clickableWithRedirector() |
233 | { | 242 | { |
@@ -410,4 +419,3 @@ function ut_curl_getinfo_rs_ct_ko($ch, $type) | |||
410 | return 'text/plain'; | 419 | return 'text/plain'; |
411 | } | 420 | } |
412 | } | 421 | } |
413 | |||
diff --git a/tests/NetscapeBookmarkUtils/BookmarkExportTest.php b/tests/NetscapeBookmarkUtils/BookmarkExportTest.php index 6a47bbb9..77fbd5f3 100644 --- a/tests/NetscapeBookmarkUtils/BookmarkExportTest.php +++ b/tests/NetscapeBookmarkUtils/BookmarkExportTest.php | |||
@@ -110,7 +110,7 @@ class BookmarkExportTest extends PHPUnit_Framework_TestCase | |||
110 | $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, ''); | 110 | $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, ''); |
111 | $this->assertEquals( | 111 | $this->assertEquals( |
112 | '?WDWyig', | 112 | '?WDWyig', |
113 | $links[0]['url'] | 113 | $links[2]['url'] |
114 | ); | 114 | ); |
115 | } | 115 | } |
116 | 116 | ||
@@ -128,7 +128,7 @@ class BookmarkExportTest extends PHPUnit_Framework_TestCase | |||
128 | ); | 128 | ); |
129 | $this->assertEquals( | 129 | $this->assertEquals( |
130 | $indexUrl . '?WDWyig', | 130 | $indexUrl . '?WDWyig', |
131 | $links[0]['url'] | 131 | $links[2]['url'] |
132 | ); | 132 | ); |
133 | } | 133 | } |
134 | } | 134 | } |
diff --git a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php index 4961aa2c..f0a958cb 100644 --- a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php +++ b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php | |||
@@ -127,6 +127,21 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase | |||
127 | } | 127 | } |
128 | 128 | ||
129 | /** | 129 | /** |
130 | * Attempt to import bookmarks from a file with a lowercase Doctype | ||
131 | */ | ||
132 | public function testImportLowecaseDoctype() | ||
133 | { | ||
134 | $files = file2array('lowercase_doctype.htm'); | ||
135 | $this->assertStringMatchesFormat( | ||
136 | 'File lowercase_doctype.htm (386 bytes) was successfully processed in %d seconds:' | ||
137 | .' 2 links imported, 0 links overwritten, 0 links skipped.', | ||
138 | NetscapeBookmarkUtils::import(null, $files, $this->linkDb, $this->conf, $this->history) | ||
139 | ); | ||
140 | $this->assertEquals(2, count($this->linkDb)); | ||
141 | } | ||
142 | |||
143 | |||
144 | /** | ||
130 | * Ensure IE dumps are supported | 145 | * Ensure IE dumps are supported |
131 | */ | 146 | */ |
132 | public function testImportInternetExplorerEncoding() | 147 | public function testImportInternetExplorerEncoding() |
diff --git a/tests/NetscapeBookmarkUtils/input/lowercase_doctype.htm b/tests/NetscapeBookmarkUtils/input/lowercase_doctype.htm new file mode 100644 index 00000000..8911ad19 --- /dev/null +++ b/tests/NetscapeBookmarkUtils/input/lowercase_doctype.htm | |||
@@ -0,0 +1,8 @@ | |||
1 | <!DOCTYPE netscape-bookmark-file-1> | ||
2 | <TITLE>Bookmarks</TITLE> | ||
3 | <H1>Bookmarks</H1> | ||
4 | <DL><p> | ||
5 | <DT><A HREF="https://private.tld" ADD_DATE="10/Oct/2000:13:55:36 +0300" PRIVATE="1" TAGS="private secret">Secret stuff</A> | ||
6 | <DD>Super-secret stuff you're not supposed to know about | ||
7 | <DT><A HREF="http://public.tld" ADD_DATE="1456433748" PRIVATE="0" TAGS="public hello world">Public stuff</A> | ||
8 | </DL><p> | ||
diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 544bcf9c..abf1bd5f 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php | |||
@@ -218,7 +218,6 @@ class RouterTest extends PHPUnit_Framework_TestCase | |||
218 | Router::$PAGE_CHANGEPASSWORD, | 218 | Router::$PAGE_CHANGEPASSWORD, |
219 | Router::findPage('do=changepasswd&stuff', array(), true) | 219 | Router::findPage('do=changepasswd&stuff', array(), true) |
220 | ); | 220 | ); |
221 | |||
222 | } | 221 | } |
223 | 222 | ||
224 | /** | 223 | /** |
diff --git a/tests/SessionManagerTest.php b/tests/SessionManagerTest.php deleted file mode 100644 index aa75962a..00000000 --- a/tests/SessionManagerTest.php +++ /dev/null | |||
@@ -1,149 +0,0 @@ | |||
1 | <?php | ||
2 | require_once 'tests/utils/FakeConfigManager.php'; | ||
3 | |||
4 | // Initialize reference data _before_ PHPUnit starts a session | ||
5 | require_once 'tests/utils/ReferenceSessionIdHashes.php'; | ||
6 | ReferenceSessionIdHashes::genAllHashes(); | ||
7 | |||
8 | use \Shaarli\SessionManager; | ||
9 | use \PHPUnit\Framework\TestCase; | ||
10 | |||
11 | |||
12 | /** | ||
13 | * Test coverage for SessionManager | ||
14 | */ | ||
15 | class SessionManagerTest extends TestCase | ||
16 | { | ||
17 | // Session ID hashes | ||
18 | protected static $sidHashes = null; | ||
19 | |||
20 | // Fake ConfigManager | ||
21 | protected static $conf = null; | ||
22 | |||
23 | /** | ||
24 | * Assign reference data | ||
25 | */ | ||
26 | public static function setUpBeforeClass() | ||
27 | { | ||
28 | self::$sidHashes = ReferenceSessionIdHashes::getHashes(); | ||
29 | self::$conf = new FakeConfigManager(); | ||
30 | } | ||
31 | |||
32 | /** | ||
33 | * Generate a session token | ||
34 | */ | ||
35 | public function testGenerateToken() | ||
36 | { | ||
37 | $session = []; | ||
38 | $sessionManager = new SessionManager($session, self::$conf); | ||
39 | |||
40 | $token = $sessionManager->generateToken(); | ||
41 | |||
42 | $this->assertEquals(1, $session['tokens'][$token]); | ||
43 | $this->assertEquals(40, strlen($token)); | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * Check a session token | ||
48 | */ | ||
49 | public function testCheckToken() | ||
50 | { | ||
51 | $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'; | ||
52 | $session = [ | ||
53 | 'tokens' => [ | ||
54 | $token => 1, | ||
55 | ], | ||
56 | ]; | ||
57 | $sessionManager = new SessionManager($session, self::$conf); | ||
58 | |||
59 | // check and destroy the token | ||
60 | $this->assertTrue($sessionManager->checkToken($token)); | ||
61 | $this->assertFalse(isset($session['tokens'][$token])); | ||
62 | |||
63 | // ensure the token has been destroyed | ||
64 | $this->assertFalse($sessionManager->checkToken($token)); | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * Generate and check a session token | ||
69 | */ | ||
70 | public function testGenerateAndCheckToken() | ||
71 | { | ||
72 | $session = []; | ||
73 | $sessionManager = new SessionManager($session, self::$conf); | ||
74 | |||
75 | $token = $sessionManager->generateToken(); | ||
76 | |||
77 | // ensure a token has been generated | ||
78 | $this->assertEquals(1, $session['tokens'][$token]); | ||
79 | $this->assertEquals(40, strlen($token)); | ||
80 | |||
81 | // check and destroy the token | ||
82 | $this->assertTrue($sessionManager->checkToken($token)); | ||
83 | $this->assertFalse(isset($session['tokens'][$token])); | ||
84 | |||
85 | // ensure the token has been destroyed | ||
86 | $this->assertFalse($sessionManager->checkToken($token)); | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * Check an invalid session token | ||
91 | */ | ||
92 | public function testCheckInvalidToken() | ||
93 | { | ||
94 | $session = []; | ||
95 | $sessionManager = new SessionManager($session, self::$conf); | ||
96 | |||
97 | $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES! | ||
102 | * | ||
103 | * This tests extensively covers all hash algorithms / bit representations | ||
104 | */ | ||
105 | public function testIsAnyHashSessionIdValid() | ||
106 | { | ||
107 | foreach (self::$sidHashes as $algo => $bpcs) { | ||
108 | foreach ($bpcs as $bpc => $hash) { | ||
109 | $this->assertTrue(SessionManager::checkId($hash)); | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Test checkId with a valid ID - SHA-1 hashes | ||
116 | */ | ||
117 | public function testIsSha1SessionIdValid() | ||
118 | { | ||
119 | $this->assertTrue(SessionManager::checkId(sha1('shaarli'))); | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * Test checkId with a valid ID - SHA-256 hashes | ||
124 | */ | ||
125 | public function testIsSha256SessionIdValid() | ||
126 | { | ||
127 | $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli'))); | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * Test checkId with a valid ID - SHA-512 hashes | ||
132 | */ | ||
133 | public function testIsSha512SessionIdValid() | ||
134 | { | ||
135 | $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli'))); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * Test checkId with invalid IDs. | ||
140 | */ | ||
141 | public function testIsSessionIdInvalid() | ||
142 | { | ||
143 | $this->assertFalse(SessionManager::checkId('')); | ||
144 | $this->assertFalse(SessionManager::checkId([])); | ||
145 | $this->assertFalse( | ||
146 | SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') | ||
147 | ); | ||
148 | } | ||
149 | } | ||
diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php new file mode 100644 index 00000000..c01849f7 --- /dev/null +++ b/tests/ThumbnailerTest.php | |||
@@ -0,0 +1,116 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Shaarli; | ||
4 | |||
5 | use PHPUnit\Framework\TestCase; | ||
6 | use Shaarli\Config\ConfigManager; | ||
7 | use WebThumbnailer\Application\ConfigManager as WTConfigManager; | ||
8 | |||
9 | /** | ||
10 | * Class ThumbnailerTest | ||
11 | * | ||
12 | * We only make 1 thumb test because: | ||
13 | * | ||
14 | * 1. the thumbnailer library is itself tested | ||
15 | * 2. we don't want to make too many external requests during the tests | ||
16 | */ | ||
17 | class ThumbnailerTest extends TestCase | ||
18 | { | ||
19 | const WIDTH = 190; | ||
20 | |||
21 | const HEIGHT = 210; | ||
22 | |||
23 | /** | ||
24 | * @var Thumbnailer; | ||
25 | */ | ||
26 | protected $thumbnailer; | ||
27 | |||
28 | /** | ||
29 | * @var ConfigManager | ||
30 | */ | ||
31 | protected $conf; | ||
32 | |||
33 | public function setUp() | ||
34 | { | ||
35 | $this->conf = new ConfigManager('tests/utils/config/configJson'); | ||
36 | $this->conf->set('thumbnails.mode', Thumbnailer::MODE_ALL); | ||
37 | $this->conf->set('thumbnails.width', self::WIDTH); | ||
38 | $this->conf->set('thumbnails.height', self::HEIGHT); | ||
39 | $this->conf->set('dev.debug', true); | ||
40 | |||
41 | $this->thumbnailer = new Thumbnailer($this->conf); | ||
42 | // cache files in the sandbox | ||
43 | WTConfigManager::addFile('tests/utils/config/wt.json'); | ||
44 | } | ||
45 | |||
46 | public function tearDown() | ||
47 | { | ||
48 | $this->rrmdirContent('sandbox/'); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * Test a thumbnail with a custom size in 'all' mode. | ||
53 | */ | ||
54 | public function testThumbnailAllValid() | ||
55 | { | ||
56 | $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/'); | ||
57 | $this->assertNotFalse($thumb); | ||
58 | $image = imagecreatefromstring(file_get_contents($thumb)); | ||
59 | $this->assertEquals(self::WIDTH, imagesx($image)); | ||
60 | $this->assertEquals(self::HEIGHT, imagesy($image)); | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * Test a thumbnail with a custom size in 'common' mode. | ||
65 | */ | ||
66 | public function testThumbnailCommonValid() | ||
67 | { | ||
68 | $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON); | ||
69 | $thumb = $this->thumbnailer->get('https://imgur.com/jlFgGpe'); | ||
70 | $this->assertNotFalse($thumb); | ||
71 | $image = imagecreatefromstring(file_get_contents($thumb)); | ||
72 | $this->assertEquals(self::WIDTH, imagesx($image)); | ||
73 | $this->assertEquals(self::HEIGHT, imagesy($image)); | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Test a thumbnail in 'common' mode which isn't include in common websites. | ||
78 | */ | ||
79 | public function testThumbnailCommonInvalid() | ||
80 | { | ||
81 | $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON); | ||
82 | $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/'); | ||
83 | $this->assertFalse($thumb); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Test a thumbnail that can't be retrieved. | ||
88 | */ | ||
89 | public function testThumbnailNotValid() | ||
90 | { | ||
91 | $oldlog = ini_get('error_log'); | ||
92 | ini_set('error_log', '/dev/null'); | ||
93 | |||
94 | $thumbnailer = new Thumbnailer(new ConfigManager()); | ||
95 | $thumb = $thumbnailer->get('nope'); | ||
96 | $this->assertFalse($thumb); | ||
97 | |||
98 | ini_set('error_log', $oldlog); | ||
99 | } | ||
100 | |||
101 | protected function rrmdirContent($dir) | ||
102 | { | ||
103 | if (is_dir($dir)) { | ||
104 | $objects = scandir($dir); | ||
105 | foreach ($objects as $object) { | ||
106 | if ($object != "." && $object != "..") { | ||
107 | if (is_dir($dir."/".$object)) { | ||
108 | $this->rrmdirContent($dir."/".$object); | ||
109 | } else { | ||
110 | unlink($dir."/".$object); | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | } | ||
diff --git a/tests/Updater/DummyUpdater.php b/tests/Updater/DummyUpdater.php index a0be4413..a805ab5e 100644 --- a/tests/Updater/DummyUpdater.php +++ b/tests/Updater/DummyUpdater.php | |||
@@ -31,7 +31,7 @@ class DummyUpdater extends Updater | |||
31 | * | 31 | * |
32 | * @return bool true. | 32 | * @return bool true. |
33 | */ | 33 | */ |
34 | private final function updateMethodDummy1() | 34 | final private function updateMethodDummy1() |
35 | { | 35 | { |
36 | return true; | 36 | return true; |
37 | } | 37 | } |
@@ -41,7 +41,7 @@ class DummyUpdater extends Updater | |||
41 | * | 41 | * |
42 | * @return bool true. | 42 | * @return bool true. |
43 | */ | 43 | */ |
44 | private final function updateMethodDummy2() | 44 | final private function updateMethodDummy2() |
45 | { | 45 | { |
46 | return true; | 46 | return true; |
47 | } | 47 | } |
@@ -51,7 +51,7 @@ class DummyUpdater extends Updater | |||
51 | * | 51 | * |
52 | * @return bool true. | 52 | * @return bool true. |
53 | */ | 53 | */ |
54 | private final function updateMethodDummy3() | 54 | final private function updateMethodDummy3() |
55 | { | 55 | { |
56 | return true; | 56 | return true; |
57 | } | 57 | } |
@@ -61,7 +61,7 @@ class DummyUpdater extends Updater | |||
61 | * | 61 | * |
62 | * @throws Exception error. | 62 | * @throws Exception error. |
63 | */ | 63 | */ |
64 | private final function updateMethodException() | 64 | final private function updateMethodException() |
65 | { | 65 | { |
66 | throw new Exception('whatever'); | 66 | throw new Exception('whatever'); |
67 | } | 67 | } |
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 77578528..608e331d 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php | |||
@@ -2,6 +2,7 @@ | |||
2 | use Shaarli\Config\ConfigJson; | 2 | use Shaarli\Config\ConfigJson; |
3 | use Shaarli\Config\ConfigManager; | 3 | use Shaarli\Config\ConfigManager; |
4 | use Shaarli\Config\ConfigPhp; | 4 | use Shaarli\Config\ConfigPhp; |
5 | use Shaarli\Thumbnailer; | ||
5 | 6 | ||
6 | require_once 'tests/Updater/DummyUpdater.php'; | 7 | require_once 'tests/Updater/DummyUpdater.php'; |
7 | require_once 'inc/rain.tpl.class.php'; | 8 | require_once 'inc/rain.tpl.class.php'; |
@@ -20,7 +21,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
20 | /** | 21 | /** |
21 | * @var string Config file path (without extension). | 22 | * @var string Config file path (without extension). |
22 | */ | 23 | */ |
23 | protected static $configFile = 'tests/utils/config/configJson'; | 24 | protected static $configFile = 'sandbox/config'; |
24 | 25 | ||
25 | /** | 26 | /** |
26 | * @var ConfigManager | 27 | * @var ConfigManager |
@@ -32,6 +33,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase | |||
32 | */ | 33 | */ |
33 | public function setUp() | 34 | public function setUp() |
34 | { | 35 | { |
36 | copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php'); | ||
35 | $this->conf = new ConfigManager(self::$configFile); | 37 | $this->conf = new ConfigManager(self::$configFile); |
36 | } | 38 | } |
37 | 39 | ||
@@ -391,20 +393,32 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; | |||
391 | $this->assertEquals('Naming conventions... #private', $linkDB[0]['description']); | 393 | $this->assertEquals('Naming conventions... #private', $linkDB[0]['description']); |
392 | $this->assertEquals('samba cartoon web', $linkDB[0]['tags']); | 394 | $this->assertEquals('samba cartoon web', $linkDB[0]['tags']); |
393 | $this->assertTrue($linkDB[0]['private']); | 395 | $this->assertTrue($linkDB[0]['private']); |
394 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'), $linkDB[0]['created']); | 396 | $this->assertEquals( |
397 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'), | ||
398 | $linkDB[0]['created'] | ||
399 | ); | ||
395 | 400 | ||
396 | $this->assertTrue(isset($linkDB[1])); | 401 | $this->assertTrue(isset($linkDB[1])); |
397 | $this->assertFalse(isset($linkDB[1]['linkdate'])); | 402 | $this->assertFalse(isset($linkDB[1]['linkdate'])); |
398 | $this->assertEquals(1, $linkDB[1]['id']); | 403 | $this->assertEquals(1, $linkDB[1]['id']); |
399 | $this->assertEquals('UserFriendly - Samba', $linkDB[1]['title']); | 404 | $this->assertEquals('UserFriendly - Samba', $linkDB[1]['title']); |
400 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'), $linkDB[1]['created']); | 405 | $this->assertEquals( |
406 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'), | ||
407 | $linkDB[1]['created'] | ||
408 | ); | ||
401 | 409 | ||
402 | $this->assertTrue(isset($linkDB[2])); | 410 | $this->assertTrue(isset($linkDB[2])); |
403 | $this->assertFalse(isset($linkDB[2]['linkdate'])); | 411 | $this->assertFalse(isset($linkDB[2]['linkdate'])); |
404 | $this->assertEquals(2, $linkDB[2]['id']); | 412 | $this->assertEquals(2, $linkDB[2]['id']); |
405 | $this->assertEquals('Geek and Poke', $linkDB[2]['title']); | 413 | $this->assertEquals('Geek and Poke', $linkDB[2]['title']); |
406 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'), $linkDB[2]['created']); | 414 | $this->assertEquals( |
407 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_190301'), $linkDB[2]['updated']); | 415 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'), |
416 | $linkDB[2]['created'] | ||
417 | ); | ||
418 | $this->assertEquals( | ||
419 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_190301'), | ||
420 | $linkDB[2]['updated'] | ||
421 | ); | ||
408 | } | 422 | } |
409 | 423 | ||
410 | /** | 424 | /** |
@@ -619,4 +633,175 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; | |||
619 | $this->assertTrue($updater->updateMethodAtomDefault()); | 633 | $this->assertTrue($updater->updateMethodAtomDefault()); |
620 | $this->assertTrue($this->conf->get('feed.show_atom')); | 634 | $this->assertTrue($this->conf->get('feed.show_atom')); |
621 | } | 635 | } |
636 | |||
637 | /** | ||
638 | * Test updateMethodDownloadSizeAndTimeoutConf, it should be set if none is already defined. | ||
639 | */ | ||
640 | public function testUpdateMethodDownloadSizeAndTimeoutConf() | ||
641 | { | ||
642 | $sandboxConf = 'sandbox/config'; | ||
643 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | ||
644 | $this->conf = new ConfigManager($sandboxConf); | ||
645 | $updater = new Updater([], [], $this->conf, true); | ||
646 | $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); | ||
647 | $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); | ||
648 | $this->assertEquals(30, $this->conf->get('general.download_timeout')); | ||
649 | |||
650 | $this->conf = new ConfigManager($sandboxConf); | ||
651 | $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); | ||
652 | $this->assertEquals(30, $this->conf->get('general.download_timeout')); | ||
653 | } | ||
654 | |||
655 | /** | ||
656 | * Test updateMethodDownloadSizeAndTimeoutConf, it shouldn't be set if it is already defined. | ||
657 | */ | ||
658 | public function testUpdateMethodDownloadSizeAndTimeoutConfIgnore() | ||
659 | { | ||
660 | $sandboxConf = 'sandbox/config'; | ||
661 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | ||
662 | $this->conf = new ConfigManager($sandboxConf); | ||
663 | $this->conf->set('general.download_max_size', 38); | ||
664 | $this->conf->set('general.download_timeout', 70); | ||
665 | $updater = new Updater([], [], $this->conf, true); | ||
666 | $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); | ||
667 | $this->assertEquals(38, $this->conf->get('general.download_max_size')); | ||
668 | $this->assertEquals(70, $this->conf->get('general.download_timeout')); | ||
669 | } | ||
670 | |||
671 | /** | ||
672 | * Test updateMethodDownloadSizeAndTimeoutConf, only the maz size should be set here. | ||
673 | */ | ||
674 | public function testUpdateMethodDownloadSizeAndTimeoutConfOnlySize() | ||
675 | { | ||
676 | $sandboxConf = 'sandbox/config'; | ||
677 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | ||
678 | $this->conf = new ConfigManager($sandboxConf); | ||
679 | $this->conf->set('general.download_max_size', 38); | ||
680 | $updater = new Updater([], [], $this->conf, true); | ||
681 | $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); | ||
682 | $this->assertEquals(38, $this->conf->get('general.download_max_size')); | ||
683 | $this->assertEquals(30, $this->conf->get('general.download_timeout')); | ||
684 | } | ||
685 | |||
686 | /** | ||
687 | * Test updateMethodDownloadSizeAndTimeoutConf, only the time out should be set here. | ||
688 | */ | ||
689 | public function testUpdateMethodDownloadSizeAndTimeoutConfOnlyTimeout() | ||
690 | { | ||
691 | $sandboxConf = 'sandbox/config'; | ||
692 | copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); | ||
693 | $this->conf = new ConfigManager($sandboxConf); | ||
694 | $this->conf->set('general.download_timeout', 3); | ||
695 | $updater = new Updater([], [], $this->conf, true); | ||
696 | $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); | ||
697 | $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); | ||
698 | $this->assertEquals(3, $this->conf->get('general.download_timeout')); | ||
699 | } | ||
700 | |||
701 | /** | ||
702 | <<<<<<< HEAD | ||
703 | * Test updateMethodWebThumbnailer with thumbnails enabled. | ||
704 | */ | ||
705 | public function testUpdateMethodWebThumbnailerEnabled() | ||
706 | { | ||
707 | $this->conf->remove('thumbnails'); | ||
708 | $this->conf->set('thumbnail.enable_thumbnails', true); | ||
709 | $updater = new Updater([], [], $this->conf, true, $_SESSION); | ||
710 | $this->assertTrue($updater->updateMethodWebThumbnailer()); | ||
711 | $this->assertFalse($this->conf->exists('thumbnail')); | ||
712 | $this->assertEquals(\Shaarli\Thumbnailer::MODE_ALL, $this->conf->get('thumbnails.mode')); | ||
713 | $this->assertEquals(125, $this->conf->get('thumbnails.width')); | ||
714 | $this->assertEquals(90, $this->conf->get('thumbnails.height')); | ||
715 | $this->assertContains('You have enabled or changed thumbnails', $_SESSION['warnings'][0]); | ||
716 | } | ||
717 | |||
718 | /** | ||
719 | * Test updateMethodWebThumbnailer with thumbnails disabled. | ||
720 | */ | ||
721 | public function testUpdateMethodWebThumbnailerDisabled() | ||
722 | { | ||
723 | $this->conf->remove('thumbnails'); | ||
724 | $this->conf->set('thumbnail.enable_thumbnails', false); | ||
725 | $updater = new Updater([], [], $this->conf, true, $_SESSION); | ||
726 | $this->assertTrue($updater->updateMethodWebThumbnailer()); | ||
727 | $this->assertFalse($this->conf->exists('thumbnail')); | ||
728 | $this->assertEquals(Thumbnailer::MODE_NONE, $this->conf->get('thumbnails.mode')); | ||
729 | $this->assertEquals(125, $this->conf->get('thumbnails.width')); | ||
730 | $this->assertEquals(90, $this->conf->get('thumbnails.height')); | ||
731 | $this->assertTrue(empty($_SESSION['warnings'])); | ||
732 | } | ||
733 | |||
734 | /** | ||
735 | * Test updateMethodWebThumbnailer with thumbnails disabled. | ||
736 | */ | ||
737 | public function testUpdateMethodWebThumbnailerNothingToDo() | ||
738 | { | ||
739 | $updater = new Updater([], [], $this->conf, true, $_SESSION); | ||
740 | $this->assertTrue($updater->updateMethodWebThumbnailer()); | ||
741 | $this->assertFalse($this->conf->exists('thumbnail')); | ||
742 | $this->assertEquals(Thumbnailer::MODE_COMMON, $this->conf->get('thumbnails.mode')); | ||
743 | $this->assertEquals(90, $this->conf->get('thumbnails.width')); | ||
744 | $this->assertEquals(53, $this->conf->get('thumbnails.height')); | ||
745 | $this->assertTrue(empty($_SESSION['warnings'])); | ||
746 | } | ||
747 | |||
748 | /** | ||
749 | * Test updateMethodSetSticky(). | ||
750 | */ | ||
751 | public function testUpdateStickyValid() | ||
752 | { | ||
753 | $blank = [ | ||
754 | 'id' => 1, | ||
755 | 'url' => 'z', | ||
756 | 'title' => '', | ||
757 | 'description' => '', | ||
758 | 'tags' => '', | ||
759 | 'created' => new DateTime(), | ||
760 | ]; | ||
761 | $links = [ | ||
762 | 1 => ['id' => 1] + $blank, | ||
763 | 2 => ['id' => 2] + $blank, | ||
764 | ]; | ||
765 | $refDB = new ReferenceLinkDB(); | ||
766 | $refDB->setLinks($links); | ||
767 | $refDB->write(self::$testDatastore); | ||
768 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
769 | |||
770 | $updater = new Updater(array(), $linkDB, $this->conf, true); | ||
771 | $this->assertTrue($updater->updateMethodSetSticky()); | ||
772 | |||
773 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
774 | foreach ($linkDB as $link) { | ||
775 | $this->assertFalse($link['sticky']); | ||
776 | } | ||
777 | } | ||
778 | |||
779 | /** | ||
780 | * Test updateMethodSetSticky(). | ||
781 | */ | ||
782 | public function testUpdateStickyNothingToDo() | ||
783 | { | ||
784 | $blank = [ | ||
785 | 'id' => 1, | ||
786 | 'url' => 'z', | ||
787 | 'title' => '', | ||
788 | 'description' => '', | ||
789 | 'tags' => '', | ||
790 | 'created' => new DateTime(), | ||
791 | ]; | ||
792 | $links = [ | ||
793 | 1 => ['id' => 1, 'sticky' => true] + $blank, | ||
794 | 2 => ['id' => 2] + $blank, | ||
795 | ]; | ||
796 | $refDB = new ReferenceLinkDB(); | ||
797 | $refDB->setLinks($links); | ||
798 | $refDB->write(self::$testDatastore); | ||
799 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
800 | |||
801 | $updater = new Updater(array(), $linkDB, $this->conf, true); | ||
802 | $this->assertTrue($updater->updateMethodSetSticky()); | ||
803 | |||
804 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
805 | $this->assertTrue($linkDB[1]['sticky']); | ||
806 | } | ||
622 | } | 807 | } |
diff --git a/tests/Url/CleanupUrlTest.php b/tests/Url/CleanupUrlTest.php index 1407d7d2..24791948 100644 --- a/tests/Url/CleanupUrlTest.php +++ b/tests/Url/CleanupUrlTest.php | |||
@@ -107,4 +107,3 @@ class CleanupUrlTest extends PHPUnit_Framework_TestCase | |||
107 | ); | 107 | ); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | |||
diff --git a/tests/Url/GetUrlSchemeTest.php b/tests/Url/GetUrlSchemeTest.php index 72d80b30..18b932d6 100644 --- a/tests/Url/GetUrlSchemeTest.php +++ b/tests/Url/GetUrlSchemeTest.php | |||
@@ -28,4 +28,3 @@ class GetUrlSchemeTest extends PHPUnit_Framework_TestCase | |||
28 | $this->assertEquals('git', get_url_scheme('git://domain.tld/push?pull=clone#checkout')); | 28 | $this->assertEquals('git', get_url_scheme('git://domain.tld/push?pull=clone#checkout')); |
29 | } | 29 | } |
30 | } | 30 | } |
31 | |||
diff --git a/tests/Url/UnparseUrlTest.php b/tests/Url/UnparseUrlTest.php index edde73e4..e314b484 100644 --- a/tests/Url/UnparseUrlTest.php +++ b/tests/Url/UnparseUrlTest.php | |||
@@ -28,4 +28,3 @@ class UnparseUrlTest extends PHPUnit_Framework_TestCase | |||
28 | $this->assertEquals($ref, unparse_url(parse_url($ref))); | 28 | $this->assertEquals($ref, unparse_url(parse_url($ref))); |
29 | } | 29 | } |
30 | } | 30 | } |
31 | |||
diff --git a/tests/Url/UrlTest.php b/tests/Url/UrlTest.php index aa2f2234..db229ce0 100644 --- a/tests/Url/UrlTest.php +++ b/tests/Url/UrlTest.php | |||
@@ -16,7 +16,7 @@ class UrlTest extends PHPUnit_Framework_TestCase | |||
16 | /** | 16 | /** |
17 | * Helper method | 17 | * Helper method |
18 | */ | 18 | */ |
19 | private function assertUrlIsCleaned($query='', $fragment='') | 19 | private function assertUrlIsCleaned($query = '', $fragment = '') |
20 | { | 20 | { |
21 | $url = new Url(self::$baseUrl.$query.$fragment); | 21 | $url = new Url(self::$baseUrl.$query.$fragment); |
22 | $url->cleanup(); | 22 | $url->cleanup(); |
@@ -135,13 +135,13 @@ class UrlTest extends PHPUnit_Framework_TestCase | |||
135 | 'about://reader?url=' . urlencode(self::$baseUrl .'?my=stuff&is=kept') | 135 | 'about://reader?url=' . urlencode(self::$baseUrl .'?my=stuff&is=kept') |
136 | ); | 136 | ); |
137 | $this->assertEquals(self::$baseUrl.'?my=stuff&is=kept', $url->cleanup()); | 137 | $this->assertEquals(self::$baseUrl.'?my=stuff&is=kept', $url->cleanup()); |
138 | |||
139 | } | 138 | } |
140 | 139 | ||
141 | /** | 140 | /** |
142 | * Test default http scheme. | 141 | * Test default http scheme. |
143 | */ | 142 | */ |
144 | public function testDefaultScheme() { | 143 | public function testDefaultScheme() |
144 | { | ||
145 | $url = new Url(self::$baseUrl); | 145 | $url = new Url(self::$baseUrl); |
146 | $this->assertEquals('http', $url->getScheme()); | 146 | $this->assertEquals('http', $url->getScheme()); |
147 | $url = new Url('domain.tld'); | 147 | $url = new Url('domain.tld'); |
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index 6cd37a7a..d0abd996 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php | |||
@@ -187,7 +187,8 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
187 | /** | 187 | /** |
188 | * Test generate location with valid data. | 188 | * Test generate location with valid data. |
189 | */ | 189 | */ |
190 | public function testGenerateLocation() { | 190 | public function testGenerateLocation() |
191 | { | ||
191 | $ref = 'http://localhost/?test'; | 192 | $ref = 'http://localhost/?test'; |
192 | $this->assertEquals($ref, generateLocation($ref, 'localhost')); | 193 | $this->assertEquals($ref, generateLocation($ref, 'localhost')); |
193 | $ref = 'http://localhost:8080/?test'; | 194 | $ref = 'http://localhost:8080/?test'; |
@@ -199,7 +200,8 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
199 | /** | 200 | /** |
200 | * Test generate location - anti loop. | 201 | * Test generate location - anti loop. |
201 | */ | 202 | */ |
202 | public function testGenerateLocationLoop() { | 203 | public function testGenerateLocationLoop() |
204 | { | ||
203 | $ref = 'http://localhost/?test'; | 205 | $ref = 'http://localhost/?test'; |
204 | $this->assertEquals('?', generateLocation($ref, 'localhost', array('test'))); | 206 | $this->assertEquals('?', generateLocation($ref, 'localhost', array('test'))); |
205 | } | 207 | } |
@@ -207,7 +209,8 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
207 | /** | 209 | /** |
208 | * Test generate location - from other domain. | 210 | * Test generate location - from other domain. |
209 | */ | 211 | */ |
210 | public function testGenerateLocationOut() { | 212 | public function testGenerateLocationOut() |
213 | { | ||
211 | $ref = 'http://somewebsite.com/?test'; | 214 | $ref = 'http://somewebsite.com/?test'; |
212 | $this->assertEquals('?', generateLocation($ref, 'localhost')); | 215 | $this->assertEquals('?', generateLocation($ref, 'localhost')); |
213 | } | 216 | } |
diff --git a/tests/api/ApiUtilsTest.php b/tests/api/ApiUtilsTest.php index 62baf4c5..df4e189a 100644 --- a/tests/api/ApiUtilsTest.php +++ b/tests/api/ApiUtilsTest.php | |||
@@ -4,7 +4,6 @@ namespace Shaarli\Api; | |||
4 | 4 | ||
5 | use Shaarli\Base64Url; | 5 | use Shaarli\Base64Url; |
6 | 6 | ||
7 | |||
8 | /** | 7 | /** |
9 | * Class ApiUtilsTest | 8 | * Class ApiUtilsTest |
10 | */ | 9 | */ |
@@ -34,7 +33,7 @@ class ApiUtilsTest extends \PHPUnit_Framework_TestCase | |||
34 | $payload = Base64Url::encode('{ | 33 | $payload = Base64Url::encode('{ |
35 | "iat": '. time() .' | 34 | "iat": '. time() .' |
36 | }'); | 35 | }'); |
37 | $signature = Base64Url::encode(hash_hmac('sha512', $header .'.'. $payload , $secret, true)); | 36 | $signature = Base64Url::encode(hash_hmac('sha512', $header .'.'. $payload, $secret, true)); |
38 | return $header .'.'. $payload .'.'. $signature; | 37 | return $header .'.'. $payload .'.'. $signature; |
39 | } | 38 | } |
40 | 39 | ||
diff --git a/tests/api/controllers/HistoryTest.php b/tests/api/controllers/history/HistoryTest.php index 61046d97..ff34e16d 100644 --- a/tests/api/controllers/HistoryTest.php +++ b/tests/api/controllers/history/HistoryTest.php | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | namespace Shaarli\Api\Controllers; | 4 | namespace Shaarli\Api\Controllers; |
5 | 5 | ||
6 | |||
7 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
8 | use Slim\Container; | 7 | use Slim\Container; |
9 | use Slim\Http\Environment; | 8 | use Slim\Http\Environment; |
diff --git a/tests/api/controllers/InfoTest.php b/tests/api/controllers/info/InfoTest.php index f7e63bfa..e437082a 100644 --- a/tests/api/controllers/InfoTest.php +++ b/tests/api/controllers/info/InfoTest.php | |||
@@ -10,9 +10,9 @@ use Slim\Http\Response; | |||
10 | 10 | ||
11 | /** | 11 | /** |
12 | * Class InfoTest | 12 | * Class InfoTest |
13 | * | 13 | * |
14 | * Test REST API controller Info. | 14 | * Test REST API controller Info. |
15 | * | 15 | * |
16 | * @package Api\Controllers | 16 | * @package Api\Controllers |
17 | */ | 17 | */ |
18 | class InfoTest extends \PHPUnit_Framework_TestCase | 18 | class InfoTest extends \PHPUnit_Framework_TestCase |
diff --git a/tests/api/controllers/DeleteLinkTest.php b/tests/api/controllers/links/DeleteLinkTest.php index 7d797137..7d797137 100644 --- a/tests/api/controllers/DeleteLinkTest.php +++ b/tests/api/controllers/links/DeleteLinkTest.php | |||
diff --git a/tests/api/controllers/GetLinkIdTest.php b/tests/api/controllers/links/GetLinkIdTest.php index 57528d5a..57528d5a 100644 --- a/tests/api/controllers/GetLinkIdTest.php +++ b/tests/api/controllers/links/GetLinkIdTest.php | |||
diff --git a/tests/api/controllers/GetLinksTest.php b/tests/api/controllers/links/GetLinksTest.php index d22ed3bf..64f02774 100644 --- a/tests/api/controllers/GetLinksTest.php +++ b/tests/api/controllers/links/GetLinksTest.php | |||
@@ -95,7 +95,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
95 | $this->assertEquals($this->refDB->countLinks(), count($data)); | 95 | $this->assertEquals($this->refDB->countLinks(), count($data)); |
96 | 96 | ||
97 | // Check order | 97 | // Check order |
98 | $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; | 98 | $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42]; |
99 | $cpt = 0; | 99 | $cpt = 0; |
100 | foreach ($data as $link) { | 100 | foreach ($data as $link) { |
101 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); | 101 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); |
@@ -103,7 +103,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
103 | } | 103 | } |
104 | 104 | ||
105 | // Check first element fields | 105 | // Check first element fields |
106 | $first = $data[0]; | 106 | $first = $data[2]; |
107 | $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); | 107 | $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); |
108 | $this->assertEquals('WDWyig', $first['shorturl']); | 108 | $this->assertEquals('WDWyig', $first['shorturl']); |
109 | $this->assertEquals('Link title: @website', $first['title']); | 109 | $this->assertEquals('Link title: @website', $first['title']); |
@@ -120,7 +120,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
120 | $this->assertEmpty($first['updated']); | 120 | $this->assertEmpty($first['updated']); |
121 | 121 | ||
122 | // Multi tags | 122 | // Multi tags |
123 | $link = $data[1]; | 123 | $link = $data[3]; |
124 | $this->assertEquals(7, count($link['tags'])); | 124 | $this->assertEquals(7, count($link['tags'])); |
125 | 125 | ||
126 | // Update date | 126 | // Update date |
@@ -138,7 +138,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
138 | { | 138 | { |
139 | $env = Environment::mock([ | 139 | $env = Environment::mock([ |
140 | 'REQUEST_METHOD' => 'GET', | 140 | 'REQUEST_METHOD' => 'GET', |
141 | 'QUERY_STRING' => 'offset=1&limit=1' | 141 | 'QUERY_STRING' => 'offset=3&limit=1' |
142 | ]); | 142 | ]); |
143 | $request = Request::createFromEnvironment($env); | 143 | $request = Request::createFromEnvironment($env); |
144 | $response = $this->controller->getLinks($request, new Response()); | 144 | $response = $this->controller->getLinks($request, new Response()); |
@@ -164,7 +164,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
164 | $data = json_decode((string) $response->getBody(), true); | 164 | $data = json_decode((string) $response->getBody(), true); |
165 | $this->assertEquals($this->refDB->countLinks(), count($data)); | 165 | $this->assertEquals($this->refDB->countLinks(), count($data)); |
166 | // Check order | 166 | // Check order |
167 | $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; | 167 | $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42]; |
168 | $cpt = 0; | 168 | $cpt = 0; |
169 | foreach ($data as $link) { | 169 | foreach ($data as $link) { |
170 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); | 170 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); |
@@ -205,7 +205,8 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
205 | $this->assertEquals(200, $response->getStatusCode()); | 205 | $this->assertEquals(200, $response->getStatusCode()); |
206 | $data = json_decode((string)$response->getBody(), true); | 206 | $data = json_decode((string)$response->getBody(), true); |
207 | $this->assertEquals($this->refDB->countLinks(), count($data)); | 207 | $this->assertEquals($this->refDB->countLinks(), count($data)); |
208 | $this->assertEquals(41, $data[0]['id']); | 208 | $this->assertEquals(10, $data[0]['id']); |
209 | $this->assertEquals(41, $data[2]['id']); | ||
209 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); | 210 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); |
210 | } | 211 | } |
211 | 212 | ||
@@ -243,7 +244,8 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
243 | $this->assertEquals(200, $response->getStatusCode()); | 244 | $this->assertEquals(200, $response->getStatusCode()); |
244 | $data = json_decode((string)$response->getBody(), true); | 245 | $data = json_decode((string)$response->getBody(), true); |
245 | $this->assertEquals($this->refDB->countPublicLinks(), count($data)); | 246 | $this->assertEquals($this->refDB->countPublicLinks(), count($data)); |
246 | $this->assertEquals(41, $data[0]['id']); | 247 | $this->assertEquals(10, $data[0]['id']); |
248 | $this->assertEquals(41, $data[2]['id']); | ||
247 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); | 249 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); |
248 | } | 250 | } |
249 | 251 | ||
@@ -413,8 +415,9 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
413 | $response = $this->controller->getLinks($request, new Response()); | 415 | $response = $this->controller->getLinks($request, new Response()); |
414 | $this->assertEquals(200, $response->getStatusCode()); | 416 | $this->assertEquals(200, $response->getStatusCode()); |
415 | $data = json_decode((string) $response->getBody(), true); | 417 | $data = json_decode((string) $response->getBody(), true); |
416 | $this->assertEquals(9, count($data)); | 418 | $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, count($data)); |
417 | $this->assertEquals(41, $data[0]['id']); | 419 | $this->assertEquals(10, $data[0]['id']); |
420 | $this->assertEquals(41, $data[2]['id']); | ||
418 | 421 | ||
419 | // wildcard: optional ('*' does not need to expand) | 422 | // wildcard: optional ('*' does not need to expand) |
420 | $env = Environment::mock([ | 423 | $env = Environment::mock([ |
diff --git a/tests/api/controllers/PostLinkTest.php b/tests/api/controllers/links/PostLinkTest.php index 31954e39..5c2b5623 100644 --- a/tests/api/controllers/PostLinkTest.php +++ b/tests/api/controllers/links/PostLinkTest.php | |||
@@ -2,12 +2,13 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Api\Controllers; | 3 | namespace Shaarli\Api\Controllers; |
4 | 4 | ||
5 | 5 | use PHPUnit\Framework\TestCase; | |
6 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
7 | use Slim\Container; | 7 | use Slim\Container; |
8 | use Slim\Http\Environment; | 8 | use Slim\Http\Environment; |
9 | use Slim\Http\Request; | 9 | use Slim\Http\Request; |
10 | use Slim\Http\Response; | 10 | use Slim\Http\Response; |
11 | use Slim\Router; | ||
11 | 12 | ||
12 | /** | 13 | /** |
13 | * Class PostLinkTest | 14 | * Class PostLinkTest |
@@ -16,7 +17,7 @@ use Slim\Http\Response; | |||
16 | * | 17 | * |
17 | * @package Shaarli\Api\Controllers | 18 | * @package Shaarli\Api\Controllers |
18 | */ | 19 | */ |
19 | class PostLinkTest extends \PHPUnit_Framework_TestCase | 20 | class PostLinkTest extends TestCase |
20 | { | 21 | { |
21 | /** | 22 | /** |
22 | * @var string datastore to test write operations | 23 | * @var string datastore to test write operations |
@@ -78,7 +79,7 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase | |||
78 | 79 | ||
79 | $this->controller = new Links($this->container); | 80 | $this->controller = new Links($this->container); |
80 | 81 | ||
81 | $mock = $this->getMock('\Slim\Router', ['relativePathFor']); | 82 | $mock = $this->createMock(Router::class); |
82 | $mock->expects($this->any()) | 83 | $mock->expects($this->any()) |
83 | ->method('relativePathFor') | 84 | ->method('relativePathFor') |
84 | ->willReturn('api/v1/links/1'); | 85 | ->willReturn('api/v1/links/1'); |
@@ -126,7 +127,9 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase | |||
126 | $this->assertEquals('', $data['description']); | 127 | $this->assertEquals('', $data['description']); |
127 | $this->assertEquals([], $data['tags']); | 128 | $this->assertEquals([], $data['tags']); |
128 | $this->assertEquals(false, $data['private']); | 129 | $this->assertEquals(false, $data['private']); |
129 | $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); | 130 | $this->assertTrue( |
131 | new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) | ||
132 | ); | ||
130 | $this->assertEquals('', $data['updated']); | 133 | $this->assertEquals('', $data['updated']); |
131 | 134 | ||
132 | $historyEntry = $this->history->getHistory()[0]; | 135 | $historyEntry = $this->history->getHistory()[0]; |
@@ -169,7 +172,9 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase | |||
169 | $this->assertEquals($link['description'], $data['description']); | 172 | $this->assertEquals($link['description'], $data['description']); |
170 | $this->assertEquals($link['tags'], $data['tags']); | 173 | $this->assertEquals($link['tags'], $data['tags']); |
171 | $this->assertEquals(true, $data['private']); | 174 | $this->assertEquals(true, $data['private']); |
172 | $this->assertTrue(new \DateTime('2 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); | 175 | $this->assertTrue( |
176 | new \DateTime('2 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) | ||
177 | ); | ||
173 | $this->assertEquals('', $data['updated']); | 178 | $this->assertEquals('', $data['updated']); |
174 | } | 179 | } |
175 | 180 | ||
diff --git a/tests/api/controllers/PutLinkTest.php b/tests/api/controllers/links/PutLinkTest.php index 8a562571..f276b4c1 100644 --- a/tests/api/controllers/PutLinkTest.php +++ b/tests/api/controllers/links/PutLinkTest.php | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | namespace Shaarli\Api\Controllers; | 4 | namespace Shaarli\Api\Controllers; |
5 | 5 | ||
6 | |||
7 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
8 | use Slim\Container; | 7 | use Slim\Container; |
9 | use Slim\Http\Environment; | 8 | use Slim\Http\Environment; |
@@ -115,7 +114,9 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase | |||
115 | \DateTime::createFromFormat('Ymd_His', '20150310_114651'), | 114 | \DateTime::createFromFormat('Ymd_His', '20150310_114651'), |
116 | \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) | 115 | \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) |
117 | ); | 116 | ); |
118 | $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); | 117 | $this->assertTrue( |
118 | new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) | ||
119 | ); | ||
119 | 120 | ||
120 | $historyEntry = $this->history->getHistory()[0]; | 121 | $historyEntry = $this->history->getHistory()[0]; |
121 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); | 122 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); |
@@ -160,7 +161,9 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase | |||
160 | \DateTime::createFromFormat('Ymd_His', '20150310_114651'), | 161 | \DateTime::createFromFormat('Ymd_His', '20150310_114651'), |
161 | \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) | 162 | \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) |
162 | ); | 163 | ); |
163 | $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); | 164 | $this->assertTrue( |
165 | new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) | ||
166 | ); | ||
164 | } | 167 | } |
165 | 168 | ||
166 | /** | 169 | /** |
diff --git a/tests/api/controllers/tags/DeleteTagTest.php b/tests/api/controllers/tags/DeleteTagTest.php new file mode 100644 index 00000000..e0787ce2 --- /dev/null +++ b/tests/api/controllers/tags/DeleteTagTest.php | |||
@@ -0,0 +1,164 @@ | |||
1 | <?php | ||
2 | |||
3 | |||
4 | namespace Shaarli\Api\Controllers; | ||
5 | |||
6 | use Shaarli\Config\ConfigManager; | ||
7 | use Slim\Container; | ||
8 | use Slim\Http\Environment; | ||
9 | use Slim\Http\Request; | ||
10 | use Slim\Http\Response; | ||
11 | |||
12 | class DeleteTagTest extends \PHPUnit_Framework_TestCase | ||
13 | { | ||
14 | /** | ||
15 | * @var string datastore to test write operations | ||
16 | */ | ||
17 | protected static $testDatastore = 'sandbox/datastore.php'; | ||
18 | |||
19 | /** | ||
20 | * @var string datastore to test write operations | ||
21 | */ | ||
22 | protected static $testHistory = 'sandbox/history.php'; | ||
23 | |||
24 | /** | ||
25 | * @var ConfigManager instance | ||
26 | */ | ||
27 | protected $conf; | ||
28 | |||
29 | /** | ||
30 | * @var \ReferenceLinkDB instance. | ||
31 | */ | ||
32 | protected $refDB = null; | ||
33 | |||
34 | /** | ||
35 | * @var \LinkDB instance. | ||
36 | */ | ||
37 | protected $linkDB; | ||
38 | |||
39 | /** | ||
40 | * @var \History instance. | ||
41 | */ | ||
42 | protected $history; | ||
43 | |||
44 | /** | ||
45 | * @var Container instance. | ||
46 | */ | ||
47 | protected $container; | ||
48 | |||
49 | /** | ||
50 | * @var Tags controller instance. | ||
51 | */ | ||
52 | protected $controller; | ||
53 | |||
54 | /** | ||
55 | * Before each test, instantiate a new Api with its config, plugins and links. | ||
56 | */ | ||
57 | public function setUp() | ||
58 | { | ||
59 | $this->conf = new ConfigManager('tests/utils/config/configJson'); | ||
60 | $this->refDB = new \ReferenceLinkDB(); | ||
61 | $this->refDB->write(self::$testDatastore); | ||
62 | $this->linkDB = new \LinkDB(self::$testDatastore, true, false); | ||
63 | $refHistory = new \ReferenceHistory(); | ||
64 | $refHistory->write(self::$testHistory); | ||
65 | $this->history = new \History(self::$testHistory); | ||
66 | $this->container = new Container(); | ||
67 | $this->container['conf'] = $this->conf; | ||
68 | $this->container['db'] = $this->linkDB; | ||
69 | $this->container['history'] = $this->history; | ||
70 | |||
71 | $this->controller = new Tags($this->container); | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * After each test, remove the test datastore. | ||
76 | */ | ||
77 | public function tearDown() | ||
78 | { | ||
79 | @unlink(self::$testDatastore); | ||
80 | @unlink(self::$testHistory); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * Test DELETE tag endpoint: the tag should be removed. | ||
85 | */ | ||
86 | public function testDeleteTagValid() | ||
87 | { | ||
88 | $tagName = 'gnu'; | ||
89 | $tags = $this->linkDB->linksCountPerTag(); | ||
90 | $this->assertTrue($tags[$tagName] > 0); | ||
91 | $env = Environment::mock([ | ||
92 | 'REQUEST_METHOD' => 'DELETE', | ||
93 | ]); | ||
94 | $request = Request::createFromEnvironment($env); | ||
95 | |||
96 | $response = $this->controller->deleteTag($request, new Response(), ['tagName' => $tagName]); | ||
97 | $this->assertEquals(204, $response->getStatusCode()); | ||
98 | $this->assertEmpty((string) $response->getBody()); | ||
99 | |||
100 | $this->linkDB = new \LinkDB(self::$testDatastore, true, false); | ||
101 | $tags = $this->linkDB->linksCountPerTag(); | ||
102 | $this->assertFalse(isset($tags[$tagName])); | ||
103 | |||
104 | // 2 links affected | ||
105 | $historyEntry = $this->history->getHistory()[0]; | ||
106 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); | ||
107 | $this->assertTrue( | ||
108 | (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] | ||
109 | ); | ||
110 | $historyEntry = $this->history->getHistory()[1]; | ||
111 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); | ||
112 | $this->assertTrue( | ||
113 | (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] | ||
114 | ); | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * Test DELETE tag endpoint: the tag should be removed. | ||
119 | */ | ||
120 | public function testDeleteTagCaseSensitivity() | ||
121 | { | ||
122 | $tagName = 'sTuff'; | ||
123 | $tags = $this->linkDB->linksCountPerTag(); | ||
124 | $this->assertTrue($tags[$tagName] > 0); | ||
125 | $env = Environment::mock([ | ||
126 | 'REQUEST_METHOD' => 'DELETE', | ||
127 | ]); | ||
128 | $request = Request::createFromEnvironment($env); | ||
129 | |||
130 | $response = $this->controller->deleteTag($request, new Response(), ['tagName' => $tagName]); | ||
131 | $this->assertEquals(204, $response->getStatusCode()); | ||
132 | $this->assertEmpty((string) $response->getBody()); | ||
133 | |||
134 | $this->linkDB = new \LinkDB(self::$testDatastore, true, false); | ||
135 | $tags = $this->linkDB->linksCountPerTag(); | ||
136 | $this->assertFalse(isset($tags[$tagName])); | ||
137 | $this->assertTrue($tags[strtolower($tagName)] > 0); | ||
138 | |||
139 | $historyEntry = $this->history->getHistory()[0]; | ||
140 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); | ||
141 | $this->assertTrue( | ||
142 | (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] | ||
143 | ); | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * Test DELETE tag endpoint: reach not existing tag. | ||
148 | * | ||
149 | * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException | ||
150 | * @expectedExceptionMessage Tag not found | ||
151 | */ | ||
152 | public function testDeleteLink404() | ||
153 | { | ||
154 | $tagName = 'nopenope'; | ||
155 | $tags = $this->linkDB->linksCountPerTag(); | ||
156 | $this->assertFalse(isset($tags[$tagName])); | ||
157 | $env = Environment::mock([ | ||
158 | 'REQUEST_METHOD' => 'DELETE', | ||
159 | ]); | ||
160 | $request = Request::createFromEnvironment($env); | ||
161 | |||
162 | $this->controller->deleteTag($request, new Response(), ['tagName' => $tagName]); | ||
163 | } | ||
164 | } | ||
diff --git a/tests/api/controllers/tags/GetTagNameTest.php b/tests/api/controllers/tags/GetTagNameTest.php new file mode 100644 index 00000000..afac228e --- /dev/null +++ b/tests/api/controllers/tags/GetTagNameTest.php | |||
@@ -0,0 +1,129 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Shaarli\Api\Controllers; | ||
4 | |||
5 | use Shaarli\Config\ConfigManager; | ||
6 | |||
7 | use Slim\Container; | ||
8 | use Slim\Http\Environment; | ||
9 | use Slim\Http\Request; | ||
10 | use Slim\Http\Response; | ||
11 | |||
12 | /** | ||
13 | * Class GetTagNameTest | ||
14 | * | ||
15 | * Test getTag by tag name API service. | ||
16 | * | ||
17 | * @package Shaarli\Api\Controllers | ||
18 | */ | ||
19 | class GetTagNameTest extends \PHPUnit_Framework_TestCase | ||
20 | { | ||
21 | /** | ||
22 | * @var string datastore to test write operations | ||
23 | */ | ||
24 | protected static $testDatastore = 'sandbox/datastore.php'; | ||
25 | |||
26 | /** | ||
27 | * @var ConfigManager instance | ||
28 | */ | ||
29 | protected $conf; | ||
30 | |||
31 | /** | ||
32 | * @var \ReferenceLinkDB instance. | ||
33 | */ | ||
34 | protected $refDB = null; | ||
35 | |||
36 | /** | ||
37 | * @var Container instance. | ||
38 | */ | ||
39 | protected $container; | ||
40 | |||
41 | /** | ||
42 | * @var Tags controller instance. | ||
43 | */ | ||
44 | protected $controller; | ||
45 | |||
46 | /** | ||
47 | * Number of JSON fields per link. | ||
48 | */ | ||
49 | const NB_FIELDS_TAG = 2; | ||
50 | |||
51 | /** | ||
52 | * Before each test, instantiate a new Api with its config, plugins and links. | ||
53 | */ | ||
54 | public function setUp() | ||
55 | { | ||
56 | $this->conf = new ConfigManager('tests/utils/config/configJson'); | ||
57 | $this->refDB = new \ReferenceLinkDB(); | ||
58 | $this->refDB->write(self::$testDatastore); | ||
59 | |||
60 | $this->container = new Container(); | ||
61 | $this->container['conf'] = $this->conf; | ||
62 | $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); | ||
63 | $this->container['history'] = null; | ||
64 | |||
65 | $this->controller = new Tags($this->container); | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * After each test, remove the test datastore. | ||
70 | */ | ||
71 | public function tearDown() | ||
72 | { | ||
73 | @unlink(self::$testDatastore); | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Test basic getTag service: return gnu tag with 2 occurrences. | ||
78 | */ | ||
79 | public function testGetTag() | ||
80 | { | ||
81 | $tagName = 'gnu'; | ||
82 | $env = Environment::mock([ | ||
83 | 'REQUEST_METHOD' => 'GET', | ||
84 | ]); | ||
85 | $request = Request::createFromEnvironment($env); | ||
86 | |||
87 | $response = $this->controller->getTag($request, new Response(), ['tagName' => $tagName]); | ||
88 | $this->assertEquals(200, $response->getStatusCode()); | ||
89 | $data = json_decode((string) $response->getBody(), true); | ||
90 | $this->assertEquals(self::NB_FIELDS_TAG, count($data)); | ||
91 | $this->assertEquals($tagName, $data['name']); | ||
92 | $this->assertEquals(2, $data['occurrences']); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Test getTag service which is not case sensitive: occurrences with both sTuff and stuff | ||
97 | */ | ||
98 | public function testGetTagNotCaseSensitive() | ||
99 | { | ||
100 | $tagName = 'sTuff'; | ||
101 | $env = Environment::mock([ | ||
102 | 'REQUEST_METHOD' => 'GET', | ||
103 | ]); | ||
104 | $request = Request::createFromEnvironment($env); | ||
105 | |||
106 | $response = $this->controller->getTag($request, new Response(), ['tagName' => $tagName]); | ||
107 | $this->assertEquals(200, $response->getStatusCode()); | ||
108 | $data = json_decode((string) $response->getBody(), true); | ||
109 | $this->assertEquals(self::NB_FIELDS_TAG, count($data)); | ||
110 | $this->assertEquals($tagName, $data['name']); | ||
111 | $this->assertEquals(2, $data['occurrences']); | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Test basic getTag service: get non existent tag => ApiTagNotFoundException. | ||
116 | * | ||
117 | * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException | ||
118 | * @expectedExceptionMessage Tag not found | ||
119 | */ | ||
120 | public function testGetTag404() | ||
121 | { | ||
122 | $env = Environment::mock([ | ||
123 | 'REQUEST_METHOD' => 'GET', | ||
124 | ]); | ||
125 | $request = Request::createFromEnvironment($env); | ||
126 | |||
127 | $this->controller->getTag($request, new Response(), ['tagName' => 'nopenope']); | ||
128 | } | ||
129 | } | ||
diff --git a/tests/api/controllers/tags/GetTagsTest.php b/tests/api/controllers/tags/GetTagsTest.php new file mode 100644 index 00000000..3fab31b0 --- /dev/null +++ b/tests/api/controllers/tags/GetTagsTest.php | |||
@@ -0,0 +1,209 @@ | |||
1 | <?php | ||
2 | namespace Shaarli\Api\Controllers; | ||
3 | |||
4 | use Shaarli\Config\ConfigManager; | ||
5 | |||
6 | use Slim\Container; | ||
7 | use Slim\Http\Environment; | ||
8 | use Slim\Http\Request; | ||
9 | use Slim\Http\Response; | ||
10 | |||
11 | /** | ||
12 | * Class GetTagsTest | ||
13 | * | ||
14 | * Test get tag list REST API service. | ||
15 | * | ||
16 | * @package Shaarli\Api\Controllers | ||
17 | */ | ||
18 | class GetTagsTest extends \PHPUnit_Framework_TestCase | ||
19 | { | ||
20 | /** | ||
21 | * @var string datastore to test write operations | ||
22 | */ | ||
23 | protected static $testDatastore = 'sandbox/datastore.php'; | ||
24 | |||
25 | /** | ||
26 | * @var ConfigManager instance | ||
27 | */ | ||
28 | protected $conf; | ||
29 | |||
30 | /** | ||
31 | * @var \ReferenceLinkDB instance. | ||
32 | */ | ||
33 | protected $refDB = null; | ||
34 | |||
35 | /** | ||
36 | * @var Container instance. | ||
37 | */ | ||
38 | protected $container; | ||
39 | |||
40 | /** | ||
41 | * @var \LinkDB instance. | ||
42 | */ | ||
43 | protected $linkDB; | ||
44 | |||
45 | /** | ||
46 | * @var Tags controller instance. | ||
47 | */ | ||
48 | protected $controller; | ||
49 | |||
50 | /** | ||
51 | * Number of JSON field per link. | ||
52 | */ | ||
53 | const NB_FIELDS_TAG = 2; | ||
54 | |||
55 | /** | ||
56 | * Before every test, instantiate a new Api with its config, plugins and links. | ||
57 | */ | ||
58 | public function setUp() | ||
59 | { | ||
60 | $this->conf = new ConfigManager('tests/utils/config/configJson'); | ||
61 | $this->refDB = new \ReferenceLinkDB(); | ||
62 | $this->refDB->write(self::$testDatastore); | ||
63 | |||
64 | $this->container = new Container(); | ||
65 | $this->container['conf'] = $this->conf; | ||
66 | $this->linkDB = new \LinkDB(self::$testDatastore, true, false); | ||
67 | $this->container['db'] = $this->linkDB; | ||
68 | $this->container['history'] = null; | ||
69 | |||
70 | $this->controller = new Tags($this->container); | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * After every test, remove the test datastore. | ||
75 | */ | ||
76 | public function tearDown() | ||
77 | { | ||
78 | @unlink(self::$testDatastore); | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * Test basic getTags service: returns all tags. | ||
83 | */ | ||
84 | public function testGetTagsAll() | ||
85 | { | ||
86 | $tags = $this->linkDB->linksCountPerTag(); | ||
87 | $env = Environment::mock([ | ||
88 | 'REQUEST_METHOD' => 'GET', | ||
89 | ]); | ||
90 | $request = Request::createFromEnvironment($env); | ||
91 | |||
92 | $response = $this->controller->getTags($request, new Response()); | ||
93 | $this->assertEquals(200, $response->getStatusCode()); | ||
94 | $data = json_decode((string) $response->getBody(), true); | ||
95 | $this->assertEquals(count($tags), count($data)); | ||
96 | |||
97 | // Check order | ||
98 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); | ||
99 | $this->assertEquals('web', $data[0]['name']); | ||
100 | $this->assertEquals(4, $data[0]['occurrences']); | ||
101 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[1])); | ||
102 | $this->assertEquals('cartoon', $data[1]['name']); | ||
103 | $this->assertEquals(3, $data[1]['occurrences']); | ||
104 | // Case insensitive | ||
105 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[5])); | ||
106 | $this->assertEquals('sTuff', $data[5]['name']); | ||
107 | $this->assertEquals(2, $data[5]['occurrences']); | ||
108 | // End | ||
109 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[count($data) - 1])); | ||
110 | $this->assertEquals('w3c', $data[count($data) - 1]['name']); | ||
111 | $this->assertEquals(1, $data[count($data) - 1]['occurrences']); | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Test getTags service with offset and limit parameter: | ||
116 | * limit=1 and offset=1 should return only the second tag, cartoon with 3 occurrences | ||
117 | */ | ||
118 | public function testGetTagsOffsetLimit() | ||
119 | { | ||
120 | $env = Environment::mock([ | ||
121 | 'REQUEST_METHOD' => 'GET', | ||
122 | 'QUERY_STRING' => 'offset=1&limit=1' | ||
123 | ]); | ||
124 | $request = Request::createFromEnvironment($env); | ||
125 | $response = $this->controller->getTags($request, new Response()); | ||
126 | $this->assertEquals(200, $response->getStatusCode()); | ||
127 | $data = json_decode((string) $response->getBody(), true); | ||
128 | $this->assertEquals(1, count($data)); | ||
129 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); | ||
130 | $this->assertEquals('cartoon', $data[0]['name']); | ||
131 | $this->assertEquals(3, $data[0]['occurrences']); | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * Test getTags with limit=all (return all tags). | ||
136 | */ | ||
137 | public function testGetTagsLimitAll() | ||
138 | { | ||
139 | $tags = $this->linkDB->linksCountPerTag(); | ||
140 | $env = Environment::mock([ | ||
141 | 'REQUEST_METHOD' => 'GET', | ||
142 | 'QUERY_STRING' => 'limit=all' | ||
143 | ]); | ||
144 | $request = Request::createFromEnvironment($env); | ||
145 | $response = $this->controller->getTags($request, new Response()); | ||
146 | $this->assertEquals(200, $response->getStatusCode()); | ||
147 | $data = json_decode((string) $response->getBody(), true); | ||
148 | $this->assertEquals(count($tags), count($data)); | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * Test getTags service with offset and limit parameter: | ||
153 | * limit=1 and offset=1 should not return any tag | ||
154 | */ | ||
155 | public function testGetTagsOffsetTooHigh() | ||
156 | { | ||
157 | $env = Environment::mock([ | ||
158 | 'REQUEST_METHOD' => 'GET', | ||
159 | 'QUERY_STRING' => 'offset=100' | ||
160 | ]); | ||
161 | $request = Request::createFromEnvironment($env); | ||
162 | $response = $this->controller->getTags($request, new Response()); | ||
163 | $this->assertEquals(200, $response->getStatusCode()); | ||
164 | $data = json_decode((string) $response->getBody(), true); | ||
165 | $this->assertEmpty(count($data)); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * Test getTags with visibility parameter set to private | ||
170 | */ | ||
171 | public function testGetTagsVisibilityPrivate() | ||
172 | { | ||
173 | $tags = $this->linkDB->linksCountPerTag([], 'private'); | ||
174 | $env = Environment::mock([ | ||
175 | 'REQUEST_METHOD' => 'GET', | ||
176 | 'QUERY_STRING' => 'visibility=private' | ||
177 | ]); | ||
178 | $request = Request::createFromEnvironment($env); | ||
179 | $response = $this->controller->getTags($request, new Response()); | ||
180 | $this->assertEquals(200, $response->getStatusCode()); | ||
181 | $data = json_decode((string) $response->getBody(), true); | ||
182 | $this->assertEquals(count($tags), count($data)); | ||
183 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); | ||
184 | $this->assertEquals('Mercurial', $data[0]['name']); | ||
185 | $this->assertEquals(1, $data[0]['occurrences']); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * Test getTags with visibility parameter set to public | ||
190 | */ | ||
191 | public function testGetTagsVisibilityPublic() | ||
192 | { | ||
193 | $tags = $this->linkDB->linksCountPerTag([], 'public'); | ||
194 | $env = Environment::mock( | ||
195 | [ | ||
196 | 'REQUEST_METHOD' => 'GET', | ||
197 | 'QUERY_STRING' => 'visibility=public' | ||
198 | ] | ||
199 | ); | ||
200 | $request = Request::createFromEnvironment($env); | ||
201 | $response = $this->controller->getTags($request, new Response()); | ||
202 | $this->assertEquals(200, $response->getStatusCode()); | ||
203 | $data = json_decode((string)$response->getBody(), true); | ||
204 | $this->assertEquals(count($tags), count($data)); | ||
205 | $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); | ||
206 | $this->assertEquals('web', $data[0]['name']); | ||
207 | $this->assertEquals(3, $data[0]['occurrences']); | ||
208 | } | ||
209 | } | ||
diff --git a/tests/api/controllers/tags/PutTagTest.php b/tests/api/controllers/tags/PutTagTest.php new file mode 100644 index 00000000..38017243 --- /dev/null +++ b/tests/api/controllers/tags/PutTagTest.php | |||
@@ -0,0 +1,208 @@ | |||
1 | <?php | ||
2 | |||
3 | |||
4 | namespace Shaarli\Api\Controllers; | ||
5 | |||
6 | use Shaarli\Api\Exceptions\ApiBadParametersException; | ||
7 | use Shaarli\Config\ConfigManager; | ||
8 | use Slim\Container; | ||
9 | use Slim\Http\Environment; | ||
10 | use Slim\Http\Request; | ||
11 | use Slim\Http\Response; | ||
12 | |||
13 | class PutTagTest extends \PHPUnit_Framework_TestCase | ||
14 | { | ||
15 | /** | ||
16 | * @var string datastore to test write operations | ||
17 | */ | ||
18 | protected static $testDatastore = 'sandbox/datastore.php'; | ||
19 | |||
20 | /** | ||
21 | * @var string datastore to test write operations | ||
22 | */ | ||
23 | protected static $testHistory = 'sandbox/history.php'; | ||
24 | |||
25 | /** | ||
26 | * @var ConfigManager instance | ||
27 | */ | ||
28 | protected $conf; | ||
29 | |||
30 | /** | ||
31 | * @var \ReferenceLinkDB instance. | ||
32 | */ | ||
33 | protected $refDB = null; | ||
34 | |||
35 | /** | ||
36 | * @var \History instance. | ||
37 | */ | ||
38 | protected $history; | ||
39 | |||
40 | /** | ||
41 | * @var Container instance. | ||
42 | */ | ||
43 | protected $container; | ||
44 | |||
45 | /** | ||
46 | * @var \LinkDB instance. | ||
47 | */ | ||
48 | protected $linkDB; | ||
49 | |||
50 | /** | ||
51 | * @var Tags controller instance. | ||
52 | */ | ||
53 | protected $controller; | ||
54 | |||
55 | /** | ||
56 | * Number of JSON field per link. | ||
57 | */ | ||
58 | const NB_FIELDS_TAG = 2; | ||
59 | |||
60 | /** | ||
61 | * Before every test, instantiate a new Api with its config, plugins and links. | ||
62 | */ | ||
63 | public function setUp() | ||
64 | { | ||
65 | $this->conf = new ConfigManager('tests/utils/config/configJson.json.php'); | ||
66 | $this->refDB = new \ReferenceLinkDB(); | ||
67 | $this->refDB->write(self::$testDatastore); | ||
68 | |||
69 | $refHistory = new \ReferenceHistory(); | ||
70 | $refHistory->write(self::$testHistory); | ||
71 | $this->history = new \History(self::$testHistory); | ||
72 | |||
73 | $this->container = new Container(); | ||
74 | $this->container['conf'] = $this->conf; | ||
75 | $this->linkDB = new \LinkDB(self::$testDatastore, true, false); | ||
76 | $this->container['db'] = $this->linkDB; | ||
77 | $this->container['history'] = $this->history; | ||
78 | |||
79 | $this->controller = new Tags($this->container); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * After every test, remove the test datastore. | ||
84 | */ | ||
85 | public function tearDown() | ||
86 | { | ||
87 | @unlink(self::$testDatastore); | ||
88 | @unlink(self::$testHistory); | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * Test tags update | ||
93 | */ | ||
94 | public function testPutLinkValid() | ||
95 | { | ||
96 | $env = Environment::mock([ | ||
97 | 'REQUEST_METHOD' => 'PUT', | ||
98 | ]); | ||
99 | $tagName = 'gnu'; | ||
100 | $update = ['name' => $newName = 'newtag']; | ||
101 | $request = Request::createFromEnvironment($env); | ||
102 | $request = $request->withParsedBody($update); | ||
103 | |||
104 | $response = $this->controller->putTag($request, new Response(), ['tagName' => $tagName]); | ||
105 | $this->assertEquals(200, $response->getStatusCode()); | ||
106 | $data = json_decode((string) $response->getBody(), true); | ||
107 | $this->assertEquals(self::NB_FIELDS_TAG, count($data)); | ||
108 | $this->assertEquals($newName, $data['name']); | ||
109 | $this->assertEquals(2, $data['occurrences']); | ||
110 | |||
111 | $tags = $this->linkDB->linksCountPerTag(); | ||
112 | $this->assertNotTrue(isset($tags[$tagName])); | ||
113 | $this->assertEquals(2, $tags[$newName]); | ||
114 | |||
115 | $historyEntry = $this->history->getHistory()[0]; | ||
116 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); | ||
117 | $this->assertTrue( | ||
118 | (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] | ||
119 | ); | ||
120 | $historyEntry = $this->history->getHistory()[1]; | ||
121 | $this->assertEquals(\History::UPDATED, $historyEntry['event']); | ||
122 | $this->assertTrue( | ||
123 | (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] | ||
124 | ); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * Test tag update with an existing tag: they should be merged | ||
129 | */ | ||
130 | public function testPutTagMerge() | ||
131 | { | ||
132 | $tagName = 'gnu'; | ||
133 | $newName = 'w3c'; | ||
134 | |||
135 | $tags = $this->linkDB->linksCountPerTag(); | ||
136 | $this->assertEquals(1, $tags[$newName]); | ||
137 | $this->assertEquals(2, $tags[$tagName]); | ||
138 | |||
139 | $env = Environment::mock([ | ||
140 | 'REQUEST_METHOD' => 'PUT', | ||
141 | ]); | ||
142 | $update = ['name' => $newName]; | ||
143 | $request = Request::createFromEnvironment($env); | ||
144 | $request = $request->withParsedBody($update); | ||
145 | |||
146 | $response = $this->controller->putTag($request, new Response(), ['tagName' => $tagName]); | ||
147 | $this->assertEquals(200, $response->getStatusCode()); | ||
148 | $data = json_decode((string) $response->getBody(), true); | ||
149 | $this->assertEquals(self::NB_FIELDS_TAG, count($data)); | ||
150 | $this->assertEquals($newName, $data['name']); | ||
151 | $this->assertEquals(3, $data['occurrences']); | ||
152 | |||
153 | $tags = $this->linkDB->linksCountPerTag(); | ||
154 | $this->assertNotTrue(isset($tags[$tagName])); | ||
155 | $this->assertEquals(3, $tags[$newName]); | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * Test tag update with an empty new tag name => ApiBadParametersException | ||
160 | * | ||
161 | * @expectedException Shaarli\Api\Exceptions\ApiBadParametersException | ||
162 | * @expectedExceptionMessage New tag name is required in the request body | ||
163 | */ | ||
164 | public function testPutTagEmpty() | ||
165 | { | ||
166 | $tagName = 'gnu'; | ||
167 | $newName = ''; | ||
168 | |||
169 | $tags = $this->linkDB->linksCountPerTag(); | ||
170 | $this->assertEquals(2, $tags[$tagName]); | ||
171 | |||
172 | $env = Environment::mock([ | ||
173 | 'REQUEST_METHOD' => 'PUT', | ||
174 | ]); | ||
175 | $request = Request::createFromEnvironment($env); | ||
176 | |||
177 | $env = Environment::mock([ | ||
178 | 'REQUEST_METHOD' => 'PUT', | ||
179 | ]); | ||
180 | $update = ['name' => $newName]; | ||
181 | $request = Request::createFromEnvironment($env); | ||
182 | $request = $request->withParsedBody($update); | ||
183 | |||
184 | try { | ||
185 | $this->controller->putTag($request, new Response(), ['tagName' => $tagName]); | ||
186 | } catch (ApiBadParametersException $e) { | ||
187 | $tags = $this->linkDB->linksCountPerTag(); | ||
188 | $this->assertEquals(2, $tags[$tagName]); | ||
189 | throw $e; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * Test tag update on non existent tag => ApiTagNotFoundException. | ||
195 | * | ||
196 | * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException | ||
197 | * @expectedExceptionMessage Tag not found | ||
198 | */ | ||
199 | public function testPutTag404() | ||
200 | { | ||
201 | $env = Environment::mock([ | ||
202 | 'REQUEST_METHOD' => 'PUT', | ||
203 | ]); | ||
204 | $request = Request::createFromEnvironment($env); | ||
205 | |||
206 | $this->controller->putTag($request, new Response(), ['tagName' => 'nopenope']); | ||
207 | } | ||
208 | } | ||
diff --git a/tests/config/ConfigManagerTest.php b/tests/config/ConfigManagerTest.php index 1ec447b2..4a4e94ac 100644 --- a/tests/config/ConfigManagerTest.php +++ b/tests/config/ConfigManagerTest.php | |||
@@ -81,6 +81,18 @@ class ConfigManagerTest extends \PHPUnit_Framework_TestCase | |||
81 | $this->assertEquals('testSetWriteGetNested', $this->conf->get('foo.bar.key.stuff')); | 81 | $this->assertEquals('testSetWriteGetNested', $this->conf->get('foo.bar.key.stuff')); |
82 | } | 82 | } |
83 | 83 | ||
84 | public function testSetDeleteNested() | ||
85 | { | ||
86 | $this->conf->set('foo.bar.key.stuff', 'testSetDeleteNested'); | ||
87 | $this->assertTrue($this->conf->exists('foo.bar')); | ||
88 | $this->assertTrue($this->conf->exists('foo.bar.key.stuff')); | ||
89 | $this->assertEquals('testSetDeleteNested', $this->conf->get('foo.bar.key.stuff')); | ||
90 | |||
91 | $this->conf->remove('foo.bar'); | ||
92 | $this->assertFalse($this->conf->exists('foo.bar.key.stuff')); | ||
93 | $this->assertFalse($this->conf->exists('foo.bar')); | ||
94 | } | ||
95 | |||
84 | /** | 96 | /** |
85 | * Set with an empty key. | 97 | * Set with an empty key. |
86 | * | 98 | * |
@@ -104,6 +116,17 @@ class ConfigManagerTest extends \PHPUnit_Framework_TestCase | |||
104 | } | 116 | } |
105 | 117 | ||
106 | /** | 118 | /** |
119 | * Remove with an empty key. | ||
120 | * | ||
121 | * @expectedException \Exception | ||
122 | * @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*# | ||
123 | */ | ||
124 | public function testRmoveEmptyKey() | ||
125 | { | ||
126 | $this->conf->remove(''); | ||
127 | } | ||
128 | |||
129 | /** | ||
107 | * Try to write the config without mandatory parameter (e.g. 'login'). | 130 | * Try to write the config without mandatory parameter (e.g. 'login'). |
108 | * | 131 | * |
109 | * @expectedException Shaarli\Config\Exception\MissingFieldConfigException | 132 | * @expectedException Shaarli\Config\Exception\MissingFieldConfigException |
diff --git a/tests/languages/de/UtilsDeTest.php b/tests/languages/de/UtilsDeTest.php index 4569c923..588c9fd6 100644 --- a/tests/languages/de/UtilsDeTest.php +++ b/tests/languages/de/UtilsDeTest.php | |||
@@ -20,7 +20,7 @@ class UtilsDeTest extends UtilsTest | |||
20 | public function testDateFormatNoTime() | 20 | public function testDateFormatNoTime() |
21 | { | 21 | { |
22 | $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); | 22 | $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); |
23 | $this->assertRegExp('/1\. Januar 2017/', format_date($date, false,true)); | 23 | $this->assertRegExp('/1\. Januar 2017/', format_date($date, false, true)); |
24 | } | 24 | } |
25 | 25 | ||
26 | /** | 26 | /** |
diff --git a/tests/languages/fr/LanguagesFrTest.php b/tests/languages/fr/LanguagesFrTest.php index 79d05172..38347de1 100644 --- a/tests/languages/fr/LanguagesFrTest.php +++ b/tests/languages/fr/LanguagesFrTest.php | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | namespace Shaarli; | 4 | namespace Shaarli; |
5 | 5 | ||
6 | |||
7 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
8 | 7 | ||
9 | /** | 8 | /** |
@@ -172,4 +171,30 @@ class LanguagesFrTest extends \PHPUnit_Framework_TestCase | |||
172 | $this->assertEquals('voiture', t($txt, $txt, 1, 'test')); | 171 | $this->assertEquals('voiture', t($txt, $txt, 1, 'test')); |
173 | $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test')); | 172 | $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test')); |
174 | } | 173 | } |
174 | |||
175 | /** | ||
176 | * Test t() with an extension language file coming from the theme in gettext mode | ||
177 | */ | ||
178 | public function testTranslationThemeExtensionGettext() | ||
179 | { | ||
180 | $this->conf->set('translation.mode', 'gettext'); | ||
181 | $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); | ||
182 | $this->conf->set('theme', 'dummy'); | ||
183 | new Languages('en', $this->conf); | ||
184 | $txt = 'rooster'; // ignore me poedit | ||
185 | $this->assertEquals('coq', t($txt, $txt, 1, 'dummy')); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * Test t() with an extension language file coming from the theme in PHP mode | ||
190 | */ | ||
191 | public function testTranslationThemeExtensionPhp() | ||
192 | { | ||
193 | $this->conf->set('translation.mode', 'php'); | ||
194 | $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); | ||
195 | $this->conf->set('theme', 'dummy'); | ||
196 | new Languages('en', $this->conf); | ||
197 | $txt = 'rooster'; // ignore me poedit | ||
198 | $this->assertEquals('coq', t($txt, $txt, 1, 'dummy')); | ||
199 | } | ||
175 | } | 200 | } |
diff --git a/tests/plugins/PluginIssoTest.php b/tests/plugins/PluginIssoTest.php index 0ae73183..2c9efbcd 100644 --- a/tests/plugins/PluginIssoTest.php +++ b/tests/plugins/PluginIssoTest.php | |||
@@ -21,7 +21,7 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase | |||
21 | /** | 21 | /** |
22 | * Test Isso init without errors. | 22 | * Test Isso init without errors. |
23 | */ | 23 | */ |
24 | public function testWallabagInitNoError() | 24 | public function testIssoInitNoError() |
25 | { | 25 | { |
26 | $conf = new ConfigManager(''); | 26 | $conf = new ConfigManager(''); |
27 | $conf->set('plugins.ISSO_SERVER', 'value'); | 27 | $conf->set('plugins.ISSO_SERVER', 'value'); |
@@ -32,7 +32,7 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase | |||
32 | /** | 32 | /** |
33 | * Test Isso init with errors. | 33 | * Test Isso init with errors. |
34 | */ | 34 | */ |
35 | public function testWallabagInitError() | 35 | public function testIssoInitError() |
36 | { | 36 | { |
37 | $conf = new ConfigManager(''); | 37 | $conf = new ConfigManager(''); |
38 | $errors = isso_init($conf); | 38 | $errors = isso_init($conf); |
@@ -96,19 +96,22 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase | |||
96 | array( | 96 | array( |
97 | 'id' => 12, | 97 | 'id' => 12, |
98 | 'url' => $str, | 98 | 'url' => $str, |
99 | 'shorturl' => $short1 = 'abcd', | ||
99 | 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date1), | 100 | 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date1), |
100 | ), | 101 | ), |
101 | array( | 102 | array( |
102 | 'id' => 13, | 103 | 'id' => 13, |
103 | 'url' => $str . '2', | 104 | 'url' => $str . '2', |
105 | 'shorturl' => $short2 = 'efgh', | ||
104 | 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date2), | 106 | 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date2), |
105 | ), | 107 | ), |
106 | ) | 108 | ) |
107 | ); | 109 | ); |
108 | 110 | ||
109 | $processed = hook_isso_render_linklist($data, $conf); | 111 | $processed = hook_isso_render_linklist($data, $conf); |
110 | // data shouldn't be altered | 112 | // link_plugin should be added for the icon |
111 | $this->assertEquals($data, $processed); | 113 | $this->assertContains('<a href="?'. $short1 .'#isso-thread">', $processed['links'][0]['link_plugin'][0]); |
114 | $this->assertContains('<a href="?'. $short2 .'#isso-thread">', $processed['links'][1]['link_plugin'][0]); | ||
112 | } | 115 | } |
113 | 116 | ||
114 | /** | 117 | /** |
@@ -127,6 +130,7 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase | |||
127 | array( | 130 | array( |
128 | 'id' => 12, | 131 | 'id' => 12, |
129 | 'url' => $str, | 132 | 'url' => $str, |
133 | 'shorturl' => $short1 = 'abcd', | ||
130 | 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date), | 134 | 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date), |
131 | ) | 135 | ) |
132 | ), | 136 | ), |
@@ -135,8 +139,8 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase | |||
135 | 139 | ||
136 | $processed = hook_isso_render_linklist($data, $conf); | 140 | $processed = hook_isso_render_linklist($data, $conf); |
137 | 141 | ||
138 | // data shouldn't be altered | 142 | // link_plugin should be added for the icon |
139 | $this->assertEquals($data, $processed); | 143 | $this->assertContains('<a href="?'. $short1 .'#isso-thread">', $processed['links'][0]['link_plugin'][0]); |
140 | } | 144 | } |
141 | 145 | ||
142 | /** | 146 | /** |
diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php index 96891f1f..44364b05 100644 --- a/tests/plugins/PluginMarkdownTest.php +++ b/tests/plugins/PluginMarkdownTest.php | |||
@@ -47,6 +47,32 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase | |||
47 | $data = hook_markdown_render_linklist($data, $this->conf); | 47 | $data = hook_markdown_render_linklist($data, $this->conf); |
48 | $this->assertNotFalse(strpos($data['links'][0]['description'], '<h1>')); | 48 | $this->assertNotFalse(strpos($data['links'][0]['description'], '<h1>')); |
49 | $this->assertNotFalse(strpos($data['links'][0]['description'], '<p>')); | 49 | $this->assertNotFalse(strpos($data['links'][0]['description'], '<p>')); |
50 | |||
51 | $this->assertEquals($markdown, $data['links'][0]['description_src']); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * Test render_feed hook. | ||
56 | */ | ||
57 | public function testMarkdownFeed() | ||
58 | { | ||
59 | $markdown = '# My title' . PHP_EOL . 'Very interesting content.'; | ||
60 | $markdown .= '— <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>'; | ||
61 | $data = array( | ||
62 | 'links' => array( | ||
63 | 0 => array( | ||
64 | 'description' => $markdown, | ||
65 | ), | ||
66 | ), | ||
67 | ); | ||
68 | |||
69 | $data = hook_markdown_render_feed($data, $this->conf); | ||
70 | $this->assertNotFalse(strpos($data['links'][0]['description'], '<h1>')); | ||
71 | $this->assertNotFalse(strpos($data['links'][0]['description'], '<p>')); | ||
72 | $this->assertStringEndsWith( | ||
73 | '— <a href="http://domain.tld/?0oc_VQ">Permalien</a></p></div>', | ||
74 | $data['links'][0]['description'] | ||
75 | ); | ||
50 | } | 76 | } |
51 | 77 | ||
52 | /** | 78 | /** |
@@ -58,20 +84,17 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase | |||
58 | $markdown = '# My title' . PHP_EOL . 'Very interesting content.'; | 84 | $markdown = '# My title' . PHP_EOL . 'Very interesting content.'; |
59 | $data = array( | 85 | $data = array( |
60 | // Columns data | 86 | // Columns data |
61 | 'cols' => array( | 87 | 'linksToDisplay' => array( |
62 | // First, second, third. | 88 | // nth link |
63 | 0 => array( | 89 | 0 => array( |
64 | // nth link | 90 | 'formatedDescription' => $markdown, |
65 | 0 => array( | ||
66 | 'formatedDescription' => $markdown, | ||
67 | ), | ||
68 | ), | 91 | ), |
69 | ), | 92 | ), |
70 | ); | 93 | ); |
71 | 94 | ||
72 | $data = hook_markdown_render_daily($data, $this->conf); | 95 | $data = hook_markdown_render_daily($data, $this->conf); |
73 | $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '<h1>')); | 96 | $this->assertNotFalse(strpos($data['linksToDisplay'][0]['formatedDescription'], '<h1>')); |
74 | $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '<p>')); | 97 | $this->assertNotFalse(strpos($data['linksToDisplay'][0]['formatedDescription'], '<p>')); |
75 | } | 98 | } |
76 | 99 | ||
77 | /** | 100 | /** |
@@ -86,6 +109,18 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase | |||
86 | } | 109 | } |
87 | 110 | ||
88 | /** | 111 | /** |
112 | * Test reverse_text2clickable(). | ||
113 | */ | ||
114 | public function testReverseText2clickableHashtags() | ||
115 | { | ||
116 | $text = file_get_contents('tests/plugins/resources/hashtags.raw'); | ||
117 | $md = file_get_contents('tests/plugins/resources/hashtags.md'); | ||
118 | $clickableText = hashtag_autolink($text); | ||
119 | $reversedText = reverse_text2clickable($clickableText); | ||
120 | $this->assertEquals($md, $reversedText); | ||
121 | } | ||
122 | |||
123 | /** | ||
89 | * Test reverse_nl2br(). | 124 | * Test reverse_nl2br(). |
90 | */ | 125 | */ |
91 | public function testReverseNl2br() | 126 | public function testReverseNl2br() |
@@ -107,6 +142,37 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase | |||
107 | $this->assertEquals($text, $reversedText); | 142 | $this->assertEquals($text, $reversedText); |
108 | } | 143 | } |
109 | 144 | ||
145 | public function testReverseFeedPermalink() | ||
146 | { | ||
147 | $text = 'Description... '; | ||
148 | $text .= '— <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>'; | ||
149 | $expected = 'Description... — [Permalien](http://domain.tld/?0oc_VQ)'; | ||
150 | $processedText = reverse_feed_permalink($text); | ||
151 | |||
152 | $this->assertEquals($expected, $processedText); | ||
153 | } | ||
154 | |||
155 | public function testReverseLastFeedPermalink() | ||
156 | { | ||
157 | $text = 'Description... '; | ||
158 | $text .= '<br>— <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>'; | ||
159 | $expected = $text; | ||
160 | $text .= '<br>— <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>'; | ||
161 | $expected .= '<br>— [Permalien](http://domain.tld/?0oc_VQ)'; | ||
162 | $processedText = reverse_feed_permalink($text); | ||
163 | |||
164 | $this->assertEquals($expected, $processedText); | ||
165 | } | ||
166 | |||
167 | public function testReverseNoFeedPermalink() | ||
168 | { | ||
169 | $text = 'Hello! Where are you from?'; | ||
170 | $expected = $text; | ||
171 | $processedText = reverse_feed_permalink($text); | ||
172 | |||
173 | $this->assertEquals($expected, $processedText); | ||
174 | } | ||
175 | |||
110 | /** | 176 | /** |
111 | * Test sanitize_html(). | 177 | * Test sanitize_html(). |
112 | */ | 178 | */ |
@@ -148,21 +214,18 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase | |||
148 | 214 | ||
149 | $data = array( | 215 | $data = array( |
150 | // Columns data | 216 | // Columns data |
151 | 'cols' => array( | 217 | 'linksToDisplay' => array( |
152 | // First, second, third. | 218 | // nth link |
153 | 0 => array( | 219 | 0 => array( |
154 | // nth link | 220 | 'formatedDescription' => $str, |
155 | 0 => array( | 221 | 'tags' => NO_MD_TAG, |
156 | 'formatedDescription' => $str, | 222 | 'taglist' => array(), |
157 | 'tags' => NO_MD_TAG, | ||
158 | 'taglist' => array(), | ||
159 | ), | ||
160 | ), | 223 | ), |
161 | ), | 224 | ), |
162 | ); | 225 | ); |
163 | 226 | ||
164 | $data = hook_markdown_render_daily($data, $this->conf); | 227 | $data = hook_markdown_render_daily($data, $this->conf); |
165 | $this->assertEquals($str, $data['cols'][0][0]['formatedDescription']); | 228 | $this->assertEquals($str, $data['linksToDisplay'][0]['formatedDescription']); |
166 | } | 229 | } |
167 | 230 | ||
168 | /** | 231 | /** |
@@ -197,7 +260,7 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase | |||
197 | $this->conf->get('security.markdown_escape', true), | 260 | $this->conf->get('security.markdown_escape', true), |
198 | $this->conf->get('security.allowed_protocols') | 261 | $this->conf->get('security.allowed_protocols') |
199 | ); | 262 | ); |
200 | $this->assertEquals($html, $data); | 263 | $this->assertEquals($html, $data . PHP_EOL); |
201 | } | 264 | } |
202 | 265 | ||
203 | /** | 266 | /** |
diff --git a/tests/plugins/PluginQrcodeTest.php b/tests/plugins/PluginQrcodeTest.php index ebfadddf..dd632eee 100644 --- a/tests/plugins/PluginQrcodeTest.php +++ b/tests/plugins/PluginQrcodeTest.php | |||
@@ -15,7 +15,8 @@ class PluginQrcodeTest extends PHPUnit_Framework_TestCase | |||
15 | /** | 15 | /** |
16 | * Reset plugin path | 16 | * Reset plugin path |
17 | */ | 17 | */ |
18 | public function setUp() { | 18 | public function setUp() |
19 | { | ||
19 | PluginManager::$PLUGINS_PATH = 'plugins'; | 20 | PluginManager::$PLUGINS_PATH = 'plugins'; |
20 | } | 21 | } |
21 | 22 | ||
diff --git a/tests/plugins/resources/hashtags.md b/tests/plugins/resources/hashtags.md new file mode 100644 index 00000000..46326de3 --- /dev/null +++ b/tests/plugins/resources/hashtags.md | |||
@@ -0,0 +1,10 @@ | |||
1 | [#lol](?addtag=lol) | ||
2 | |||
3 | #test | ||
4 | |||
5 | `#test2` | ||
6 | |||
7 | ``` | ||
8 | bla #bli blo | ||
9 | #bla | ||
10 | ``` | ||
diff --git a/tests/plugins/resources/hashtags.raw b/tests/plugins/resources/hashtags.raw new file mode 100644 index 00000000..9d2dc98a --- /dev/null +++ b/tests/plugins/resources/hashtags.raw | |||
@@ -0,0 +1,10 @@ | |||
1 | #lol | ||
2 | |||
3 | #test | ||
4 | |||
5 | `#test2` | ||
6 | |||
7 | ``` | ||
8 | bla #bli blo | ||
9 | #bla | ||
10 | ``` | ||
diff --git a/tests/plugins/resources/markdown.html b/tests/plugins/resources/markdown.html index 844a6f31..c3460bf7 100644 --- a/tests/plugins/resources/markdown.html +++ b/tests/plugins/resources/markdown.html | |||
@@ -8,15 +8,15 @@ | |||
8 | </ul> | 8 | </ul> |
9 | <ol> | 9 | <ol> |
10 | <li><a href="http://link.tld">zero</a> | 10 | <li><a href="http://link.tld">zero</a> |
11 | <ol> | 11 | <ol start="2"> |
12 | <li><a href="http://link.tld">two</a></li> | 12 | <li><a href="http://link.tld">two</a></li> |
13 | <li><a href="http://link.tld">three</a></li> | 13 | <li><a href="http://link.tld">three</a></li> |
14 | <li><a href="http://link.tld">four</a></li> | 14 | <li><a href="http://link.tld">four</a></li> |
15 | <li>foo <a href="?addtag=foobar" title="Hashtag foobar">#foobar</a></li> | 15 | <li>foo <a href="?addtag=foobar">#foobar</a></li> |
16 | </ol></li> | 16 | </ol></li> |
17 | </ol> | 17 | </ol> |
18 | <p><a href="?addtag=foobar" title="Hashtag foobar">#foobar</a> foo <code>lol #foo</code> <a href="?addtag=bar" title="Hashtag bar">#bar</a></p> | 18 | <p><a href="?addtag=foobar">#foobar</a> foo <code>lol #foo</code> <a href="?addtag=bar">#bar</a></p> |
19 | <p>fsdfs <a href="http://link.tld">http://link.tld</a> <a href="?addtag=foobar" title="Hashtag foobar">#foobar</a> <code>http://link.tld</code></p> | 19 | <p>fsdfs <a href="http://link.tld">http://link.tld</a> <a href="?addtag=foobar">#foobar</a> <code>http://link.tld</code></p> |
20 | <pre><code>http://link.tld #foobar | 20 | <pre><code>http://link.tld #foobar |
21 | next #foo</code></pre> | 21 | next #foo</code></pre> |
22 | <p>Block:</p> | 22 | <p>Block:</p> |
@@ -29,5 +29,5 @@ next #foo</code></pre> | |||
29 | <a href="https://test.tld/path/?query=value#hash">link</a><br /> | 29 | <a href="https://test.tld/path/?query=value#hash">link</a><br /> |
30 | <a href="ftp://test.tld/path/?query=value#hash">link</a><br /> | 30 | <a href="ftp://test.tld/path/?query=value#hash">link</a><br /> |
31 | <a href="magnet:test.tld/path/?query=value#hash">link</a><br /> | 31 | <a href="magnet:test.tld/path/?query=value#hash">link</a><br /> |
32 | <a href="http://alert('xss')">link</a><br /> | 32 | <a href="http://alert('xss')">link</a><br /> |
33 | <a href="http://test.tld/path/?query=value#hash">link</a></p></div> \ No newline at end of file | 33 | <a href="http://test.tld/path/?query=value#hash">link</a></p></div> |
diff --git a/tests/plugins/resources/markdown.md b/tests/plugins/resources/markdown.md index b8ebd934..9350a8c7 100644 --- a/tests/plugins/resources/markdown.md +++ b/tests/plugins/resources/markdown.md | |||
@@ -31,4 +31,4 @@ lorem ipsum #foobar http://link.tld | |||
31 | [link](ftp://test.tld/path/?query=value#hash) | 31 | [link](ftp://test.tld/path/?query=value#hash) |
32 | [link](magnet:test.tld/path/?query=value#hash) | 32 | [link](magnet:test.tld/path/?query=value#hash) |
33 | [link](javascript:alert('xss')) | 33 | [link](javascript:alert('xss')) |
34 | [link](other://test.tld/path/?query=value#hash) \ No newline at end of file | 34 | [link](other://test.tld/path/?query=value#hash) |
diff --git a/tests/plugins/test/test.php b/tests/plugins/test/test.php index 3d750c90..2aaf5122 100644 --- a/tests/plugins/test/test.php +++ b/tests/plugins/test/test.php | |||
@@ -11,7 +11,7 @@ function hook_test_random($data) | |||
11 | { | 11 | { |
12 | if (isset($data['_PAGE_']) && $data['_PAGE_'] == 'test') { | 12 | if (isset($data['_PAGE_']) && $data['_PAGE_'] == 'test') { |
13 | $data[1] = 'page test'; | 13 | $data[1] = 'page test'; |
14 | } else if (isset($data['_LOGGEDIN_']) && $data['_LOGGEDIN_'] === true) { | 14 | } elseif (isset($data['_LOGGEDIN_']) && $data['_LOGGEDIN_'] === true) { |
15 | $data[1] = 'loggedin'; | 15 | $data[1] = 'loggedin'; |
16 | } else { | 16 | } else { |
17 | $data[1] = $data[0]; | 17 | $data[1] = $data[0]; |
diff --git a/tests/security/LoginManagerTest.php b/tests/security/LoginManagerTest.php new file mode 100644 index 00000000..f26cd1eb --- /dev/null +++ b/tests/security/LoginManagerTest.php | |||
@@ -0,0 +1,374 @@ | |||
1 | <?php | ||
2 | namespace Shaarli\Security; | ||
3 | |||
4 | require_once 'tests/utils/FakeConfigManager.php'; | ||
5 | use \PHPUnit\Framework\TestCase; | ||
6 | |||
7 | /** | ||
8 | * Test coverage for LoginManager | ||
9 | */ | ||
10 | class LoginManagerTest extends TestCase | ||
11 | { | ||
12 | /** @var \FakeConfigManager Configuration Manager instance */ | ||
13 | protected $configManager = null; | ||
14 | |||
15 | /** @var LoginManager Login Manager instance */ | ||
16 | protected $loginManager = null; | ||
17 | |||
18 | /** @var SessionManager Session Manager instance */ | ||
19 | protected $sessionManager = null; | ||
20 | |||
21 | /** @var string Banned IP filename */ | ||
22 | protected $banFile = 'sandbox/ipbans.php'; | ||
23 | |||
24 | /** @var string Log filename */ | ||
25 | protected $logFile = 'sandbox/shaarli.log'; | ||
26 | |||
27 | /** @var array Simulates the $_COOKIE array */ | ||
28 | protected $cookie = []; | ||
29 | |||
30 | /** @var array Simulates the $GLOBALS array */ | ||
31 | protected $globals = []; | ||
32 | |||
33 | /** @var array Simulates the $_SERVER array */ | ||
34 | protected $server = []; | ||
35 | |||
36 | /** @var array Simulates the $_SESSION array */ | ||
37 | protected $session = []; | ||
38 | |||
39 | /** @var string Advertised client IP address */ | ||
40 | protected $clientIpAddress = '10.1.47.179'; | ||
41 | |||
42 | /** @var string Local client IP address */ | ||
43 | protected $ipAddr = '127.0.0.1'; | ||
44 | |||
45 | /** @var string Trusted proxy IP address */ | ||
46 | protected $trustedProxy = '10.1.1.100'; | ||
47 | |||
48 | /** @var string User login */ | ||
49 | protected $login = 'johndoe'; | ||
50 | |||
51 | /** @var string User password */ | ||
52 | protected $password = 'IC4nHazL0g1n?'; | ||
53 | |||
54 | /** @var string Hash of the salted user password */ | ||
55 | protected $passwordHash = ''; | ||
56 | |||
57 | /** @var string Salt used by hash functions */ | ||
58 | protected $salt = '669e24fa9c5a59a613f98e8e38327384504a4af2'; | ||
59 | |||
60 | /** | ||
61 | * Prepare or reset test resources | ||
62 | */ | ||
63 | public function setUp() | ||
64 | { | ||
65 | if (file_exists($this->banFile)) { | ||
66 | unlink($this->banFile); | ||
67 | } | ||
68 | |||
69 | $this->passwordHash = sha1($this->password . $this->login . $this->salt); | ||
70 | |||
71 | $this->configManager = new \FakeConfigManager([ | ||
72 | 'credentials.login' => $this->login, | ||
73 | 'credentials.hash' => $this->passwordHash, | ||
74 | 'credentials.salt' => $this->salt, | ||
75 | 'resource.ban_file' => $this->banFile, | ||
76 | 'resource.log' => $this->logFile, | ||
77 | 'security.ban_after' => 4, | ||
78 | 'security.ban_duration' => 3600, | ||
79 | 'security.trusted_proxies' => [$this->trustedProxy], | ||
80 | ]); | ||
81 | |||
82 | $this->cookie = []; | ||
83 | |||
84 | $this->globals = &$GLOBALS; | ||
85 | unset($this->globals['IPBANS']); | ||
86 | |||
87 | $this->session = []; | ||
88 | |||
89 | $this->sessionManager = new SessionManager($this->session, $this->configManager); | ||
90 | $this->loginManager = new LoginManager($this->globals, $this->configManager, $this->sessionManager); | ||
91 | $this->server['REMOTE_ADDR'] = $this->ipAddr; | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * Wipe test resources | ||
96 | */ | ||
97 | public function tearDown() | ||
98 | { | ||
99 | unset($this->globals['IPBANS']); | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * Instantiate a LoginManager and load ban records | ||
104 | */ | ||
105 | public function testReadBanFile() | ||
106 | { | ||
107 | file_put_contents( | ||
108 | $this->banFile, | ||
109 | "<?php\n\$GLOBALS['IPBANS']=array('FAILURES' => array('127.0.0.1' => 99));\n?>" | ||
110 | ); | ||
111 | new LoginManager($this->globals, $this->configManager, null); | ||
112 | $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * Record a failed login attempt | ||
117 | */ | ||
118 | public function testHandleFailedLogin() | ||
119 | { | ||
120 | $this->loginManager->handleFailedLogin($this->server); | ||
121 | $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
122 | |||
123 | $this->loginManager->handleFailedLogin($this->server); | ||
124 | $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * Record a failed login attempt - IP behind a trusted proxy | ||
129 | */ | ||
130 | public function testHandleFailedLoginBehindTrustedProxy() | ||
131 | { | ||
132 | $server = [ | ||
133 | 'REMOTE_ADDR' => $this->trustedProxy, | ||
134 | 'HTTP_X_FORWARDED_FOR' => $this->ipAddr, | ||
135 | ]; | ||
136 | $this->loginManager->handleFailedLogin($server); | ||
137 | $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
138 | |||
139 | $this->loginManager->handleFailedLogin($server); | ||
140 | $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Record a failed login attempt - IP behind a trusted proxy but not forwarded | ||
145 | */ | ||
146 | public function testHandleFailedLoginBehindTrustedProxyNoIp() | ||
147 | { | ||
148 | $server = [ | ||
149 | 'REMOTE_ADDR' => $this->trustedProxy, | ||
150 | ]; | ||
151 | $this->loginManager->handleFailedLogin($server); | ||
152 | $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); | ||
153 | |||
154 | $this->loginManager->handleFailedLogin($server); | ||
155 | $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * Record a failed login attempt and ban the IP after too many failures | ||
160 | */ | ||
161 | public function testHandleFailedLoginBanIp() | ||
162 | { | ||
163 | $this->loginManager->handleFailedLogin($this->server); | ||
164 | $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
165 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
166 | |||
167 | $this->loginManager->handleFailedLogin($this->server); | ||
168 | $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
169 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
170 | |||
171 | $this->loginManager->handleFailedLogin($this->server); | ||
172 | $this->assertEquals(3, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
173 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
174 | |||
175 | $this->loginManager->handleFailedLogin($this->server); | ||
176 | $this->assertEquals(4, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
177 | $this->assertFalse($this->loginManager->canLogin($this->server)); | ||
178 | |||
179 | // handleFailedLogin is not supposed to be called at this point: | ||
180 | // - no login form should be displayed once an IP has been banned | ||
181 | // - yet this could happen when using custom templates / scripts | ||
182 | $this->loginManager->handleFailedLogin($this->server); | ||
183 | $this->assertEquals(5, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
184 | $this->assertFalse($this->loginManager->canLogin($this->server)); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Nothing to do | ||
189 | */ | ||
190 | public function testHandleSuccessfulLogin() | ||
191 | { | ||
192 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
193 | |||
194 | $this->loginManager->handleSuccessfulLogin($this->server); | ||
195 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * Erase failure records after successfully logging in from this IP | ||
200 | */ | ||
201 | public function testHandleSuccessfulLoginAfterFailure() | ||
202 | { | ||
203 | $this->loginManager->handleFailedLogin($this->server); | ||
204 | $this->loginManager->handleFailedLogin($this->server); | ||
205 | $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); | ||
206 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
207 | |||
208 | $this->loginManager->handleSuccessfulLogin($this->server); | ||
209 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
210 | $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); | ||
211 | $this->assertFalse(isset($this->globals['IPBANS']['BANS'][$this->ipAddr])); | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * The IP is not banned | ||
216 | */ | ||
217 | public function testCanLoginIpNotBanned() | ||
218 | { | ||
219 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * The IP is banned | ||
224 | */ | ||
225 | public function testCanLoginIpBanned() | ||
226 | { | ||
227 | // ban the IP for an hour | ||
228 | $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; | ||
229 | $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; | ||
230 | |||
231 | $this->assertFalse($this->loginManager->canLogin($this->server)); | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * The IP is banned, and the ban duration is over | ||
236 | */ | ||
237 | public function testCanLoginIpBanExpired() | ||
238 | { | ||
239 | // ban the IP for an hour | ||
240 | $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; | ||
241 | $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; | ||
242 | $this->assertFalse($this->loginManager->canLogin($this->server)); | ||
243 | |||
244 | // lift the ban | ||
245 | $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600; | ||
246 | $this->assertTrue($this->loginManager->canLogin($this->server)); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * Generate a token depending on the user credentials and client IP | ||
251 | */ | ||
252 | public function testGenerateStaySignedInToken() | ||
253 | { | ||
254 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
255 | |||
256 | $this->assertEquals( | ||
257 | sha1($this->passwordHash . $this->clientIpAddress . $this->salt), | ||
258 | $this->loginManager->getStaySignedInToken() | ||
259 | ); | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * Check user login - Shaarli has not yet been configured | ||
264 | */ | ||
265 | public function testCheckLoginStateNotConfigured() | ||
266 | { | ||
267 | $configManager = new \FakeConfigManager([ | ||
268 | 'resource.ban_file' => $this->banFile, | ||
269 | ]); | ||
270 | $loginManager = new LoginManager($this->globals, $configManager, null); | ||
271 | $loginManager->checkLoginState([], ''); | ||
272 | |||
273 | $this->assertFalse($loginManager->isLoggedIn()); | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * Check user login - the client cookie does not match the server token | ||
278 | */ | ||
279 | public function testCheckLoginStateStaySignedInWithInvalidToken() | ||
280 | { | ||
281 | // simulate a previous login | ||
282 | $this->session = [ | ||
283 | 'ip' => $this->clientIpAddress, | ||
284 | 'expires_on' => time() + 100, | ||
285 | ]; | ||
286 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
287 | $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = 'nope'; | ||
288 | |||
289 | $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); | ||
290 | |||
291 | $this->assertTrue($this->loginManager->isLoggedIn()); | ||
292 | $this->assertTrue(empty($this->session['username'])); | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * Check user login - the client cookie matches the server token | ||
297 | */ | ||
298 | public function testCheckLoginStateStaySignedInWithValidToken() | ||
299 | { | ||
300 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
301 | $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = $this->loginManager->getStaySignedInToken(); | ||
302 | |||
303 | $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); | ||
304 | |||
305 | $this->assertTrue($this->loginManager->isLoggedIn()); | ||
306 | $this->assertEquals($this->login, $this->session['username']); | ||
307 | $this->assertEquals($this->clientIpAddress, $this->session['ip']); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * Check user login - the session has expired | ||
312 | */ | ||
313 | public function testCheckLoginStateSessionExpired() | ||
314 | { | ||
315 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
316 | $this->session['expires_on'] = time() - 100; | ||
317 | |||
318 | $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); | ||
319 | |||
320 | $this->assertFalse($this->loginManager->isLoggedIn()); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * Check user login - the remote client IP has changed | ||
325 | */ | ||
326 | public function testCheckLoginStateClientIpChanged() | ||
327 | { | ||
328 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
329 | |||
330 | $this->loginManager->checkLoginState($this->cookie, '10.7.157.98'); | ||
331 | |||
332 | $this->assertFalse($this->loginManager->isLoggedIn()); | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * Check user credentials - wrong login supplied | ||
337 | */ | ||
338 | public function testCheckCredentialsWrongLogin() | ||
339 | { | ||
340 | $this->assertFalse( | ||
341 | $this->loginManager->checkCredentials('', '', 'b4dl0g1n', $this->password) | ||
342 | ); | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * Check user credentials - wrong password supplied | ||
347 | */ | ||
348 | public function testCheckCredentialsWrongPassword() | ||
349 | { | ||
350 | $this->assertFalse( | ||
351 | $this->loginManager->checkCredentials('', '', $this->login, 'b4dp455wd') | ||
352 | ); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Check user credentials - wrong login and password supplied | ||
357 | */ | ||
358 | public function testCheckCredentialsWrongLoginAndPassword() | ||
359 | { | ||
360 | $this->assertFalse( | ||
361 | $this->loginManager->checkCredentials('', '', 'b4dl0g1n', 'b4dp455wd') | ||
362 | ); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * Check user credentials - correct login and password supplied | ||
367 | */ | ||
368 | public function testCheckCredentialsGoodLoginAndPassword() | ||
369 | { | ||
370 | $this->assertTrue( | ||
371 | $this->loginManager->checkCredentials('', '', $this->login, $this->password) | ||
372 | ); | ||
373 | } | ||
374 | } | ||
diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php new file mode 100644 index 00000000..7961e771 --- /dev/null +++ b/tests/security/SessionManagerTest.php | |||
@@ -0,0 +1,272 @@ | |||
1 | <?php | ||
2 | require_once 'tests/utils/FakeConfigManager.php'; | ||
3 | |||
4 | // Initialize reference data _before_ PHPUnit starts a session | ||
5 | require_once 'tests/utils/ReferenceSessionIdHashes.php'; | ||
6 | ReferenceSessionIdHashes::genAllHashes(); | ||
7 | |||
8 | use \Shaarli\Security\SessionManager; | ||
9 | use \PHPUnit\Framework\TestCase; | ||
10 | |||
11 | /** | ||
12 | * Test coverage for SessionManager | ||
13 | */ | ||
14 | class SessionManagerTest extends TestCase | ||
15 | { | ||
16 | /** @var array Session ID hashes */ | ||
17 | protected static $sidHashes = null; | ||
18 | |||
19 | /** @var \FakeConfigManager ConfigManager substitute for testing */ | ||
20 | protected $conf = null; | ||
21 | |||
22 | /** @var array $_SESSION array for testing */ | ||
23 | protected $session = []; | ||
24 | |||
25 | /** @var SessionManager Server-side session management abstraction */ | ||
26 | protected $sessionManager = null; | ||
27 | |||
28 | /** | ||
29 | * Assign reference data | ||
30 | */ | ||
31 | public static function setUpBeforeClass() | ||
32 | { | ||
33 | self::$sidHashes = ReferenceSessionIdHashes::getHashes(); | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Initialize or reset test resources | ||
38 | */ | ||
39 | public function setUp() | ||
40 | { | ||
41 | $this->conf = new FakeConfigManager([ | ||
42 | 'credentials.login' => 'johndoe', | ||
43 | 'credentials.salt' => 'salt', | ||
44 | 'security.session_protection_disabled' => false, | ||
45 | ]); | ||
46 | $this->session = []; | ||
47 | $this->sessionManager = new SessionManager($this->session, $this->conf); | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * Generate a session token | ||
52 | */ | ||
53 | public function testGenerateToken() | ||
54 | { | ||
55 | $token = $this->sessionManager->generateToken(); | ||
56 | |||
57 | $this->assertEquals(1, $this->session['tokens'][$token]); | ||
58 | $this->assertEquals(40, strlen($token)); | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * Check a session token | ||
63 | */ | ||
64 | public function testCheckToken() | ||
65 | { | ||
66 | $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'; | ||
67 | $session = [ | ||
68 | 'tokens' => [ | ||
69 | $token => 1, | ||
70 | ], | ||
71 | ]; | ||
72 | $sessionManager = new SessionManager($session, $this->conf); | ||
73 | |||
74 | // check and destroy the token | ||
75 | $this->assertTrue($sessionManager->checkToken($token)); | ||
76 | $this->assertFalse(isset($session['tokens'][$token])); | ||
77 | |||
78 | // ensure the token has been destroyed | ||
79 | $this->assertFalse($sessionManager->checkToken($token)); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Generate and check a session token | ||
84 | */ | ||
85 | public function testGenerateAndCheckToken() | ||
86 | { | ||
87 | $token = $this->sessionManager->generateToken(); | ||
88 | |||
89 | // ensure a token has been generated | ||
90 | $this->assertEquals(1, $this->session['tokens'][$token]); | ||
91 | $this->assertEquals(40, strlen($token)); | ||
92 | |||
93 | // check and destroy the token | ||
94 | $this->assertTrue($this->sessionManager->checkToken($token)); | ||
95 | $this->assertFalse(isset($this->session['tokens'][$token])); | ||
96 | |||
97 | // ensure the token has been destroyed | ||
98 | $this->assertFalse($this->sessionManager->checkToken($token)); | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * Check an invalid session token | ||
103 | */ | ||
104 | public function testCheckInvalidToken() | ||
105 | { | ||
106 | $this->assertFalse($this->sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES! | ||
111 | * | ||
112 | * This tests extensively covers all hash algorithms / bit representations | ||
113 | */ | ||
114 | public function testIsAnyHashSessionIdValid() | ||
115 | { | ||
116 | foreach (self::$sidHashes as $algo => $bpcs) { | ||
117 | foreach ($bpcs as $bpc => $hash) { | ||
118 | $this->assertTrue(SessionManager::checkId($hash)); | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * Test checkId with a valid ID - SHA-1 hashes | ||
125 | */ | ||
126 | public function testIsSha1SessionIdValid() | ||
127 | { | ||
128 | $this->assertTrue(SessionManager::checkId(sha1('shaarli'))); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Test checkId with a valid ID - SHA-256 hashes | ||
133 | */ | ||
134 | public function testIsSha256SessionIdValid() | ||
135 | { | ||
136 | $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli'))); | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * Test checkId with a valid ID - SHA-512 hashes | ||
141 | */ | ||
142 | public function testIsSha512SessionIdValid() | ||
143 | { | ||
144 | $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli'))); | ||
145 | } | ||
146 | |||
147 | /** | ||
148 | * Test checkId with invalid IDs. | ||
149 | */ | ||
150 | public function testIsSessionIdInvalid() | ||
151 | { | ||
152 | $this->assertFalse(SessionManager::checkId('')); | ||
153 | $this->assertFalse(SessionManager::checkId([])); | ||
154 | $this->assertFalse( | ||
155 | SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') | ||
156 | ); | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * Store login information after a successful login | ||
161 | */ | ||
162 | public function testStoreLoginInfo() | ||
163 | { | ||
164 | $this->sessionManager->storeLoginInfo('ip_id'); | ||
165 | |||
166 | $this->assertGreaterThan(time(), $this->session['expires_on']); | ||
167 | $this->assertEquals('ip_id', $this->session['ip']); | ||
168 | $this->assertEquals('johndoe', $this->session['username']); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * Extend a server-side session by SessionManager::$SHORT_TIMEOUT | ||
173 | */ | ||
174 | public function testExtendSession() | ||
175 | { | ||
176 | $this->sessionManager->extendSession(); | ||
177 | |||
178 | $this->assertGreaterThan(time(), $this->session['expires_on']); | ||
179 | $this->assertLessThanOrEqual( | ||
180 | time() + SessionManager::$SHORT_TIMEOUT, | ||
181 | $this->session['expires_on'] | ||
182 | ); | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * Extend a server-side session by SessionManager::$LONG_TIMEOUT | ||
187 | */ | ||
188 | public function testExtendSessionStaySignedIn() | ||
189 | { | ||
190 | $this->sessionManager->setStaySignedIn(true); | ||
191 | $this->sessionManager->extendSession(); | ||
192 | |||
193 | $this->assertGreaterThan(time(), $this->session['expires_on']); | ||
194 | $this->assertGreaterThan( | ||
195 | time() + SessionManager::$LONG_TIMEOUT - 10, | ||
196 | $this->session['expires_on'] | ||
197 | ); | ||
198 | $this->assertLessThanOrEqual( | ||
199 | time() + SessionManager::$LONG_TIMEOUT, | ||
200 | $this->session['expires_on'] | ||
201 | ); | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * Unset session variables after logging out | ||
206 | */ | ||
207 | public function testLogout() | ||
208 | { | ||
209 | $this->session = [ | ||
210 | 'ip' => 'ip_id', | ||
211 | 'expires_on' => time() + 1000, | ||
212 | 'username' => 'johndoe', | ||
213 | 'visibility' => 'public', | ||
214 | 'untaggedonly' => false, | ||
215 | ]; | ||
216 | $this->sessionManager->logout(); | ||
217 | |||
218 | $this->assertFalse(isset($this->session['ip'])); | ||
219 | $this->assertFalse(isset($this->session['expires_on'])); | ||
220 | $this->assertFalse(isset($this->session['username'])); | ||
221 | $this->assertFalse(isset($this->session['visibility'])); | ||
222 | $this->assertFalse(isset($this->session['untaggedonly'])); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * The session is active and expiration time has been reached | ||
227 | */ | ||
228 | public function testHasExpiredTimeElapsed() | ||
229 | { | ||
230 | $this->session['expires_on'] = time() - 10; | ||
231 | |||
232 | $this->assertTrue($this->sessionManager->hasSessionExpired()); | ||
233 | } | ||
234 | |||
235 | /** | ||
236 | * The session is active and expiration time has not been reached | ||
237 | */ | ||
238 | public function testHasNotExpired() | ||
239 | { | ||
240 | $this->session['expires_on'] = time() + 1000; | ||
241 | |||
242 | $this->assertFalse($this->sessionManager->hasSessionExpired()); | ||
243 | } | ||
244 | |||
245 | /** | ||
246 | * Session hijacking protection is disabled, we assume the IP has not changed | ||
247 | */ | ||
248 | public function testHasClientIpChangedNoSessionProtection() | ||
249 | { | ||
250 | $this->conf->set('security.session_protection_disabled', true); | ||
251 | |||
252 | $this->assertFalse($this->sessionManager->hasClientIpChanged('')); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * The client IP identifier has not changed | ||
257 | */ | ||
258 | public function testHasClientIpChangedNope() | ||
259 | { | ||
260 | $this->session['ip'] = 'ip_id'; | ||
261 | $this->assertFalse($this->sessionManager->hasClientIpChanged('ip_id')); | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * The client IP identifier has changed | ||
266 | */ | ||
267 | public function testHasClientIpChanged() | ||
268 | { | ||
269 | $this->session['ip'] = 'ip_id_one'; | ||
270 | $this->assertTrue($this->sessionManager->hasClientIpChanged('ip_id_two')); | ||
271 | } | ||
272 | } | ||
diff --git a/tests/utils/FakeConfigManager.php b/tests/utils/FakeConfigManager.php index f29760cb..360b34a9 100644 --- a/tests/utils/FakeConfigManager.php +++ b/tests/utils/FakeConfigManager.php | |||
@@ -5,8 +5,53 @@ | |||
5 | */ | 5 | */ |
6 | class FakeConfigManager | 6 | class FakeConfigManager |
7 | { | 7 | { |
8 | public static function get($key) | 8 | protected $values = []; |
9 | |||
10 | /** | ||
11 | * Initialize with test values | ||
12 | * | ||
13 | * @param array $values Initial values | ||
14 | */ | ||
15 | public function __construct($values = []) | ||
16 | { | ||
17 | $this->values = $values; | ||
18 | } | ||
19 | |||
20 | /** | ||
21 | * Set a given value | ||
22 | * | ||
23 | * @param string $key Key of the value to set | ||
24 | * @param mixed $value Value to set | ||
25 | */ | ||
26 | public function set($key, $value) | ||
27 | { | ||
28 | $this->values[$key] = $value; | ||
29 | } | ||
30 | |||
31 | /** | ||
32 | * Get a given configuration value | ||
33 | * | ||
34 | * @param string $key Index of the value to retrieve | ||
35 | * | ||
36 | * @return mixed The value if set, else the name of the key | ||
37 | */ | ||
38 | public function get($key) | ||
9 | { | 39 | { |
40 | if (isset($this->values[$key])) { | ||
41 | return $this->values[$key]; | ||
42 | } | ||
10 | return $key; | 43 | return $key; |
11 | } | 44 | } |
45 | |||
46 | /** | ||
47 | * Check if a setting exists | ||
48 | * | ||
49 | * @param string $setting Asked setting, keys separated with dots | ||
50 | * | ||
51 | * @return bool true if the setting exists, false otherwise | ||
52 | */ | ||
53 | public function exists($setting) | ||
54 | { | ||
55 | return array_key_exists($setting, $this->values); | ||
56 | } | ||
12 | } | 57 | } |
diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php index e887aa78..59679e38 100644 --- a/tests/utils/ReferenceLinkDB.php +++ b/tests/utils/ReferenceLinkDB.php | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | class ReferenceLinkDB | 5 | class ReferenceLinkDB |
6 | { | 6 | { |
7 | public static $NB_LINKS_TOTAL = 9; | 7 | public static $NB_LINKS_TOTAL = 11; |
8 | 8 | ||
9 | private $_links = array(); | 9 | private $_links = array(); |
10 | private $_publicCount = 0; | 10 | private $_publicCount = 0; |
@@ -16,6 +16,32 @@ class ReferenceLinkDB | |||
16 | public function __construct() | 16 | public function __construct() |
17 | { | 17 | { |
18 | $this->addLink( | 18 | $this->addLink( |
19 | 11, | ||
20 | 'Pined older', | ||
21 | '?PCRizQ', | ||
22 | 'This is an older pinned link', | ||
23 | 0, | ||
24 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20100309_101010'), | ||
25 | '', | ||
26 | null, | ||
27 | 'PCRizQ', | ||
28 | true | ||
29 | ); | ||
30 | |||
31 | $this->addLink( | ||
32 | 10, | ||
33 | 'Pined', | ||
34 | '?0gCTjQ', | ||
35 | 'This is a pinned link', | ||
36 | 0, | ||
37 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121207_152312'), | ||
38 | '', | ||
39 | null, | ||
40 | '0gCTjQ', | ||
41 | true | ||
42 | ); | ||
43 | |||
44 | $this->addLink( | ||
19 | 41, | 45 | 41, |
20 | 'Link title: @website', | 46 | 'Link title: @website', |
21 | '?WDWyig', | 47 | '?WDWyig', |
@@ -114,8 +140,18 @@ class ReferenceLinkDB | |||
114 | /** | 140 | /** |
115 | * Adds a new link | 141 | * Adds a new link |
116 | */ | 142 | */ |
117 | protected function addLink($id, $title, $url, $description, $private, $date, $tags, $updated = '', $shorturl = '') | 143 | protected function addLink( |
118 | { | 144 | $id, |
145 | $title, | ||
146 | $url, | ||
147 | $description, | ||
148 | $private, | ||
149 | $date, | ||
150 | $tags, | ||
151 | $updated = '', | ||
152 | $shorturl = '', | ||
153 | $pinned = false | ||
154 | ) { | ||
119 | $link = array( | 155 | $link = array( |
120 | 'id' => $id, | 156 | 'id' => $id, |
121 | 'title' => $title, | 157 | 'title' => $title, |
@@ -126,6 +162,7 @@ class ReferenceLinkDB | |||
126 | 'created' => $date, | 162 | 'created' => $date, |
127 | 'updated' => $updated, | 163 | 'updated' => $updated, |
128 | 'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id), | 164 | 'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id), |
165 | 'sticky' => $pinned | ||
129 | ); | 166 | ); |
130 | $this->_links[$id] = $link; | 167 | $this->_links[$id] = $link; |
131 | 168 | ||
@@ -164,7 +201,11 @@ class ReferenceLinkDB | |||
164 | 201 | ||
165 | $order = $order === 'ASC' ? -1 : 1; | 202 | $order = $order === 'ASC' ? -1 : 1; |
166 | // Reorder array by dates. | 203 | // Reorder array by dates. |
167 | usort($this->_links, function($a, $b) use ($order) { | 204 | usort($this->_links, function ($a, $b) use ($order) { |
205 | if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) { | ||
206 | return $a['sticky'] ? -1 : 1; | ||
207 | } | ||
208 | |||
168 | return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; | 209 | return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; |
169 | }); | 210 | }); |
170 | } | 211 | } |
diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index 9c9288f3..1549ddfc 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php | |||
@@ -1,35 +1,84 @@ | |||
1 | <?php /* | 1 | <?php /* |
2 | { | 2 | { |
3 | "credentials": { | 3 | "credentials": { |
4 | "login":"root", | 4 | "login": "root", |
5 | "hash":"hash", | 5 | "hash": "hash", |
6 | "salt":"salt" | 6 | "salt": "salt" |
7 | }, | 7 | }, |
8 | "security": { | 8 | "security": { |
9 | "session_protection_disabled":false | 9 | "session_protection_disabled": false, |
10 | "ban_after": 4, | ||
11 | "ban_duration": 1800, | ||
12 | "open_shaarli": false, | ||
13 | "allowed_protocols": [ | ||
14 | "ftp", | ||
15 | "ftps", | ||
16 | "magnet" | ||
17 | ] | ||
10 | }, | 18 | }, |
11 | "general": { | 19 | "general": { |
12 | "timezone":"Europe\/Paris", | 20 | "timezone": "Europe\/Paris", |
13 | "title": "Shaarli", | 21 | "title": "Shaarli", |
14 | "header_link": "?" | 22 | "header_link": "?", |
23 | "links_per_page": 20, | ||
24 | "enabled_plugins": [ | ||
25 | "qrcode" | ||
26 | ], | ||
27 | "default_note_title": "Note: " | ||
15 | }, | 28 | }, |
16 | "privacy": { | 29 | "privacy": { |
17 | "default_private_links":true | 30 | "default_private_links": true, |
31 | "hide_public_links": false, | ||
32 | "force_login": false, | ||
33 | "hide_timestamps": false, | ||
34 | "remember_user_default": true | ||
18 | }, | 35 | }, |
19 | "redirector": { | 36 | "redirector": { |
20 | "url":"lala" | 37 | "url": "lala", |
38 | "encode_url": true | ||
21 | }, | 39 | }, |
22 | "config": { | 40 | "config": { |
23 | "foo": "bar" | 41 | "foo": "bar" |
24 | }, | 42 | }, |
25 | "resource": { | 43 | "resource": { |
26 | "datastore": "tests\/utils\/config\/datastore.php", | 44 | "datastore": "tests\/utils\/config\/datastore.php", |
27 | "data_dir": "sandbox/", | 45 | "data_dir": "sandbox\/", |
28 | "raintpl_tpl": "tpl/" | 46 | "raintpl_tpl": "tpl\/", |
47 | "config": "data\/config.php", | ||
48 | "ban_file": "data\/ipbans.php", | ||
49 | "updates": "data\/updates.txt", | ||
50 | "log": "data\/log.txt", | ||
51 | "update_check": "data\/lastupdatecheck.txt", | ||
52 | "history": "data\/history.php", | ||
53 | "theme": "default", | ||
54 | "raintpl_tmp": "tmp\/", | ||
55 | "thumbnails_cache": "cache", | ||
56 | "page_cache": "pagecache" | ||
29 | }, | 57 | }, |
30 | "plugins": { | 58 | "plugins": { |
31 | "WALLABAG_VERSION": 1 | 59 | "WALLABAG_VERSION": 1 |
60 | }, | ||
61 | "dev": { | ||
62 | "debug": true | ||
63 | }, | ||
64 | "updates": { | ||
65 | "check_updates": false, | ||
66 | "check_updates_branch": "stable", | ||
67 | "check_updates_interval": 86400 | ||
68 | }, | ||
69 | "feed": { | ||
70 | "rss_permalinks": true, | ||
71 | "show_atom": true | ||
72 | }, | ||
73 | "translation": { | ||
74 | "language": "auto", | ||
75 | "mode": "php", | ||
76 | "extensions": [] | ||
77 | }, | ||
78 | "thumbnails": { | ||
79 | "mode": "common", | ||
80 | "width": 90, | ||
81 | "height": 53 | ||
32 | } | 82 | } |
33 | } | 83 | } |
34 | */ ?> | 84 | */ ?> |
35 | |||
diff --git a/tests/utils/config/configPhp.php b/tests/utils/config/configPhp.php index 0e034175..34b11fcd 100644 --- a/tests/utils/config/configPhp.php +++ b/tests/utils/config/configPhp.php | |||
@@ -1,4 +1,4 @@ | |||
1 | <?php | 1 | <?php |
2 | $GLOBALS['login'] = 'root'; | 2 | $GLOBALS['login'] = 'root'; |
3 | $GLOBALS['hash'] = 'hash'; | 3 | $GLOBALS['hash'] = 'hash'; |
4 | $GLOBALS['salt'] = 'salt'; | 4 | $GLOBALS['salt'] = 'salt'; |
diff --git a/tests/utils/config/wt.json b/tests/utils/config/wt.json new file mode 100644 index 00000000..69ce49a6 --- /dev/null +++ b/tests/utils/config/wt.json | |||
@@ -0,0 +1,12 @@ | |||
1 | { | ||
2 | "settings": { | ||
3 | "default": { | ||
4 | "_comment": "infinite cache", | ||
5 | "cache_duration": -1, | ||
6 | "timeout": 10 | ||
7 | }, | ||
8 | "path": { | ||
9 | "cache": "sandbox/" | ||
10 | } | ||
11 | } | ||
12 | } \ No newline at end of file | ||
diff --git a/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo new file mode 100644 index 00000000..8daae0c9 --- /dev/null +++ b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo | |||
Binary files differ | |||
diff --git a/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po new file mode 100644 index 00000000..90d1abb0 --- /dev/null +++ b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po | |||
@@ -0,0 +1,16 @@ | |||
1 | msgid "" | ||
2 | msgstr "" | ||
3 | "Project-Id-Version: Theme extension test\n" | ||
4 | "POT-Creation-Date: 2017-05-20 13:54+0200\n" | ||
5 | "PO-Revision-Date: 2018-03-26 19:09+0200\n" | ||
6 | "Last-Translator: \n" | ||
7 | "Language-Team: Shaarli\n" | ||
8 | "Language: fr_FR\n" | ||
9 | "MIME-Version: 1.0\n" | ||
10 | "Content-Type: text/plain; charset=UTF-8\n" | ||
11 | "Content-Transfer-Encoding: 8bit\n" | ||
12 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" | ||
13 | "X-Generator: Poedit 2.0.6\n" | ||
14 | |||
15 | msgid "rooster" | ||
16 | msgstr "coq" | ||