aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ApplicationUtilsTest.php6
-rw-r--r--tests/CacheTest.php2
-rw-r--r--tests/FeedBuilderTest.php18
-rw-r--r--tests/HttpUtils/ClientIpIdTest.php52
-rw-r--r--tests/HttpUtils/GetIpAdressFromProxyTest.php3
-rw-r--r--tests/LanguagesTest.php26
-rw-r--r--tests/LinkDBTest.php116
-rw-r--r--tests/LinkFilterTest.php18
-rw-r--r--tests/LinkUtilsTest.php24
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkExportTest.php4
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkImportTest.php15
-rw-r--r--tests/NetscapeBookmarkUtils/input/lowercase_doctype.htm8
-rw-r--r--tests/RouterTest.php1
-rw-r--r--tests/SessionManagerTest.php149
-rw-r--r--tests/ThumbnailerTest.php116
-rw-r--r--tests/Updater/DummyUpdater.php8
-rw-r--r--tests/Updater/UpdaterTest.php195
-rw-r--r--tests/Url/CleanupUrlTest.php1
-rw-r--r--tests/Url/GetUrlSchemeTest.php1
-rw-r--r--tests/Url/UnparseUrlTest.php1
-rw-r--r--tests/Url/UrlTest.php6
-rw-r--r--tests/UtilsTest.php9
-rw-r--r--tests/api/ApiUtilsTest.php3
-rw-r--r--tests/api/controllers/history/HistoryTest.php (renamed from tests/api/controllers/HistoryTest.php)1
-rw-r--r--tests/api/controllers/info/InfoTest.php (renamed from tests/api/controllers/InfoTest.php)4
-rw-r--r--tests/api/controllers/links/DeleteLinkTest.php (renamed from tests/api/controllers/DeleteLinkTest.php)0
-rw-r--r--tests/api/controllers/links/GetLinkIdTest.php (renamed from tests/api/controllers/GetLinkIdTest.php)0
-rw-r--r--tests/api/controllers/links/GetLinksTest.php (renamed from tests/api/controllers/GetLinksTest.php)21
-rw-r--r--tests/api/controllers/links/PostLinkTest.php (renamed from tests/api/controllers/PostLinkTest.php)15
-rw-r--r--tests/api/controllers/links/PutLinkTest.php (renamed from tests/api/controllers/PutLinkTest.php)9
-rw-r--r--tests/api/controllers/tags/DeleteTagTest.php164
-rw-r--r--tests/api/controllers/tags/GetTagNameTest.php129
-rw-r--r--tests/api/controllers/tags/GetTagsTest.php209
-rw-r--r--tests/api/controllers/tags/PutTagTest.php208
-rw-r--r--tests/config/ConfigManagerTest.php23
-rw-r--r--tests/languages/de/UtilsDeTest.php2
-rw-r--r--tests/languages/fr/LanguagesFrTest.php27
-rw-r--r--tests/plugins/PluginIssoTest.php16
-rw-r--r--tests/plugins/PluginMarkdownTest.php99
-rw-r--r--tests/plugins/PluginQrcodeTest.php3
-rw-r--r--tests/plugins/resources/hashtags.md10
-rw-r--r--tests/plugins/resources/hashtags.raw10
-rw-r--r--tests/plugins/resources/markdown.html12
-rw-r--r--tests/plugins/resources/markdown.md2
-rw-r--r--tests/plugins/test/test.php2
-rw-r--r--tests/security/LoginManagerTest.php374
-rw-r--r--tests/security/SessionManagerTest.php272
-rw-r--r--tests/utils/FakeConfigManager.php47
-rw-r--r--tests/utils/ReferenceLinkDB.php49
-rw-r--r--tests/utils/config/configJson.json.php71
-rw-r--r--tests/utils/config/configPhp.php2
-rw-r--r--tests/utils/config/wt.json12
-rw-r--r--tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mobin0 -> 431 bytes
-rw-r--r--tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po16
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
6require_once 'application/HttpUtils.php';
7
8/**
9 * Unitary tests for client_ip_id()
10 */
11class 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 */
8class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase { 8class 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
2require_once 'tests/utils/FakeConfigManager.php';
3
4// Initialize reference data _before_ PHPUnit starts a session
5require_once 'tests/utils/ReferenceSessionIdHashes.php';
6ReferenceSessionIdHashes::genAllHashes();
7
8use \Shaarli\SessionManager;
9use \PHPUnit\Framework\TestCase;
10
11
12/**
13 * Test coverage for SessionManager
14 */
15class 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
3namespace Shaarli;
4
5use PHPUnit\Framework\TestCase;
6use Shaarli\Config\ConfigManager;
7use 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 */
17class 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 @@
2use Shaarli\Config\ConfigJson; 2use Shaarli\Config\ConfigJson;
3use Shaarli\Config\ConfigManager; 3use Shaarli\Config\ConfigManager;
4use Shaarli\Config\ConfigPhp; 4use Shaarli\Config\ConfigPhp;
5use Shaarli\Thumbnailer;
5 6
6require_once 'tests/Updater/DummyUpdater.php'; 7require_once 'tests/Updater/DummyUpdater.php';
7require_once 'inc/rain.tpl.class.php'; 8require_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
5use Shaarli\Base64Url; 5use 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
4namespace Shaarli\Api\Controllers; 4namespace Shaarli\Api\Controllers;
5 5
6
7use Shaarli\Config\ConfigManager; 6use Shaarli\Config\ConfigManager;
8use Slim\Container; 7use Slim\Container;
9use Slim\Http\Environment; 8use 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 */
18class InfoTest extends \PHPUnit_Framework_TestCase 18class 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
3namespace Shaarli\Api\Controllers; 3namespace Shaarli\Api\Controllers;
4 4
5 5use PHPUnit\Framework\TestCase;
6use Shaarli\Config\ConfigManager; 6use Shaarli\Config\ConfigManager;
7use Slim\Container; 7use Slim\Container;
8use Slim\Http\Environment; 8use Slim\Http\Environment;
9use Slim\Http\Request; 9use Slim\Http\Request;
10use Slim\Http\Response; 10use Slim\Http\Response;
11use 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 */
19class PostLinkTest extends \PHPUnit_Framework_TestCase 20class 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
4namespace Shaarli\Api\Controllers; 4namespace Shaarli\Api\Controllers;
5 5
6
7use Shaarli\Config\ConfigManager; 6use Shaarli\Config\ConfigManager;
8use Slim\Container; 7use Slim\Container;
9use Slim\Http\Environment; 8use 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
4namespace Shaarli\Api\Controllers;
5
6use Shaarli\Config\ConfigManager;
7use Slim\Container;
8use Slim\Http\Environment;
9use Slim\Http\Request;
10use Slim\Http\Response;
11
12class 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
3namespace Shaarli\Api\Controllers;
4
5use Shaarli\Config\ConfigManager;
6
7use Slim\Container;
8use Slim\Http\Environment;
9use Slim\Http\Request;
10use Slim\Http\Response;
11
12/**
13 * Class GetTagNameTest
14 *
15 * Test getTag by tag name API service.
16 *
17 * @package Shaarli\Api\Controllers
18 */
19class 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
2namespace Shaarli\Api\Controllers;
3
4use Shaarli\Config\ConfigManager;
5
6use Slim\Container;
7use Slim\Http\Environment;
8use Slim\Http\Request;
9use Slim\Http\Response;
10
11/**
12 * Class GetTagsTest
13 *
14 * Test get tag list REST API service.
15 *
16 * @package Shaarli\Api\Controllers
17 */
18class 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
4namespace Shaarli\Api\Controllers;
5
6use Shaarli\Api\Exceptions\ApiBadParametersException;
7use Shaarli\Config\ConfigManager;
8use Slim\Container;
9use Slim\Http\Environment;
10use Slim\Http\Request;
11use Slim\Http\Response;
12
13class 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
4namespace Shaarli; 4namespace Shaarli;
5 5
6
7use Shaarli\Config\ConfigManager; 6use 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 .= '&#8212; <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 '&#8212; <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 .= '&#8212; <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>';
149 $expected = 'Description... &#8212; [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>&#8212; <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>';
159 $expected = $text;
160 $text .= '<br>&#8212; <a href="http://domain.tld/?0oc_VQ" title="Permalien">Permalien</a>';
161 $expected .= '<br>&#8212; [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```
8bla #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```
8bla #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 &lt;a href=&quot;?addtag=foobar&quot; title=&quot;Hashtag foobar&quot;&gt;#foobar&lt;/a&gt;</li> 15<li>foo <a href="?addtag=foobar">#foobar</a></li>
16</ol></li> 16</ol></li>
17</ol> 17</ol>
18<p>&lt;a href=&quot;?addtag=foobar&quot; title=&quot;Hashtag foobar&quot;&gt;#foobar&lt;/a&gt; foo <code>lol #foo</code> &lt;a href=&quot;?addtag=bar&quot; title=&quot;Hashtag bar&quot;&gt;#bar&lt;/a&gt;</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> &lt;a href=&quot;?addtag=foobar&quot; title=&quot;Hashtag foobar&quot;&gt;#foobar&lt;/a&gt; <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
21next #foo</code></pre> 21next #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(&#039;xss&#039;)">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
2namespace Shaarli\Security;
3
4require_once 'tests/utils/FakeConfigManager.php';
5use \PHPUnit\Framework\TestCase;
6
7/**
8 * Test coverage for LoginManager
9 */
10class 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
2require_once 'tests/utils/FakeConfigManager.php';
3
4// Initialize reference data _before_ PHPUnit starts a session
5require_once 'tests/utils/ReferenceSessionIdHashes.php';
6ReferenceSessionIdHashes::genAllHashes();
7
8use \Shaarli\Security\SessionManager;
9use \PHPUnit\Framework\TestCase;
10
11/**
12 * Test coverage for SessionManager
13 */
14class 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 */
6class FakeConfigManager 6class 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 */
5class ReferenceLinkDB 5class 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 @@
1msgid ""
2msgstr ""
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
15msgid "rooster"
16msgstr "coq"