From 50142efd1b4b826f60b1e5673dba5ccbe26e0108 Mon Sep 17 00:00:00 2001 From: kalvn Date: Thu, 1 Feb 2018 13:16:58 +0100 Subject: Executes daily hooks before creating columns. --- tests/plugins/PluginMarkdownTest.php | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php index 96891f1f..ddc2728d 100644 --- a/tests/plugins/PluginMarkdownTest.php +++ b/tests/plugins/PluginMarkdownTest.php @@ -58,20 +58,17 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $markdown = '# My title' . PHP_EOL . 'Very interesting content.'; $data = array( // Columns data - 'cols' => array( - // First, second, third. + 'linksToDisplay' => array( + // nth link 0 => array( - // nth link - 0 => array( - 'formatedDescription' => $markdown, - ), + 'formatedDescription' => $markdown, ), ), ); $data = hook_markdown_render_daily($data, $this->conf); - $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '

')); - $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '

')); + $this->assertNotFalse(strpos($data['linksToDisplay'][0]['formatedDescription'], '

')); + $this->assertNotFalse(strpos($data['linksToDisplay'][0]['formatedDescription'], '

')); } /** @@ -148,21 +145,18 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $data = array( // Columns data - 'cols' => array( - // First, second, third. + 'linksToDisplay' => array( + // nth link 0 => array( - // nth link - 0 => array( - 'formatedDescription' => $str, - 'tags' => NO_MD_TAG, - 'taglist' => array(), - ), + 'formatedDescription' => $str, + 'tags' => NO_MD_TAG, + 'taglist' => array(), ), ), ); $data = hook_markdown_render_daily($data, $this->conf); - $this->assertEquals($str, $data['cols'][0][0]['formatedDescription']); + $this->assertEquals($str, $data['linksToDisplay'][0]['formatedDescription']); } /** -- cgit v1.2.3 From 5617dcf9d2b378385315161f37da5a85c700c905 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sun, 22 Oct 2017 13:43:19 +0200 Subject: Drop PHP 5.5 compatibility and upgrade PHPUnit to v5.x PHPUnit 4.x contains deprecated PHP functions in PHP 7.2. --- tests/api/controllers/PostLinkTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/api/controllers/PostLinkTest.php b/tests/api/controllers/PostLinkTest.php index 31954e39..100a9170 100644 --- a/tests/api/controllers/PostLinkTest.php +++ b/tests/api/controllers/PostLinkTest.php @@ -3,11 +3,13 @@ namespace Shaarli\Api\Controllers; +use PHPUnit\Framework\TestCase; use Shaarli\Config\ConfigManager; use Slim\Container; use Slim\Http\Environment; use Slim\Http\Request; use Slim\Http\Response; +use Slim\Router; /** * Class PostLinkTest @@ -16,7 +18,7 @@ use Slim\Http\Response; * * @package Shaarli\Api\Controllers */ -class PostLinkTest extends \PHPUnit_Framework_TestCase +class PostLinkTest extends TestCase { /** * @var string datastore to test write operations @@ -78,7 +80,7 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase $this->controller = new Links($this->container); - $mock = $this->getMock('\Slim\Router', ['relativePathFor']); + $mock = $this->createMock(Router::class); $mock->expects($this->any()) ->method('relativePathFor') ->willReturn('api/v1/links/1'); -- cgit v1.2.3 From 44acf706812bc77812e6648c2cc28af36e172a14 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Wed, 25 Oct 2017 23:03:31 +0200 Subject: Refactor login / ban authentication steps Relates to https://github.com/shaarli/Shaarli/issues/324 Added: - Add the `LoginManager` class to manage logins and bans Changed: - Refactor IP ban management - Simplify logic - Avoid using globals, inject dependencies Fixed: - Use `ban_duration` instead of `ban_after` when setting a new ban Signed-off-by: VirtualTam --- tests/LoginManagerTest.php | 199 ++++++++++++++++++++++++++++++++++++++ tests/utils/FakeConfigManager.php | 35 ++++++- 2 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 tests/LoginManagerTest.php (limited to 'tests') diff --git a/tests/LoginManagerTest.php b/tests/LoginManagerTest.php new file mode 100644 index 00000000..4159038e --- /dev/null +++ b/tests/LoginManagerTest.php @@ -0,0 +1,199 @@ +banFile)) { + unlink($this->banFile); + } + + $this->configManager = new \FakeConfigManager([ + 'resource.ban_file' => $this->banFile, + 'resource.log' => $this->logFile, + 'security.ban_after' => 4, + 'security.ban_duration' => 3600, + 'security.trusted_proxies' => [$this->trustedProxy], + ]); + + $this->globals = &$GLOBALS; + unset($this->globals['IPBANS']); + + $this->loginManager = new LoginManager($this->globals, $this->configManager); + $this->server['REMOTE_ADDR'] = $this->ipAddr; + } + + /** + * Wipe test resources + */ + public function tearDown() + { + unset($this->globals['IPBANS']); + } + + /** + * Instantiate a LoginManager and load ban records + */ + public function testReadBanFile() + { + file_put_contents( + $this->banFile, + " array('127.0.0.1' => 99));\n?>" + ); + new LoginManager($this->globals, $this->configManager); + $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); + } + + /** + * Record a failed login attempt + */ + public function testHandleFailedLogin() + { + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + } + + /** + * Record a failed login attempt - IP behind a trusted proxy + */ + public function testHandleFailedLoginBehindTrustedProxy() + { + $server = [ + 'REMOTE_ADDR' => $this->trustedProxy, + 'HTTP_X_FORWARDED_FOR' => $this->ipAddr, + ]; + $this->loginManager->handleFailedLogin($server); + $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + + $this->loginManager->handleFailedLogin($server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + } + + /** + * Record a failed login attempt - IP behind a trusted proxy but not forwarded + */ + public function testHandleFailedLoginBehindTrustedProxyNoIp() + { + $server = [ + 'REMOTE_ADDR' => $this->trustedProxy, + ]; + $this->loginManager->handleFailedLogin($server); + $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); + + $this->loginManager->handleFailedLogin($server); + $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); + } + + /** + * Record a failed login attempt and ban the IP after too many failures + */ + public function testHandleFailedLoginBanIp() + { + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(3, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(4, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertFalse($this->loginManager->canLogin($this->server)); + + // handleFailedLogin is not supposed to be called at this point: + // - no login form should be displayed once an IP has been banned + // - yet this could happen when using custom templates / scripts + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(5, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertFalse($this->loginManager->canLogin($this->server)); + } + + /** + * Nothing to do + */ + public function testHandleSuccessfulLogin() + { + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleSuccessfulLogin($this->server); + $this->assertTrue($this->loginManager->canLogin($this->server)); + } + + /** + * Erase failure records after successfully logging in from this IP + */ + public function testHandleSuccessfulLoginAfterFailure() + { + $this->loginManager->handleFailedLogin($this->server); + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleSuccessfulLogin($this->server); + $this->assertTrue($this->loginManager->canLogin($this->server)); + $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); + $this->assertFalse(isset($this->globals['IPBANS']['BANS'][$this->ipAddr])); + } + + /** + * The IP is not banned + */ + public function testCanLoginIpNotBanned() + { + $this->assertTrue($this->loginManager->canLogin($this->server)); + } + + /** + * The IP is banned + */ + public function testCanLoginIpBanned() + { + // ban the IP for an hour + $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; + $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; + + $this->assertFalse($this->loginManager->canLogin($this->server)); + } + + /** + * The IP is banned, and the ban duration is over + */ + public function testCanLoginIpBanExpired() + { + // ban the IP for an hour + $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; + $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; + $this->assertFalse($this->loginManager->canLogin($this->server)); + + // lift the ban + $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600; + $this->assertTrue($this->loginManager->canLogin($this->server)); + } +} diff --git a/tests/utils/FakeConfigManager.php b/tests/utils/FakeConfigManager.php index f29760cb..85434de7 100644 --- a/tests/utils/FakeConfigManager.php +++ b/tests/utils/FakeConfigManager.php @@ -5,8 +5,41 @@ */ class FakeConfigManager { - public static function get($key) + protected $values = []; + + /** + * Initialize with test values + * + * @param array $values Initial values + */ + public function __construct($values = []) + { + $this->values = $values; + } + + /** + * Set a given value + * + * @param string $key Key of the value to set + * @param mixed $value Value to set + */ + public function set($key, $value) + { + $this->values[$key] = $value; + } + + /** + * Get a given configuration value + * + * @param string $key Index of the value to retrieve + * + * @return mixed The value if set, else the name of the key + */ + public function get($key) { + if (isset($this->values[$key])) { + return $this->values[$key]; + } return $key; } } -- cgit v1.2.3 From 3ff1ce47bc9e512ae67b009296c8ac7a6654c9ad Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 23 Feb 2018 20:34:06 +0100 Subject: Ignore the case while checking DOCTYPE during the file import Fixes #1091 --- tests/NetscapeBookmarkUtils/BookmarkImportTest.php | 15 +++++++++++++++ tests/NetscapeBookmarkUtils/input/lowercase_doctype.htm | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/NetscapeBookmarkUtils/input/lowercase_doctype.htm (limited to 'tests') 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 @@ -126,6 +126,21 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase $this->assertEquals(0, count($this->linkDb)); } + /** + * Attempt to import bookmarks from a file with a lowercase Doctype + */ + public function testImportLowecaseDoctype() + { + $files = file2array('lowercase_doctype.htm'); + $this->assertStringMatchesFormat( + 'File lowercase_doctype.htm (386 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import(null, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + } + + /** * Ensure IE dumps are supported */ 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 @@ + +Bookmarks +

Bookmarks

+

+

Secret stuff +
Super-secret stuff you're not supposed to know about +
Public stuff +

-- cgit v1.2.3 From d2d4f993e1e76bc68b65c48cb18476c404c97a41 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 28 Feb 2018 22:34:40 +0100 Subject: PSR: use elseif instead of else if See https://www.php-fig.org/psr/psr-2/\#51-if-elseif-else --- tests/plugins/test/test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') 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) { if (isset($data['_PAGE_']) && $data['_PAGE_'] == 'test') { $data[1] = 'page test'; - } else if (isset($data['_LOGGEDIN_']) && $data['_LOGGEDIN_'] === true) { + } elseif (isset($data['_LOGGEDIN_']) && $data['_LOGGEDIN_'] === true) { $data[1] = 'loggedin'; } else { $data[1] = $data[0]; -- cgit v1.2.3 From 4ff3ed1c47365d5b28f70cb2921b0ac0075612c3 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 28 Feb 2018 22:29:43 +0100 Subject: Make max download size and timeout configurable Fixes #1061 --- tests/Updater/UpdaterTest.php | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'tests') diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index fed175df..94e3c7d3 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -620,4 +620,68 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $this->assertTrue($updater->updateMethodAtomDefault()); $this->assertTrue($this->conf->get('feed.show_atom')); } + + /** + * Test updateMethodDownloadSizeAndTimeoutConf, it should be set if none is already defined. + */ + public function testUpdateMethodDownloadSizeAndTimeoutConf() + { + $sandboxConf = 'sandbox/config'; + copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); + $this->conf = new ConfigManager($sandboxConf); + $updater = new Updater([], [], $this->conf, true); + $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); + $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); + $this->assertEquals(30, $this->conf->get('general.download_timeout')); + + $this->conf = new ConfigManager($sandboxConf); + $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); + $this->assertEquals(30, $this->conf->get('general.download_timeout')); + } + + /** + * Test updateMethodDownloadSizeAndTimeoutConf, it shouldn't be set if it is already defined. + */ + public function testUpdateMethodDownloadSizeAndTimeoutConfIgnore() + { + $sandboxConf = 'sandbox/config'; + copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); + $this->conf = new ConfigManager($sandboxConf); + $this->conf->set('general.download_max_size', 38); + $this->conf->set('general.download_timeout', 70); + $updater = new Updater([], [], $this->conf, true); + $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); + $this->assertEquals(38, $this->conf->get('general.download_max_size')); + $this->assertEquals(70, $this->conf->get('general.download_timeout')); + } + + /** + * Test updateMethodDownloadSizeAndTimeoutConf, only the maz size should be set here. + */ + public function testUpdateMethodDownloadSizeAndTimeoutConfOnlySize() + { + $sandboxConf = 'sandbox/config'; + copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); + $this->conf = new ConfigManager($sandboxConf); + $this->conf->set('general.download_max_size', 38); + $updater = new Updater([], [], $this->conf, true); + $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); + $this->assertEquals(38, $this->conf->get('general.download_max_size')); + $this->assertEquals(30, $this->conf->get('general.download_timeout')); + } + + /** + * Test updateMethodDownloadSizeAndTimeoutConf, only the time out should be set here. + */ + public function testUpdateMethodDownloadSizeAndTimeoutConfOnlyTimeout() + { + $sandboxConf = 'sandbox/config'; + copy(self::$configFile . '.json.php', $sandboxConf . '.json.php'); + $this->conf = new ConfigManager($sandboxConf); + $this->conf->set('general.download_timeout', 3); + $updater = new Updater([], [], $this->conf, true); + $this->assertTrue($updater->updateMethodDownloadSizeAndTimeoutConf()); + $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); + $this->assertEquals(3, $this->conf->get('general.download_timeout')); + } } -- cgit v1.2.3 From 68c6afc56f3758154cfb96cba6fd48a6b5535590 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 26 Feb 2018 22:53:00 +0100 Subject: Load theme translations files automatically Fixes #1077 Take a look at the docs update to see how it works --- tests/LanguagesTest.php | 26 +++++++++++++++++++++ tests/languages/fr/LanguagesFrTest.php | 26 +++++++++++++++++++++ .../dummy/language/fr/LC_MESSAGES/dummy.mo | Bin 0 -> 431 bytes .../dummy/language/fr/LC_MESSAGES/dummy.po | 16 +++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo create mode 100644 tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po (limited to 'tests') diff --git a/tests/LanguagesTest.php b/tests/LanguagesTest.php index 864ce630..4951e09a 100644 --- a/tests/LanguagesTest.php +++ b/tests/LanguagesTest.php @@ -175,6 +175,32 @@ class LanguagesTest extends \PHPUnit_Framework_TestCase $this->assertEquals($text, t($text)); } + /** + * Test t() with an extension language file coming from the theme in gettext mode + */ + public function testTranslationThemeExtensionGettext() + { + $this->conf->set('translation.mode', 'gettext'); + $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); + $this->conf->set('theme', 'dummy'); + new Languages('en', $this->conf); + $txt = 'rooster'; // ignore me poedit + $this->assertEquals('rooster', t($txt, $txt, 1, 'dummy')); + } + + /** + * Test t() with an extension language file coming from the theme in PHP mode + */ + public function testTranslationThemeExtensionPhp() + { + $this->conf->set('translation.mode', 'php'); + $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); + $this->conf->set('theme', 'dummy'); + new Languages('en', $this->conf); + $txt = 'rooster'; // ignore me poedit + $this->assertEquals('rooster', t($txt, $txt, 1, 'dummy')); + } + /** * Test t() with an extension language file in gettext mode */ diff --git a/tests/languages/fr/LanguagesFrTest.php b/tests/languages/fr/LanguagesFrTest.php index 79d05172..0cf74891 100644 --- a/tests/languages/fr/LanguagesFrTest.php +++ b/tests/languages/fr/LanguagesFrTest.php @@ -172,4 +172,30 @@ class LanguagesFrTest extends \PHPUnit_Framework_TestCase $this->assertEquals('voiture', t($txt, $txt, 1, 'test')); $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test')); } + + /** + * Test t() with an extension language file coming from the theme in gettext mode + */ + public function testTranslationThemeExtensionGettext() + { + $this->conf->set('translation.mode', 'gettext'); + $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); + $this->conf->set('theme', 'dummy'); + new Languages('en', $this->conf); + $txt = 'rooster'; // ignore me poedit + $this->assertEquals('coq', t($txt, $txt, 1, 'dummy')); + } + + /** + * Test t() with an extension language file coming from the theme in PHP mode + */ + public function testTranslationThemeExtensionPhp() + { + $this->conf->set('translation.mode', 'php'); + $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/'); + $this->conf->set('theme', 'dummy'); + new Languages('en', $this->conf); + $txt = 'rooster'; // ignore me poedit + $this->assertEquals('coq', t($txt, $txt, 1, 'dummy')); + } } 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 Binary files /dev/null and b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo 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 @@ +msgid "" +msgstr "" +"Project-Id-Version: Theme extension test\n" +"POT-Creation-Date: 2017-05-20 13:54+0200\n" +"PO-Revision-Date: 2018-03-26 19:09+0200\n" +"Last-Translator: \n" +"Language-Team: Shaarli\n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.0.6\n" + +msgid "rooster" +msgstr "coq" -- cgit v1.2.3 From c5ee13181ef9b0cd09886051aaf0754859090e76 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 31 Mar 2018 12:50:03 +0200 Subject: Update parsedown to its latest version instead of fixed 1.6 --- tests/plugins/resources/markdown.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/plugins/resources/markdown.html b/tests/plugins/resources/markdown.html index 844a6f31..f1df4e7e 100644 --- a/tests/plugins/resources/markdown.html +++ b/tests/plugins/resources/markdown.html @@ -8,7 +8,7 @@

  1. zero -
      +
      1. two
      2. three
      3. four
      4. @@ -29,5 +29,5 @@ next #foo link
        link
        link
        -link
        +link
        link

        \ No newline at end of file -- cgit v1.2.3 From dd6794cff8a1f26c4d08544d89e1df1f521dcb26 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 19 May 2018 12:55:43 +0200 Subject: Fix feed permalink rendering with markdown escape set to true Fixes #1134 --- tests/plugins/PluginMarkdownTest.php | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'tests') diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php index ddc2728d..b31e817f 100644 --- a/tests/plugins/PluginMarkdownTest.php +++ b/tests/plugins/PluginMarkdownTest.php @@ -49,6 +49,30 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $this->assertNotFalse(strpos($data['links'][0]['description'], '

        ')); } + /** + * Test render_feed hook. + */ + public function testMarkdownFeed() + { + $markdown = '# My title' . PHP_EOL . 'Very interesting content.'; + $markdown .= '— Permalien'; + $data = array( + 'links' => array( + 0 => array( + 'description' => $markdown, + ), + ), + ); + + $data = hook_markdown_render_feed($data, $this->conf); + $this->assertNotFalse(strpos($data['links'][0]['description'], '

        ')); + $this->assertNotFalse(strpos($data['links'][0]['description'], '

        ')); + $this->assertStringEndsWith( + '— Permalien

        ', + $data['links'][0]['description'] + ); + } + /** * Test render_daily hook. * Only check that there is basic markdown rendering. @@ -104,6 +128,37 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $this->assertEquals($text, $reversedText); } + public function testReverseFeedPermalink() + { + $text = 'Description... '; + $text .= '— Permalien'; + $expected = 'Description... — [Permalien](http://domain.tld/?0oc_VQ)'; + $processedText = reverse_feed_permalink($text); + + $this->assertEquals($expected, $processedText); + } + + public function testReverseLastFeedPermalink() + { + $text = 'Description... '; + $text .= '
        Permalien'; + $expected = $text; + $text .= '
        Permalien'; + $expected .= '
        — [Permalien](http://domain.tld/?0oc_VQ)'; + $processedText = reverse_feed_permalink($text); + + $this->assertEquals($expected, $processedText); + } + + public function testReverseNoFeedPermalink() + { + $text = 'Hello! Where are you from?'; + $expected = $text; + $processedText = reverse_feed_permalink($text); + + $this->assertEquals($expected, $processedText); + } + /** * Test sanitize_html(). */ -- cgit v1.2.3 From f8c5660df82432c7f3bb0686e393db5a2b46eeb5 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Tue, 29 May 2018 20:52:30 +0200 Subject: Tag sort - UT + comment + fix filter and visibility Before this, linksCountPerTag call without would have ignored visibility parameter --- tests/LinkDBTest.php | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'tests') diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index 5b2f3667..3b980878 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php @@ -542,4 +542,104 @@ class LinkDBTest extends PHPUnit_Framework_TestCase $this->assertEquals(3, count($res)); $this->assertNotContains('cartoon', $linkDB[4]['tags']); } + + /** + * Test linksCountPerTag all tags without filter. + * Equal occurrences should be sorted alphabetically. + */ + public function testCountLinkPerTagAllNoFilter() + { + $expected = [ + 'web' => 4, + 'cartoon' => 3, + 'dev' => 2, + 'gnu' => 2, + 'hashtag' => 2, + 'sTuff' => 2, + '-exclude' => 1, + '.hidden' => 1, + 'Mercurial' => 1, + 'css' => 1, + 'free' => 1, + 'html' => 1, + 'media' => 1, + 'samba' => 1, + 'software' => 1, + 'stallman' => 1, + 'tag1' => 1, + 'tag2' => 1, + 'tag3' => 1, + 'tag4' => 1, + 'ut' => 1, + 'w3c' => 1, + ]; + $tags = self::$privateLinkDB->linksCountPerTag(); + + $this->assertEquals($expected, $tags, var_export($tags, true)); + } + + /** + * Test linksCountPerTag all tags with filter. + * Equal occurrences should be sorted alphabetically. + */ + public function testCountLinkPerTagAllWithFilter() + { + $expected = [ + 'gnu' => 2, + 'hashtag' => 2, + '-exclude' => 1, + '.hidden' => 1, + 'free' => 1, + 'media' => 1, + 'software' => 1, + 'stallman' => 1, + 'stuff' => 1, + 'web' => 1, + ]; + $tags = self::$privateLinkDB->linksCountPerTag(['gnu']); + + $this->assertEquals($expected, $tags, var_export($tags, true)); + } + + /** + * Test linksCountPerTag public tags with filter. + * Equal occurrences should be sorted alphabetically. + */ + public function testCountLinkPerTagPublicWithFilter() + { + $expected = [ + 'gnu' => 2, + 'hashtag' => 2, + '-exclude' => 1, + '.hidden' => 1, + 'free' => 1, + 'media' => 1, + 'software' => 1, + 'stallman' => 1, + 'stuff' => 1, + 'web' => 1, + ]; + $tags = self::$privateLinkDB->linksCountPerTag(['gnu'], 'public'); + + $this->assertEquals($expected, $tags, var_export($tags, true)); + } + + /** + * Test linksCountPerTag public tags with filter. + * Equal occurrences should be sorted alphabetically. + */ + public function testCountLinkPerTagPrivateWithFilter() + { + $expected = [ + 'cartoon' => 1, + 'dev' => 1, + 'tag1' => 1, + 'tag2' => 1, + 'tag3' => 1, + 'tag4' => 1, + ]; + $tags = self::$privateLinkDB->linksCountPerTag(['dev'], 'private'); + + $this->assertEquals($expected, $tags, var_export($tags, true)); + } } -- cgit v1.2.3 From 88110550b89617dcda16441212599b8a40faa20c Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Fri, 16 Feb 2018 21:51:44 +0100 Subject: Refactor client session hijacking protection Signed-off-by: VirtualTam --- tests/HttpUtils/ClientIpIdTest.php | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/HttpUtils/ClientIpIdTest.php (limited to 'tests') 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 @@ +assertEquals( + '10.1.167.42', + client_ip_id(['REMOTE_ADDR' => '10.1.167.42']) + ); + } + + /** + * Get a remote client ID based on its IP and proxy information (1) + */ + public function testClientIpIdRemoteForwarded() + { + $this->assertEquals( + '10.1.167.42_127.0.1.47', + client_ip_id([ + 'REMOTE_ADDR' => '10.1.167.42', + 'HTTP_X_FORWARDED_FOR' => '127.0.1.47' + ]) + ); + } + + /** + * Get a remote client ID based on its IP and proxy information (2) + */ + public function testClientIpIdRemoteForwardedClient() + { + $this->assertEquals( + '10.1.167.42_10.1.167.56_127.0.1.47', + client_ip_id([ + 'REMOTE_ADDR' => '10.1.167.42', + 'HTTP_X_FORWARDED_FOR' => '10.1.167.56', + 'HTTP_CLIENT_IP' => '127.0.1.47' + ]) + ); + } +} -- cgit v1.2.3 From 63ea23c2a67d2a1cf6cda79fa2fe49a143571cde Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sat, 17 Feb 2018 01:46:27 +0100 Subject: Refactor user credential validation at login time Changed: - move login/password verification to LoginManager - code cleanup Signed-off-by: VirtualTam --- tests/LoginManagerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/LoginManagerTest.php b/tests/LoginManagerTest.php index 4159038e..27ca0db5 100644 --- a/tests/LoginManagerTest.php +++ b/tests/LoginManagerTest.php @@ -38,7 +38,7 @@ class LoginManagerTest extends TestCase $this->globals = &$GLOBALS; unset($this->globals['IPBANS']); - $this->loginManager = new LoginManager($this->globals, $this->configManager); + $this->loginManager = new LoginManager($this->globals, $this->configManager, null); $this->server['REMOTE_ADDR'] = $this->ipAddr; } @@ -59,7 +59,7 @@ class LoginManagerTest extends TestCase $this->banFile, " array('127.0.0.1' => 99));\n?>" ); - new LoginManager($this->globals, $this->configManager); + new LoginManager($this->globals, $this->configManager, null); $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); } -- cgit v1.2.3 From fab87c2696b9d6a26310f1bfc024b018ca5184fe Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Fri, 27 Apr 2018 22:12:22 +0200 Subject: Move LoginManager and SessionManager to the Security namespace Signed-off-by: VirtualTam --- tests/LoginManagerTest.php | 199 ---------------------------------- tests/SessionManagerTest.php | 149 ------------------------- tests/security/LoginManagerTest.php | 199 ++++++++++++++++++++++++++++++++++ tests/security/SessionManagerTest.php | 149 +++++++++++++++++++++++++ 4 files changed, 348 insertions(+), 348 deletions(-) delete mode 100644 tests/LoginManagerTest.php delete mode 100644 tests/SessionManagerTest.php create mode 100644 tests/security/LoginManagerTest.php create mode 100644 tests/security/SessionManagerTest.php (limited to 'tests') diff --git a/tests/LoginManagerTest.php b/tests/LoginManagerTest.php deleted file mode 100644 index 27ca0db5..00000000 --- a/tests/LoginManagerTest.php +++ /dev/null @@ -1,199 +0,0 @@ -banFile)) { - unlink($this->banFile); - } - - $this->configManager = new \FakeConfigManager([ - 'resource.ban_file' => $this->banFile, - 'resource.log' => $this->logFile, - 'security.ban_after' => 4, - 'security.ban_duration' => 3600, - 'security.trusted_proxies' => [$this->trustedProxy], - ]); - - $this->globals = &$GLOBALS; - unset($this->globals['IPBANS']); - - $this->loginManager = new LoginManager($this->globals, $this->configManager, null); - $this->server['REMOTE_ADDR'] = $this->ipAddr; - } - - /** - * Wipe test resources - */ - public function tearDown() - { - unset($this->globals['IPBANS']); - } - - /** - * Instantiate a LoginManager and load ban records - */ - public function testReadBanFile() - { - file_put_contents( - $this->banFile, - " array('127.0.0.1' => 99));\n?>" - ); - new LoginManager($this->globals, $this->configManager, null); - $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); - } - - /** - * Record a failed login attempt - */ - public function testHandleFailedLogin() - { - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - } - - /** - * Record a failed login attempt - IP behind a trusted proxy - */ - public function testHandleFailedLoginBehindTrustedProxy() - { - $server = [ - 'REMOTE_ADDR' => $this->trustedProxy, - 'HTTP_X_FORWARDED_FOR' => $this->ipAddr, - ]; - $this->loginManager->handleFailedLogin($server); - $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - - $this->loginManager->handleFailedLogin($server); - $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - } - - /** - * Record a failed login attempt - IP behind a trusted proxy but not forwarded - */ - public function testHandleFailedLoginBehindTrustedProxyNoIp() - { - $server = [ - 'REMOTE_ADDR' => $this->trustedProxy, - ]; - $this->loginManager->handleFailedLogin($server); - $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); - - $this->loginManager->handleFailedLogin($server); - $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); - } - - /** - * Record a failed login attempt and ban the IP after too many failures - */ - public function testHandleFailedLoginBanIp() - { - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - $this->assertTrue($this->loginManager->canLogin($this->server)); - - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - $this->assertTrue($this->loginManager->canLogin($this->server)); - - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(3, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - $this->assertTrue($this->loginManager->canLogin($this->server)); - - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(4, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - $this->assertFalse($this->loginManager->canLogin($this->server)); - - // handleFailedLogin is not supposed to be called at this point: - // - no login form should be displayed once an IP has been banned - // - yet this could happen when using custom templates / scripts - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(5, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - $this->assertFalse($this->loginManager->canLogin($this->server)); - } - - /** - * Nothing to do - */ - public function testHandleSuccessfulLogin() - { - $this->assertTrue($this->loginManager->canLogin($this->server)); - - $this->loginManager->handleSuccessfulLogin($this->server); - $this->assertTrue($this->loginManager->canLogin($this->server)); - } - - /** - * Erase failure records after successfully logging in from this IP - */ - public function testHandleSuccessfulLoginAfterFailure() - { - $this->loginManager->handleFailedLogin($this->server); - $this->loginManager->handleFailedLogin($this->server); - $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); - $this->assertTrue($this->loginManager->canLogin($this->server)); - - $this->loginManager->handleSuccessfulLogin($this->server); - $this->assertTrue($this->loginManager->canLogin($this->server)); - $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); - $this->assertFalse(isset($this->globals['IPBANS']['BANS'][$this->ipAddr])); - } - - /** - * The IP is not banned - */ - public function testCanLoginIpNotBanned() - { - $this->assertTrue($this->loginManager->canLogin($this->server)); - } - - /** - * The IP is banned - */ - public function testCanLoginIpBanned() - { - // ban the IP for an hour - $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; - $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; - - $this->assertFalse($this->loginManager->canLogin($this->server)); - } - - /** - * The IP is banned, and the ban duration is over - */ - public function testCanLoginIpBanExpired() - { - // ban the IP for an hour - $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; - $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; - $this->assertFalse($this->loginManager->canLogin($this->server)); - - // lift the ban - $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600; - $this->assertTrue($this->loginManager->canLogin($this->server)); - } -} 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 @@ -generateToken(); - - $this->assertEquals(1, $session['tokens'][$token]); - $this->assertEquals(40, strlen($token)); - } - - /** - * Check a session token - */ - public function testCheckToken() - { - $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'; - $session = [ - 'tokens' => [ - $token => 1, - ], - ]; - $sessionManager = new SessionManager($session, self::$conf); - - // check and destroy the token - $this->assertTrue($sessionManager->checkToken($token)); - $this->assertFalse(isset($session['tokens'][$token])); - - // ensure the token has been destroyed - $this->assertFalse($sessionManager->checkToken($token)); - } - - /** - * Generate and check a session token - */ - public function testGenerateAndCheckToken() - { - $session = []; - $sessionManager = new SessionManager($session, self::$conf); - - $token = $sessionManager->generateToken(); - - // ensure a token has been generated - $this->assertEquals(1, $session['tokens'][$token]); - $this->assertEquals(40, strlen($token)); - - // check and destroy the token - $this->assertTrue($sessionManager->checkToken($token)); - $this->assertFalse(isset($session['tokens'][$token])); - - // ensure the token has been destroyed - $this->assertFalse($sessionManager->checkToken($token)); - } - - /** - * Check an invalid session token - */ - public function testCheckInvalidToken() - { - $session = []; - $sessionManager = new SessionManager($session, self::$conf); - - $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); - } - - /** - * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES! - * - * This tests extensively covers all hash algorithms / bit representations - */ - public function testIsAnyHashSessionIdValid() - { - foreach (self::$sidHashes as $algo => $bpcs) { - foreach ($bpcs as $bpc => $hash) { - $this->assertTrue(SessionManager::checkId($hash)); - } - } - } - - /** - * Test checkId with a valid ID - SHA-1 hashes - */ - public function testIsSha1SessionIdValid() - { - $this->assertTrue(SessionManager::checkId(sha1('shaarli'))); - } - - /** - * Test checkId with a valid ID - SHA-256 hashes - */ - public function testIsSha256SessionIdValid() - { - $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli'))); - } - - /** - * Test checkId with a valid ID - SHA-512 hashes - */ - public function testIsSha512SessionIdValid() - { - $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli'))); - } - - /** - * Test checkId with invalid IDs. - */ - public function testIsSessionIdInvalid() - { - $this->assertFalse(SessionManager::checkId('')); - $this->assertFalse(SessionManager::checkId([])); - $this->assertFalse( - SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') - ); - } -} diff --git a/tests/security/LoginManagerTest.php b/tests/security/LoginManagerTest.php new file mode 100644 index 00000000..b957abe3 --- /dev/null +++ b/tests/security/LoginManagerTest.php @@ -0,0 +1,199 @@ +banFile)) { + unlink($this->banFile); + } + + $this->configManager = new \FakeConfigManager([ + 'resource.ban_file' => $this->banFile, + 'resource.log' => $this->logFile, + 'security.ban_after' => 4, + 'security.ban_duration' => 3600, + 'security.trusted_proxies' => [$this->trustedProxy], + ]); + + $this->globals = &$GLOBALS; + unset($this->globals['IPBANS']); + + $this->loginManager = new LoginManager($this->globals, $this->configManager, null); + $this->server['REMOTE_ADDR'] = $this->ipAddr; + } + + /** + * Wipe test resources + */ + public function tearDown() + { + unset($this->globals['IPBANS']); + } + + /** + * Instantiate a LoginManager and load ban records + */ + public function testReadBanFile() + { + file_put_contents( + $this->banFile, + " array('127.0.0.1' => 99));\n?>" + ); + new LoginManager($this->globals, $this->configManager, null); + $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); + } + + /** + * Record a failed login attempt + */ + public function testHandleFailedLogin() + { + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + } + + /** + * Record a failed login attempt - IP behind a trusted proxy + */ + public function testHandleFailedLoginBehindTrustedProxy() + { + $server = [ + 'REMOTE_ADDR' => $this->trustedProxy, + 'HTTP_X_FORWARDED_FOR' => $this->ipAddr, + ]; + $this->loginManager->handleFailedLogin($server); + $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + + $this->loginManager->handleFailedLogin($server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + } + + /** + * Record a failed login attempt - IP behind a trusted proxy but not forwarded + */ + public function testHandleFailedLoginBehindTrustedProxyNoIp() + { + $server = [ + 'REMOTE_ADDR' => $this->trustedProxy, + ]; + $this->loginManager->handleFailedLogin($server); + $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); + + $this->loginManager->handleFailedLogin($server); + $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); + } + + /** + * Record a failed login attempt and ban the IP after too many failures + */ + public function testHandleFailedLoginBanIp() + { + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(1, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(3, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(4, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertFalse($this->loginManager->canLogin($this->server)); + + // handleFailedLogin is not supposed to be called at this point: + // - no login form should be displayed once an IP has been banned + // - yet this could happen when using custom templates / scripts + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(5, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertFalse($this->loginManager->canLogin($this->server)); + } + + /** + * Nothing to do + */ + public function testHandleSuccessfulLogin() + { + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleSuccessfulLogin($this->server); + $this->assertTrue($this->loginManager->canLogin($this->server)); + } + + /** + * Erase failure records after successfully logging in from this IP + */ + public function testHandleSuccessfulLoginAfterFailure() + { + $this->loginManager->handleFailedLogin($this->server); + $this->loginManager->handleFailedLogin($this->server); + $this->assertEquals(2, $this->globals['IPBANS']['FAILURES'][$this->ipAddr]); + $this->assertTrue($this->loginManager->canLogin($this->server)); + + $this->loginManager->handleSuccessfulLogin($this->server); + $this->assertTrue($this->loginManager->canLogin($this->server)); + $this->assertFalse(isset($this->globals['IPBANS']['FAILURES'][$this->ipAddr])); + $this->assertFalse(isset($this->globals['IPBANS']['BANS'][$this->ipAddr])); + } + + /** + * The IP is not banned + */ + public function testCanLoginIpNotBanned() + { + $this->assertTrue($this->loginManager->canLogin($this->server)); + } + + /** + * The IP is banned + */ + public function testCanLoginIpBanned() + { + // ban the IP for an hour + $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; + $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; + + $this->assertFalse($this->loginManager->canLogin($this->server)); + } + + /** + * The IP is banned, and the ban duration is over + */ + public function testCanLoginIpBanExpired() + { + // ban the IP for an hour + $this->globals['IPBANS']['FAILURES'][$this->ipAddr] = 10; + $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() + 3600; + $this->assertFalse($this->loginManager->canLogin($this->server)); + + // lift the ban + $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600; + $this->assertTrue($this->loginManager->canLogin($this->server)); + } +} diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php new file mode 100644 index 00000000..e4e1cfbc --- /dev/null +++ b/tests/security/SessionManagerTest.php @@ -0,0 +1,149 @@ +generateToken(); + + $this->assertEquals(1, $session['tokens'][$token]); + $this->assertEquals(40, strlen($token)); + } + + /** + * Check a session token + */ + public function testCheckToken() + { + $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'; + $session = [ + 'tokens' => [ + $token => 1, + ], + ]; + $sessionManager = new SessionManager($session, self::$conf); + + // check and destroy the token + $this->assertTrue($sessionManager->checkToken($token)); + $this->assertFalse(isset($session['tokens'][$token])); + + // ensure the token has been destroyed + $this->assertFalse($sessionManager->checkToken($token)); + } + + /** + * Generate and check a session token + */ + public function testGenerateAndCheckToken() + { + $session = []; + $sessionManager = new SessionManager($session, self::$conf); + + $token = $sessionManager->generateToken(); + + // ensure a token has been generated + $this->assertEquals(1, $session['tokens'][$token]); + $this->assertEquals(40, strlen($token)); + + // check and destroy the token + $this->assertTrue($sessionManager->checkToken($token)); + $this->assertFalse(isset($session['tokens'][$token])); + + // ensure the token has been destroyed + $this->assertFalse($sessionManager->checkToken($token)); + } + + /** + * Check an invalid session token + */ + public function testCheckInvalidToken() + { + $session = []; + $sessionManager = new SessionManager($session, self::$conf); + + $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); + } + + /** + * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES! + * + * This tests extensively covers all hash algorithms / bit representations + */ + public function testIsAnyHashSessionIdValid() + { + foreach (self::$sidHashes as $algo => $bpcs) { + foreach ($bpcs as $bpc => $hash) { + $this->assertTrue(SessionManager::checkId($hash)); + } + } + } + + /** + * Test checkId with a valid ID - SHA-1 hashes + */ + public function testIsSha1SessionIdValid() + { + $this->assertTrue(SessionManager::checkId(sha1('shaarli'))); + } + + /** + * Test checkId with a valid ID - SHA-256 hashes + */ + public function testIsSha256SessionIdValid() + { + $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli'))); + } + + /** + * Test checkId with a valid ID - SHA-512 hashes + */ + public function testIsSha512SessionIdValid() + { + $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli'))); + } + + /** + * Test checkId with invalid IDs. + */ + public function testIsSessionIdInvalid() + { + $this->assertFalse(SessionManager::checkId('')); + $this->assertFalse(SessionManager::checkId([])); + $this->assertFalse( + SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') + ); + } +} -- cgit v1.2.3 From 51f0128cdba52099c40693379e72f094b42a6f80 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Fri, 27 Apr 2018 23:17:38 +0200 Subject: Refactor session and cookie timeout control Signed-off-by: VirtualTam --- tests/security/SessionManagerTest.php | 181 +++++++++++++++++++++++++++++----- 1 file changed, 159 insertions(+), 22 deletions(-) (limited to 'tests') diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php index e4e1cfbc..e1c72707 100644 --- a/tests/security/SessionManagerTest.php +++ b/tests/security/SessionManagerTest.php @@ -14,11 +14,17 @@ use \PHPUnit\Framework\TestCase; */ class SessionManagerTest extends TestCase { - // Session ID hashes + /** @var array Session ID hashes */ protected static $sidHashes = null; - // Fake ConfigManager - protected static $conf = null; + /** @var FakeConfigManager ConfigManager substitute for testing */ + protected $conf = null; + + /** @var array $_SESSION array for testing */ + protected $session = []; + + /** @var SessionManager Server-side session management abstraction */ + protected $sessionManager = null; /** * Assign reference data @@ -26,7 +32,20 @@ class SessionManagerTest extends TestCase public static function setUpBeforeClass() { self::$sidHashes = ReferenceSessionIdHashes::getHashes(); - self::$conf = new FakeConfigManager(); + } + + /** + * Initialize or reset test resources + */ + public function setUp() + { + $this->conf = new FakeConfigManager([ + 'credentials.login' => 'johndoe', + 'credentials.salt' => 'salt', + 'security.session_protection_disabled' => false, + ]); + $this->session = []; + $this->sessionManager = new SessionManager($this->session, $this->conf); } /** @@ -34,12 +53,9 @@ class SessionManagerTest extends TestCase */ public function testGenerateToken() { - $session = []; - $sessionManager = new SessionManager($session, self::$conf); - - $token = $sessionManager->generateToken(); + $token = $this->sessionManager->generateToken(); - $this->assertEquals(1, $session['tokens'][$token]); + $this->assertEquals(1, $this->session['tokens'][$token]); $this->assertEquals(40, strlen($token)); } @@ -54,7 +70,7 @@ class SessionManagerTest extends TestCase $token => 1, ], ]; - $sessionManager = new SessionManager($session, self::$conf); + $sessionManager = new SessionManager($session, $this->conf); // check and destroy the token $this->assertTrue($sessionManager->checkToken($token)); @@ -69,21 +85,18 @@ class SessionManagerTest extends TestCase */ public function testGenerateAndCheckToken() { - $session = []; - $sessionManager = new SessionManager($session, self::$conf); - - $token = $sessionManager->generateToken(); + $token = $this->sessionManager->generateToken(); // ensure a token has been generated - $this->assertEquals(1, $session['tokens'][$token]); + $this->assertEquals(1, $this->session['tokens'][$token]); $this->assertEquals(40, strlen($token)); // check and destroy the token - $this->assertTrue($sessionManager->checkToken($token)); - $this->assertFalse(isset($session['tokens'][$token])); + $this->assertTrue($this->sessionManager->checkToken($token)); + $this->assertFalse(isset($this->session['tokens'][$token])); // ensure the token has been destroyed - $this->assertFalse($sessionManager->checkToken($token)); + $this->assertFalse($this->sessionManager->checkToken($token)); } /** @@ -91,10 +104,7 @@ class SessionManagerTest extends TestCase */ public function testCheckInvalidToken() { - $session = []; - $sessionManager = new SessionManager($session, self::$conf); - - $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); + $this->assertFalse($this->sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); } /** @@ -146,4 +156,131 @@ class SessionManagerTest extends TestCase SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') ); } + + /** + * Store login information after a successful login + */ + public function testStoreLoginInfo() + { + $this->sessionManager->storeLoginInfo('ip_id'); + + $this->assertTrue(isset($this->session['uid'])); + $this->assertGreaterThan(time(), $this->session['expires_on']); + $this->assertEquals('ip_id', $this->session['ip']); + $this->assertEquals('johndoe', $this->session['username']); + } + + /** + * Extend a server-side session by SessionManager::$SHORT_TIMEOUT + */ + public function testExtendSession() + { + $this->sessionManager->extendSession(); + + $this->assertGreaterThan(time(), $this->session['expires_on']); + $this->assertLessThanOrEqual( + time() + SessionManager::$SHORT_TIMEOUT, + $this->session['expires_on'] + ); + } + + /** + * Extend a server-side session by SessionManager::$LONG_TIMEOUT + */ + public function testExtendSessionStaySignedIn() + { + $this->sessionManager->setStaySignedIn(true); + $this->sessionManager->extendSession(); + + $this->assertGreaterThan(time(), $this->session['expires_on']); + $this->assertGreaterThan( + time() + SessionManager::$LONG_TIMEOUT - 10, + $this->session['expires_on'] + ); + $this->assertLessThanOrEqual( + time() + SessionManager::$LONG_TIMEOUT, + $this->session['expires_on'] + ); + } + + /** + * Unset session variables after logging out + */ + public function testLogout() + { + $this->session = [ + 'uid' => 'some-uid', + 'ip' => 'ip_id', + 'expires_on' => time() + 1000, + 'username' => 'johndoe', + 'visibility' => 'public', + 'untaggedonly' => false, + ]; + $this->sessionManager->logout(); + + $this->assertFalse(isset($this->session['uid'])); + $this->assertFalse(isset($this->session['ip'])); + $this->assertFalse(isset($this->session['expires_on'])); + $this->assertFalse(isset($this->session['username'])); + $this->assertFalse(isset($this->session['visibility'])); + $this->assertFalse(isset($this->session['untaggedonly'])); + } + + /** + * The session is considered as expired because the UID is missing + */ + public function testHasExpiredNoUid() + { + $this->assertTrue($this->sessionManager->hasSessionExpired()); + } + + /** + * The session is active and expiration time has been reached + */ + public function testHasExpiredTimeElapsed() + { + $this->session['uid'] = 'some-uid'; + $this->session['expires_on'] = time() - 10; + + $this->assertTrue($this->sessionManager->hasSessionExpired()); + } + + /** + * The session is active and expiration time has not been reached + */ + public function testHasNotExpired() + { + $this->session['uid'] = 'some-uid'; + $this->session['expires_on'] = time() + 1000; + + $this->assertFalse($this->sessionManager->hasSessionExpired()); + } + + /** + * Session hijacking protection is disabled, we assume the IP has not changed + */ + public function testHasClientIpChangedNoSessionProtection() + { + $this->conf->set('security.session_protection_disabled', true); + + $this->assertFalse($this->sessionManager->hasClientIpChanged('')); + } + + /** + * The client IP identifier has not changed + */ + public function testHasClientIpChangedNope() + { + $this->session['ip'] = 'ip_id'; + $this->assertFalse($this->sessionManager->hasClientIpChanged('ip_id')); + } + + /** + * The client IP identifier has changed + */ + public function testHasClientIpChanged() + { + $this->session['ip'] = 'ip_id_one'; + $this->assertTrue($this->sessionManager->hasClientIpChanged('ip_id_two')); + } } -- cgit v1.2.3 From c689e108639a4f6aa9e15928422e14db7cbe30ca Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sun, 6 May 2018 17:06:36 +0200 Subject: Refactor LoginManager stay-signed-in token management Signed-off-by: VirtualTam --- tests/security/LoginManagerTest.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tests') diff --git a/tests/security/LoginManagerTest.php b/tests/security/LoginManagerTest.php index b957abe3..633f1bb9 100644 --- a/tests/security/LoginManagerTest.php +++ b/tests/security/LoginManagerTest.php @@ -18,6 +18,18 @@ class LoginManagerTest extends TestCase protected $server = []; protected $trustedProxy = '10.1.1.100'; + /** @var string User login */ + protected $login = 'johndoe'; + + /** @var string User password */ + protected $password = 'IC4nHazL0g1n?'; + + /** @var string Hash of the salted user password */ + protected $passwordHash = ''; + + /** @var string Salt used by hash functions */ + protected $salt = '669e24fa9c5a59a613f98e8e38327384504a4af2'; + /** * Prepare or reset test resources */ @@ -27,7 +39,12 @@ class LoginManagerTest extends TestCase unlink($this->banFile); } + $this->passwordHash = sha1($this->password . $this->login . $this->salt); + $this->configManager = new \FakeConfigManager([ + 'credentials.login' => $this->login, + 'credentials.hash' => $this->passwordHash, + 'credentials.salt' => $this->salt, 'resource.ban_file' => $this->banFile, 'resource.log' => $this->logFile, 'security.ban_after' => 4, @@ -196,4 +213,18 @@ class LoginManagerTest extends TestCase $this->globals['IPBANS']['BANS'][$this->ipAddr] = time() - 3600; $this->assertTrue($this->loginManager->canLogin($this->server)); } + + /** + * Generate a token depending on the user credentials and client IP + */ + public function testGenerateStaySignedInToken() + { + $ipAddress = '10.1.47.179'; + $this->loginManager->generateStaySignedInToken($ipAddress); + + $this->assertEquals( + sha1($this->passwordHash . $ipAddress . $this->salt), + $this->loginManager->getStaySignedInToken() + ); + } } -- cgit v1.2.3 From ebf615173824a46de82fa97a165bcfd883db15ce Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Thu, 10 May 2018 13:07:51 +0200 Subject: SessionManager: remove unused UID token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There already are dedicated tokens for: - CSRF protection - user stay-signed-in feature, via cookie This token was most likely intended as a randomly generated, server-side, secret key to be used when generating hashes. See http://sebsauvage.net/wiki/doku.php?id=php:session [FR] Relevant section: Une clé secrète unique aléatoire est générée côté serveur (et jamais envoyée). Elle peut servir pour signer les formulaires (HMAC) ou générer des token de formulaires (protection contre XSRF). Voir $_SESSION['uid']. Translation: A unique, server-side secret key is randomly generated (and never transmitted). It can be used to sign forms (HMAC) or generate form tokens (protection against XSRF). See $_SESSION['uid'] Signed-off-by: VirtualTam --- tests/security/SessionManagerTest.php | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'tests') diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php index e1c72707..ae10ffa6 100644 --- a/tests/security/SessionManagerTest.php +++ b/tests/security/SessionManagerTest.php @@ -164,7 +164,6 @@ class SessionManagerTest extends TestCase { $this->sessionManager->storeLoginInfo('ip_id'); - $this->assertTrue(isset($this->session['uid'])); $this->assertGreaterThan(time(), $this->session['expires_on']); $this->assertEquals('ip_id', $this->session['ip']); $this->assertEquals('johndoe', $this->session['username']); @@ -209,7 +208,6 @@ class SessionManagerTest extends TestCase public function testLogout() { $this->session = [ - 'uid' => 'some-uid', 'ip' => 'ip_id', 'expires_on' => time() + 1000, 'username' => 'johndoe', @@ -218,7 +216,6 @@ class SessionManagerTest extends TestCase ]; $this->sessionManager->logout(); - $this->assertFalse(isset($this->session['uid'])); $this->assertFalse(isset($this->session['ip'])); $this->assertFalse(isset($this->session['expires_on'])); $this->assertFalse(isset($this->session['username'])); @@ -226,20 +223,11 @@ class SessionManagerTest extends TestCase $this->assertFalse(isset($this->session['untaggedonly'])); } - /** - * The session is considered as expired because the UID is missing - */ - public function testHasExpiredNoUid() - { - $this->assertTrue($this->sessionManager->hasSessionExpired()); - } - /** * The session is active and expiration time has been reached */ public function testHasExpiredTimeElapsed() { - $this->session['uid'] = 'some-uid'; $this->session['expires_on'] = time() - 10; $this->assertTrue($this->sessionManager->hasSessionExpired()); @@ -250,7 +238,6 @@ class SessionManagerTest extends TestCase */ public function testHasNotExpired() { - $this->session['uid'] = 'some-uid'; $this->session['expires_on'] = time() + 1000; $this->assertFalse($this->sessionManager->hasSessionExpired()); -- cgit v1.2.3 From 704637bfebc73ada4b800b35c457e9fe56ad3567 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sun, 6 May 2018 17:12:48 +0200 Subject: Add test coverage for LoginManager methods Signed-off-by: VirtualTam --- tests/security/LoginManagerTest.php | 149 ++++++++++++++++++++++++++++++++-- tests/security/SessionManagerTest.php | 2 +- tests/utils/FakeConfigManager.php | 12 +++ 3 files changed, 157 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/security/LoginManagerTest.php b/tests/security/LoginManagerTest.php index 633f1bb9..fad09992 100644 --- a/tests/security/LoginManagerTest.php +++ b/tests/security/LoginManagerTest.php @@ -9,13 +9,40 @@ use \PHPUnit\Framework\TestCase; */ class LoginManagerTest extends TestCase { + /** @var \FakeConfigManager Configuration Manager instance */ protected $configManager = null; + + /** @var LoginManager Login Manager instance */ protected $loginManager = null; + + /** @var SessionManager Session Manager instance */ + protected $sessionManager = null; + + /** @var string Banned IP filename */ protected $banFile = 'sandbox/ipbans.php'; + + /** @var string Log filename */ protected $logFile = 'sandbox/shaarli.log'; + + /** @var array Simulates the $_COOKIE array */ + protected $cookie = []; + + /** @var array Simulates the $GLOBALS array */ protected $globals = []; - protected $ipAddr = '127.0.0.1'; + + /** @var array Simulates the $_SERVER array */ protected $server = []; + + /** @var array Simulates the $_SESSION array */ + protected $session = []; + + /** @var string Advertised client IP address */ + protected $clientIpAddress = '10.1.47.179'; + + /** @var string Local client IP address */ + protected $ipAddr = '127.0.0.1'; + + /** @var string Trusted proxy IP address */ protected $trustedProxy = '10.1.1.100'; /** @var string User login */ @@ -52,10 +79,18 @@ class LoginManagerTest extends TestCase 'security.trusted_proxies' => [$this->trustedProxy], ]); + $this->cookie = []; + $this->globals = &$GLOBALS; unset($this->globals['IPBANS']); - $this->loginManager = new LoginManager($this->globals, $this->configManager, null); + $this->session = [ + 'expires_on' => time() + 100, + 'ip' => $this->clientIpAddress, + ]; + + $this->sessionManager = new SessionManager($this->session, $this->configManager); + $this->loginManager = new LoginManager($this->globals, $this->configManager, $this->sessionManager); $this->server['REMOTE_ADDR'] = $this->ipAddr; } @@ -219,12 +254,116 @@ class LoginManagerTest extends TestCase */ public function testGenerateStaySignedInToken() { - $ipAddress = '10.1.47.179'; - $this->loginManager->generateStaySignedInToken($ipAddress); + $this->loginManager->generateStaySignedInToken($this->clientIpAddress); $this->assertEquals( - sha1($this->passwordHash . $ipAddress . $this->salt), + sha1($this->passwordHash . $this->clientIpAddress . $this->salt), $this->loginManager->getStaySignedInToken() ); } + + /** + * Check user login - Shaarli has not yet been configured + */ + public function testCheckLoginStateNotConfigured() + { + $configManager = new \FakeConfigManager([ + 'resource.ban_file' => $this->banFile, + ]); + $loginManager = new LoginManager($this->globals, $configManager, null); + $loginManager->checkLoginState([], ''); + + $this->assertFalse($loginManager->isLoggedIn()); + } + + /** + * Check user login - the client cookie does not match the server token + */ + public function testCheckLoginStateStaySignedInWithInvalidToken() + { + $this->loginManager->generateStaySignedInToken($this->clientIpAddress); + $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = 'nope'; + + $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); + + $this->assertFalse($this->loginManager->isLoggedIn()); + } + + /** + * Check user login - the client cookie matches the server token + */ + public function testCheckLoginStateStaySignedInWithValidToken() + { + $this->loginManager->generateStaySignedInToken($this->clientIpAddress); + $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = $this->loginManager->getStaySignedInToken(); + + $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); + + $this->assertTrue($this->loginManager->isLoggedIn()); + } + + /** + * Check user login - the session has expired + */ + public function testCheckLoginStateSessionExpired() + { + $this->loginManager->generateStaySignedInToken($this->clientIpAddress); + $this->session['expires_on'] = time() - 100; + + $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); + + $this->assertFalse($this->loginManager->isLoggedIn()); + } + + /** + * Check user login - the remote client IP has changed + */ + public function testCheckLoginStateClientIpChanged() + { + $this->loginManager->generateStaySignedInToken($this->clientIpAddress); + + $this->loginManager->checkLoginState($this->cookie, '10.7.157.98'); + + $this->assertFalse($this->loginManager->isLoggedIn()); + } + + /** + * Check user credentials - wrong login supplied + */ + public function testCheckCredentialsWrongLogin() + { + $this->assertFalse( + $this->loginManager->checkCredentials('', '', 'b4dl0g1n', $this->password) + ); + } + + /** + * Check user credentials - wrong password supplied + */ + public function testCheckCredentialsWrongPassword() + { + $this->assertFalse( + $this->loginManager->checkCredentials('', '', $this->login, 'b4dp455wd') + ); + } + + /** + * Check user credentials - wrong login and password supplied + */ + public function testCheckCredentialsWrongLoginAndPassword() + { + $this->assertFalse( + $this->loginManager->checkCredentials('', '', 'b4dl0g1n', 'b4dp455wd') + ); + } + + /** + * Check user credentials - correct login and password supplied + */ + public function testCheckCredentialsGoodLoginAndPassword() + { + $this->assertTrue( + $this->loginManager->checkCredentials('', '', $this->login, $this->password) + ); + } } diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php index ae10ffa6..9bd868f8 100644 --- a/tests/security/SessionManagerTest.php +++ b/tests/security/SessionManagerTest.php @@ -17,7 +17,7 @@ class SessionManagerTest extends TestCase /** @var array Session ID hashes */ protected static $sidHashes = null; - /** @var FakeConfigManager ConfigManager substitute for testing */ + /** @var \FakeConfigManager ConfigManager substitute for testing */ protected $conf = null; /** @var array $_SESSION array for testing */ diff --git a/tests/utils/FakeConfigManager.php b/tests/utils/FakeConfigManager.php index 85434de7..360b34a9 100644 --- a/tests/utils/FakeConfigManager.php +++ b/tests/utils/FakeConfigManager.php @@ -42,4 +42,16 @@ class FakeConfigManager } return $key; } + + /** + * Check if a setting exists + * + * @param string $setting Asked setting, keys separated with dots + * + * @return bool true if the setting exists, false otherwise + */ + public function exists($setting) + { + return array_key_exists($setting, $this->values); + } } -- cgit v1.2.3 From 8edd7f15886620b07064aa889aea05c5acbc0e58 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Wed, 30 May 2018 02:09:09 +0200 Subject: SessionManager+LoginManager: fix checkLoginState logic Signed-off-by: VirtualTam --- tests/security/LoginManagerTest.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/security/LoginManagerTest.php b/tests/security/LoginManagerTest.php index fad09992..f26cd1eb 100644 --- a/tests/security/LoginManagerTest.php +++ b/tests/security/LoginManagerTest.php @@ -84,10 +84,7 @@ class LoginManagerTest extends TestCase $this->globals = &$GLOBALS; unset($this->globals['IPBANS']); - $this->session = [ - 'expires_on' => time() + 100, - 'ip' => $this->clientIpAddress, - ]; + $this->session = []; $this->sessionManager = new SessionManager($this->session, $this->configManager); $this->loginManager = new LoginManager($this->globals, $this->configManager, $this->sessionManager); @@ -281,12 +278,18 @@ class LoginManagerTest extends TestCase */ public function testCheckLoginStateStaySignedInWithInvalidToken() { + // simulate a previous login + $this->session = [ + 'ip' => $this->clientIpAddress, + 'expires_on' => time() + 100, + ]; $this->loginManager->generateStaySignedInToken($this->clientIpAddress); $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = 'nope'; $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); - $this->assertFalse($this->loginManager->isLoggedIn()); + $this->assertTrue($this->loginManager->isLoggedIn()); + $this->assertTrue(empty($this->session['username'])); } /** @@ -300,6 +303,8 @@ class LoginManagerTest extends TestCase $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); $this->assertTrue($this->loginManager->isLoggedIn()); + $this->assertEquals($this->login, $this->session['username']); + $this->assertEquals($this->clientIpAddress, $this->session['ip']); } /** -- cgit v1.2.3 From d3f42ca487287447efb81061609644108044a038 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 19 May 2018 15:04:04 +0200 Subject: Implements Tags endpoints for Shaarli's REST API Endpoints: * List All Tags [GET] * Get a tag [GET] * Update a tag [PUT] * Delete a tag [DELETE] Fixes #904 References shaarli/api-documentation#34 --- tests/api/controllers/DeleteLinkTest.php | 126 ------- tests/api/controllers/GetLinkIdTest.php | 132 ------- tests/api/controllers/GetLinksTest.php | 472 ------------------------- tests/api/controllers/HistoryTest.php | 216 ----------- tests/api/controllers/InfoTest.php | 115 ------ tests/api/controllers/PostLinkTest.php | 218 ------------ tests/api/controllers/PutLinkTest.php | 222 ------------ tests/api/controllers/history/HistoryTest.php | 216 +++++++++++ tests/api/controllers/info/InfoTest.php | 115 ++++++ tests/api/controllers/links/DeleteLinkTest.php | 126 +++++++ tests/api/controllers/links/GetLinkIdTest.php | 132 +++++++ tests/api/controllers/links/GetLinksTest.php | 472 +++++++++++++++++++++++++ tests/api/controllers/links/PostLinkTest.php | 218 ++++++++++++ tests/api/controllers/links/PutLinkTest.php | 222 ++++++++++++ tests/api/controllers/tags/DeleteTagTest.php | 164 +++++++++ tests/api/controllers/tags/GetTagNameTest.php | 129 +++++++ tests/api/controllers/tags/GetTagsTest.php | 209 +++++++++++ tests/api/controllers/tags/PutTagTest.php | 209 +++++++++++ 18 files changed, 2212 insertions(+), 1501 deletions(-) delete mode 100644 tests/api/controllers/DeleteLinkTest.php delete mode 100644 tests/api/controllers/GetLinkIdTest.php delete mode 100644 tests/api/controllers/GetLinksTest.php delete mode 100644 tests/api/controllers/HistoryTest.php delete mode 100644 tests/api/controllers/InfoTest.php delete mode 100644 tests/api/controllers/PostLinkTest.php delete mode 100644 tests/api/controllers/PutLinkTest.php create mode 100644 tests/api/controllers/history/HistoryTest.php create mode 100644 tests/api/controllers/info/InfoTest.php create mode 100644 tests/api/controllers/links/DeleteLinkTest.php create mode 100644 tests/api/controllers/links/GetLinkIdTest.php create mode 100644 tests/api/controllers/links/GetLinksTest.php create mode 100644 tests/api/controllers/links/PostLinkTest.php create mode 100644 tests/api/controllers/links/PutLinkTest.php create mode 100644 tests/api/controllers/tags/DeleteTagTest.php create mode 100644 tests/api/controllers/tags/GetTagNameTest.php create mode 100644 tests/api/controllers/tags/GetTagsTest.php create mode 100644 tests/api/controllers/tags/PutTagTest.php (limited to 'tests') diff --git a/tests/api/controllers/DeleteLinkTest.php b/tests/api/controllers/DeleteLinkTest.php deleted file mode 100644 index 7d797137..00000000 --- a/tests/api/controllers/DeleteLinkTest.php +++ /dev/null @@ -1,126 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson'); - $this->refDB = new \ReferenceLinkDB(); - $this->refDB->write(self::$testDatastore); - $this->linkDB = new \LinkDB(self::$testDatastore, true, false); - $refHistory = new \ReferenceHistory(); - $refHistory->write(self::$testHistory); - $this->history = new \History(self::$testHistory); - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = $this->linkDB; - $this->container['history'] = $this->history; - - $this->controller = new Links($this->container); - } - - /** - * After each test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testDatastore); - @unlink(self::$testHistory); - } - - /** - * Test DELETE link endpoint: the link should be removed. - */ - public function testDeleteLinkValid() - { - $id = '41'; - $this->assertTrue(isset($this->linkDB[$id])); - $env = Environment::mock([ - 'REQUEST_METHOD' => 'DELETE', - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->deleteLink($request, new Response(), ['id' => $id]); - $this->assertEquals(204, $response->getStatusCode()); - $this->assertEmpty((string) $response->getBody()); - - $this->linkDB = new \LinkDB(self::$testDatastore, true, false); - $this->assertFalse(isset($this->linkDB[$id])); - - $historyEntry = $this->history->getHistory()[0]; - $this->assertEquals(\History::DELETED, $historyEntry['event']); - $this->assertTrue( - (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] - ); - $this->assertEquals($id, $historyEntry['id']); - } - - /** - * Test DELETE link endpoint: reach not existing ID. - * - * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException - */ - public function testDeleteLink404() - { - $id = -1; - $this->assertFalse(isset($this->linkDB[$id])); - $env = Environment::mock([ - 'REQUEST_METHOD' => 'DELETE', - ]); - $request = Request::createFromEnvironment($env); - - $this->controller->deleteLink($request, new Response(), ['id' => $id]); - } -} diff --git a/tests/api/controllers/GetLinkIdTest.php b/tests/api/controllers/GetLinkIdTest.php deleted file mode 100644 index 57528d5a..00000000 --- a/tests/api/controllers/GetLinkIdTest.php +++ /dev/null @@ -1,132 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson'); - $this->refDB = new \ReferenceLinkDB(); - $this->refDB->write(self::$testDatastore); - - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); - $this->container['history'] = null; - - $this->controller = new Links($this->container); - } - - /** - * After each test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testDatastore); - } - - /** - * Test basic getLink service: return link ID=41. - */ - public function testGetLinkId() - { - // Used by index_url(). - $_SERVER['SERVER_NAME'] = 'domain.tld'; - $_SERVER['SERVER_PORT'] = 80; - $_SERVER['SCRIPT_NAME'] = '/'; - - $id = 41; - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getLink($request, new Response(), ['id' => $id]); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals($id, $data['id']); - - // Check link elements - $this->assertEquals('http://domain.tld/?WDWyig', $data['url']); - $this->assertEquals('WDWyig', $data['shorturl']); - $this->assertEquals('Link title: @website', $data['title']); - $this->assertEquals( - 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag', - $data['description'] - ); - $this->assertEquals('sTuff', $data['tags'][0]); - $this->assertEquals(false, $data['private']); - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM), - $data['created'] - ); - $this->assertEmpty($data['updated']); - } - - /** - * Test basic getLink service: get non existent link => ApiLinkNotFoundException. - * - * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException - * @expectedExceptionMessage Link not found - */ - public function testGetLink404() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - ]); - $request = Request::createFromEnvironment($env); - - $this->controller->getLink($request, new Response(), ['id' => -1]); - } -} diff --git a/tests/api/controllers/GetLinksTest.php b/tests/api/controllers/GetLinksTest.php deleted file mode 100644 index d22ed3bf..00000000 --- a/tests/api/controllers/GetLinksTest.php +++ /dev/null @@ -1,472 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson'); - $this->refDB = new \ReferenceLinkDB(); - $this->refDB->write(self::$testDatastore); - - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); - $this->container['history'] = null; - - $this->controller = new Links($this->container); - } - - /** - * After every test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testDatastore); - } - - /** - * Test basic getLinks service: returns all links. - */ - public function testGetLinks() - { - // Used by index_url(). - $_SERVER['SERVER_NAME'] = 'domain.tld'; - $_SERVER['SERVER_PORT'] = 80; - $_SERVER['SCRIPT_NAME'] = '/'; - - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals($this->refDB->countLinks(), count($data)); - - // Check order - $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; - $cpt = 0; - foreach ($data as $link) { - $this->assertEquals(self::NB_FIELDS_LINK, count($link)); - $this->assertEquals($order[$cpt++], $link['id']); - } - - // Check first element fields - $first = $data[0]; - $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); - $this->assertEquals('WDWyig', $first['shorturl']); - $this->assertEquals('Link title: @website', $first['title']); - $this->assertEquals( - 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag', - $first['description'] - ); - $this->assertEquals('sTuff', $first['tags'][0]); - $this->assertEquals(false, $first['private']); - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM), - $first['created'] - ); - $this->assertEmpty($first['updated']); - - // Multi tags - $link = $data[1]; - $this->assertEquals(7, count($link['tags'])); - - // Update date - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20160803_093033')->format(\DateTime::ATOM), - $link['updated'] - ); - } - - /** - * Test getLinks service with offset and limit parameter: - * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC). - */ - public function testGetLinksOffsetLimit() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'offset=1&limit=1' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(1, count($data)); - $this->assertEquals(8, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - } - - /** - * Test getLinks with limit=all (return all link). - */ - public function testGetLinksLimitAll() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'limit=all' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals($this->refDB->countLinks(), count($data)); - // Check order - $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; - $cpt = 0; - foreach ($data as $link) { - $this->assertEquals(self::NB_FIELDS_LINK, count($link)); - $this->assertEquals($order[$cpt++], $link['id']); - } - } - - /** - * Test getLinks service with offset and limit parameter: - * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC). - */ - public function testGetLinksOffsetTooHigh() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'offset=100' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEmpty(count($data)); - } - - /** - * Test getLinks with visibility parameter set to all - */ - public function testGetLinksVisibilityAll() - { - $env = Environment::mock( - [ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'visibility=all' - ] - ); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string)$response->getBody(), true); - $this->assertEquals($this->refDB->countLinks(), count($data)); - $this->assertEquals(41, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - } - - /** - * Test getLinks with visibility parameter set to private - */ - public function testGetLinksVisibilityPrivate() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'visibility=private' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals($this->refDB->countPrivateLinks(), count($data)); - $this->assertEquals(6, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - } - - /** - * Test getLinks with visibility parameter set to public - */ - public function testGetLinksVisibilityPublic() - { - $env = Environment::mock( - [ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'visibility=public' - ] - ); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string)$response->getBody(), true); - $this->assertEquals($this->refDB->countPublicLinks(), count($data)); - $this->assertEquals(41, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - } - - /** - * Test getLinks service with offset and limit parameter: - * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC). - */ - public function testGetLinksSearchTerm() - { - // Only in description - 1 result - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm=Tropical' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(1, count($data)); - $this->assertEquals(1, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - - // Only in tags - 1 result - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm=tag3' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(1, count($data)); - $this->assertEquals(0, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - - // Multiple results (2) - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm=stallman' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(2, count($data)); - $this->assertEquals(41, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - $this->assertEquals(8, $data[1]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); - - // Multiword - 2 results - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm=stallman+software' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(2, count($data)); - $this->assertEquals(41, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - $this->assertEquals(8, $data[1]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); - - // URL encoding - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm='. urlencode('@web') - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(2, count($data)); - $this->assertEquals(41, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - $this->assertEquals(8, $data[1]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); - } - - public function testGetLinksSearchTermNoResult() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm=nope' - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(0, count($data)); - } - - public function testGetLinksSearchTags() - { - // Single tag - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=dev', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(2, count($data)); - $this->assertEquals(0, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - $this->assertEquals(4, $data[1]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); - - // Multitag + exclude - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=stuff+-gnu', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(1, count($data)); - $this->assertEquals(41, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - - // wildcard: placeholder at the start - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=*Tuff', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(2, count($data)); - $this->assertEquals(41, $data[0]['id']); - - // wildcard: placeholder at the end - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=c*', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(4, count($data)); - $this->assertEquals(6, $data[0]['id']); - - // wildcard: placeholder at the middle - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=w*b', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(4, count($data)); - $this->assertEquals(6, $data[0]['id']); - - // wildcard: match all - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=*', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(9, count($data)); - $this->assertEquals(41, $data[0]['id']); - - // wildcard: optional ('*' does not need to expand) - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=*stuff*', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(2, count($data)); - $this->assertEquals(41, $data[0]['id']); - - // wildcard: exclusions - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=*a*+-*e*', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(1, count($data)); - $this->assertEquals(41, $data[0]['id']); // finds '#hashtag' in descr. - - // wildcard: exclude all - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchtags=-*', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(0, count($data)); - } - - /** - * Test getLinks service with search tags+terms. - */ - public function testGetLinksSearchTermsAndTags() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'searchterm=poke&searchtags=dev', - ]); - $request = Request::createFromEnvironment($env); - $response = $this->controller->getLinks($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(1, count($data)); - $this->assertEquals(0, $data[0]['id']); - $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); - } -} diff --git a/tests/api/controllers/HistoryTest.php b/tests/api/controllers/HistoryTest.php deleted file mode 100644 index 61046d97..00000000 --- a/tests/api/controllers/HistoryTest.php +++ /dev/null @@ -1,216 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson.json.php'); - $this->refHistory = new \ReferenceHistory(); - $this->refHistory->write(self::$testHistory); - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = true; - $this->container['history'] = new \History(self::$testHistory); - - $this->controller = new History($this->container); - } - - /** - * After every test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testHistory); - } - - /** - * Test /history service without parameter. - */ - public function testGetHistory() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getHistory($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals($this->refHistory->count(), count($data)); - - $this->assertEquals(\History::DELETED, $data[0]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170303_121216')->format(\DateTime::ATOM), - $data[0]['datetime'] - ); - $this->assertEquals(124, $data[0]['id']); - - $this->assertEquals(\History::SETTINGS, $data[1]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170302_121215')->format(\DateTime::ATOM), - $data[1]['datetime'] - ); - $this->assertNull($data[1]['id']); - - $this->assertEquals(\History::UPDATED, $data[2]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170301_121214')->format(\DateTime::ATOM), - $data[2]['datetime'] - ); - $this->assertEquals(123, $data[2]['id']); - - $this->assertEquals(\History::CREATED, $data[3]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170201_121214')->format(\DateTime::ATOM), - $data[3]['datetime'] - ); - $this->assertEquals(124, $data[3]['id']); - - $this->assertEquals(\History::CREATED, $data[4]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170101_121212')->format(\DateTime::ATOM), - $data[4]['datetime'] - ); - $this->assertEquals(123, $data[4]['id']); - } - - /** - * Test /history service with limit parameter. - */ - public function testGetHistoryLimit() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'limit=1' - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getHistory($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals(1, count($data)); - - $this->assertEquals(\History::DELETED, $data[0]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170303_121216')->format(\DateTime::ATOM), - $data[0]['datetime'] - ); - $this->assertEquals(124, $data[0]['id']); - } - - /** - * Test /history service with offset parameter. - */ - public function testGetHistoryOffset() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'offset=4' - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getHistory($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals(1, count($data)); - - $this->assertEquals(\History::CREATED, $data[0]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170101_121212')->format(\DateTime::ATOM), - $data[0]['datetime'] - ); - $this->assertEquals(123, $data[0]['id']); - } - - /** - * Test /history service with since parameter. - */ - public function testGetHistorySince() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'since=2017-03-03T00:00:00%2B00:00' - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getHistory($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals(1, count($data)); - - $this->assertEquals(\History::DELETED, $data[0]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170303_121216')->format(\DateTime::ATOM), - $data[0]['datetime'] - ); - $this->assertEquals(124, $data[0]['id']); - } - - /** - * Test /history service with since parameter. - */ - public function testGetHistorySinceOffsetLimit() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'since=2017-02-01T00:00:00%2B00:00&offset=1&limit=1' - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getHistory($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals(1, count($data)); - - $this->assertEquals(\History::SETTINGS, $data[0]['event']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20170302_121215')->format(\DateTime::ATOM), - $data[0]['datetime'] - ); - } -} diff --git a/tests/api/controllers/InfoTest.php b/tests/api/controllers/InfoTest.php deleted file mode 100644 index f7e63bfa..00000000 --- a/tests/api/controllers/InfoTest.php +++ /dev/null @@ -1,115 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson.json.php'); - $this->refDB = new \ReferenceLinkDB(); - $this->refDB->write(self::$testDatastore); - - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); - $this->container['history'] = null; - - $this->controller = new Info($this->container); - } - - /** - * After every test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testDatastore); - } - - /** - * Test /info service. - */ - public function testGetInfo() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'GET', - ]); - $request = Request::createFromEnvironment($env); - - $response = $this->controller->getInfo($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, $data['global_counter']); - $this->assertEquals(2, $data['private_counter']); - $this->assertEquals('Shaarli', $data['settings']['title']); - $this->assertEquals('?', $data['settings']['header_link']); - $this->assertEquals('UTC', $data['settings']['timezone']); - $this->assertEquals(ConfigManager::$DEFAULT_PLUGINS, $data['settings']['enabled_plugins']); - $this->assertEquals(false, $data['settings']['default_private_links']); - - $title = 'My links'; - $headerLink = 'http://shaarli.tld'; - $timezone = 'Europe/Paris'; - $enabledPlugins = array('foo', 'bar'); - $defaultPrivateLinks = true; - $this->conf->set('general.title', $title); - $this->conf->set('general.header_link', $headerLink); - $this->conf->set('general.timezone', $timezone); - $this->conf->set('general.enabled_plugins', $enabledPlugins); - $this->conf->set('privacy.default_private_links', $defaultPrivateLinks); - - $response = $this->controller->getInfo($request, new Response()); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - - $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, $data['global_counter']); - $this->assertEquals(2, $data['private_counter']); - $this->assertEquals($title, $data['settings']['title']); - $this->assertEquals($headerLink, $data['settings']['header_link']); - $this->assertEquals($timezone, $data['settings']['timezone']); - $this->assertEquals($enabledPlugins, $data['settings']['enabled_plugins']); - $this->assertEquals($defaultPrivateLinks, $data['settings']['default_private_links']); - } -} diff --git a/tests/api/controllers/PostLinkTest.php b/tests/api/controllers/PostLinkTest.php deleted file mode 100644 index 100a9170..00000000 --- a/tests/api/controllers/PostLinkTest.php +++ /dev/null @@ -1,218 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson.json.php'); - $this->refDB = new \ReferenceLinkDB(); - $this->refDB->write(self::$testDatastore); - - $refHistory = new \ReferenceHistory(); - $refHistory->write(self::$testHistory); - $this->history = new \History(self::$testHistory); - - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); - $this->container['history'] = new \History(self::$testHistory); - - $this->controller = new Links($this->container); - - $mock = $this->createMock(Router::class); - $mock->expects($this->any()) - ->method('relativePathFor') - ->willReturn('api/v1/links/1'); - - // affect @property-read... seems to work - $this->controller->getCi()->router = $mock; - - // Used by index_url(). - $this->controller->getCi()['environment'] = [ - 'SERVER_NAME' => 'domain.tld', - 'SERVER_PORT' => 80, - 'SCRIPT_NAME' => '/', - ]; - } - - /** - * After every test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testDatastore); - @unlink(self::$testHistory); - } - - /** - * Test link creation without any field: creates a blank note. - */ - public function testPostLinkMinimal() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'POST', - ]); - - $request = Request::createFromEnvironment($env); - - $response = $this->controller->postLink($request, new Response()); - $this->assertEquals(201, $response->getStatusCode()); - $this->assertEquals('api/v1/links/1', $response->getHeader('Location')[0]); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals(43, $data['id']); - $this->assertRegExp('/[\w-_]{6}/', $data['shorturl']); - $this->assertEquals('http://domain.tld/?' . $data['shorturl'], $data['url']); - $this->assertEquals('?' . $data['shorturl'], $data['title']); - $this->assertEquals('', $data['description']); - $this->assertEquals([], $data['tags']); - $this->assertEquals(false, $data['private']); - $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); - $this->assertEquals('', $data['updated']); - - $historyEntry = $this->history->getHistory()[0]; - $this->assertEquals(\History::CREATED, $historyEntry['event']); - $this->assertTrue( - (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] - ); - $this->assertEquals(43, $historyEntry['id']); - } - - /** - * Test link creation with all available fields. - */ - public function testPostLinkFull() - { - $link = [ - 'url' => 'website.tld/test?foo=bar', - 'title' => 'new entry', - 'description' => 'shaare description', - 'tags' => ['one', 'two'], - 'private' => true, - ]; - $env = Environment::mock([ - 'REQUEST_METHOD' => 'POST', - 'CONTENT_TYPE' => 'application/json' - ]); - - $request = Request::createFromEnvironment($env); - $request = $request->withParsedBody($link); - $response = $this->controller->postLink($request, new Response()); - - $this->assertEquals(201, $response->getStatusCode()); - $this->assertEquals('api/v1/links/1', $response->getHeader('Location')[0]); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals(43, $data['id']); - $this->assertRegExp('/[\w-_]{6}/', $data['shorturl']); - $this->assertEquals('http://' . $link['url'], $data['url']); - $this->assertEquals($link['title'], $data['title']); - $this->assertEquals($link['description'], $data['description']); - $this->assertEquals($link['tags'], $data['tags']); - $this->assertEquals(true, $data['private']); - $this->assertTrue(new \DateTime('2 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); - $this->assertEquals('', $data['updated']); - } - - /** - * Test link creation with an existing link (duplicate URL). Should return a 409 HTTP error and the existing link. - */ - public function testPostLinkDuplicate() - { - $link = [ - 'url' => 'mediagoblin.org/', - 'title' => 'new entry', - 'description' => 'shaare description', - 'tags' => ['one', 'two'], - 'private' => true, - ]; - $env = Environment::mock([ - 'REQUEST_METHOD' => 'POST', - 'CONTENT_TYPE' => 'application/json' - ]); - - $request = Request::createFromEnvironment($env); - $request = $request->withParsedBody($link); - $response = $this->controller->postLink($request, new Response()); - - $this->assertEquals(409, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals(7, $data['id']); - $this->assertEquals('IuWvgA', $data['shorturl']); - $this->assertEquals('http://mediagoblin.org/', $data['url']); - $this->assertEquals('MediaGoblin', $data['title']); - $this->assertEquals('A free software media publishing platform #hashtagOther', $data['description']); - $this->assertEquals(['gnu', 'media', 'web', '.hidden', 'hashtag'], $data['tags']); - $this->assertEquals(false, $data['private']); - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130614_184135'), - \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) - ); - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130615_184230'), - \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) - ); - } -} diff --git a/tests/api/controllers/PutLinkTest.php b/tests/api/controllers/PutLinkTest.php deleted file mode 100644 index 8a562571..00000000 --- a/tests/api/controllers/PutLinkTest.php +++ /dev/null @@ -1,222 +0,0 @@ -conf = new ConfigManager('tests/utils/config/configJson.json.php'); - $this->refDB = new \ReferenceLinkDB(); - $this->refDB->write(self::$testDatastore); - - $refHistory = new \ReferenceHistory(); - $refHistory->write(self::$testHistory); - $this->history = new \History(self::$testHistory); - - $this->container = new Container(); - $this->container['conf'] = $this->conf; - $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); - $this->container['history'] = new \History(self::$testHistory); - - $this->controller = new Links($this->container); - - // Used by index_url(). - $this->controller->getCi()['environment'] = [ - 'SERVER_NAME' => 'domain.tld', - 'SERVER_PORT' => 80, - 'SCRIPT_NAME' => '/', - ]; - } - - /** - * After every test, remove the test datastore. - */ - public function tearDown() - { - @unlink(self::$testDatastore); - @unlink(self::$testHistory); - } - - /** - * Test link update without value: reset the link to default values - */ - public function testPutLinkMinimal() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'PUT', - ]); - $id = '41'; - $request = Request::createFromEnvironment($env); - - $response = $this->controller->putLink($request, new Response(), ['id' => $id]); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals($id, $data['id']); - $this->assertEquals('WDWyig', $data['shorturl']); - $this->assertEquals('http://domain.tld/?WDWyig', $data['url']); - $this->assertEquals('?WDWyig', $data['title']); - $this->assertEquals('', $data['description']); - $this->assertEquals([], $data['tags']); - $this->assertEquals(false, $data['private']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20150310_114651'), - \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) - ); - $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); - - $historyEntry = $this->history->getHistory()[0]; - $this->assertEquals(\History::UPDATED, $historyEntry['event']); - $this->assertTrue( - (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] - ); - $this->assertEquals($id, $historyEntry['id']); - } - - /** - * Test link update with new values - */ - public function testPutLinkWithValues() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'PUT', - 'CONTENT_TYPE' => 'application/json' - ]); - $id = 41; - $update = [ - 'url' => 'http://somewhere.else', - 'title' => 'Le Cid', - 'description' => 'Percé jusques au fond du cœur [...]', - 'tags' => ['corneille', 'rodrigue'], - 'private' => true, - ]; - $request = Request::createFromEnvironment($env); - $request = $request->withParsedBody($update); - - $response = $this->controller->putLink($request, new Response(), ['id' => $id]); - $this->assertEquals(200, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals($id, $data['id']); - $this->assertEquals('WDWyig', $data['shorturl']); - $this->assertEquals('http://somewhere.else', $data['url']); - $this->assertEquals('Le Cid', $data['title']); - $this->assertEquals('Percé jusques au fond du cœur [...]', $data['description']); - $this->assertEquals(['corneille', 'rodrigue'], $data['tags']); - $this->assertEquals(true, $data['private']); - $this->assertEquals( - \DateTime::createFromFormat('Ymd_His', '20150310_114651'), - \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) - ); - $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); - } - - /** - * Test link update with an existing URL: 409 Conflict with the existing link as body - */ - public function testPutLinkDuplicate() - { - $link = [ - 'url' => 'mediagoblin.org/', - 'title' => 'new entry', - 'description' => 'shaare description', - 'tags' => ['one', 'two'], - 'private' => true, - ]; - $env = Environment::mock([ - 'REQUEST_METHOD' => 'PUT', - 'CONTENT_TYPE' => 'application/json' - ]); - - $request = Request::createFromEnvironment($env); - $request = $request->withParsedBody($link); - $response = $this->controller->putLink($request, new Response(), ['id' => 41]); - - $this->assertEquals(409, $response->getStatusCode()); - $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(self::NB_FIELDS_LINK, count($data)); - $this->assertEquals(7, $data['id']); - $this->assertEquals('IuWvgA', $data['shorturl']); - $this->assertEquals('http://mediagoblin.org/', $data['url']); - $this->assertEquals('MediaGoblin', $data['title']); - $this->assertEquals('A free software media publishing platform #hashtagOther', $data['description']); - $this->assertEquals(['gnu', 'media', 'web', '.hidden', 'hashtag'], $data['tags']); - $this->assertEquals(false, $data['private']); - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130614_184135'), - \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) - ); - $this->assertEquals( - \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130615_184230'), - \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) - ); - } - - /** - * Test link update on non existent link => ApiLinkNotFoundException. - * - * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException - * @expectedExceptionMessage Link not found - */ - public function testGetLink404() - { - $env = Environment::mock([ - 'REQUEST_METHOD' => 'PUT', - ]); - $request = Request::createFromEnvironment($env); - - $this->controller->putLink($request, new Response(), ['id' => -1]); - } -} diff --git a/tests/api/controllers/history/HistoryTest.php b/tests/api/controllers/history/HistoryTest.php new file mode 100644 index 00000000..61046d97 --- /dev/null +++ b/tests/api/controllers/history/HistoryTest.php @@ -0,0 +1,216 @@ +conf = new ConfigManager('tests/utils/config/configJson.json.php'); + $this->refHistory = new \ReferenceHistory(); + $this->refHistory->write(self::$testHistory); + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = true; + $this->container['history'] = new \History(self::$testHistory); + + $this->controller = new History($this->container); + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testHistory); + } + + /** + * Test /history service without parameter. + */ + public function testGetHistory() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getHistory($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals($this->refHistory->count(), count($data)); + + $this->assertEquals(\History::DELETED, $data[0]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170303_121216')->format(\DateTime::ATOM), + $data[0]['datetime'] + ); + $this->assertEquals(124, $data[0]['id']); + + $this->assertEquals(\History::SETTINGS, $data[1]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170302_121215')->format(\DateTime::ATOM), + $data[1]['datetime'] + ); + $this->assertNull($data[1]['id']); + + $this->assertEquals(\History::UPDATED, $data[2]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170301_121214')->format(\DateTime::ATOM), + $data[2]['datetime'] + ); + $this->assertEquals(123, $data[2]['id']); + + $this->assertEquals(\History::CREATED, $data[3]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170201_121214')->format(\DateTime::ATOM), + $data[3]['datetime'] + ); + $this->assertEquals(124, $data[3]['id']); + + $this->assertEquals(\History::CREATED, $data[4]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170101_121212')->format(\DateTime::ATOM), + $data[4]['datetime'] + ); + $this->assertEquals(123, $data[4]['id']); + } + + /** + * Test /history service with limit parameter. + */ + public function testGetHistoryLimit() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'limit=1' + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getHistory($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals(1, count($data)); + + $this->assertEquals(\History::DELETED, $data[0]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170303_121216')->format(\DateTime::ATOM), + $data[0]['datetime'] + ); + $this->assertEquals(124, $data[0]['id']); + } + + /** + * Test /history service with offset parameter. + */ + public function testGetHistoryOffset() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'offset=4' + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getHistory($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals(1, count($data)); + + $this->assertEquals(\History::CREATED, $data[0]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170101_121212')->format(\DateTime::ATOM), + $data[0]['datetime'] + ); + $this->assertEquals(123, $data[0]['id']); + } + + /** + * Test /history service with since parameter. + */ + public function testGetHistorySince() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'since=2017-03-03T00:00:00%2B00:00' + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getHistory($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals(1, count($data)); + + $this->assertEquals(\History::DELETED, $data[0]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170303_121216')->format(\DateTime::ATOM), + $data[0]['datetime'] + ); + $this->assertEquals(124, $data[0]['id']); + } + + /** + * Test /history service with since parameter. + */ + public function testGetHistorySinceOffsetLimit() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'since=2017-02-01T00:00:00%2B00:00&offset=1&limit=1' + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getHistory($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals(1, count($data)); + + $this->assertEquals(\History::SETTINGS, $data[0]['event']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20170302_121215')->format(\DateTime::ATOM), + $data[0]['datetime'] + ); + } +} diff --git a/tests/api/controllers/info/InfoTest.php b/tests/api/controllers/info/InfoTest.php new file mode 100644 index 00000000..f7e63bfa --- /dev/null +++ b/tests/api/controllers/info/InfoTest.php @@ -0,0 +1,115 @@ +conf = new ConfigManager('tests/utils/config/configJson.json.php'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; + + $this->controller = new Info($this->container); + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + } + + /** + * Test /info service. + */ + public function testGetInfo() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getInfo($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, $data['global_counter']); + $this->assertEquals(2, $data['private_counter']); + $this->assertEquals('Shaarli', $data['settings']['title']); + $this->assertEquals('?', $data['settings']['header_link']); + $this->assertEquals('UTC', $data['settings']['timezone']); + $this->assertEquals(ConfigManager::$DEFAULT_PLUGINS, $data['settings']['enabled_plugins']); + $this->assertEquals(false, $data['settings']['default_private_links']); + + $title = 'My links'; + $headerLink = 'http://shaarli.tld'; + $timezone = 'Europe/Paris'; + $enabledPlugins = array('foo', 'bar'); + $defaultPrivateLinks = true; + $this->conf->set('general.title', $title); + $this->conf->set('general.header_link', $headerLink); + $this->conf->set('general.timezone', $timezone); + $this->conf->set('general.enabled_plugins', $enabledPlugins); + $this->conf->set('privacy.default_private_links', $defaultPrivateLinks); + + $response = $this->controller->getInfo($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + + $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, $data['global_counter']); + $this->assertEquals(2, $data['private_counter']); + $this->assertEquals($title, $data['settings']['title']); + $this->assertEquals($headerLink, $data['settings']['header_link']); + $this->assertEquals($timezone, $data['settings']['timezone']); + $this->assertEquals($enabledPlugins, $data['settings']['enabled_plugins']); + $this->assertEquals($defaultPrivateLinks, $data['settings']['default_private_links']); + } +} diff --git a/tests/api/controllers/links/DeleteLinkTest.php b/tests/api/controllers/links/DeleteLinkTest.php new file mode 100644 index 00000000..7d797137 --- /dev/null +++ b/tests/api/controllers/links/DeleteLinkTest.php @@ -0,0 +1,126 @@ +conf = new ConfigManager('tests/utils/config/configJson'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = $this->linkDB; + $this->container['history'] = $this->history; + + $this->controller = new Links($this->container); + } + + /** + * After each test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + @unlink(self::$testHistory); + } + + /** + * Test DELETE link endpoint: the link should be removed. + */ + public function testDeleteLinkValid() + { + $id = '41'; + $this->assertTrue(isset($this->linkDB[$id])); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'DELETE', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->deleteLink($request, new Response(), ['id' => $id]); + $this->assertEquals(204, $response->getStatusCode()); + $this->assertEmpty((string) $response->getBody()); + + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $this->assertFalse(isset($this->linkDB[$id])); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::DELETED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $this->assertEquals($id, $historyEntry['id']); + } + + /** + * Test DELETE link endpoint: reach not existing ID. + * + * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException + */ + public function testDeleteLink404() + { + $id = -1; + $this->assertFalse(isset($this->linkDB[$id])); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'DELETE', + ]); + $request = Request::createFromEnvironment($env); + + $this->controller->deleteLink($request, new Response(), ['id' => $id]); + } +} diff --git a/tests/api/controllers/links/GetLinkIdTest.php b/tests/api/controllers/links/GetLinkIdTest.php new file mode 100644 index 00000000..57528d5a --- /dev/null +++ b/tests/api/controllers/links/GetLinkIdTest.php @@ -0,0 +1,132 @@ +conf = new ConfigManager('tests/utils/config/configJson'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; + + $this->controller = new Links($this->container); + } + + /** + * After each test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + } + + /** + * Test basic getLink service: return link ID=41. + */ + public function testGetLinkId() + { + // Used by index_url(). + $_SERVER['SERVER_NAME'] = 'domain.tld'; + $_SERVER['SERVER_PORT'] = 80; + $_SERVER['SCRIPT_NAME'] = '/'; + + $id = 41; + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getLink($request, new Response(), ['id' => $id]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals($id, $data['id']); + + // Check link elements + $this->assertEquals('http://domain.tld/?WDWyig', $data['url']); + $this->assertEquals('WDWyig', $data['shorturl']); + $this->assertEquals('Link title: @website', $data['title']); + $this->assertEquals( + 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag', + $data['description'] + ); + $this->assertEquals('sTuff', $data['tags'][0]); + $this->assertEquals(false, $data['private']); + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM), + $data['created'] + ); + $this->assertEmpty($data['updated']); + } + + /** + * Test basic getLink service: get non existent link => ApiLinkNotFoundException. + * + * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException + * @expectedExceptionMessage Link not found + */ + public function testGetLink404() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $this->controller->getLink($request, new Response(), ['id' => -1]); + } +} diff --git a/tests/api/controllers/links/GetLinksTest.php b/tests/api/controllers/links/GetLinksTest.php new file mode 100644 index 00000000..d22ed3bf --- /dev/null +++ b/tests/api/controllers/links/GetLinksTest.php @@ -0,0 +1,472 @@ +conf = new ConfigManager('tests/utils/config/configJson'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; + + $this->controller = new Links($this->container); + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + } + + /** + * Test basic getLinks service: returns all links. + */ + public function testGetLinks() + { + // Used by index_url(). + $_SERVER['SERVER_NAME'] = 'domain.tld'; + $_SERVER['SERVER_PORT'] = 80; + $_SERVER['SCRIPT_NAME'] = '/'; + + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals($this->refDB->countLinks(), count($data)); + + // Check order + $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; + $cpt = 0; + foreach ($data as $link) { + $this->assertEquals(self::NB_FIELDS_LINK, count($link)); + $this->assertEquals($order[$cpt++], $link['id']); + } + + // Check first element fields + $first = $data[0]; + $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); + $this->assertEquals('WDWyig', $first['shorturl']); + $this->assertEquals('Link title: @website', $first['title']); + $this->assertEquals( + 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag', + $first['description'] + ); + $this->assertEquals('sTuff', $first['tags'][0]); + $this->assertEquals(false, $first['private']); + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM), + $first['created'] + ); + $this->assertEmpty($first['updated']); + + // Multi tags + $link = $data[1]; + $this->assertEquals(7, count($link['tags'])); + + // Update date + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20160803_093033')->format(\DateTime::ATOM), + $link['updated'] + ); + } + + /** + * Test getLinks service with offset and limit parameter: + * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC). + */ + public function testGetLinksOffsetLimit() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'offset=1&limit=1' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(8, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + } + + /** + * Test getLinks with limit=all (return all link). + */ + public function testGetLinksLimitAll() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'limit=all' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals($this->refDB->countLinks(), count($data)); + // Check order + $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; + $cpt = 0; + foreach ($data as $link) { + $this->assertEquals(self::NB_FIELDS_LINK, count($link)); + $this->assertEquals($order[$cpt++], $link['id']); + } + } + + /** + * Test getLinks service with offset and limit parameter: + * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC). + */ + public function testGetLinksOffsetTooHigh() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'offset=100' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEmpty(count($data)); + } + + /** + * Test getLinks with visibility parameter set to all + */ + public function testGetLinksVisibilityAll() + { + $env = Environment::mock( + [ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'visibility=all' + ] + ); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string)$response->getBody(), true); + $this->assertEquals($this->refDB->countLinks(), count($data)); + $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + } + + /** + * Test getLinks with visibility parameter set to private + */ + public function testGetLinksVisibilityPrivate() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'visibility=private' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals($this->refDB->countPrivateLinks(), count($data)); + $this->assertEquals(6, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + } + + /** + * Test getLinks with visibility parameter set to public + */ + public function testGetLinksVisibilityPublic() + { + $env = Environment::mock( + [ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'visibility=public' + ] + ); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string)$response->getBody(), true); + $this->assertEquals($this->refDB->countPublicLinks(), count($data)); + $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + } + + /** + * Test getLinks service with offset and limit parameter: + * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC). + */ + public function testGetLinksSearchTerm() + { + // Only in description - 1 result + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm=Tropical' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(1, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + + // Only in tags - 1 result + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm=tag3' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(0, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + + // Multiple results (2) + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm=stallman' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(2, count($data)); + $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + $this->assertEquals(8, $data[1]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); + + // Multiword - 2 results + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm=stallman+software' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(2, count($data)); + $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + $this->assertEquals(8, $data[1]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); + + // URL encoding + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm='. urlencode('@web') + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(2, count($data)); + $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + $this->assertEquals(8, $data[1]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); + } + + public function testGetLinksSearchTermNoResult() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm=nope' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(0, count($data)); + } + + public function testGetLinksSearchTags() + { + // Single tag + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=dev', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(2, count($data)); + $this->assertEquals(0, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + $this->assertEquals(4, $data[1]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[1])); + + // Multitag + exclude + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=stuff+-gnu', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + + // wildcard: placeholder at the start + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=*Tuff', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(2, count($data)); + $this->assertEquals(41, $data[0]['id']); + + // wildcard: placeholder at the end + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=c*', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(4, count($data)); + $this->assertEquals(6, $data[0]['id']); + + // wildcard: placeholder at the middle + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=w*b', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(4, count($data)); + $this->assertEquals(6, $data[0]['id']); + + // wildcard: match all + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=*', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(9, count($data)); + $this->assertEquals(41, $data[0]['id']); + + // wildcard: optional ('*' does not need to expand) + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=*stuff*', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(2, count($data)); + $this->assertEquals(41, $data[0]['id']); + + // wildcard: exclusions + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=*a*+-*e*', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(41, $data[0]['id']); // finds '#hashtag' in descr. + + // wildcard: exclude all + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchtags=-*', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(0, count($data)); + } + + /** + * Test getLinks service with search tags+terms. + */ + public function testGetLinksSearchTermsAndTags() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'searchterm=poke&searchtags=dev', + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getLinks($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(0, $data[0]['id']); + $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); + } +} diff --git a/tests/api/controllers/links/PostLinkTest.php b/tests/api/controllers/links/PostLinkTest.php new file mode 100644 index 00000000..100a9170 --- /dev/null +++ b/tests/api/controllers/links/PostLinkTest.php @@ -0,0 +1,218 @@ +conf = new ConfigManager('tests/utils/config/configJson.json.php'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = new \History(self::$testHistory); + + $this->controller = new Links($this->container); + + $mock = $this->createMock(Router::class); + $mock->expects($this->any()) + ->method('relativePathFor') + ->willReturn('api/v1/links/1'); + + // affect @property-read... seems to work + $this->controller->getCi()->router = $mock; + + // Used by index_url(). + $this->controller->getCi()['environment'] = [ + 'SERVER_NAME' => 'domain.tld', + 'SERVER_PORT' => 80, + 'SCRIPT_NAME' => '/', + ]; + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + @unlink(self::$testHistory); + } + + /** + * Test link creation without any field: creates a blank note. + */ + public function testPostLinkMinimal() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'POST', + ]); + + $request = Request::createFromEnvironment($env); + + $response = $this->controller->postLink($request, new Response()); + $this->assertEquals(201, $response->getStatusCode()); + $this->assertEquals('api/v1/links/1', $response->getHeader('Location')[0]); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals(43, $data['id']); + $this->assertRegExp('/[\w-_]{6}/', $data['shorturl']); + $this->assertEquals('http://domain.tld/?' . $data['shorturl'], $data['url']); + $this->assertEquals('?' . $data['shorturl'], $data['title']); + $this->assertEquals('', $data['description']); + $this->assertEquals([], $data['tags']); + $this->assertEquals(false, $data['private']); + $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); + $this->assertEquals('', $data['updated']); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::CREATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $this->assertEquals(43, $historyEntry['id']); + } + + /** + * Test link creation with all available fields. + */ + public function testPostLinkFull() + { + $link = [ + 'url' => 'website.tld/test?foo=bar', + 'title' => 'new entry', + 'description' => 'shaare description', + 'tags' => ['one', 'two'], + 'private' => true, + ]; + $env = Environment::mock([ + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'application/json' + ]); + + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($link); + $response = $this->controller->postLink($request, new Response()); + + $this->assertEquals(201, $response->getStatusCode()); + $this->assertEquals('api/v1/links/1', $response->getHeader('Location')[0]); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals(43, $data['id']); + $this->assertRegExp('/[\w-_]{6}/', $data['shorturl']); + $this->assertEquals('http://' . $link['url'], $data['url']); + $this->assertEquals($link['title'], $data['title']); + $this->assertEquals($link['description'], $data['description']); + $this->assertEquals($link['tags'], $data['tags']); + $this->assertEquals(true, $data['private']); + $this->assertTrue(new \DateTime('2 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); + $this->assertEquals('', $data['updated']); + } + + /** + * Test link creation with an existing link (duplicate URL). Should return a 409 HTTP error and the existing link. + */ + public function testPostLinkDuplicate() + { + $link = [ + 'url' => 'mediagoblin.org/', + 'title' => 'new entry', + 'description' => 'shaare description', + 'tags' => ['one', 'two'], + 'private' => true, + ]; + $env = Environment::mock([ + 'REQUEST_METHOD' => 'POST', + 'CONTENT_TYPE' => 'application/json' + ]); + + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($link); + $response = $this->controller->postLink($request, new Response()); + + $this->assertEquals(409, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals(7, $data['id']); + $this->assertEquals('IuWvgA', $data['shorturl']); + $this->assertEquals('http://mediagoblin.org/', $data['url']); + $this->assertEquals('MediaGoblin', $data['title']); + $this->assertEquals('A free software media publishing platform #hashtagOther', $data['description']); + $this->assertEquals(['gnu', 'media', 'web', '.hidden', 'hashtag'], $data['tags']); + $this->assertEquals(false, $data['private']); + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130614_184135'), + \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) + ); + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130615_184230'), + \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) + ); + } +} diff --git a/tests/api/controllers/links/PutLinkTest.php b/tests/api/controllers/links/PutLinkTest.php new file mode 100644 index 00000000..8a562571 --- /dev/null +++ b/tests/api/controllers/links/PutLinkTest.php @@ -0,0 +1,222 @@ +conf = new ConfigManager('tests/utils/config/configJson.json.php'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = new \History(self::$testHistory); + + $this->controller = new Links($this->container); + + // Used by index_url(). + $this->controller->getCi()['environment'] = [ + 'SERVER_NAME' => 'domain.tld', + 'SERVER_PORT' => 80, + 'SCRIPT_NAME' => '/', + ]; + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + @unlink(self::$testHistory); + } + + /** + * Test link update without value: reset the link to default values + */ + public function testPutLinkMinimal() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $id = '41'; + $request = Request::createFromEnvironment($env); + + $response = $this->controller->putLink($request, new Response(), ['id' => $id]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals($id, $data['id']); + $this->assertEquals('WDWyig', $data['shorturl']); + $this->assertEquals('http://domain.tld/?WDWyig', $data['url']); + $this->assertEquals('?WDWyig', $data['title']); + $this->assertEquals('', $data['description']); + $this->assertEquals([], $data['tags']); + $this->assertEquals(false, $data['private']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20150310_114651'), + \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) + ); + $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $this->assertEquals($id, $historyEntry['id']); + } + + /** + * Test link update with new values + */ + public function testPutLinkWithValues() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + 'CONTENT_TYPE' => 'application/json' + ]); + $id = 41; + $update = [ + 'url' => 'http://somewhere.else', + 'title' => 'Le Cid', + 'description' => 'Percé jusques au fond du cœur [...]', + 'tags' => ['corneille', 'rodrigue'], + 'private' => true, + ]; + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($update); + + $response = $this->controller->putLink($request, new Response(), ['id' => $id]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals($id, $data['id']); + $this->assertEquals('WDWyig', $data['shorturl']); + $this->assertEquals('http://somewhere.else', $data['url']); + $this->assertEquals('Le Cid', $data['title']); + $this->assertEquals('Percé jusques au fond du cœur [...]', $data['description']); + $this->assertEquals(['corneille', 'rodrigue'], $data['tags']); + $this->assertEquals(true, $data['private']); + $this->assertEquals( + \DateTime::createFromFormat('Ymd_His', '20150310_114651'), + \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) + ); + $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); + } + + /** + * Test link update with an existing URL: 409 Conflict with the existing link as body + */ + public function testPutLinkDuplicate() + { + $link = [ + 'url' => 'mediagoblin.org/', + 'title' => 'new entry', + 'description' => 'shaare description', + 'tags' => ['one', 'two'], + 'private' => true, + ]; + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + 'CONTENT_TYPE' => 'application/json' + ]); + + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($link); + $response = $this->controller->putLink($request, new Response(), ['id' => 41]); + + $this->assertEquals(409, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_LINK, count($data)); + $this->assertEquals(7, $data['id']); + $this->assertEquals('IuWvgA', $data['shorturl']); + $this->assertEquals('http://mediagoblin.org/', $data['url']); + $this->assertEquals('MediaGoblin', $data['title']); + $this->assertEquals('A free software media publishing platform #hashtagOther', $data['description']); + $this->assertEquals(['gnu', 'media', 'web', '.hidden', 'hashtag'], $data['tags']); + $this->assertEquals(false, $data['private']); + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130614_184135'), + \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) + ); + $this->assertEquals( + \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20130615_184230'), + \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) + ); + } + + /** + * Test link update on non existent link => ApiLinkNotFoundException. + * + * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException + * @expectedExceptionMessage Link not found + */ + public function testGetLink404() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $request = Request::createFromEnvironment($env); + + $this->controller->putLink($request, new Response(), ['id' => -1]); + } +} diff --git a/tests/api/controllers/tags/DeleteTagTest.php b/tests/api/controllers/tags/DeleteTagTest.php new file mode 100644 index 00000000..7ba5a862 --- /dev/null +++ b/tests/api/controllers/tags/DeleteTagTest.php @@ -0,0 +1,164 @@ +conf = new ConfigManager('tests/utils/config/configJson'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = $this->linkDB; + $this->container['history'] = $this->history; + + $this->controller = new Tags($this->container); + } + + /** + * After each test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + @unlink(self::$testHistory); + } + + /** + * Test DELETE tag endpoint: the tag should be removed. + */ + public function testDeleteTagValid() + { + $tagName = 'gnu'; + $tags = $this->linkDB->linksCountPerTag(); + $this->assertTrue($tags[$tagName] > 0); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'DELETE', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->deleteTag($request, new Response(), ['tagName' => $tagName]); + $this->assertEquals(204, $response->getStatusCode()); + $this->assertEmpty((string) $response->getBody()); + + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $tags = $this->linkDB->linksCountPerTag(); + $this->assertFalse(isset($tags[$tagName])); + + // 2 links affected + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $historyEntry = $this->history->getHistory()[1]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + } + + /** + * Test DELETE tag endpoint: the tag should be removed. + */ + public function testDeleteTagCaseSensitivity() + { + $tagName = 'sTuff'; + $tags = $this->linkDB->linksCountPerTag(); + $this->assertTrue($tags[$tagName] > 0); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'DELETE', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->deleteTag($request, new Response(), ['tagName' => $tagName]); + $this->assertEquals(204, $response->getStatusCode()); + $this->assertEmpty((string) $response->getBody()); + + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $tags = $this->linkDB->linksCountPerTag(); + $this->assertFalse(isset($tags[$tagName])); + $this->assertTrue($tags[strtolower($tagName)] > 0); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + } + + /** + * Test DELETE link endpoint: reach not existing ID. + * + * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException + * @expectedExceptionMessage Tag not found + */ + public function testDeleteLink404() + { + $tagName = 'nopenope'; + $tags = $this->linkDB->linksCountPerTag(); + $this->assertFalse(isset($tags[$tagName])); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'DELETE', + ]); + $request = Request::createFromEnvironment($env); + + $this->controller->deleteTag($request, new Response(), ['tagName' => $tagName]); + } +} diff --git a/tests/api/controllers/tags/GetTagNameTest.php b/tests/api/controllers/tags/GetTagNameTest.php new file mode 100644 index 00000000..d60f5b38 --- /dev/null +++ b/tests/api/controllers/tags/GetTagNameTest.php @@ -0,0 +1,129 @@ +conf = new ConfigManager('tests/utils/config/configJson'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); + $this->container['history'] = null; + + $this->controller = new Tags($this->container); + } + + /** + * After each test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + } + + /** + * Test basic getTag service: return gnu tag with 2 occurrences. + */ + public function testGetTag() + { + $tagName = 'gnu'; + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getTag($request, new Response(), ['tagName' => $tagName]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_TAG, count($data)); + $this->assertEquals($tagName, $data['name']); + $this->assertEquals(2, $data['occurrences']); + } + + /** + * Test getTag service which is not case sensitive: occurrences with both sTuff and stuff + */ + public function testGetTagNotCaseSensitive() + { + $tagName = 'sTuff'; + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getTag($request, new Response(), ['tagName' => $tagName]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_TAG, count($data)); + $this->assertEquals($tagName, $data['name']); + $this->assertEquals(2, $data['occurrences']); + } + + /** + * Test basic getLink service: get non existent link => ApiLinkNotFoundException. + * + * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException + * @expectedExceptionMessage Tag not found + */ + public function testGetTag404() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $this->controller->getTag($request, new Response(), ['tagName' => 'nopenope']); + } +} diff --git a/tests/api/controllers/tags/GetTagsTest.php b/tests/api/controllers/tags/GetTagsTest.php new file mode 100644 index 00000000..cf066bc3 --- /dev/null +++ b/tests/api/controllers/tags/GetTagsTest.php @@ -0,0 +1,209 @@ +conf = new ConfigManager('tests/utils/config/configJson'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $this->container['db'] = $this->linkDB; + $this->container['history'] = null; + + $this->controller = new Tags($this->container); + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + } + + /** + * Test basic getLinks service: returns all tags. + */ + public function testGetTagsAll() + { + $tags = $this->linkDB->linksCountPerTag(); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + ]); + $request = Request::createFromEnvironment($env); + + $response = $this->controller->getTags($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(count($tags), count($data)); + + // Check order + $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); + $this->assertEquals('web', $data[0]['name']); + $this->assertEquals(4, $data[0]['occurrences']); + $this->assertEquals(self::NB_FIELDS_TAG, count($data[1])); + $this->assertEquals('cartoon', $data[1]['name']); + $this->assertEquals(3, $data[1]['occurrences']); + // Case insensitive + $this->assertEquals(self::NB_FIELDS_TAG, count($data[2])); + $this->assertEquals('sTuff', $data[2]['name']); + $this->assertEquals(2, $data[2]['occurrences']); + // End + $this->assertEquals(self::NB_FIELDS_TAG, count($data[count($data) - 1])); + $this->assertEquals('ut', $data[count($data) - 1]['name']); + $this->assertEquals(1, $data[count($data) - 1]['occurrences']); + } + + /** + * Test getTags service with offset and limit parameter: + * limit=1 and offset=1 should return only the second tag, cartoon with 3 occurrences + */ + public function testGetTagsOffsetLimit() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'offset=1&limit=1' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getTags($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(1, count($data)); + $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); + $this->assertEquals('cartoon', $data[0]['name']); + $this->assertEquals(3, $data[0]['occurrences']); + } + + /** + * Test getTags with limit=all (return all tags). + */ + public function testGetTagsLimitAll() + { + $tags = $this->linkDB->linksCountPerTag(); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'limit=all' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getTags($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(count($tags), count($data)); + } + + /** + * Test getTags service with offset and limit parameter: + * limit=1 and offset=1 should not return any tag + */ + public function testGetTagsOffsetTooHigh() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'offset=100' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getTags($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEmpty(count($data)); + } + + /** + * Test getTags with visibility parameter set to private + */ + public function testGetTagsVisibilityPrivate() + { + $tags = $this->linkDB->linksCountPerTag([], 'private'); + $env = Environment::mock([ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'visibility=private' + ]); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getTags($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(count($tags), count($data)); + $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); + $this->assertEquals('css', $data[0]['name']); + $this->assertEquals(1, $data[0]['occurrences']); + } + + /** + * Test getTags with visibility parameter set to public + */ + public function testGetTagsVisibilityPublic() + { + $tags = $this->linkDB->linksCountPerTag([], 'public'); + $env = Environment::mock( + [ + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => 'visibility=public' + ] + ); + $request = Request::createFromEnvironment($env); + $response = $this->controller->getTags($request, new Response()); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string)$response->getBody(), true); + $this->assertEquals(count($tags), count($data)); + $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); + $this->assertEquals('web', $data[0]['name']); + $this->assertEquals(3, $data[0]['occurrences']); + } +} diff --git a/tests/api/controllers/tags/PutTagTest.php b/tests/api/controllers/tags/PutTagTest.php new file mode 100644 index 00000000..6f7dec22 --- /dev/null +++ b/tests/api/controllers/tags/PutTagTest.php @@ -0,0 +1,209 @@ +conf = new ConfigManager('tests/utils/config/configJson.json.php'); + $this->refDB = new \ReferenceLinkDB(); + $this->refDB->write(self::$testDatastore); + + $refHistory = new \ReferenceHistory(); + $refHistory->write(self::$testHistory); + $this->history = new \History(self::$testHistory); + + $this->container = new Container(); + $this->container['conf'] = $this->conf; + $this->linkDB = new \LinkDB(self::$testDatastore, true, false); + $this->container['db'] = $this->linkDB; + $this->container['history'] = $this->history; + + $this->controller = new Tags($this->container); + } + + /** + * After every test, remove the test datastore. + */ + public function tearDown() + { + @unlink(self::$testDatastore); + @unlink(self::$testHistory); + } + + /** + * Test tags update + */ + public function testPutLinkValid() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $tagName = 'gnu'; + $update = ['name' => $newName = 'newtag']; + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($update); + + $response = $this->controller->putTag($request, new Response(), ['tagName' => $tagName]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_TAG, count($data)); + $this->assertEquals($newName, $data['name']); + $this->assertEquals(2, $data['occurrences']); + + $tags = $this->linkDB->linksCountPerTag(); + $this->assertNotTrue(isset($tags[$tagName])); + $this->assertEquals(2, $tags[$newName]); + + $historyEntry = $this->history->getHistory()[0]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + $historyEntry = $this->history->getHistory()[1]; + $this->assertEquals(\History::UPDATED, $historyEntry['event']); + $this->assertTrue( + (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime'] + ); + } + + /** + * Test tag update with an existing tag: they should be merged + */ + public function testPutTagMerge() + { + $tagName = 'gnu'; + $newName = 'w3c'; + + $tags = $this->linkDB->linksCountPerTag(); + $this->assertEquals(1, $tags[$newName]); + $this->assertEquals(2, $tags[$tagName]); + + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $update = ['name' => $newName]; + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($update); + + $response = $this->controller->putTag($request, new Response(), ['tagName' => $tagName]); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode((string) $response->getBody(), true); + $this->assertEquals(self::NB_FIELDS_TAG, count($data)); + $this->assertEquals($newName, $data['name']); + $this->assertEquals(3, $data['occurrences']); + + $tags = $this->linkDB->linksCountPerTag(); + $this->assertNotTrue(isset($tags[$tagName])); + $this->assertEquals(3, $tags[$newName]); + } + + /** + * Test tag update with an empty new tag name => ApiBadParametersException + * + * @expectedException Shaarli\Api\Exceptions\ApiBadParametersException + * @expectedExceptionMessage New tag name is required in the request body + */ + public function testPutTagEmpty() + { + $tagName = 'gnu'; + $newName = ''; + + $tags = $this->linkDB->linksCountPerTag(); + $this->assertEquals(2, $tags[$tagName]); + + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $request = Request::createFromEnvironment($env); + + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $update = ['name' => $newName]; + $request = Request::createFromEnvironment($env); + $request = $request->withParsedBody($update); + + try { + $this->controller->putTag($request, new Response(), ['tagName' => $tagName]); + } catch (ApiBadParametersException $e) { + $tags = $this->linkDB->linksCountPerTag(); + $this->assertEquals(2, $tags[$tagName]); + throw $e; + } + } + + /** + * Test tag update on non existent tag => ApiTagNotFoundException. + * + * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException + * @expectedExceptionMessage Tag not found + */ + public function testPutTag404() + { + $env = Environment::mock([ + 'REQUEST_METHOD' => 'PUT', + ]); + $request = Request::createFromEnvironment($env); + + $this->controller->putTag($request, new Response(), ['tagName' => 'nopenope']); + } +} -- cgit v1.2.3 From 1168abb484ce8fd6a524a4849d9d4dd3e0589b20 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sat, 16 Jun 2018 23:54:10 +0200 Subject: docker: move testing resources to tests/docker Relates to https://github.com/shaarli/Shaarli/issues/1153 Signed-off-by: VirtualTam --- tests/docker/alpine36/Dockerfile | 34 ++++++++++++++++++++++++++++++++++ tests/docker/debian8/Dockerfile | 35 +++++++++++++++++++++++++++++++++++ tests/docker/debian9/Dockerfile | 36 ++++++++++++++++++++++++++++++++++++ tests/docker/ubuntu16/Dockerfile | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 tests/docker/alpine36/Dockerfile create mode 100644 tests/docker/debian8/Dockerfile create mode 100644 tests/docker/debian9/Dockerfile create mode 100644 tests/docker/ubuntu16/Dockerfile (limited to 'tests') diff --git a/tests/docker/alpine36/Dockerfile b/tests/docker/alpine36/Dockerfile new file mode 100644 index 00000000..fa84f6e2 --- /dev/null +++ b/tests/docker/alpine36/Dockerfile @@ -0,0 +1,34 @@ +FROM alpine:3.6 +MAINTAINER Shaarli Community + +RUN apk --update --no-cache add \ + ca-certificates \ + curl \ + make \ + php7 \ + php7-ctype \ + php7-curl \ + php7-dom \ + php7-gd \ + php7-iconv \ + php7-intl \ + php7-json \ + php7-mbstring \ + php7-openssl \ + php7-phar \ + php7-session \ + php7-simplexml \ + php7-tokenizer \ + php7-xdebug \ + php7-xml \ + php7-zlib \ + rsync + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +RUN mkdir /shaarli +WORKDIR /shaarli +VOLUME /shaarli + +ENTRYPOINT ["make"] +CMD [] diff --git a/tests/docker/debian8/Dockerfile b/tests/docker/debian8/Dockerfile new file mode 100644 index 00000000..eaa34e9b --- /dev/null +++ b/tests/docker/debian8/Dockerfile @@ -0,0 +1,35 @@ +FROM debian:jessie +MAINTAINER Shaarli Community + +ENV TERM dumb +ENV DEBIAN_FRONTEND noninteractive +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en + +RUN apt-get update \ + && apt-get install --no-install-recommends -y \ + ca-certificates \ + curl \ + locales \ + make \ + php5 \ + php5-curl \ + php5-gd \ + php5-intl \ + php5-xdebug \ + rsync \ + && apt-get clean + +RUN locale-gen en_US.UTF-8 \ + && locale-gen de_DE.UTF-8 \ + && locale-gen fr_FR.UTF-8 + +ADD https://getcomposer.org/composer.phar /usr/local/bin/composer +RUN chmod 755 /usr/local/bin/composer + +RUN mkdir /shaarli +WORKDIR /shaarli +VOLUME /shaarli + +ENTRYPOINT ["make"] +CMD [] diff --git a/tests/docker/debian9/Dockerfile b/tests/docker/debian9/Dockerfile new file mode 100644 index 00000000..3ab4b93d --- /dev/null +++ b/tests/docker/debian9/Dockerfile @@ -0,0 +1,36 @@ +FROM debian:stretch +MAINTAINER Shaarli Community + +ENV TERM dumb +ENV DEBIAN_FRONTEND noninteractive +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en + +RUN apt-get update \ + && apt-get install --no-install-recommends -y \ + ca-certificates \ + curl \ + locales \ + make \ + php7.0 \ + php7.0-curl \ + php7.0-gd \ + php7.0-intl \ + php7.0-xml \ + php-xdebug \ + rsync \ + && apt-get clean + +RUN locale-gen en_US.UTF-8 \ + && locale-gen de_DE.UTF-8 \ + && locale-gen fr_FR.UTF-8 + +ADD https://getcomposer.org/composer.phar /usr/local/bin/composer +RUN chmod 755 /usr/local/bin/composer + +RUN mkdir /shaarli +WORKDIR /shaarli +VOLUME /shaarli + +ENTRYPOINT ["make"] +CMD [] diff --git a/tests/docker/ubuntu16/Dockerfile b/tests/docker/ubuntu16/Dockerfile new file mode 100644 index 00000000..e53ed9e3 --- /dev/null +++ b/tests/docker/ubuntu16/Dockerfile @@ -0,0 +1,36 @@ +FROM ubuntu:16.04 +MAINTAINER Shaarli Community + +ENV TERM dumb +ENV DEBIAN_FRONTEND noninteractive +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en + +RUN apt-get update \ + && apt-get install --no-install-recommends -y \ + ca-certificates \ + curl \ + language-pack-de \ + language-pack-en \ + language-pack-fr \ + locales \ + make \ + php7.0 \ + php7.0-curl \ + php7.0-gd \ + php7.0-intl \ + php7.0-xml \ + php-xdebug \ + rsync \ + && apt-get clean + +ADD https://getcomposer.org/composer.phar /usr/local/bin/composer +RUN chmod 755 /usr/local/bin/composer + +RUN useradd -m dev \ + && mkdir /shaarli +USER dev +WORKDIR /shaarli + +ENTRYPOINT ["make"] +CMD [] -- cgit v1.2.3 From 1b93137e16694f52952c930848e1a7928e8a00a6 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 9 Nov 2016 18:57:02 +0100 Subject: Use web-thumbnailer to retrieve thumbnails * requires PHP 5.6 * use blazy on linklist since a lot more thumbs are retrieved * thumbnails can be disabled * thumbs size is now 120x120 * thumbs are now cropped to fit the expected size Fixes #345 #425 #487 #543 #588 #590 --- tests/ThumbnailerTest.php | 51 ++++++++++++++++++++++++++++++++++ tests/utils/config/configJson.json.php | 3 ++ 2 files changed, 54 insertions(+) create mode 100644 tests/ThumbnailerTest.php (limited to 'tests') diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php new file mode 100644 index 00000000..db109321 --- /dev/null +++ b/tests/ThumbnailerTest.php @@ -0,0 +1,51 @@ +set('thumbnails.width', $width); + $conf->set('thumbnails.height', $height); + + $thumbnailer = new Thumbnailer($conf); + $thumb = $thumbnailer->get('https://github.com/shaarli/Shaarli/'); + $this->assertNotFalse($thumb); + $image = imagecreatefromstring(file_get_contents($thumb)); + $this->assertEquals($width, imagesx($image)); + $this->assertEquals($height, imagesy($image)); + } + + /** + * Test a thumbnail that can't be retrieved. + * + * @expectedException WebThumbnailer\Exception\ThumbnailNotFoundException + */ + public function testThumbnailNotValid() + { + $oldlog = ini_get('error_log'); + ini_set('error_log', '/dev/null'); + + $thumbnailer = new Thumbnailer(new ConfigManager()); + $thumb = $thumbnailer->get('nope'); + $this->assertFalse($thumb); + + ini_set('error_log', $oldlog); + } +} diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index 9c9288f3..3101b225 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php @@ -29,6 +29,9 @@ }, "plugins": { "WALLABAG_VERSION": 1 + }, + "dev": { + "debug": true } } */ ?> -- cgit v1.2.3 From a3724717ec37d4bd54dc117ef439c8a182157882 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 11 Nov 2017 14:00:18 +0100 Subject: ConfigManager: add a method to remove an entry --- tests/config/ConfigManagerTest.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') 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 $this->assertEquals('testSetWriteGetNested', $this->conf->get('foo.bar.key.stuff')); } + public function testSetDeleteNested() + { + $this->conf->set('foo.bar.key.stuff', 'testSetDeleteNested'); + $this->assertTrue($this->conf->exists('foo.bar')); + $this->assertTrue($this->conf->exists('foo.bar.key.stuff')); + $this->assertEquals('testSetDeleteNested', $this->conf->get('foo.bar.key.stuff')); + + $this->conf->remove('foo.bar'); + $this->assertFalse($this->conf->exists('foo.bar.key.stuff')); + $this->assertFalse($this->conf->exists('foo.bar')); + } + /** * Set with an empty key. * @@ -103,6 +115,17 @@ class ConfigManagerTest extends \PHPUnit_Framework_TestCase $this->conf->set(array('foo' => 'bar'), 'stuff'); } + /** + * Remove with an empty key. + * + * @expectedException \Exception + * @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*# + */ + public function testRmoveEmptyKey() + { + $this->conf->remove(''); + } + /** * Try to write the config without mandatory parameter (e.g. 'login'). * -- cgit v1.2.3 From e85b7a05a177f803ae36ba5c12835313f31177bc Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 11 Nov 2017 14:01:21 +0100 Subject: Update thumbnail integration after rebasing the branch --- tests/ThumbnailerTest.php | 64 +++++++++++++++++++++++-------- tests/Updater/UpdaterTest.php | 15 ++++++++ tests/utils/config/configJson.json.php | 70 ++++++++++++++++++++++++++++------ tests/utils/config/wt.json | 12 ++++++ 4 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 tests/utils/config/wt.json (limited to 'tests') diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php index db109321..c04b8fb5 100644 --- a/tests/ThumbnailerTest.php +++ b/tests/ThumbnailerTest.php @@ -1,7 +1,10 @@ set('thumbnails.width', $width); - $conf->set('thumbnails.height', $height); + $conf->set('thumbnails.width', self::WIDTH); + $conf->set('thumbnails.height', self::HEIGHT); + $conf->set('dev.debug', true); + + $this->thumbnailer = new Thumbnailer($conf); + // cache files in the sandbox + WTConfigManager::addFile('tests/utils/config/wt.json'); + } + + public function tearDown() + { + $this->rrmdirContent('sandbox/'); + } - $thumbnailer = new Thumbnailer($conf); - $thumb = $thumbnailer->get('https://github.com/shaarli/Shaarli/'); + /** + * Test a thumbnail with a custom size. + */ + public function testThumbnailValid() + { + $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/'); $this->assertNotFalse($thumb); $image = imagecreatefromstring(file_get_contents($thumb)); - $this->assertEquals($width, imagesx($image)); - $this->assertEquals($height, imagesy($image)); + $this->assertEquals(self::WIDTH, imagesx($image)); + $this->assertEquals(self::HEIGHT, imagesy($image)); } /** * Test a thumbnail that can't be retrieved. - * - * @expectedException WebThumbnailer\Exception\ThumbnailNotFoundException */ public function testThumbnailNotValid() { @@ -48,4 +68,18 @@ class ThumbnailerTest extends PHPUnit_Framework_TestCase ini_set('error_log', $oldlog); } + + protected function rrmdirContent($dir) { + if (is_dir($dir)) { + $objects = scandir($dir); + foreach ($objects as $object) { + if ($object != "." && $object != "..") { + if (is_dir($dir."/".$object)) + $this->rrmdirContent($dir."/".$object); + else + unlink($dir."/".$object); + } + } + } + } } diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 94e3c7d3..8b90fd5e 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -684,4 +684,19 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $this->assertEquals(4194304, $this->conf->get('general.download_max_size')); $this->assertEquals(3, $this->conf->get('general.download_timeout')); } + + /** + * Test updateMethodAtomDefault with show_atom set to true. + * => nothing to do + */ + public function testUpdateMethodWebThumbnailerEnabled() + { + $this->conf->set('thumbnail.enable_thumbnails', true); + $updater = new Updater([], [], $this->conf, true); + $this->assertTrue($updater->updateMethodWebThumbnailer()); + $this->assertFalse($this->conf->exists('thumbnail')); + $this->assertTrue($this->conf->get('thumbnails.enabled')); + $this->assertEquals(125, $this->conf->get('thumbnails.width')); + $this->assertEquals(90, $this->conf->get('thumbnails.height')); + } } diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index 3101b225..061d4c28 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php @@ -1,38 +1,84 @@ - +*/ ?> \ No newline at end of file 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 @@ +{ + "settings": { + "default": { + "_comment": "infinite cache", + "cache_duration": -1, + "timeout": 10 + }, + "path": { + "cache": "sandbox/" + } + } +} \ No newline at end of file -- cgit v1.2.3 From 28f26524609338316cc6e51c743058e6e8c7b12b Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 8 Jun 2018 12:50:49 +0200 Subject: Add a page to update all thumbnails through AJAX requests in both templates --- tests/Updater/UpdaterTest.php | 40 ++++++++++++++++++++++++++++++---- tests/utils/config/configJson.json.php | 12 +++++----- 2 files changed, 42 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 8b90fd5e..92ff5690 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -20,7 +20,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase /** * @var string Config file path (without extension). */ - protected static $configFile = 'tests/utils/config/configJson'; + protected static $configFile = 'sandbox/config'; /** * @var ConfigManager @@ -32,6 +32,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase */ public function setUp() { + copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php'); $this->conf = new ConfigManager(self::$configFile); } @@ -686,17 +687,48 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; } /** - * Test updateMethodAtomDefault with show_atom set to true. - * => nothing to do + * Test updateMethodWebThumbnailer with thumbnails enabled. */ public function testUpdateMethodWebThumbnailerEnabled() { + $this->conf->remove('thumbnails'); $this->conf->set('thumbnail.enable_thumbnails', true); - $updater = new Updater([], [], $this->conf, true); + $updater = new Updater([], [], $this->conf, true, $_SESSION); $this->assertTrue($updater->updateMethodWebThumbnailer()); $this->assertFalse($this->conf->exists('thumbnail')); $this->assertTrue($this->conf->get('thumbnails.enabled')); $this->assertEquals(125, $this->conf->get('thumbnails.width')); $this->assertEquals(90, $this->conf->get('thumbnails.height')); + $this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]); + } + + /** + * Test updateMethodWebThumbnailer with thumbnails disabled. + */ + public function testUpdateMethodWebThumbnailerDisabled() + { + $this->conf->remove('thumbnails'); + $this->conf->set('thumbnail.enable_thumbnails', false); + $updater = new Updater([], [], $this->conf, true, $_SESSION); + $this->assertTrue($updater->updateMethodWebThumbnailer()); + $this->assertFalse($this->conf->exists('thumbnail')); + $this->assertFalse($this->conf->get('thumbnails.enabled')); + $this->assertEquals(125, $this->conf->get('thumbnails.width')); + $this->assertEquals(90, $this->conf->get('thumbnails.height')); + $this->assertTrue(empty($_SESSION['warnings'])); + } + + /** + * Test updateMethodWebThumbnailer with thumbnails disabled. + */ + public function testUpdateMethodWebThumbnailerNothingToDo() + { + $updater = new Updater([], [], $this->conf, true, $_SESSION); + $this->assertTrue($updater->updateMethodWebThumbnailer()); + $this->assertFalse($this->conf->exists('thumbnail')); + $this->assertTrue($this->conf->get('thumbnails.enabled')); + $this->assertEquals(90, $this->conf->get('thumbnails.width')); + $this->assertEquals(53, $this->conf->get('thumbnails.height')); + $this->assertTrue(empty($_SESSION['warnings'])); } } diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index 061d4c28..a656b67c 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php @@ -61,11 +61,6 @@ "dev": { "debug": true }, - "thumbnails": { - "enabled": true, - "width": 125, - "height": 90 - }, "updates": { "check_updates": false, "check_updates_branch": "stable", @@ -79,6 +74,11 @@ "language": "auto", "mode": "php", "extensions": [] + }, + "thumbnails": { + "enabled": true, + "width": 90, + "height": 53 } } -*/ ?> \ No newline at end of file +*/ ?> -- cgit v1.2.3 From b302b3c584b84f22f0e6f187b072180ecbacdfab Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 5 Jul 2018 20:29:55 +0200 Subject: Thumbnails: add a common mode to only retrieve thumbs from popular media websites --- tests/ThumbnailerTest.php | 43 ++++++++++++++++++++++++++++------ tests/Updater/UpdaterTest.php | 7 +++--- tests/utils/config/configJson.json.php | 2 +- 3 files changed, 41 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php index c04b8fb5..08311545 100644 --- a/tests/ThumbnailerTest.php +++ b/tests/ThumbnailerTest.php @@ -25,14 +25,20 @@ class ThumbnailerTest extends TestCase */ protected $thumbnailer; + /** + * @var ConfigManager + */ + protected $conf; + public function setUp() { - $conf = new ConfigManager('tests/utils/config/configJson'); - $conf->set('thumbnails.width', self::WIDTH); - $conf->set('thumbnails.height', self::HEIGHT); - $conf->set('dev.debug', true); + $this->conf = new ConfigManager('tests/utils/config/configJson'); + $this->conf->set('thumbnails.mode', Thumbnailer::MODE_ALL); + $this->conf->set('thumbnails.width', self::WIDTH); + $this->conf->set('thumbnails.height', self::HEIGHT); + $this->conf->set('dev.debug', true); - $this->thumbnailer = new Thumbnailer($conf); + $this->thumbnailer = new Thumbnailer($this->conf); // cache files in the sandbox WTConfigManager::addFile('tests/utils/config/wt.json'); } @@ -43,9 +49,9 @@ class ThumbnailerTest extends TestCase } /** - * Test a thumbnail with a custom size. + * Test a thumbnail with a custom size in 'all' mode. */ - public function testThumbnailValid() + public function testThumbnailAllValid() { $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/'); $this->assertNotFalse($thumb); @@ -54,6 +60,29 @@ class ThumbnailerTest extends TestCase $this->assertEquals(self::HEIGHT, imagesy($image)); } + /** + * Test a thumbnail with a custom size in 'common' mode. + */ + public function testThumbnailCommonValid() + { + $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON); + $thumb = $this->thumbnailer->get('https://imgur.com/jlFgGpe'); + $this->assertNotFalse($thumb); + $image = imagecreatefromstring(file_get_contents($thumb)); + $this->assertEquals(self::WIDTH, imagesx($image)); + $this->assertEquals(self::HEIGHT, imagesy($image)); + } + + /** + * Test a thumbnail in 'common' mode which isn't include in common websites. + */ + public function testThumbnailCommonInvalid() + { + $this->conf->set('thumbnails.mode', Thumbnailer::MODE_COMMON); + $thumb = $this->thumbnailer->get('https://github.com/shaarli/Shaarli/'); + $this->assertFalse($thumb); + } + /** * Test a thumbnail that can't be retrieved. */ diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 92ff5690..05f4b8e1 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -2,6 +2,7 @@ use Shaarli\Config\ConfigJson; use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigPhp; +use Shaarli\Thumbnailer; require_once 'tests/Updater/DummyUpdater.php'; require_once 'inc/rain.tpl.class.php'; @@ -696,7 +697,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $updater = new Updater([], [], $this->conf, true, $_SESSION); $this->assertTrue($updater->updateMethodWebThumbnailer()); $this->assertFalse($this->conf->exists('thumbnail')); - $this->assertTrue($this->conf->get('thumbnails.enabled')); + $this->assertEquals(\Shaarli\Thumbnailer::MODE_ALL, $this->conf->get('thumbnails.mode')); $this->assertEquals(125, $this->conf->get('thumbnails.width')); $this->assertEquals(90, $this->conf->get('thumbnails.height')); $this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]); @@ -712,7 +713,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $updater = new Updater([], [], $this->conf, true, $_SESSION); $this->assertTrue($updater->updateMethodWebThumbnailer()); $this->assertFalse($this->conf->exists('thumbnail')); - $this->assertFalse($this->conf->get('thumbnails.enabled')); + $this->assertEquals(Thumbnailer::MODE_NONE, $this->conf->get('thumbnails.mode')); $this->assertEquals(125, $this->conf->get('thumbnails.width')); $this->assertEquals(90, $this->conf->get('thumbnails.height')); $this->assertTrue(empty($_SESSION['warnings'])); @@ -726,7 +727,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $updater = new Updater([], [], $this->conf, true, $_SESSION); $this->assertTrue($updater->updateMethodWebThumbnailer()); $this->assertFalse($this->conf->exists('thumbnail')); - $this->assertTrue($this->conf->get('thumbnails.enabled')); + $this->assertEquals(Thumbnailer::MODE_COMMON, $this->conf->get('thumbnails.mode')); $this->assertEquals(90, $this->conf->get('thumbnails.width')); $this->assertEquals(53, $this->conf->get('thumbnails.height')); $this->assertTrue(empty($_SESSION['warnings'])); diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php index a656b67c..1549ddfc 100644 --- a/tests/utils/config/configJson.json.php +++ b/tests/utils/config/configJson.json.php @@ -76,7 +76,7 @@ "extensions": [] }, "thumbnails": { - "enabled": true, + "mode": "common", "width": 90, "height": 53 } -- cgit v1.2.3 From 7c57bd95383ec7a7d40735957ea9a792c370b5db Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 4 Jun 2018 18:58:59 +0200 Subject: GetTagsTest - Update to alpha sort for equal occurences --- tests/api/controllers/tags/DeleteTagTest.php | 2 +- tests/api/controllers/tags/GetTagNameTest.php | 2 +- tests/api/controllers/tags/GetTagsTest.php | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/api/controllers/tags/DeleteTagTest.php b/tests/api/controllers/tags/DeleteTagTest.php index 7ba5a862..e0787ce2 100644 --- a/tests/api/controllers/tags/DeleteTagTest.php +++ b/tests/api/controllers/tags/DeleteTagTest.php @@ -144,7 +144,7 @@ class DeleteTagTest extends \PHPUnit_Framework_TestCase } /** - * Test DELETE link endpoint: reach not existing ID. + * Test DELETE tag endpoint: reach not existing tag. * * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException * @expectedExceptionMessage Tag not found diff --git a/tests/api/controllers/tags/GetTagNameTest.php b/tests/api/controllers/tags/GetTagNameTest.php index d60f5b38..afac228e 100644 --- a/tests/api/controllers/tags/GetTagNameTest.php +++ b/tests/api/controllers/tags/GetTagNameTest.php @@ -112,7 +112,7 @@ class GetTagNameTest extends \PHPUnit_Framework_TestCase } /** - * Test basic getLink service: get non existent link => ApiLinkNotFoundException. + * Test basic getTag service: get non existent tag => ApiTagNotFoundException. * * @expectedException Shaarli\Api\Exceptions\ApiTagNotFoundException * @expectedExceptionMessage Tag not found diff --git a/tests/api/controllers/tags/GetTagsTest.php b/tests/api/controllers/tags/GetTagsTest.php index cf066bc3..3fab31b0 100644 --- a/tests/api/controllers/tags/GetTagsTest.php +++ b/tests/api/controllers/tags/GetTagsTest.php @@ -79,7 +79,7 @@ class GetTagsTest extends \PHPUnit_Framework_TestCase } /** - * Test basic getLinks service: returns all tags. + * Test basic getTags service: returns all tags. */ public function testGetTagsAll() { @@ -102,12 +102,12 @@ class GetTagsTest extends \PHPUnit_Framework_TestCase $this->assertEquals('cartoon', $data[1]['name']); $this->assertEquals(3, $data[1]['occurrences']); // Case insensitive - $this->assertEquals(self::NB_FIELDS_TAG, count($data[2])); - $this->assertEquals('sTuff', $data[2]['name']); - $this->assertEquals(2, $data[2]['occurrences']); + $this->assertEquals(self::NB_FIELDS_TAG, count($data[5])); + $this->assertEquals('sTuff', $data[5]['name']); + $this->assertEquals(2, $data[5]['occurrences']); // End $this->assertEquals(self::NB_FIELDS_TAG, count($data[count($data) - 1])); - $this->assertEquals('ut', $data[count($data) - 1]['name']); + $this->assertEquals('w3c', $data[count($data) - 1]['name']); $this->assertEquals(1, $data[count($data) - 1]['occurrences']); } @@ -181,7 +181,7 @@ class GetTagsTest extends \PHPUnit_Framework_TestCase $data = json_decode((string) $response->getBody(), true); $this->assertEquals(count($tags), count($data)); $this->assertEquals(self::NB_FIELDS_TAG, count($data[0])); - $this->assertEquals('css', $data[0]['name']); + $this->assertEquals('Mercurial', $data[0]['name']); $this->assertEquals(1, $data[0]['occurrences']); } -- cgit v1.2.3 From 7b4fea0e39be9e74e9aef13e73af9bbd2b1a6397 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Tue, 17 Jul 2018 13:13:26 +0200 Subject: Bunch of improvement for thumbnails integration: - add a default thumb size value (125x90px) - improve private vertical bar visual, especially with thumbnails - translations - add a sync thumbs button in tool and empty picwall page - fixes WT download mode in JSON config --- tests/Updater/UpdaterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 05f4b8e1..cacee2d2 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -700,7 +700,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $this->assertEquals(\Shaarli\Thumbnailer::MODE_ALL, $this->conf->get('thumbnails.mode')); $this->assertEquals(125, $this->conf->get('thumbnails.width')); $this->assertEquals(90, $this->conf->get('thumbnails.height')); - $this->assertContains('You have enabled thumbnails', $_SESSION['warnings'][0]); + $this->assertContains('You have enabled or changed thumbnails', $_SESSION['warnings'][0]); } /** -- cgit v1.2.3 From a120fb2977331e0f7d7ffe05861ba179fdae8764 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 13 Aug 2018 10:42:27 +0200 Subject: Add OpenGraph meta tags on permalink page Includes: - og:title - og:type -> article - og:image -> if there is a thumbnail - og:url -> permalink - og:description -> first 300 chars of raw description - article:published_time - article:modified_time - article:tag -> one OG meta tag for each shaare tag Fixes #258 --- tests/plugins/PluginMarkdownTest.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php index b31e817f..31c1f8b7 100644 --- a/tests/plugins/PluginMarkdownTest.php +++ b/tests/plugins/PluginMarkdownTest.php @@ -47,6 +47,8 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $data = hook_markdown_render_linklist($data, $this->conf); $this->assertNotFalse(strpos($data['links'][0]['description'], '

        ')); $this->assertNotFalse(strpos($data['links'][0]['description'], '

        ')); + + $this->assertEquals($markdown, $data['links'][0]['description_src']); } /** -- cgit v1.2.3 From cb7940e2deacba66f2510816732be654b255cc70 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Tue, 14 Aug 2018 12:26:51 +0200 Subject: Fix hashtags with markdown escape enabled They're now transformed to markdown syntax links before processing them through Parsedown. Fixes #1210 --- tests/plugins/PluginMarkdownTest.php | 14 +++++++++++++- tests/plugins/resources/hashtags.md | 10 ++++++++++ tests/plugins/resources/hashtags.raw | 10 ++++++++++ tests/plugins/resources/markdown.html | 8 ++++---- tests/plugins/resources/markdown.md | 2 +- 5 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 tests/plugins/resources/hashtags.md create mode 100644 tests/plugins/resources/hashtags.raw (limited to 'tests') diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php index b31e817f..319a94ba 100644 --- a/tests/plugins/PluginMarkdownTest.php +++ b/tests/plugins/PluginMarkdownTest.php @@ -106,6 +106,18 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $this->assertEquals($text, $reversedText); } + /** + * Test reverse_text2clickable(). + */ + public function testReverseText2clickableHashtags() + { + $text = file_get_contents('tests/plugins/resources/hashtags.raw'); + $md = file_get_contents('tests/plugins/resources/hashtags.md'); + $clickableText = hashtag_autolink($text); + $reversedText = reverse_text2clickable($clickableText); + $this->assertEquals($md, $reversedText); + } + /** * Test reverse_nl2br(). */ @@ -246,7 +258,7 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase $this->conf->get('security.markdown_escape', true), $this->conf->get('security.allowed_protocols') ); - $this->assertEquals($html, $data); + $this->assertEquals($html, $data . PHP_EOL); } /** 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 @@ +[#lol](?addtag=lol) + + #test + +`#test2` + +``` +bla #bli blo +#bla +``` 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 @@ +#lol + + #test + +`#test2` + +``` +bla #bli blo +#bla +``` diff --git a/tests/plugins/resources/markdown.html b/tests/plugins/resources/markdown.html index f1df4e7e..c3460bf7 100644 --- a/tests/plugins/resources/markdown.html +++ b/tests/plugins/resources/markdown.html @@ -12,11 +12,11 @@

      5. two
      6. three
      7. four
      8. -
      9. foo <a href="?addtag=foobar" title="Hashtag foobar">#foobar</a>
      10. +
      11. foo #foobar
    -

    <a href="?addtag=foobar" title="Hashtag foobar">#foobar</a> foo lol #foo <a href="?addtag=bar" title="Hashtag bar">#bar</a>

    -

    fsdfs http://link.tld <a href="?addtag=foobar" title="Hashtag foobar">#foobar</a> http://link.tld

    +

    #foobar foo lol #foo #bar

    +

    fsdfs http://link.tld #foobar http://link.tld

    http://link.tld #foobar
     next #foo

    Block:

    @@ -30,4 +30,4 @@ next #foo link
    link
    link
    -link

    \ No newline at end of file +link

    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 [link](ftp://test.tld/path/?query=value#hash) [link](magnet:test.tld/path/?query=value#hash) [link](javascript:alert('xss')) -[link](other://test.tld/path/?query=value#hash) \ No newline at end of file +[link](other://test.tld/path/?query=value#hash) -- cgit v1.2.3 From 0e54e1059f3c3aa353a448567a9314ad694abbe1 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Tue, 14 Aug 2018 13:39:31 +0200 Subject: Isso plugin: add an icon in linklist if enabled Fixes #1075 --- tests/plugins/PluginIssoTest.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'tests') 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 /** * Test Isso init without errors. */ - public function testWallabagInitNoError() + public function testIssoInitNoError() { $conf = new ConfigManager(''); $conf->set('plugins.ISSO_SERVER', 'value'); @@ -32,7 +32,7 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase /** * Test Isso init with errors. */ - public function testWallabagInitError() + public function testIssoInitError() { $conf = new ConfigManager(''); $errors = isso_init($conf); @@ -96,19 +96,22 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase array( 'id' => 12, 'url' => $str, + 'shorturl' => $short1 = 'abcd', 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date1), ), array( 'id' => 13, 'url' => $str . '2', + 'shorturl' => $short2 = 'efgh', 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date2), ), ) ); $processed = hook_isso_render_linklist($data, $conf); - // data shouldn't be altered - $this->assertEquals($data, $processed); + // link_plugin should be added for the icon + $this->assertContains('', $processed['links'][0]['link_plugin'][0]); + $this->assertContains('', $processed['links'][1]['link_plugin'][0]); } /** @@ -127,6 +130,7 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase array( 'id' => 12, 'url' => $str, + 'shorturl' => $short1 = 'abcd', 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date), ) ), @@ -135,8 +139,8 @@ class PluginIssoTest extends PHPUnit_Framework_TestCase $processed = hook_isso_render_linklist($data, $conf); - // data shouldn't be altered - $this->assertEquals($data, $processed); + // link_plugin should be added for the icon + $this->assertContains('', $processed['links'][0]['link_plugin'][0]); } /** -- cgit v1.2.3 From 4154c25b5f2f8044a37d7f84e04173bb54f2375b Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Tue, 22 May 2018 22:44:38 +0200 Subject: Add a button to set links as sticky Meaning that they always appear on top of all links Fixes #186 --- tests/FeedBuilderTest.php | 18 +++---- tests/LinkDBTest.php | 10 ++-- tests/NetscapeBookmarkUtils/BookmarkExportTest.php | 4 +- tests/Updater/UpdaterTest.php | 61 ++++++++++++++++++++++ tests/api/controllers/links/GetLinksTest.php | 21 ++++---- tests/utils/ReferenceLinkDB.php | 45 +++++++++++++++- 6 files changed, 133 insertions(+), 26 deletions(-) (limited to 'tests') 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 $this->assertFalse($data['usepermalinks']); $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); - // Test first link (note link) - $link = reset($data['links']); + // Test first not pinned link (note link) + $link = $data['links'][array_keys($data['links'])[2]]; $this->assertEquals(41, $link['id']); $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); @@ -119,7 +119,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase $data = $feedBuilder->buildData(); $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']); - $link = reset($data['links']); + $link = $data['links'][array_keys($data['links'])[2]]; $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']); $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']); } @@ -148,13 +148,13 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase public function testBuildDataCount() { $criteria = array( - 'nb' => '1', + 'nb' => '3', ); $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false); $feedBuilder->setLocale(self::$LOCALE); $data = $feedBuilder->buildData(); - $this->assertEquals(1, count($data['links'])); - $link = array_shift($data['links']); + $this->assertEquals(3, count($data['links'])); + $link = $data['links'][array_keys($data['links'])[2]]; $this->assertEquals(41, $link['id']); $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); } @@ -171,7 +171,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); $this->assertTrue($data['usepermalinks']); // First link is a permalink - $link = array_shift($data['links']); + $link = $data['links'][array_keys($data['links'])[2]]; $this->assertEquals(41, $link['id']); $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); @@ -179,7 +179,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase $this->assertContains('Direct link', $link['description']); $this->assertContains('http://host.tld/?WDWyig', $link['description']); // Second link is a direct link - $link = array_shift($data['links']); + $link = $data['links'][array_keys($data['links'])[3]]; $this->assertEquals(8, $link['id']); $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']); $this->assertEquals('http://host.tld/?RttfEw', $link['guid']); @@ -237,7 +237,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase ); // Test first link (note link) - $link = array_shift($data['links']); + $link = $data['links'][array_keys($data['links'])[2]]; $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']); $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']); $this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']); diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index 3b980878..fcab76f6 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php @@ -239,12 +239,12 @@ class LinkDBTest extends PHPUnit_Framework_TestCase public function testDays() { $this->assertEquals( - array('20100310', '20121206', '20130614', '20150310'), + array('20100309', '20100310', '20121206', '20121207', '20130614', '20150310'), self::$publicLinkDB->days() ); $this->assertEquals( - array('20100310', '20121206', '20130614', '20141125', '20150310'), + array('20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'), self::$privateLinkDB->days() ); } @@ -475,13 +475,15 @@ class LinkDBTest extends PHPUnit_Framework_TestCase public function testReorderLinksDesc() { self::$privateLinkDB->reorder('ASC'); - $linkIds = array(42, 4, 9, 1, 0, 7, 6, 8, 41); + $stickyIds = [11, 10]; + $standardIds = [42, 4, 9, 1, 0, 7, 6, 8, 41]; + $linkIds = array_merge($stickyIds, $standardIds); $cpt = 0; foreach (self::$privateLinkDB as $key => $value) { $this->assertEquals($linkIds[$cpt++], $key); } self::$privateLinkDB->reorder('DESC'); - $linkIds = array_reverse($linkIds); + $linkIds = array_merge(array_reverse($stickyIds), array_reverse($standardIds)); $cpt = 0; foreach (self::$privateLinkDB as $key => $value) { $this->assertEquals($linkIds[$cpt++], $key); 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 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, ''); $this->assertEquals( '?WDWyig', - $links[0]['url'] + $links[2]['url'] ); } @@ -128,7 +128,7 @@ class BookmarkExportTest extends PHPUnit_Framework_TestCase ); $this->assertEquals( $indexUrl . '?WDWyig', - $links[0]['url'] + $links[2]['url'] ); } } diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index cacee2d2..870f169a 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -688,6 +688,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; } /** +<<<<<<< HEAD * Test updateMethodWebThumbnailer with thumbnails enabled. */ public function testUpdateMethodWebThumbnailerEnabled() @@ -732,4 +733,64 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $this->assertEquals(53, $this->conf->get('thumbnails.height')); $this->assertTrue(empty($_SESSION['warnings'])); } + + /** + * Test updateMethodSetSticky(). + */ + public function testUpdateStickyValid() + { + $blank = [ + 'id' => 1, + 'url' => 'z', + 'title' => '', + 'description' => '', + 'tags' => '', + 'created' => new DateTime(), + ]; + $links = [ + 1 => ['id' => 1] + $blank, + 2 => ['id' => 2] + $blank, + ]; + $refDB = new ReferenceLinkDB(); + $refDB->setLinks($links); + $refDB->write(self::$testDatastore); + $linkDB = new LinkDB(self::$testDatastore, true, false); + + $updater = new Updater(array(), $linkDB, $this->conf, true); + $this->assertTrue($updater->updateMethodSetSticky()); + + $linkDB = new LinkDB(self::$testDatastore, true, false); + foreach ($linkDB as $link) { + $this->assertFalse($link['sticky']); + } + } + + /** + * Test updateMethodSetSticky(). + */ + public function testUpdateStickyNothingToDo() + { + $blank = [ + 'id' => 1, + 'url' => 'z', + 'title' => '', + 'description' => '', + 'tags' => '', + 'created' => new DateTime(), + ]; + $links = [ + 1 => ['id' => 1, 'sticky' => true] + $blank, + 2 => ['id' => 2] + $blank, + ]; + $refDB = new ReferenceLinkDB(); + $refDB->setLinks($links); + $refDB->write(self::$testDatastore); + $linkDB = new LinkDB(self::$testDatastore, true, false); + + $updater = new Updater(array(), $linkDB, $this->conf, true); + $this->assertTrue($updater->updateMethodSetSticky()); + + $linkDB = new LinkDB(self::$testDatastore, true, false); + $this->assertTrue($linkDB[1]['sticky']); + } } diff --git a/tests/api/controllers/links/GetLinksTest.php b/tests/api/controllers/links/GetLinksTest.php index d22ed3bf..64f02774 100644 --- a/tests/api/controllers/links/GetLinksTest.php +++ b/tests/api/controllers/links/GetLinksTest.php @@ -95,7 +95,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->refDB->countLinks(), count($data)); // Check order - $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; + $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42]; $cpt = 0; foreach ($data as $link) { $this->assertEquals(self::NB_FIELDS_LINK, count($link)); @@ -103,7 +103,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase } // Check first element fields - $first = $data[0]; + $first = $data[2]; $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); $this->assertEquals('WDWyig', $first['shorturl']); $this->assertEquals('Link title: @website', $first['title']); @@ -120,7 +120,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase $this->assertEmpty($first['updated']); // Multi tags - $link = $data[1]; + $link = $data[3]; $this->assertEquals(7, count($link['tags'])); // Update date @@ -138,7 +138,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase { $env = Environment::mock([ 'REQUEST_METHOD' => 'GET', - 'QUERY_STRING' => 'offset=1&limit=1' + 'QUERY_STRING' => 'offset=3&limit=1' ]); $request = Request::createFromEnvironment($env); $response = $this->controller->getLinks($request, new Response()); @@ -164,7 +164,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase $data = json_decode((string) $response->getBody(), true); $this->assertEquals($this->refDB->countLinks(), count($data)); // Check order - $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; + $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42]; $cpt = 0; foreach ($data as $link) { $this->assertEquals(self::NB_FIELDS_LINK, count($link)); @@ -205,7 +205,8 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase $this->assertEquals(200, $response->getStatusCode()); $data = json_decode((string)$response->getBody(), true); $this->assertEquals($this->refDB->countLinks(), count($data)); - $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(10, $data[0]['id']); + $this->assertEquals(41, $data[2]['id']); $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); } @@ -243,7 +244,8 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase $this->assertEquals(200, $response->getStatusCode()); $data = json_decode((string)$response->getBody(), true); $this->assertEquals($this->refDB->countPublicLinks(), count($data)); - $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(10, $data[0]['id']); + $this->assertEquals(41, $data[2]['id']); $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); } @@ -413,8 +415,9 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase $response = $this->controller->getLinks($request, new Response()); $this->assertEquals(200, $response->getStatusCode()); $data = json_decode((string) $response->getBody(), true); - $this->assertEquals(9, count($data)); - $this->assertEquals(41, $data[0]['id']); + $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, count($data)); + $this->assertEquals(10, $data[0]['id']); + $this->assertEquals(41, $data[2]['id']); // wildcard: optional ('*' does not need to expand) $env = Environment::mock([ diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php index e887aa78..7426ad07 100644 --- a/tests/utils/ReferenceLinkDB.php +++ b/tests/utils/ReferenceLinkDB.php @@ -4,7 +4,7 @@ */ class ReferenceLinkDB { - public static $NB_LINKS_TOTAL = 9; + public static $NB_LINKS_TOTAL = 11; private $_links = array(); private $_publicCount = 0; @@ -15,6 +15,32 @@ class ReferenceLinkDB */ public function __construct() { + $this->addLink( + 11, + 'Pined older', + '?PCRizQ', + 'This is an older pinned link', + 0, + DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20100309_101010'), + '', + null, + 'PCRizQ', + true + ); + + $this->addLink( + 10, + 'Pined', + '?0gCTjQ', + 'This is a pinned link', + 0, + DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121207_152312'), + '', + null, + '0gCTjQ', + true + ); + $this->addLink( 41, 'Link title: @website', @@ -114,7 +140,17 @@ class ReferenceLinkDB /** * Adds a new link */ - protected function addLink($id, $title, $url, $description, $private, $date, $tags, $updated = '', $shorturl = '') + protected function addLink( + $id, + $title, + $url, + $description, + $private, + $date, + $tags, + $updated = '', + $shorturl = '', + $pinned = false) { $link = array( 'id' => $id, @@ -126,6 +162,7 @@ class ReferenceLinkDB 'created' => $date, 'updated' => $updated, 'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id), + 'sticky' => $pinned ); $this->_links[$id] = $link; @@ -165,6 +202,10 @@ class ReferenceLinkDB $order = $order === 'ASC' ? -1 : 1; // Reorder array by dates. usort($this->_links, function($a, $b) use ($order) { + if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) { + return $a['sticky'] ? -1 : 1; + } + return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; }); } -- cgit v1.2.3 From 067c2dd8f5f6eb6cc808ddc4bd30aec104caf73d Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sat, 13 Oct 2018 00:35:47 +0200 Subject: lint: apply phpcbf to tests/ Signed-off-by: VirtualTam --- tests/ApplicationUtilsTest.php | 6 +++--- tests/CacheTest.php | 2 +- tests/HttpUtils/GetIpAdressFromProxyTest.php | 3 ++- tests/LinkDBTest.php | 6 +++--- tests/LinkFilterTest.php | 2 +- tests/LinkUtilsTest.php | 1 - tests/RouterTest.php | 1 - tests/ThumbnailerTest.php | 8 +++++--- tests/Updater/DummyUpdater.php | 8 ++++---- tests/Url/CleanupUrlTest.php | 1 - tests/Url/GetUrlSchemeTest.php | 1 - tests/Url/UnparseUrlTest.php | 1 - tests/Url/UrlTest.php | 6 +++--- tests/UtilsTest.php | 9 ++++++--- tests/api/ApiUtilsTest.php | 3 +-- tests/api/controllers/history/HistoryTest.php | 1 - tests/api/controllers/info/InfoTest.php | 4 ++-- tests/api/controllers/links/PostLinkTest.php | 1 - tests/api/controllers/links/PutLinkTest.php | 1 - tests/api/controllers/tags/PutTagTest.php | 1 - tests/languages/de/UtilsDeTest.php | 2 +- tests/languages/fr/LanguagesFrTest.php | 1 - tests/plugins/PluginQrcodeTest.php | 3 ++- tests/security/SessionManagerTest.php | 1 - tests/utils/ReferenceLinkDB.php | 6 +++--- tests/utils/config/configPhp.php | 2 +- 26 files changed, 38 insertions(+), 43 deletions(-) (limited to 'tests') 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 /** * Toggle HTTP requests, allow overriding the version code */ - public static function getVersion($url, $timeout=0) + public static function getVersion($url, $timeout = 0) { return self::$VERSION_CODE; } @@ -67,7 +67,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase '0.5.4', ApplicationUtils::getVersion( 'https://raw.githubusercontent.com/shaarli/Shaarli/' - .'v0.5.4/shaarli_version.php', + .'v0.5.4/shaarli_version.php', $testTimeout ) ); @@ -75,7 +75,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase self::$versionPattern, ApplicationUtils::getVersion( 'https://raw.githubusercontent.com/shaarli/Shaarli/' - .'latest/shaarli_version.php', + .'latest/shaarli_version.php', $testTimeout ) ); 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 invalidateCaches(self::$testCacheDir); foreach (self::$pages as $page) { $this->assertFileNotExists(self::$testCacheDir.'/'.$page.'.cache'); - } + } $this->assertArrayNotHasKey('tags', $_SESSION); } 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'; /** * Unitary tests for getIpAddressFromProxy() */ -class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase { +class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase +{ /** * Test without proxy diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index fcab76f6..c763c0cb 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php @@ -362,7 +362,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase public function testLinkRealUrlWithoutRedirector() { $db = new LinkDB(self::$testDatastore, false, false); - foreach($db as $link) { + foreach ($db as $link) { $this->assertEquals($link['url'], $link['real_url']); } } @@ -374,13 +374,13 @@ class LinkDBTest extends PHPUnit_Framework_TestCase { $redirector = 'http://redirector.to?'; $db = new LinkDB(self::$testDatastore, false, false, $redirector); - foreach($db as $link) { + foreach ($db as $link) { $this->assertStringStartsWith($redirector, $link['real_url']); $this->assertNotFalse(strpos($link['real_url'], urlencode('://'))); } $db = new LinkDB(self::$testDatastore, false, false, $redirector, false); - foreach($db as $link) { + foreach ($db as $link) { $this->assertStringStartsWith($redirector, $link['real_url']); $this->assertFalse(strpos($link['real_url'], urlencode('://'))); } diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php index 9cd6dbd4..250046f8 100644 --- a/tests/LinkFilterTest.php +++ b/tests/LinkFilterTest.php @@ -297,7 +297,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase $this->assertEquals( 3, count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"')) - ); + ); } /** diff --git a/tests/LinkUtilsTest.php b/tests/LinkUtilsTest.php index 7fbd59b0..ca062f05 100644 --- a/tests/LinkUtilsTest.php +++ b/tests/LinkUtilsTest.php @@ -410,4 +410,3 @@ function ut_curl_getinfo_rs_ct_ko($ch, $type) return 'text/plain'; } } - 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 Router::$PAGE_CHANGEPASSWORD, Router::findPage('do=changepasswd&stuff', array(), true) ); - } /** diff --git a/tests/ThumbnailerTest.php b/tests/ThumbnailerTest.php index 08311545..c01849f7 100644 --- a/tests/ThumbnailerTest.php +++ b/tests/ThumbnailerTest.php @@ -98,15 +98,17 @@ class ThumbnailerTest extends TestCase ini_set('error_log', $oldlog); } - protected function rrmdirContent($dir) { + protected function rrmdirContent($dir) + { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { - if (is_dir($dir."/".$object)) + if (is_dir($dir."/".$object)) { $this->rrmdirContent($dir."/".$object); - else + } else { unlink($dir."/".$object); + } } } } 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 * * @return bool true. */ - private final function updateMethodDummy1() + final private function updateMethodDummy1() { return true; } @@ -41,7 +41,7 @@ class DummyUpdater extends Updater * * @return bool true. */ - private final function updateMethodDummy2() + final private function updateMethodDummy2() { return true; } @@ -51,7 +51,7 @@ class DummyUpdater extends Updater * * @return bool true. */ - private final function updateMethodDummy3() + final private function updateMethodDummy3() { return true; } @@ -61,7 +61,7 @@ class DummyUpdater extends Updater * * @throws Exception error. */ - private final function updateMethodException() + final private function updateMethodException() { throw new Exception('whatever'); } 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 ); } } - 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 $this->assertEquals('git', get_url_scheme('git://domain.tld/push?pull=clone#checkout')); } } - 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 $this->assertEquals($ref, unparse_url(parse_url($ref))); } } - 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 /** * Helper method */ - private function assertUrlIsCleaned($query='', $fragment='') + private function assertUrlIsCleaned($query = '', $fragment = '') { $url = new Url(self::$baseUrl.$query.$fragment); $url->cleanup(); @@ -135,13 +135,13 @@ class UrlTest extends PHPUnit_Framework_TestCase 'about://reader?url=' . urlencode(self::$baseUrl .'?my=stuff&is=kept') ); $this->assertEquals(self::$baseUrl.'?my=stuff&is=kept', $url->cleanup()); - } /** * Test default http scheme. */ - public function testDefaultScheme() { + public function testDefaultScheme() + { $url = new Url(self::$baseUrl); $this->assertEquals('http', $url->getScheme()); $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 /** * Test generate location with valid data. */ - public function testGenerateLocation() { + public function testGenerateLocation() + { $ref = 'http://localhost/?test'; $this->assertEquals($ref, generateLocation($ref, 'localhost')); $ref = 'http://localhost:8080/?test'; @@ -199,7 +200,8 @@ class UtilsTest extends PHPUnit_Framework_TestCase /** * Test generate location - anti loop. */ - public function testGenerateLocationLoop() { + public function testGenerateLocationLoop() + { $ref = 'http://localhost/?test'; $this->assertEquals('?', generateLocation($ref, 'localhost', array('test'))); } @@ -207,7 +209,8 @@ class UtilsTest extends PHPUnit_Framework_TestCase /** * Test generate location - from other domain. */ - public function testGenerateLocationOut() { + public function testGenerateLocationOut() + { $ref = 'http://somewebsite.com/?test'; $this->assertEquals('?', generateLocation($ref, 'localhost')); } 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; use Shaarli\Base64Url; - /** * Class ApiUtilsTest */ @@ -34,7 +33,7 @@ class ApiUtilsTest extends \PHPUnit_Framework_TestCase $payload = Base64Url::encode('{ "iat": '. time() .' }'); - $signature = Base64Url::encode(hash_hmac('sha512', $header .'.'. $payload , $secret, true)); + $signature = Base64Url::encode(hash_hmac('sha512', $header .'.'. $payload, $secret, true)); return $header .'.'. $payload .'.'. $signature; } diff --git a/tests/api/controllers/history/HistoryTest.php b/tests/api/controllers/history/HistoryTest.php index 61046d97..ff34e16d 100644 --- a/tests/api/controllers/history/HistoryTest.php +++ b/tests/api/controllers/history/HistoryTest.php @@ -3,7 +3,6 @@ namespace Shaarli\Api\Controllers; - use Shaarli\Config\ConfigManager; use Slim\Container; use Slim\Http\Environment; diff --git a/tests/api/controllers/info/InfoTest.php b/tests/api/controllers/info/InfoTest.php index f7e63bfa..e437082a 100644 --- a/tests/api/controllers/info/InfoTest.php +++ b/tests/api/controllers/info/InfoTest.php @@ -10,9 +10,9 @@ use Slim\Http\Response; /** * Class InfoTest - * + * * Test REST API controller Info. - * + * * @package Api\Controllers */ class InfoTest extends \PHPUnit_Framework_TestCase diff --git a/tests/api/controllers/links/PostLinkTest.php b/tests/api/controllers/links/PostLinkTest.php index 100a9170..37617611 100644 --- a/tests/api/controllers/links/PostLinkTest.php +++ b/tests/api/controllers/links/PostLinkTest.php @@ -2,7 +2,6 @@ namespace Shaarli\Api\Controllers; - use PHPUnit\Framework\TestCase; use Shaarli\Config\ConfigManager; use Slim\Container; diff --git a/tests/api/controllers/links/PutLinkTest.php b/tests/api/controllers/links/PutLinkTest.php index 8a562571..72b895f2 100644 --- a/tests/api/controllers/links/PutLinkTest.php +++ b/tests/api/controllers/links/PutLinkTest.php @@ -3,7 +3,6 @@ namespace Shaarli\Api\Controllers; - use Shaarli\Config\ConfigManager; use Slim\Container; use Slim\Http\Environment; diff --git a/tests/api/controllers/tags/PutTagTest.php b/tests/api/controllers/tags/PutTagTest.php index 6f7dec22..38017243 100644 --- a/tests/api/controllers/tags/PutTagTest.php +++ b/tests/api/controllers/tags/PutTagTest.php @@ -3,7 +3,6 @@ namespace Shaarli\Api\Controllers; - use Shaarli\Api\Exceptions\ApiBadParametersException; use Shaarli\Config\ConfigManager; use Slim\Container; 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 public function testDateFormatNoTime() { $date = DateTime::createFromFormat('Ymd_His', '20170101_101112'); - $this->assertRegExp('/1\. Januar 2017/', format_date($date, false,true)); + $this->assertRegExp('/1\. Januar 2017/', format_date($date, false, true)); } /** diff --git a/tests/languages/fr/LanguagesFrTest.php b/tests/languages/fr/LanguagesFrTest.php index 0cf74891..38347de1 100644 --- a/tests/languages/fr/LanguagesFrTest.php +++ b/tests/languages/fr/LanguagesFrTest.php @@ -3,7 +3,6 @@ namespace Shaarli; - use Shaarli\Config\ConfigManager; /** 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 /** * Reset plugin path */ - public function setUp() { + public function setUp() + { PluginManager::$PLUGINS_PATH = 'plugins'; } diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php index 9bd868f8..7961e771 100644 --- a/tests/security/SessionManagerTest.php +++ b/tests/security/SessionManagerTest.php @@ -8,7 +8,6 @@ ReferenceSessionIdHashes::genAllHashes(); use \Shaarli\Security\SessionManager; use \PHPUnit\Framework\TestCase; - /** * Test coverage for SessionManager */ diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php index 7426ad07..59679e38 100644 --- a/tests/utils/ReferenceLinkDB.php +++ b/tests/utils/ReferenceLinkDB.php @@ -150,8 +150,8 @@ class ReferenceLinkDB $tags, $updated = '', $shorturl = '', - $pinned = false) - { + $pinned = false + ) { $link = array( 'id' => $id, 'title' => $title, @@ -201,7 +201,7 @@ class ReferenceLinkDB $order = $order === 'ASC' ? -1 : 1; // Reorder array by dates. - usort($this->_links, function($a, $b) use ($order) { + usort($this->_links, function ($a, $b) use ($order) { if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) { return $a['sticky'] ? -1 : 1; } 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 @@ - Date: Sat, 13 Oct 2018 01:40:04 +0200 Subject: lint: fix line-length warnings Signed-off-by: VirtualTam --- tests/LinkFilterTest.php | 16 ++++++++++++---- tests/LinkUtilsTest.php | 23 ++++++++++++++++------- tests/Updater/UpdaterTest.php | 20 ++++++++++++++++---- tests/api/controllers/links/PostLinkTest.php | 8 ++++++-- tests/api/controllers/links/PutLinkTest.php | 8 ++++++-- 5 files changed, 56 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php index 250046f8..eb54c359 100644 --- a/tests/LinkFilterTest.php +++ b/tests/LinkFilterTest.php @@ -76,7 +76,15 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase $this->assertEquals( self::$refDB->countUntaggedLinks(), - count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, /*$request=*/'', /*$casesensitive=*/false, /*$visibility=*/'all', /*$untaggedonly=*/true)) + count( + self::$linkFilter->filter( + LinkFilter::$FILTER_TAG, + /*$request=*/'', + /*$casesensitive=*/false, + /*$visibility=*/'all', + /*$untaggedonly=*/true + ) + ) ); $this->assertEquals( @@ -246,7 +254,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase 2, count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org')) ); - + $this->assertEquals( 2, count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org')) @@ -288,12 +296,12 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase 1, count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media')) ); - + $this->assertEquals( 1, count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c')) ); - + $this->assertEquals( 3, count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"')) diff --git a/tests/LinkUtilsTest.php b/tests/LinkUtilsTest.php index ca062f05..5407159a 100644 --- a/tests/LinkUtilsTest.php +++ b/tests/LinkUtilsTest.php @@ -83,7 +83,9 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase 'Date: Sat, 28 Oct 2017 12:01:33 GMT', 'Content-Type: text/html; charset=utf-8', 'Status: 200 OK', - 'end' => 'th=device-width">Refactoring · GitHub' + .'Refactoring · GitHub' + .'Refactoring · GitHub' + .'Refactoring · GitHub' + .'', - 'end' => 'th=device-width">Refactoring · GitHub' + .'Refactoring · GitHub' + .'http://hello.there/is=someone#here otherstuff'; + $expectedText = 'stuff ' + .'http://hello.there/is=someone#here otherstuff'; $processedText = text2clickable($text, ''); $this->assertEquals($expectedText, $processedText); $text = 'stuff http://hello.there/is=someone#here(please) otherstuff'; - $expectedText = 'stuff http://hello.there/is=someone#here(please) otherstuff'; + $expectedText = 'stuff ' + .'http://hello.there/is=someone#here(please) otherstuff'; $processedText = text2clickable($text, ''); $this->assertEquals($expectedText, $processedText); $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff'; - $expectedText = 'stuff http://hello.there/is=someone#here(please)&no otherstuff'; + $expectedText = 'stuff ' + .'http://hello.there/is=someone#here(please)&no otherstuff'; $processedText = text2clickable($text, ''); $this->assertEquals($expectedText, $processedText); } /** - * Test text2clickable a redirector set. + * Test text2clickable with a redirector set. */ public function testText2clickableWithRedirector() { diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index 870f169a..c4a6e7ef 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php @@ -393,20 +393,32 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; $this->assertEquals('Naming conventions... #private', $linkDB[0]['description']); $this->assertEquals('samba cartoon web', $linkDB[0]['tags']); $this->assertTrue($linkDB[0]['private']); - $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'), $linkDB[0]['created']); + $this->assertEquals( + DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'), + $linkDB[0]['created'] + ); $this->assertTrue(isset($linkDB[1])); $this->assertFalse(isset($linkDB[1]['linkdate'])); $this->assertEquals(1, $linkDB[1]['id']); $this->assertEquals('UserFriendly - Samba', $linkDB[1]['title']); - $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'), $linkDB[1]['created']); + $this->assertEquals( + DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'), + $linkDB[1]['created'] + ); $this->assertTrue(isset($linkDB[2])); $this->assertFalse(isset($linkDB[2]['linkdate'])); $this->assertEquals(2, $linkDB[2]['id']); $this->assertEquals('Geek and Poke', $linkDB[2]['title']); - $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'), $linkDB[2]['created']); - $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_190301'), $linkDB[2]['updated']); + $this->assertEquals( + DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'), + $linkDB[2]['created'] + ); + $this->assertEquals( + DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_190301'), + $linkDB[2]['updated'] + ); } /** diff --git a/tests/api/controllers/links/PostLinkTest.php b/tests/api/controllers/links/PostLinkTest.php index 37617611..5c2b5623 100644 --- a/tests/api/controllers/links/PostLinkTest.php +++ b/tests/api/controllers/links/PostLinkTest.php @@ -127,7 +127,9 @@ class PostLinkTest extends TestCase $this->assertEquals('', $data['description']); $this->assertEquals([], $data['tags']); $this->assertEquals(false, $data['private']); - $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); + $this->assertTrue( + new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) + ); $this->assertEquals('', $data['updated']); $historyEntry = $this->history->getHistory()[0]; @@ -170,7 +172,9 @@ class PostLinkTest extends TestCase $this->assertEquals($link['description'], $data['description']); $this->assertEquals($link['tags'], $data['tags']); $this->assertEquals(true, $data['private']); - $this->assertTrue(new \DateTime('2 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); + $this->assertTrue( + new \DateTime('2 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) + ); $this->assertEquals('', $data['updated']); } diff --git a/tests/api/controllers/links/PutLinkTest.php b/tests/api/controllers/links/PutLinkTest.php index 72b895f2..f276b4c1 100644 --- a/tests/api/controllers/links/PutLinkTest.php +++ b/tests/api/controllers/links/PutLinkTest.php @@ -114,7 +114,9 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase \DateTime::createFromFormat('Ymd_His', '20150310_114651'), \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) ); - $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); + $this->assertTrue( + new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) + ); $historyEntry = $this->history->getHistory()[0]; $this->assertEquals(\History::UPDATED, $historyEntry['event']); @@ -159,7 +161,9 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase \DateTime::createFromFormat('Ymd_His', '20150310_114651'), \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) ); - $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); + $this->assertTrue( + new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) + ); } /** -- cgit v1.2.3