From 8fabcd0224b1122a48b495326854bb3562cd2e9d Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 27 Aug 2020 15:25:18 +0200 Subject: Add Markdown Extra formatter Library: [Parsedown Extra](https://github.com/erusev/parsedown-extra) Also sort dependencies alphabetically. Fixes #1169 --- tests/front/controller/admin/ConfigureControllerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ConfigureControllerTest.php b/tests/front/controller/admin/ConfigureControllerTest.php index aca6cff3..d82db0a7 100644 --- a/tests/front/controller/admin/ConfigureControllerTest.php +++ b/tests/front/controller/admin/ConfigureControllerTest.php @@ -51,7 +51,7 @@ class ConfigureControllerTest extends TestCase static::assertSame('general.title', $assignedVariables['title']); static::assertSame('resource.theme', $assignedVariables['theme']); static::assertEmpty($assignedVariables['theme_available']); - static::assertSame(['default', 'markdown'], $assignedVariables['formatter_available']); + static::assertSame(['default', 'markdown', 'markdownExtra'], $assignedVariables['formatter_available']); static::assertNotEmpty($assignedVariables['continents']); static::assertNotEmpty($assignedVariables['cities']); static::assertSame('general.retrieve_description', $assignedVariables['retrieve_description']); -- cgit v1.2.3 From efb7d21b52eb033530e80e5e49d175e6e3b031f4 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 2 Oct 2020 17:50:59 +0200 Subject: Add strict types for bookmarks management Parameters typing and using strict types overall increase the codebase quality by enforcing the a given parameter will have the expected type. It also removes the need to unnecessary unit tests checking methods behavior with invalid input. --- .../DeleteBookmarkTest.php | 4 ++++ .../ManageShaareControllerTest/SaveBookmarkTest.php | 20 +++++++++++++++----- .../controller/admin/ThumbnailsControllerTest.php | 4 +++- 3 files changed, 22 insertions(+), 6 deletions(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php index ba774e21..83bbee7c 100644 --- a/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php +++ b/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php @@ -356,6 +356,10 @@ class DeleteBookmarkTest extends TestCase ; $response = new Response(); + $this->container->bookmarkService->method('get')->with('123')->willReturn( + (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123') + ); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); $this->container->formatterFactory ->expects(static::once()) diff --git a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php index f7a68226..37542c26 100644 --- a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php +++ b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php @@ -66,23 +66,27 @@ class SaveBookmarkTest extends TestCase $this->container->bookmarkService ->expects(static::once()) ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { static::assertFalse($save); $checkBookmark($bookmark); $bookmark->setId($id); + + return $bookmark; }) ; $this->container->bookmarkService ->expects(static::once()) ->method('set') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { static::assertTrue($save); $checkBookmark($bookmark); static::assertSame($id, $bookmark->getId()); + + return $bookmark; }) ; @@ -155,21 +159,25 @@ class SaveBookmarkTest extends TestCase $this->container->bookmarkService ->expects(static::once()) ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { static::assertFalse($save); $checkBookmark($bookmark); + + return $bookmark; }) ; $this->container->bookmarkService ->expects(static::once()) ->method('set') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): void { + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { static::assertTrue($save); $checkBookmark($bookmark); static::assertSame($id, $bookmark->getId()); + + return $bookmark; }) ; @@ -230,8 +238,10 @@ class SaveBookmarkTest extends TestCase $this->container->bookmarkService ->expects(static::once()) ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): void { + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): Bookmark { static::assertSame($thumb, $bookmark->getThumbnail()); + + return $bookmark; }) ; diff --git a/tests/front/controller/admin/ThumbnailsControllerTest.php b/tests/front/controller/admin/ThumbnailsControllerTest.php index f4a8acff..e5749654 100644 --- a/tests/front/controller/admin/ThumbnailsControllerTest.php +++ b/tests/front/controller/admin/ThumbnailsControllerTest.php @@ -89,8 +89,10 @@ class ThumbnailsControllerTest extends TestCase $this->container->bookmarkService ->expects(static::once()) ->method('set') - ->willReturnCallback(function (Bookmark $bookmark) use ($thumb) { + ->willReturnCallback(function (Bookmark $bookmark) use ($thumb): Bookmark { static::assertSame($thumb, $bookmark->getThumbnail()); + + return $bookmark; }) ; -- cgit v1.2.3 From 4cf3564d28dc8e4d08a3e64f09ad045ffbde97ae Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 25 Sep 2020 13:29:36 +0200 Subject: Add a setting to retrieve bookmark metadata asynchrounously - There is a new standalone script (metadata.js) which requests a new controller to get bookmark metadata and fill the form async - This feature is enabled with the new setting: general.enable_async_metadata (enabled by default) - general.retrieve_description is now enabled by default - A small rotating loader animation has a been added to bookmark inputs when metadata is being retrieved (default template) - Custom JS htmlentities has been removed and mathiasbynens/he library is used instead Fixes #1563 --- .../DisplayCreateFormTest.php | 118 +++++++++++++++------ 1 file changed, 83 insertions(+), 35 deletions(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php b/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php index 2eb95251..4fd88480 100644 --- a/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php +++ b/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php @@ -9,6 +9,7 @@ use Shaarli\Config\ConfigManager; use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper; use Shaarli\Front\Controller\Admin\ManageShaareController; use Shaarli\Http\HttpAccess; +use Shaarli\Http\MetadataRetriever; use Shaarli\TestCase; use Slim\Http\Request; use Slim\Http\Response; @@ -25,6 +26,7 @@ class DisplayCreateFormTest extends TestCase $this->createContainer(); $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->container->metadataRetriever = $this->createMock(MetadataRetriever::class); $this->controller = new ManageShaareController($this->container); } @@ -32,7 +34,7 @@ class DisplayCreateFormTest extends TestCase * Test displaying bookmark create form * Ensure that every step of the standard workflow works properly. */ - public function testDisplayCreateFormWithUrl(): void + public function testDisplayCreateFormWithUrlAndWithMetadataRetrieval(): void { $this->container->environment = [ 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' @@ -53,40 +55,20 @@ class DisplayCreateFormTest extends TestCase }); $response = new Response(); - $this->container->httpAccess - ->expects(static::once()) - ->method('getCurlDownloadCallback') - ->willReturnCallback( - function (&$charset, &$title, &$description, &$tags) use ( - $remoteTitle, - $remoteDesc, - $remoteTags - ): callable { - return function () use ( - &$charset, - &$title, - &$description, - &$tags, - $remoteTitle, - $remoteDesc, - $remoteTags - ): void { - $charset = 'ISO-8859-1'; - $title = $remoteTitle; - $description = $remoteDesc; - $tags = $remoteTags; - }; - } - ) - ; - $this->container->httpAccess - ->expects(static::once()) - ->method('getHttpResponse') - ->with($expectedUrl, 30, 4194304) - ->willReturnCallback(function($url, $timeout, $maxBytes, $callback): void { - $callback(); - }) - ; + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $param, $default) { + if ($param === 'general.enable_async_metadata') { + return false; + } + + return $default; + }); + + $this->container->metadataRetriever->expects(static::once())->method('retrieve')->willReturn([ + 'title' => $remoteTitle, + 'description' => $remoteDesc, + 'tags' => $remoteTags, + ]); $this->container->bookmarkService ->expects(static::once()) @@ -127,6 +109,72 @@ class DisplayCreateFormTest extends TestCase static::assertSame($tags, $assignedVariables['tags']); static::assertArrayHasKey('source', $assignedVariables); static::assertArrayHasKey('default_private_links', $assignedVariables); + static::assertArrayHasKey('async_metadata', $assignedVariables); + static::assertArrayHasKey('retrieve_description', $assignedVariables); + } + + /** + * Test displaying bookmark create form without any external metadata retrieval attempt + */ + public function testDisplayCreateFormWithUrlAndWithoutMetadata(): void + { + $this->container->environment = [ + 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' + ]; + + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; + $expectedUrl = str_replace('&utm_ad=pay', '', $url); + + $request = $this->createMock(Request::class); + $request->method('getParam')->willReturnCallback(function (string $key) use ($url): ?string { + return $key === 'post' ? $url : null; + }); + $response = new Response(); + + $this->container->metadataRetriever->expects(static::never())->method('retrieve'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('bookmarksCountPerTag') + ->willReturn($tags = ['tag1' => 2, 'tag2' => 1]) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::at(0)) + ->method('executeHooks') + ->willReturnCallback(function (string $hook, array $data): array { + static::assertSame('render_editlink', $hook); + static::assertSame('', $data['link']['title']); + static::assertSame('', $data['link']['description']); + + return $data; + }) + ; + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + + static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); + + static::assertSame($expectedUrl, $assignedVariables['link']['url']); + static::assertSame('', $assignedVariables['link']['title']); + static::assertSame('', $assignedVariables['link']['description']); + static::assertSame('', $assignedVariables['link']['tags']); + static::assertFalse($assignedVariables['link']['private']); + + static::assertTrue($assignedVariables['link_is_new']); + static::assertSame($referer, $assignedVariables['http_referer']); + static::assertSame($tags, $assignedVariables['tags']); + static::assertArrayHasKey('source', $assignedVariables); + static::assertArrayHasKey('default_private_links', $assignedVariables); + static::assertArrayHasKey('async_metadata', $assignedVariables); + static::assertArrayHasKey('retrieve_description', $assignedVariables); } /** -- cgit v1.2.3 From 21e72da9ee34cec56b10c83ae0c75b4bf320dfcb Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 15 Oct 2020 11:46:24 +0200 Subject: Asynchronous retrieval of bookmark's thumbnails This feature is based general.enable_async_metadata setting and works with existing metadata.js file. The script is compatible with any template: - the thumbnail div bloc must have attribute - the bookmark bloc must have attribute with the bookmark ID as value Fixes #1564 --- .../DisplayCreateFormTest.php | 10 ++-- .../SaveBookmarkTest.php | 55 ++++++++++++++++++++- .../visitor/BookmarkListControllerTest.php | 57 +++++++++++++++++++++- 3 files changed, 114 insertions(+), 8 deletions(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php b/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php index 4fd88480..eafa54eb 100644 --- a/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php +++ b/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php @@ -144,12 +144,14 @@ class DisplayCreateFormTest extends TestCase // Make sure that PluginManager hook is triggered $this->container->pluginManager - ->expects(static::at(0)) + ->expects(static::atLeastOnce()) ->method('executeHooks') + ->withConsecutive(['render_editlink'], ['render_includes']) ->willReturnCallback(function (string $hook, array $data): array { - static::assertSame('render_editlink', $hook); - static::assertSame('', $data['link']['title']); - static::assertSame('', $data['link']['description']); + if ('render_editlink' === $hook) { + static::assertSame('', $data['link']['title']); + static::assertSame('', $data['link']['description']); + } return $data; }) diff --git a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php index 37542c26..1adeef5a 100644 --- a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php +++ b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php @@ -209,7 +209,7 @@ class SaveBookmarkTest extends TestCase /** * Test save a bookmark - try to retrieve the thumbnail */ - public function testSaveBookmarkWithThumbnail(): void + public function testSaveBookmarkWithThumbnailSync(): void { $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; @@ -224,7 +224,13 @@ class SaveBookmarkTest extends TestCase $this->container->conf = $this->createMock(ConfigManager::class); $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { - return $key === 'thumbnails.mode' ? Thumbnailer::MODE_ALL : $default; + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return false; + } + + return $default; }); $this->container->thumbnailer = $this->createMock(Thumbnailer::class); @@ -274,6 +280,51 @@ class SaveBookmarkTest extends TestCase static::assertSame(302, $result->getStatusCode()); } + /** + * Test save a bookmark - do not attempt to retrieve thumbnails if async mode is enabled. + */ + public function testSaveBookmarkWithThumbnailAsync(): void + { + $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return true; + } + + return $default; + }); + + $this->container->thumbnailer = $this->createMock(Thumbnailer::class); + $this->container->thumbnailer->expects(static::never())->method('get'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('addOrSet') + ->willReturnCallback(function (Bookmark $bookmark): Bookmark { + static::assertNull($bookmark->getThumbnail()); + + return $bookmark; + }) + ; + + $result = $this->controller->save($request, $response); + + static::assertSame(302, $result->getStatusCode()); + } + /** * Change the password with a wrong existing password */ diff --git a/tests/front/controller/visitor/BookmarkListControllerTest.php b/tests/front/controller/visitor/BookmarkListControllerTest.php index 0c95df97..5ca92507 100644 --- a/tests/front/controller/visitor/BookmarkListControllerTest.php +++ b/tests/front/controller/visitor/BookmarkListControllerTest.php @@ -307,7 +307,13 @@ class BookmarkListControllerTest extends TestCase $this->container->conf ->method('get') ->willReturnCallback(function (string $key, $default) { - return $key === 'thumbnails.mode' ? Thumbnailer::MODE_ALL : $default; + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return false; + } + + return $default; }) ; @@ -357,7 +363,13 @@ class BookmarkListControllerTest extends TestCase $this->container->conf ->method('get') ->willReturnCallback(function (string $key, $default) { - return $key === 'thumbnails.mode' ? Thumbnailer::MODE_ALL : $default; + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return false; + } + + return $default; }) ; @@ -378,6 +390,47 @@ class BookmarkListControllerTest extends TestCase static::assertSame('linklist', (string) $result->getBody()); } + /** + * Test getting a permalink with thumbnail update with async setting: no update should run. + */ + public function testThumbnailUpdateFromPermalinkAsync(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->loginManager = $this->createMock(LoginManager::class); + $this->container->loginManager->method('isLoggedIn')->willReturn(true); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf + ->method('get') + ->willReturnCallback(function (string $key, $default) { + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return true; + } + + return $default; + }) + ; + + $this->container->thumbnailer = $this->createMock(Thumbnailer::class); + $this->container->thumbnailer->expects(static::never())->method('get'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->willReturn((new Bookmark())->setId(2)->setUrl('https://url.tld')->setTitle('Title 1')) + ; + $this->container->bookmarkService->expects(static::never())->method('set'); + $this->container->bookmarkService->expects(static::never())->method('save'); + + $result = $this->controller->permalink($request, $response, ['hash' => 'abc']); + + static::assertSame(200, $result->getStatusCode()); + } + /** * Trigger legacy controller in link list controller: permalink */ -- cgit v1.2.3 From b38a1b0209f546d4824a0db81a34c4e30fcdebaf Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Tue, 20 Oct 2020 11:47:07 +0200 Subject: Use PSR-3 logger for login attempts Fixes #1122 --- tests/front/controller/visitor/LoginControllerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/front') diff --git a/tests/front/controller/visitor/LoginControllerTest.php b/tests/front/controller/visitor/LoginControllerTest.php index 1312ccb7..00d9eab3 100644 --- a/tests/front/controller/visitor/LoginControllerTest.php +++ b/tests/front/controller/visitor/LoginControllerTest.php @@ -195,7 +195,7 @@ class LoginControllerTest extends TestCase $this->container->loginManager ->expects(static::once()) ->method('checkCredentials') - ->with('1.2.3.4', '1.2.3.4', 'bob', 'pass') + ->with('1.2.3.4', 'bob', 'pass') ->willReturn(true) ; $this->container->loginManager->method('getStaySignedInToken')->willReturn(bin2hex(random_bytes(8))); -- cgit v1.2.3 From 0cf76ccb4736473a958d9fd36ed914e2d25d594a Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 21 Oct 2020 13:12:15 +0200 Subject: Feature: add a Server administration page It contains mostly read only information about the current Shaarli instance, PHP version, extensions, file and folder permissions, etc. Also action buttons to clear the cache or sync thumbnails. Part of the content of this page is also displayed on the install page, to check server requirement before installing Shaarli config file. Fixes #40 Fixes #185 --- .../controller/admin/ServerControllerTest.php | 184 +++++++++++++++++++++ .../controller/visitor/InstallControllerTest.php | 9 + 2 files changed, 193 insertions(+) create mode 100644 tests/front/controller/admin/ServerControllerTest.php (limited to 'tests/front') diff --git a/tests/front/controller/admin/ServerControllerTest.php b/tests/front/controller/admin/ServerControllerTest.php new file mode 100644 index 00000000..355cce7d --- /dev/null +++ b/tests/front/controller/admin/ServerControllerTest.php @@ -0,0 +1,184 @@ +createContainer(); + + $this->controller = new ServerController($this->container); + + // initialize dummy cache + @mkdir('sandbox/'); + foreach (['pagecache', 'tmp', 'cache'] as $folder) { + @mkdir('sandbox/' . $folder); + @touch('sandbox/' . $folder . '/.htaccess'); + @touch('sandbox/' . $folder . '/1'); + @touch('sandbox/' . $folder . '/2'); + } + } + + public function tearDown(): void + { + foreach (['pagecache', 'tmp', 'cache'] as $folder) { + @unlink('sandbox/' . $folder . '/.htaccess'); + @unlink('sandbox/' . $folder . '/1'); + @unlink('sandbox/' . $folder . '/2'); + @rmdir('sandbox/' . $folder); + } + } + + /** + * Test default display of server administration page. + */ + public function testIndex(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + // Save RainTPL assigned variables + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $result = $this->controller->index($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('server', (string) $result->getBody()); + + static::assertSame(PHP_VERSION, $assignedVariables['php_version']); + static::assertArrayHasKey('php_has_reached_eol', $assignedVariables); + static::assertArrayHasKey('php_eol', $assignedVariables); + static::assertArrayHasKey('php_extensions', $assignedVariables); + static::assertArrayHasKey('permissions', $assignedVariables); + static::assertEmpty($assignedVariables['permissions']); + + static::assertRegExp( + '#https://github\.com/shaarli/Shaarli/releases/tag/v\d+\.\d+\.\d+#', + $assignedVariables['release_url'] + ); + static::assertRegExp('#v\d+\.\d+\.\d+#', $assignedVariables['latest_version']); + static::assertRegExp('#(v\d+\.\d+\.\d+|dev)#', $assignedVariables['current_version']); + static::assertArrayHasKey('index_url', $assignedVariables); + static::assertArrayHasKey('client_ip', $assignedVariables); + static::assertArrayHasKey('trusted_proxies', $assignedVariables); + + static::assertSame('Server administration - Shaarli', $assignedVariables['pagetitle']); + } + + /** + * Test clearing the main cache + */ + public function testClearMainCache(): void + { + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { + if ($key === 'resource.page_cache') { + return 'sandbox/pagecache'; + } elseif ($key === 'resource.raintpl_tmp') { + return 'sandbox/tmp'; + } elseif ($key === 'resource.thumbnails_cache') { + return 'sandbox/cache'; + } else { + return $default; + } + }); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_SUCCESS_MESSAGES, ['Shaarli\'s cache folder has been cleared!']) + ; + + $request = $this->createMock(Request::class); + $request->method('getQueryParam')->with('type')->willReturn('main'); + $response = new Response(); + + $result = $this->controller->clearCache($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame('/subfolder/admin/server', (string) $result->getHeaderLine('Location')); + + static::assertFileNotExists('sandbox/pagecache/1'); + static::assertFileNotExists('sandbox/pagecache/2'); + static::assertFileNotExists('sandbox/tmp/1'); + static::assertFileNotExists('sandbox/tmp/2'); + + static::assertFileExists('sandbox/pagecache/.htaccess'); + static::assertFileExists('sandbox/tmp/.htaccess'); + static::assertFileExists('sandbox/cache'); + static::assertFileExists('sandbox/cache/.htaccess'); + static::assertFileExists('sandbox/cache/1'); + static::assertFileExists('sandbox/cache/2'); + } + + /** + * Test clearing thumbnails cache + */ + public function testClearThumbnailsCache(): void + { + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { + if ($key === 'resource.page_cache') { + return 'sandbox/pagecache'; + } elseif ($key === 'resource.raintpl_tmp') { + return 'sandbox/tmp'; + } elseif ($key === 'resource.thumbnails_cache') { + return 'sandbox/cache'; + } else { + return $default; + } + }); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->willReturnCallback(function (string $key, array $value): SessionManager { + static::assertSame(SessionManager::KEY_WARNING_MESSAGES, $key); + static::assertCount(1, $value); + static::assertStringStartsWith('Thumbnails cache has been cleared.', $value[0]); + + return $this->container->sessionManager; + }); + ; + + $request = $this->createMock(Request::class); + $request->method('getQueryParam')->with('type')->willReturn('thumbnails'); + $response = new Response(); + + $result = $this->controller->clearCache($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame('/subfolder/admin/server', (string) $result->getHeaderLine('Location')); + + static::assertFileNotExists('sandbox/cache/1'); + static::assertFileNotExists('sandbox/cache/2'); + + static::assertFileExists('sandbox/cache/.htaccess'); + static::assertFileExists('sandbox/pagecache'); + static::assertFileExists('sandbox/pagecache/.htaccess'); + static::assertFileExists('sandbox/pagecache/1'); + static::assertFileExists('sandbox/pagecache/2'); + static::assertFileExists('sandbox/tmp'); + static::assertFileExists('sandbox/tmp/.htaccess'); + static::assertFileExists('sandbox/tmp/1'); + static::assertFileExists('sandbox/tmp/2'); + } +} diff --git a/tests/front/controller/visitor/InstallControllerTest.php b/tests/front/controller/visitor/InstallControllerTest.php index 345ad544..2105ed77 100644 --- a/tests/front/controller/visitor/InstallControllerTest.php +++ b/tests/front/controller/visitor/InstallControllerTest.php @@ -79,6 +79,15 @@ class InstallControllerTest extends TestCase static::assertIsArray($assignedVariables['languages']); static::assertSame('Automatic', $assignedVariables['languages']['auto']); static::assertSame('French', $assignedVariables['languages']['fr']); + + static::assertSame(PHP_VERSION, $assignedVariables['php_version']); + static::assertArrayHasKey('php_has_reached_eol', $assignedVariables); + static::assertArrayHasKey('php_eol', $assignedVariables); + static::assertArrayHasKey('php_extensions', $assignedVariables); + static::assertArrayHasKey('permissions', $assignedVariables); + static::assertEmpty($assignedVariables['permissions']); + + static::assertSame('Install Shaarli', $assignedVariables['pagetitle']); } /** -- cgit v1.2.3 From 9c04921a8c28c18ef757f2d43ba35e7e2a7f1a4b Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 16 Oct 2020 20:17:08 +0200 Subject: Feature: Share private bookmarks using a URL containing a private key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add a share link next to « Permalink » in linklist (using share icon from fork awesome) - This link generates a private key associated to the bookmark - Accessing the bookmark while logged out with the proper key will display it Fixes #475 --- .../SharePrivateTest.php | 139 +++++++++++++++++++++ .../visitor/BookmarkListControllerTest.php | 31 +++++ 2 files changed, 170 insertions(+) create mode 100644 tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php (limited to 'tests/front') diff --git a/tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php b/tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php new file mode 100644 index 00000000..1e7877c7 --- /dev/null +++ b/tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php @@ -0,0 +1,139 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ManageShaareController($this->container); + } + + /** + * Test shaare private with a private bookmark which does not have a key yet. + */ + public function testSharePrivateWithNewPrivateBookmark(): void + { + $hash = 'abcdcef'; + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setPrivate(true) + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash) + ->willReturn($bookmark) + ; + $this->container->bookmarkService + ->expects(static::once()) + ->method('set') + ->with($bookmark, true) + ->willReturnCallback(function (Bookmark $bookmark): Bookmark { + static::assertSame(32, strlen($bookmark->getAdditionalContentEntry('private_key'))); + + return $bookmark; + }) + ; + + $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); + + static::assertSame(302, $result->getStatusCode()); + static::assertRegExp('#/subfolder/shaare/' . $hash . '\?key=\w{32}#', $result->getHeaderLine('Location')); + } + + /** + * Test shaare private with a private bookmark which does already have a key. + */ + public function testSharePrivateWithExistingPrivateBookmark(): void + { + $hash = 'abcdcef'; + $existingKey = 'this is a private key'; + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setPrivate(true) + ->addAdditionalContentEntry('private_key', $existingKey) + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash) + ->willReturn($bookmark) + ; + $this->container->bookmarkService + ->expects(static::never()) + ->method('set') + ; + + $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame('/subfolder/shaare/' . $hash . '?key=' . $existingKey, $result->getHeaderLine('Location')); + } + + /** + * Test shaare private with a public bookmark. + */ + public function testSharePrivateWithPublicBookmark(): void + { + $hash = 'abcdcef'; + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setPrivate(false) + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash) + ->willReturn($bookmark) + ; + $this->container->bookmarkService + ->expects(static::never()) + ->method('set') + ; + + $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame('/subfolder/shaare/' . $hash, $result->getHeaderLine('Location')); + } +} diff --git a/tests/front/controller/visitor/BookmarkListControllerTest.php b/tests/front/controller/visitor/BookmarkListControllerTest.php index 5ca92507..5cbc8c73 100644 --- a/tests/front/controller/visitor/BookmarkListControllerTest.php +++ b/tests/front/controller/visitor/BookmarkListControllerTest.php @@ -291,6 +291,37 @@ class BookmarkListControllerTest extends TestCase ); } + /** + * Test GET /shaare/{hash}?key={key} - Find a link by hash using a private link. + */ + public function testPermalinkWithPrivateKey(): void + { + $hash = 'abcdef'; + $privateKey = 'this is a private key'; + + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $request = $this->createMock(Request::class); + $request->method('getParam')->willReturnCallback(function (string $key, $default = null) use ($privateKey) { + return $key === 'key' ? $privateKey : $default; + }); + $response = new Response(); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash, $privateKey) + ->willReturn((new Bookmark())->setId(123)->setTitle('Title 1')->setUrl('http://url1.tld')) + ; + + $result = $this->controller->permalink($request, $response, ['hash' => $hash]); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('linklist', (string) $result->getBody()); + static::assertCount(1, $assignedVariables['links']); + } + /** * Test getting link list with thumbnail updates. * -> 2 thumbnails update, only 1 datastore write -- cgit v1.2.3 From 36e6d88dbfd753665224664d5214f39ccfbbf6a5 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 16 Oct 2020 11:50:53 +0200 Subject: Feature: add weekly and monthly view/RSS feed for daily page - Heavy refactoring of DailyController - Add a banner like in tag cloud to display monthly and weekly links - Translations: t() now supports variables with optional first letter uppercase Fixes #160 --- .../controller/visitor/DailyControllerTest.php | 412 ++++++++++++++++----- 1 file changed, 325 insertions(+), 87 deletions(-) (limited to 'tests/front') diff --git a/tests/front/controller/visitor/DailyControllerTest.php b/tests/front/controller/visitor/DailyControllerTest.php index fc78bc13..758e7219 100644 --- a/tests/front/controller/visitor/DailyControllerTest.php +++ b/tests/front/controller/visitor/DailyControllerTest.php @@ -28,52 +28,49 @@ class DailyControllerTest extends TestCase public function testValidIndexControllerInvokeDefault(): void { $currentDay = new \DateTimeImmutable('2020-05-13'); + $previousDate = new \DateTime('2 days ago 00:00:00'); + $nextDate = new \DateTime('today 00:00:00'); $request = $this->createMock(Request::class); - $request->method('getQueryParam')->willReturn($currentDay->format('Ymd')); + $request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string { + return $key === 'day' ? $currentDay->format('Ymd') : null; + }); $response = new Response(); // Save RainTPL assigned variables $assignedVariables = []; $this->assignTemplateVars($assignedVariables); - // Links dataset: 2 links with thumbnails - $this->container->bookmarkService - ->expects(static::once()) - ->method('days') - ->willReturnCallback(function () use ($currentDay): array { - return [ - '20200510', - $currentDay->format('Ymd'), - '20200516', - ]; - }) - ; $this->container->bookmarkService ->expects(static::once()) - ->method('filterDay') - ->willReturnCallback(function (): array { - return [ - (new Bookmark()) - ->setId(1) - ->setUrl('http://url.tld') - ->setTitle(static::generateString(50)) - ->setDescription(static::generateString(500)) - , - (new Bookmark()) - ->setId(2) - ->setUrl('http://url2.tld') - ->setTitle(static::generateString(50)) - ->setDescription(static::generateString(500)) - , - (new Bookmark()) - ->setId(3) - ->setUrl('http://url3.tld') - ->setTitle(static::generateString(50)) - ->setDescription(static::generateString(500)) - , - ]; - }) + ->method('findByDate') + ->willReturnCallback( + function ($from, $to, &$previous, &$next) use ($currentDay, $previousDate, $nextDate): array { + $previous = $previousDate; + $next = $nextDate; + + return [ + (new Bookmark()) + ->setId(1) + ->setUrl('http://url.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + (new Bookmark()) + ->setId(2) + ->setUrl('http://url2.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + (new Bookmark()) + ->setId(3) + ->setUrl('http://url3.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + ]; + } + ) ; // Make sure that PluginManager hook is triggered @@ -81,20 +78,22 @@ class DailyControllerTest extends TestCase ->expects(static::atLeastOnce()) ->method('executeHooks') ->withConsecutive(['render_daily']) - ->willReturnCallback(function (string $hook, array $data, array $param) use ($currentDay): array { - if ('render_daily' === $hook) { - static::assertArrayHasKey('linksToDisplay', $data); - static::assertCount(3, $data['linksToDisplay']); - static::assertSame(1, $data['linksToDisplay'][0]['id']); - static::assertSame($currentDay->getTimestamp(), $data['day']); - static::assertSame('20200510', $data['previousday']); - static::assertSame('20200516', $data['nextday']); - - static::assertArrayHasKey('loggedin', $param); + ->willReturnCallback( + function (string $hook, array $data, array $param) use ($currentDay, $previousDate, $nextDate): array { + if ('render_daily' === $hook) { + static::assertArrayHasKey('linksToDisplay', $data); + static::assertCount(3, $data['linksToDisplay']); + static::assertSame(1, $data['linksToDisplay'][0]['id']); + static::assertSame($currentDay->getTimestamp(), $data['day']); + static::assertSame($previousDate->format('Ymd'), $data['previousday']); + static::assertSame($nextDate->format('Ymd'), $data['nextday']); + + static::assertArrayHasKey('loggedin', $param); + } + + return $data; } - - return $data; - }) + ) ; $result = $this->controller->index($request, $response); @@ -107,6 +106,11 @@ class DailyControllerTest extends TestCase ); static::assertEquals($currentDay, $assignedVariables['dayDate']); static::assertEquals($currentDay->getTimestamp(), $assignedVariables['day']); + static::assertSame($previousDate->format('Ymd'), $assignedVariables['previousday']); + static::assertSame($nextDate->format('Ymd'), $assignedVariables['nextday']); + static::assertSame('day', $assignedVariables['type']); + static::assertSame('May 13, 2020', $assignedVariables['dayDesc']); + static::assertSame('Daily', $assignedVariables['localizedType']); static::assertCount(3, $assignedVariables['linksToDisplay']); $link = $assignedVariables['linksToDisplay'][0]; @@ -171,26 +175,19 @@ class DailyControllerTest extends TestCase $currentDay = new \DateTimeImmutable('2020-05-13'); $request = $this->createMock(Request::class); + $request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string { + return $key === 'day' ? $currentDay->format('Ymd') : null; + }); $response = new Response(); // Save RainTPL assigned variables $assignedVariables = []; $this->assignTemplateVars($assignedVariables); - // Links dataset: 2 links with thumbnails $this->container->bookmarkService ->expects(static::once()) - ->method('days') + ->method('findByDate') ->willReturnCallback(function () use ($currentDay): array { - return [ - $currentDay->format($currentDay->format('Ymd')), - ]; - }) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('filterDay') - ->willReturnCallback(function (): array { return [ (new Bookmark()) ->setId(1) @@ -250,20 +247,10 @@ class DailyControllerTest extends TestCase $assignedVariables = []; $this->assignTemplateVars($assignedVariables); - // Links dataset: 2 links with thumbnails $this->container->bookmarkService ->expects(static::once()) - ->method('days') + ->method('findByDate') ->willReturnCallback(function () use ($currentDay): array { - return [ - $currentDay->format($currentDay->format('Ymd')), - ]; - }) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('filterDay') - ->willReturnCallback(function (): array { return [ (new Bookmark())->setId(1)->setUrl('http://url.tld')->setTitle('title'), (new Bookmark()) @@ -320,14 +307,7 @@ class DailyControllerTest extends TestCase // Links dataset: 2 links with thumbnails $this->container->bookmarkService ->expects(static::once()) - ->method('days') - ->willReturnCallback(function (): array { - return []; - }) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('filterDay') + ->method('findByDate') ->willReturnCallback(function (): array { return []; }) @@ -347,7 +327,7 @@ class DailyControllerTest extends TestCase static::assertSame(200, $result->getStatusCode()); static::assertSame('daily', (string) $result->getBody()); static::assertCount(0, $assignedVariables['linksToDisplay']); - static::assertSame('Today', $assignedVariables['dayDesc']); + static::assertSame('Today - ' . (new \DateTime())->format('F d, Y'), $assignedVariables['dayDesc']); static::assertEquals((new \DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']); static::assertEquals((new \DateTime())->setTime(0, 0), $assignedVariables['dayDate']); } @@ -361,6 +341,7 @@ class DailyControllerTest extends TestCase new \DateTimeImmutable('2020-05-17'), new \DateTimeImmutable('2020-05-15'), new \DateTimeImmutable('2020-05-13'), + new \DateTimeImmutable('+1 month'), ]; $request = $this->createMock(Request::class); @@ -371,6 +352,7 @@ class DailyControllerTest extends TestCase (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), (new Bookmark())->setId(4)->setCreated($dates[2])->setUrl('http://domain.tld/4'), + (new Bookmark())->setId(5)->setCreated($dates[3])->setUrl('http://domain.tld/5'), ]); $this->container->pageCacheManager @@ -397,13 +379,14 @@ class DailyControllerTest extends TestCase static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']); static::assertSame('http://shaarli/subfolder/daily-rss', $assignedVariables['page_url']); static::assertFalse($assignedVariables['hide_timestamps']); - static::assertCount(2, $assignedVariables['days']); + static::assertCount(3, $assignedVariables['days']); $day = $assignedVariables['days'][$dates[0]->format('Ymd')]; + $date = $dates[0]->setTime(23, 59, 59); - static::assertEquals($dates[0], $day['date']); - static::assertSame($dates[0]->format(\DateTime::RSS), $day['date_rss']); - static::assertSame(format_date($dates[0], false), $day['date_human']); + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame(format_date($date, false), $day['date_human']); static::assertSame('http://shaarli/subfolder/daily?day='. $dates[0]->format('Ymd'), $day['absolute_url']); static::assertCount(1, $day['links']); static::assertSame(1, $day['links'][0]['id']); @@ -411,10 +394,11 @@ class DailyControllerTest extends TestCase static::assertEquals($dates[0], $day['links'][0]['created']); $day = $assignedVariables['days'][$dates[1]->format('Ymd')]; + $date = $dates[1]->setTime(23, 59, 59); - static::assertEquals($dates[1], $day['date']); - static::assertSame($dates[1]->format(\DateTime::RSS), $day['date_rss']); - static::assertSame(format_date($dates[1], false), $day['date_human']); + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame(format_date($date, false), $day['date_human']); static::assertSame('http://shaarli/subfolder/daily?day='. $dates[1]->format('Ymd'), $day['absolute_url']); static::assertCount(2, $day['links']); @@ -424,6 +408,18 @@ class DailyControllerTest extends TestCase static::assertSame(3, $day['links'][1]['id']); static::assertSame('http://domain.tld/3', $day['links'][1]['url']); static::assertEquals($dates[1], $day['links'][1]['created']); + + $day = $assignedVariables['days'][$dates[2]->format('Ymd')]; + $date = $dates[2]->setTime(23, 59, 59); + + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame(format_date($date, false), $day['date_human']); + static::assertSame('http://shaarli/subfolder/daily?day='. $dates[2]->format('Ymd'), $day['absolute_url']); + static::assertCount(1, $day['links']); + static::assertSame(4, $day['links'][0]['id']); + static::assertSame('http://domain.tld/4', $day['links'][0]['url']); + static::assertEquals($dates[2], $day['links'][0]['created']); } /** @@ -475,4 +471,246 @@ class DailyControllerTest extends TestCase static::assertFalse($assignedVariables['hide_timestamps']); static::assertCount(0, $assignedVariables['days']); } + + /** + * Test simple display index with week parameter + */ + public function testSimpleIndexWeekly(): void + { + $currentDay = new \DateTimeImmutable('2020-05-13'); + $expectedDay = new \DateTimeImmutable('2020-05-11'); + + $request = $this->createMock(Request::class); + $request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string { + return $key === 'week' ? $currentDay->format('YW') : null; + }); + $response = new Response(); + + // Save RainTPL assigned variables + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByDate') + ->willReturnCallback( + function (): array { + return [ + (new Bookmark()) + ->setId(1) + ->setUrl('http://url.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + (new Bookmark()) + ->setId(2) + ->setUrl('http://url2.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + ]; + } + ) + ; + + $result = $this->controller->index($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('daily', (string) $result->getBody()); + static::assertSame( + 'Weekly - Week 20 (May 11, 2020) - Shaarli', + $assignedVariables['pagetitle'] + ); + + static::assertCount(2, $assignedVariables['linksToDisplay']); + static::assertEquals($expectedDay->setTime(0, 0), $assignedVariables['dayDate']); + static::assertSame($expectedDay->setTime(0, 0)->getTimestamp(), $assignedVariables['day']); + static::assertSame('', $assignedVariables['previousday']); + static::assertSame('', $assignedVariables['nextday']); + static::assertSame('Week 20 (May 11, 2020)', $assignedVariables['dayDesc']); + static::assertSame('week', $assignedVariables['type']); + static::assertSame('Weekly', $assignedVariables['localizedType']); + } + + /** + * Test simple display index with month parameter + */ + public function testSimpleIndexMonthly(): void + { + $currentDay = new \DateTimeImmutable('2020-05-13'); + $expectedDay = new \DateTimeImmutable('2020-05-01'); + + $request = $this->createMock(Request::class); + $request->method('getQueryParam')->willReturnCallback(function (string $key) use ($currentDay): ?string { + return $key === 'month' ? $currentDay->format('Ym') : null; + }); + $response = new Response(); + + // Save RainTPL assigned variables + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByDate') + ->willReturnCallback( + function (): array { + return [ + (new Bookmark()) + ->setId(1) + ->setUrl('http://url.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + (new Bookmark()) + ->setId(2) + ->setUrl('http://url2.tld') + ->setTitle(static::generateString(50)) + ->setDescription(static::generateString(500)) + , + ]; + } + ) + ; + + $result = $this->controller->index($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('daily', (string) $result->getBody()); + static::assertSame( + 'Monthly - May, 2020 - Shaarli', + $assignedVariables['pagetitle'] + ); + + static::assertCount(2, $assignedVariables['linksToDisplay']); + static::assertEquals($expectedDay->setTime(0, 0), $assignedVariables['dayDate']); + static::assertSame($expectedDay->setTime(0, 0)->getTimestamp(), $assignedVariables['day']); + static::assertSame('', $assignedVariables['previousday']); + static::assertSame('', $assignedVariables['nextday']); + static::assertSame('May, 2020', $assignedVariables['dayDesc']); + static::assertSame('month', $assignedVariables['type']); + static::assertSame('Monthly', $assignedVariables['localizedType']); + } + + /** + * Test simple display RSS with week parameter + */ + public function testSimpleRssWeekly(): void + { + $dates = [ + new \DateTimeImmutable('2020-05-19'), + new \DateTimeImmutable('2020-05-13'), + ]; + $expectedDates = [ + new \DateTimeImmutable('2020-05-24 23:59:59'), + new \DateTimeImmutable('2020-05-17 23:59:59'), + ]; + + $this->container->environment['QUERY_STRING'] = 'week'; + $request = $this->createMock(Request::class); + $request->method('getQueryParam')->willReturnCallback(function (string $key): ?string { + return $key === 'week' ? '' : null; + }); + $response = new Response(); + + $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([ + (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), + (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), + (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), + ]); + + // Save RainTPL assigned variables + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $result = $this->controller->rss($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]); + static::assertSame('dailyrss', (string) $result->getBody()); + static::assertSame('Shaarli', $assignedVariables['title']); + static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']); + static::assertSame('http://shaarli/subfolder/daily-rss?week', $assignedVariables['page_url']); + static::assertFalse($assignedVariables['hide_timestamps']); + static::assertCount(2, $assignedVariables['days']); + + $day = $assignedVariables['days'][$dates[0]->format('YW')]; + $date = $expectedDates[0]; + + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame('Week 21 (May 18, 2020)', $day['date_human']); + static::assertSame('http://shaarli/subfolder/daily?week='. $dates[0]->format('YW'), $day['absolute_url']); + static::assertCount(1, $day['links']); + + $day = $assignedVariables['days'][$dates[1]->format('YW')]; + $date = $expectedDates[1]; + + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame('Week 20 (May 11, 2020)', $day['date_human']); + static::assertSame('http://shaarli/subfolder/daily?week='. $dates[1]->format('YW'), $day['absolute_url']); + static::assertCount(2, $day['links']); + } + + /** + * Test simple display RSS with month parameter + */ + public function testSimpleRssMonthly(): void + { + $dates = [ + new \DateTimeImmutable('2020-05-19'), + new \DateTimeImmutable('2020-04-13'), + ]; + $expectedDates = [ + new \DateTimeImmutable('2020-05-31 23:59:59'), + new \DateTimeImmutable('2020-04-30 23:59:59'), + ]; + + $this->container->environment['QUERY_STRING'] = 'month'; + $request = $this->createMock(Request::class); + $request->method('getQueryParam')->willReturnCallback(function (string $key): ?string { + return $key === 'month' ? '' : null; + }); + $response = new Response(); + + $this->container->bookmarkService->expects(static::once())->method('search')->willReturn([ + (new Bookmark())->setId(1)->setCreated($dates[0])->setUrl('http://domain.tld/1'), + (new Bookmark())->setId(2)->setCreated($dates[1])->setUrl('http://domain.tld/2'), + (new Bookmark())->setId(3)->setCreated($dates[1])->setUrl('http://domain.tld/3'), + ]); + + // Save RainTPL assigned variables + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $result = $this->controller->rss($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertStringContainsString('application/rss', $result->getHeader('Content-Type')[0]); + static::assertSame('dailyrss', (string) $result->getBody()); + static::assertSame('Shaarli', $assignedVariables['title']); + static::assertSame('http://shaarli/subfolder/', $assignedVariables['index_url']); + static::assertSame('http://shaarli/subfolder/daily-rss?month', $assignedVariables['page_url']); + static::assertFalse($assignedVariables['hide_timestamps']); + static::assertCount(2, $assignedVariables['days']); + + $day = $assignedVariables['days'][$dates[0]->format('Ym')]; + $date = $expectedDates[0]; + + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame('May, 2020', $day['date_human']); + static::assertSame('http://shaarli/subfolder/daily?month='. $dates[0]->format('Ym'), $day['absolute_url']); + static::assertCount(1, $day['links']); + + $day = $assignedVariables['days'][$dates[1]->format('Ym')]; + $date = $expectedDates[1]; + + static::assertEquals($date, $day['date']); + static::assertSame($date->format(\DateTime::RSS), $day['date_rss']); + static::assertSame('April, 2020', $day['date_human']); + static::assertSame('http://shaarli/subfolder/daily?month='. $dates[1]->format('Ym'), $day['absolute_url']); + static::assertCount(2, $day['links']); + } } -- cgit v1.2.3 From 5d8de7587d67b5c3e5d1fed8562d9b87ecde80c1 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 10 Oct 2020 17:40:26 +0200 Subject: Feature: bulk creation of bookmarks This changes creates a new form in addlink page allowing to create multiple bookmarks at once more easily. It focuses on re-using as much existing code and template component as possible. These changes includes: - a new form in addlink (hidden behind a button by default), containing a text area for URL, and tags/private status to apply to created links - this form displays a new template called editlink.batch, itself including editlink template multiple times - User interation in this new templates are handle by a new JS script (shaare-batch.js) making AJAX requests, and therefore does not need page reloading - ManageShaareController has been split into 3 distinct controllers: + ShaareAdd: displays addlink template + ShaareManage: various operation applied on existing shaares (change visibility, pin, deletion, etc.) + ShaarePublish: handles creation/edit forms and saving Shaare's form - Updated translations Fixes #137 --- .../ManageShaareControllerTest/AddShaareTest.php | 47 --- .../ChangeVisibilityBookmarkTest.php | 418 --------------------- .../DeleteBookmarkTest.php | 380 ------------------- .../DisplayCreateFormTest.php | 367 ------------------ .../DisplayEditFormTest.php | 155 -------- .../ManageShaareControllerTest/PinBookmarkTest.php | 145 ------- .../SaveBookmarkTest.php | 369 ------------------ .../SharePrivateTest.php | 139 ------- .../controller/admin/ShaareAddControllerTest.php | 97 +++++ .../ChangeVisibilityBookmarkTest.php | 418 +++++++++++++++++++++ .../DeleteBookmarkTest.php | 380 +++++++++++++++++++ .../ShaareManageControllerTest/PinBookmarkTest.php | 145 +++++++ .../SharePrivateTest.php | 139 +++++++ .../DisplayCreateBatchFormTest.php | 62 +++ .../DisplayCreateFormTest.php | 367 ++++++++++++++++++ .../DisplayEditFormTest.php | 155 ++++++++ .../SaveBookmarkTest.php | 369 ++++++++++++++++++ 17 files changed, 2132 insertions(+), 2020 deletions(-) delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/AddShaareTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/DisplayEditFormTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/PinBookmarkTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php delete mode 100644 tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php create mode 100644 tests/front/controller/admin/ShaareAddControllerTest.php create mode 100644 tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php create mode 100644 tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php create mode 100644 tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php create mode 100644 tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php create mode 100644 tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php create mode 100644 tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php create mode 100644 tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php create mode 100644 tests/front/controller/admin/ShaarePublishControllerTest/SaveBookmarkTest.php (limited to 'tests/front') diff --git a/tests/front/controller/admin/ManageShaareControllerTest/AddShaareTest.php b/tests/front/controller/admin/ManageShaareControllerTest/AddShaareTest.php deleted file mode 100644 index 0f27ec2f..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/AddShaareTest.php +++ /dev/null @@ -1,47 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Test displaying add link page - */ - public function testAddShaare(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $request = $this->createMock(Request::class); - $response = new Response(); - - $result = $this->controller->addShaare($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('addlink', (string) $result->getBody()); - - static::assertSame('Shaare a new link - Shaarli', $assignedVariables['pagetitle']); - } -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php deleted file mode 100644 index 096d0774..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/ChangeVisibilityBookmarkTest.php +++ /dev/null @@ -1,418 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Change bookmark visibility - Set private - Single public bookmark with valid parameters - */ - public function testSetSingleBookmarkPrivate(): void - { - $parameters = ['id' => '123', 'newVisibility' => 'private']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(false); - - static::assertFalse($bookmark->isPrivate()); - - $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); - $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturnCallback(function () use ($bookmark): BookmarkFormatter { - return new BookmarkRawFormatter($this->container->conf, true); - }) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::once()) - ->method('executeHooks') - ->with('save_link') - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertTrue($bookmark->isPrivate()); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Set public - Single private bookmark with valid parameters - */ - public function testSetSingleBookmarkPublic(): void - { - $parameters = ['id' => '123', 'newVisibility' => 'public']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true); - - static::assertTrue($bookmark->isPrivate()); - - $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); - $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::once()) - ->method('executeHooks') - ->with('save_link') - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertFalse($bookmark->isPrivate()); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Set private on single already private bookmark - */ - public function testSetSinglePrivateBookmarkPrivate(): void - { - $parameters = ['id' => '123', 'newVisibility' => 'private']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true); - - static::assertTrue($bookmark->isPrivate()); - - $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); - $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::once()) - ->method('executeHooks') - ->with('save_link') - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertTrue($bookmark->isPrivate()); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Set multiple bookmarks private - */ - public function testSetMultipleBookmarksPrivate(): void - { - $parameters = ['id' => '123 456 789', 'newVisibility' => 'private']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmarks = [ - (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(false), - (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456')->setPrivate(true), - (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789')->setPrivate(false), - ]; - - $this->container->bookmarkService - ->expects(static::exactly(3)) - ->method('get') - ->withConsecutive([123], [456], [789]) - ->willReturnOnConsecutiveCalls(...$bookmarks) - ; - $this->container->bookmarkService - ->expects(static::exactly(3)) - ->method('set') - ->withConsecutive(...array_map(function (Bookmark $bookmark): array { - return [$bookmark, false]; - }, $bookmarks)) - ; - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::exactly(3)) - ->method('executeHooks') - ->with('save_link') - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertTrue($bookmarks[0]->isPrivate()); - static::assertTrue($bookmarks[1]->isPrivate()); - static::assertTrue($bookmarks[2]->isPrivate()); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Single bookmark not found. - */ - public function testChangeVisibilitySingleBookmarkNotFound(): void - { - $parameters = ['id' => '123', 'newVisibility' => 'private']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('get') - ->willThrowException(new BookmarkNotFoundException()) - ; - $this->container->bookmarkService->expects(static::never())->method('set'); - $this->container->bookmarkService->expects(static::never())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) - ; - - // Make sure that PluginManager hook is not triggered - $this->container->pluginManager - ->expects(static::never()) - ->method('executeHooks') - ->with('save_link') - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Multiple bookmarks with one not found. - */ - public function testChangeVisibilityMultipleBookmarksOneNotFound(): void - { - $parameters = ['id' => '123 456 789', 'newVisibility' => 'public']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmarks = [ - (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true), - (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789')->setPrivate(false), - ]; - - $this->container->bookmarkService - ->expects(static::exactly(3)) - ->method('get') - ->withConsecutive([123], [456], [789]) - ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark { - if ($id === 123) { - return $bookmarks[0]; - } - if ($id === 789) { - return $bookmarks[1]; - } - throw new BookmarkNotFoundException(); - }) - ; - $this->container->bookmarkService - ->expects(static::exactly(2)) - ->method('set') - ->withConsecutive(...array_map(function (Bookmark $bookmark): array { - return [$bookmark, false]; - }, $bookmarks)) - ; - $this->container->bookmarkService->expects(static::once())->method('save'); - - // Make sure that PluginManager hook is not triggered - $this->container->pluginManager - ->expects(static::exactly(2)) - ->method('executeHooks') - ->with('save_link') - ; - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.']) - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Invalid ID - */ - public function testChangeVisibilityInvalidId(): void - { - $parameters = ['id' => 'nope not an ID', 'newVisibility' => 'private']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - Empty ID - */ - public function testChangeVisibilityEmptyId(): void - { - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Change bookmark visibility - with invalid visibility - */ - public function testChangeVisibilityWithInvalidVisibility(): void - { - $parameters = ['id' => '123', 'newVisibility' => 'invalid']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid visibility provided.']) - ; - - $result = $this->controller->changeVisibility($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php deleted file mode 100644 index 83bbee7c..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/DeleteBookmarkTest.php +++ /dev/null @@ -1,380 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Delete bookmark - Single bookmark with valid parameters - */ - public function testDeleteSingleBookmark(): void - { - $parameters = ['id' => '123']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'); - - $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); - $this->container->bookmarkService->expects(static::once())->method('remove')->with($bookmark, false); - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturnCallback(function () use ($bookmark): BookmarkFormatter { - $formatter = $this->createMock(BookmarkFormatter::class); - $formatter - ->expects(static::once()) - ->method('format') - ->with($bookmark) - ->willReturn(['formatted' => $bookmark]) - ; - - return $formatter; - }) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::once()) - ->method('executeHooks') - ->with('delete_link', ['formatted' => $bookmark]) - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Delete bookmark - Multiple bookmarks with valid parameters - */ - public function testDeleteMultipleBookmarks(): void - { - $parameters = ['id' => '123 456 789']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmarks = [ - (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'), - (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456'), - (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'), - ]; - - $this->container->bookmarkService - ->expects(static::exactly(3)) - ->method('get') - ->withConsecutive([123], [456], [789]) - ->willReturnOnConsecutiveCalls(...$bookmarks) - ; - $this->container->bookmarkService - ->expects(static::exactly(3)) - ->method('remove') - ->withConsecutive(...array_map(function (Bookmark $bookmark): array { - return [$bookmark, false]; - }, $bookmarks)) - ; - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter { - $formatter = $this->createMock(BookmarkFormatter::class); - - $formatter - ->expects(static::exactly(3)) - ->method('format') - ->withConsecutive(...array_map(function (Bookmark $bookmark): array { - return [$bookmark]; - }, $bookmarks)) - ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array { - return ['formatted' => $bookmark]; - }, $bookmarks)) - ; - - return $formatter; - }) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::exactly(3)) - ->method('executeHooks') - ->with('delete_link') - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Delete bookmark - Single bookmark not found in the data store - */ - public function testDeleteSingleBookmarkNotFound(): void - { - $parameters = ['id' => '123']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('get') - ->willThrowException(new BookmarkNotFoundException()) - ; - $this->container->bookmarkService->expects(static::never())->method('remove'); - $this->container->bookmarkService->expects(static::never())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturnCallback(function (): BookmarkFormatter { - $formatter = $this->createMock(BookmarkFormatter::class); - - $formatter->expects(static::never())->method('format'); - - return $formatter; - }) - ; - // Make sure that PluginManager hook is not triggered - $this->container->pluginManager - ->expects(static::never()) - ->method('executeHooks') - ->with('delete_link') - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Delete bookmark - Multiple bookmarks with one not found in the data store - */ - public function testDeleteMultipleBookmarksOneNotFound(): void - { - $parameters = ['id' => '123 456 789']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $bookmarks = [ - (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'), - (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'), - ]; - - $this->container->bookmarkService - ->expects(static::exactly(3)) - ->method('get') - ->withConsecutive([123], [456], [789]) - ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark { - if ($id === 123) { - return $bookmarks[0]; - } - if ($id === 789) { - return $bookmarks[1]; - } - throw new BookmarkNotFoundException(); - }) - ; - $this->container->bookmarkService - ->expects(static::exactly(2)) - ->method('remove') - ->withConsecutive(...array_map(function (Bookmark $bookmark): array { - return [$bookmark, false]; - }, $bookmarks)) - ; - $this->container->bookmarkService->expects(static::once())->method('save'); - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->with('raw') - ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter { - $formatter = $this->createMock(BookmarkFormatter::class); - - $formatter - ->expects(static::exactly(2)) - ->method('format') - ->withConsecutive(...array_map(function (Bookmark $bookmark): array { - return [$bookmark]; - }, $bookmarks)) - ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array { - return ['formatted' => $bookmark]; - }, $bookmarks)) - ; - - return $formatter; - }) - ; - - // Make sure that PluginManager hook is not triggered - $this->container->pluginManager - ->expects(static::exactly(2)) - ->method('executeHooks') - ->with('delete_link') - ; - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.']) - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Delete bookmark - Invalid ID - */ - public function testDeleteInvalidId(): void - { - $parameters = ['id' => 'nope not an ID']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Delete bookmark - Empty ID - */ - public function testDeleteEmptyId(): void - { - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Delete bookmark - from bookmarklet - */ - public function testDeleteBookmarkFromBookmarklet(): void - { - $parameters = [ - 'id' => '123', - 'source' => 'bookmarklet', - ]; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->bookmarkService->method('get')->with('123')->willReturn( - (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123') - ); - - $this->container->formatterFactory = $this->createMock(FormatterFactory::class); - $this->container->formatterFactory - ->expects(static::once()) - ->method('getFormatter') - ->willReturnCallback(function (): BookmarkFormatter { - $formatter = $this->createMock(BookmarkFormatter::class); - $formatter->method('format')->willReturn(['formatted']); - - return $formatter; - }) - ; - - $result = $this->controller->deleteBookmark($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('', (string) $result->getBody('location')); - } -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php b/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php deleted file mode 100644 index eafa54eb..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/DisplayCreateFormTest.php +++ /dev/null @@ -1,367 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->container->metadataRetriever = $this->createMock(MetadataRetriever::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Test displaying bookmark create form - * Ensure that every step of the standard workflow works properly. - */ - public function testDisplayCreateFormWithUrlAndWithMetadataRetrieval(): void - { - $this->container->environment = [ - 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' - ]; - - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; - $expectedUrl = str_replace('&utm_ad=pay', '', $url); - $remoteTitle = 'Remote Title'; - $remoteDesc = 'Sometimes the meta description is relevant.'; - $remoteTags = 'abc def'; - - $request = $this->createMock(Request::class); - $request->method('getParam')->willReturnCallback(function (string $key) use ($url): ?string { - return $key === 'post' ? $url : null; - }); - $response = new Response(); - - $this->container->conf = $this->createMock(ConfigManager::class); - $this->container->conf->method('get')->willReturnCallback(function (string $param, $default) { - if ($param === 'general.enable_async_metadata') { - return false; - } - - return $default; - }); - - $this->container->metadataRetriever->expects(static::once())->method('retrieve')->willReturn([ - 'title' => $remoteTitle, - 'description' => $remoteDesc, - 'tags' => $remoteTags, - ]); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('bookmarksCountPerTag') - ->willReturn($tags = ['tag1' => 2, 'tag2' => 1]) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::atLeastOnce()) - ->method('executeHooks') - ->withConsecutive(['render_editlink'], ['render_includes']) - ->willReturnCallback(function (string $hook, array $data) use ($remoteTitle, $remoteDesc): array { - if ('render_editlink' === $hook) { - static::assertSame($remoteTitle, $data['link']['title']); - static::assertSame($remoteDesc, $data['link']['description']); - } - - return $data; - }) - ; - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - - static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); - - static::assertSame($expectedUrl, $assignedVariables['link']['url']); - static::assertSame($remoteTitle, $assignedVariables['link']['title']); - static::assertSame($remoteDesc, $assignedVariables['link']['description']); - static::assertSame($remoteTags, $assignedVariables['link']['tags']); - static::assertFalse($assignedVariables['link']['private']); - - static::assertTrue($assignedVariables['link_is_new']); - static::assertSame($referer, $assignedVariables['http_referer']); - static::assertSame($tags, $assignedVariables['tags']); - static::assertArrayHasKey('source', $assignedVariables); - static::assertArrayHasKey('default_private_links', $assignedVariables); - static::assertArrayHasKey('async_metadata', $assignedVariables); - static::assertArrayHasKey('retrieve_description', $assignedVariables); - } - - /** - * Test displaying bookmark create form without any external metadata retrieval attempt - */ - public function testDisplayCreateFormWithUrlAndWithoutMetadata(): void - { - $this->container->environment = [ - 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' - ]; - - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; - $expectedUrl = str_replace('&utm_ad=pay', '', $url); - - $request = $this->createMock(Request::class); - $request->method('getParam')->willReturnCallback(function (string $key) use ($url): ?string { - return $key === 'post' ? $url : null; - }); - $response = new Response(); - - $this->container->metadataRetriever->expects(static::never())->method('retrieve'); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('bookmarksCountPerTag') - ->willReturn($tags = ['tag1' => 2, 'tag2' => 1]) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::atLeastOnce()) - ->method('executeHooks') - ->withConsecutive(['render_editlink'], ['render_includes']) - ->willReturnCallback(function (string $hook, array $data): array { - if ('render_editlink' === $hook) { - static::assertSame('', $data['link']['title']); - static::assertSame('', $data['link']['description']); - } - - return $data; - }) - ; - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - - static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); - - static::assertSame($expectedUrl, $assignedVariables['link']['url']); - static::assertSame('', $assignedVariables['link']['title']); - static::assertSame('', $assignedVariables['link']['description']); - static::assertSame('', $assignedVariables['link']['tags']); - static::assertFalse($assignedVariables['link']['private']); - - static::assertTrue($assignedVariables['link_is_new']); - static::assertSame($referer, $assignedVariables['http_referer']); - static::assertSame($tags, $assignedVariables['tags']); - static::assertArrayHasKey('source', $assignedVariables); - static::assertArrayHasKey('default_private_links', $assignedVariables); - static::assertArrayHasKey('async_metadata', $assignedVariables); - static::assertArrayHasKey('retrieve_description', $assignedVariables); - } - - /** - * Test displaying bookmark create form - * Ensure all available query parameters are handled properly. - */ - public function testDisplayCreateFormWithFullParameters(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $parameters = [ - 'post' => 'http://url.tld/other?part=3&utm_ad=pay#hash', - 'title' => 'Provided Title', - 'description' => 'Provided description.', - 'tags' => 'abc def', - 'private' => '1', - 'source' => 'apps', - ]; - $expectedUrl = str_replace('&utm_ad=pay', '', $parameters['post']); - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }); - $response = new Response(); - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - - static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); - - static::assertSame($expectedUrl, $assignedVariables['link']['url']); - static::assertSame($parameters['title'], $assignedVariables['link']['title']); - static::assertSame($parameters['description'], $assignedVariables['link']['description']); - static::assertSame($parameters['tags'], $assignedVariables['link']['tags']); - static::assertTrue($assignedVariables['link']['private']); - static::assertTrue($assignedVariables['link_is_new']); - static::assertSame($parameters['source'], $assignedVariables['source']); - } - - /** - * Test displaying bookmark create form - * Without any parameter. - */ - public function testDisplayCreateFormEmpty(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); - $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - static::assertSame('', $assignedVariables['link']['url']); - static::assertSame('Note: ', $assignedVariables['link']['title']); - static::assertSame('', $assignedVariables['link']['description']); - static::assertSame('', $assignedVariables['link']['tags']); - static::assertFalse($assignedVariables['link']['private']); - static::assertTrue($assignedVariables['link_is_new']); - } - - /** - * Test displaying bookmark create form - * URL not using HTTP protocol: do not try to retrieve the title - */ - public function testDisplayCreateFormNotHttp(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $url = 'magnet://kubuntu.torrent'; - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($url): ?string { - return $key === 'post' ? $url : null; - }); - $response = new Response(); - - $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); - $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - static::assertSame($url, $assignedVariables['link']['url']); - static::assertTrue($assignedVariables['link_is_new']); - } - - /** - * Test displaying bookmark create form - * When markdown formatter is enabled, the no markdown tag should be added to existing tags. - */ - public function testDisplayCreateFormWithMarkdownEnabled(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $this->container->conf = $this->createMock(ConfigManager::class); - $this->container->conf - ->expects(static::atLeastOnce()) - ->method('get')->willReturnCallback(function (string $key): ?string { - if ($key === 'formatter') { - return 'markdown'; - } - - return $key; - }) - ; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - static::assertSame(['nomarkdown' => 1], $assignedVariables['tags']); - } - - /** - * Test displaying bookmark create form - * When an existing URL is submitted, we want to edit the existing link. - */ - public function testDisplayCreateFormWithExistingUrl(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; - $expectedUrl = str_replace('&utm_ad=pay', '', $url); - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($url): ?string { - return $key === 'post' ? $url : null; - }); - $response = new Response(); - - $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); - $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('findByUrl') - ->with($expectedUrl) - ->willReturn( - (new Bookmark()) - ->setId($id = 23) - ->setUrl($expectedUrl) - ->setTitle($title = 'Bookmark Title') - ->setDescription($description = 'Bookmark description.') - ->setTags($tags = ['abc', 'def']) - ->setPrivate(true) - ->setCreated($createdAt = new \DateTime('2020-06-10 18:45:44')) - ) - ; - - $result = $this->controller->displayCreateForm($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - - static::assertSame('Edit Shaare - Shaarli', $assignedVariables['pagetitle']); - static::assertFalse($assignedVariables['link_is_new']); - - static::assertSame($id, $assignedVariables['link']['id']); - static::assertSame($expectedUrl, $assignedVariables['link']['url']); - static::assertSame($title, $assignedVariables['link']['title']); - static::assertSame($description, $assignedVariables['link']['description']); - static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); - static::assertTrue($assignedVariables['link']['private']); - static::assertSame($createdAt, $assignedVariables['link']['created']); - } -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/DisplayEditFormTest.php b/tests/front/controller/admin/ManageShaareControllerTest/DisplayEditFormTest.php deleted file mode 100644 index 2dc3f41c..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/DisplayEditFormTest.php +++ /dev/null @@ -1,155 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Test displaying bookmark edit form - * When an existing ID is provided, ensure that default workflow works properly. - */ - public function testDisplayEditFormDefault(): void - { - $assignedVariables = []; - $this->assignTemplateVars($assignedVariables); - - $id = 11; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); - $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('get') - ->with($id) - ->willReturn( - (new Bookmark()) - ->setId($id) - ->setUrl($url = 'http://domain.tld') - ->setTitle($title = 'Bookmark Title') - ->setDescription($description = 'Bookmark description.') - ->setTags($tags = ['abc', 'def']) - ->setPrivate(true) - ->setCreated($createdAt = new \DateTime('2020-06-10 18:45:44')) - ) - ; - - $result = $this->controller->displayEditForm($request, $response, ['id' => (string) $id]); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('editlink', (string) $result->getBody()); - - static::assertSame('Edit Shaare - Shaarli', $assignedVariables['pagetitle']); - static::assertFalse($assignedVariables['link_is_new']); - - static::assertSame($id, $assignedVariables['link']['id']); - static::assertSame($url, $assignedVariables['link']['url']); - static::assertSame($title, $assignedVariables['link']['title']); - static::assertSame($description, $assignedVariables['link']['description']); - static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); - static::assertTrue($assignedVariables['link']['private']); - static::assertSame($createdAt, $assignedVariables['link']['created']); - } - - /** - * Test displaying bookmark edit form - * Invalid ID provided. - */ - public function testDisplayEditFormInvalidId(): void - { - $id = 'invalid'; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier invalid could not be found.']) - ; - - $result = $this->controller->displayEditForm($request, $response, ['id' => $id]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Test displaying bookmark edit form - * ID not provided. - */ - public function testDisplayEditFormIdNotProvided(): void - { - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier could not be found.']) - ; - - $result = $this->controller->displayEditForm($request, $response, []); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Test displaying bookmark edit form - * Bookmark not found. - */ - public function testDisplayEditFormBookmarkNotFound(): void - { - $id = 123; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('get') - ->with($id) - ->willThrowException(new BookmarkNotFoundException()) - ; - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 123 could not be found.']) - ; - - $result = $this->controller->displayEditForm($request, $response, ['id' => (string) $id]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/PinBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/PinBookmarkTest.php deleted file mode 100644 index 50ce7df1..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/PinBookmarkTest.php +++ /dev/null @@ -1,145 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Test pin bookmark - with valid input - * - * @dataProvider initialStickyValuesProvider() - */ - public function testPinBookmarkIsStickyNull(?bool $sticky, bool $expectedValue): void - { - $id = 123; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $bookmark = (new Bookmark()) - ->setId(123) - ->setUrl('http://domain.tld') - ->setTitle('Title 123') - ->setSticky($sticky) - ; - - $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); - $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, true); - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::once()) - ->method('executeHooks') - ->with('save_link') - ; - - $result = $this->controller->pinBookmark($request, $response, ['id' => (string) $id]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - - static::assertSame($expectedValue, $bookmark->isSticky()); - } - - public function initialStickyValuesProvider(): array - { - // [initialStickyState, isStickyAfterPin] - return [[null, true], [false, true], [true, false]]; - } - - /** - * Test pin bookmark - invalid bookmark ID - */ - public function testDisplayEditFormInvalidId(): void - { - $id = 'invalid'; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier invalid could not be found.']) - ; - - $result = $this->controller->pinBookmark($request, $response, ['id' => $id]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Test pin bookmark - Bookmark ID not provided - */ - public function testDisplayEditFormIdNotProvided(): void - { - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier could not be found.']) - ; - - $result = $this->controller->pinBookmark($request, $response, []); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } - - /** - * Test pin bookmark - bookmark not found - */ - public function testDisplayEditFormBookmarkNotFound(): void - { - $id = 123; - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('get') - ->with($id) - ->willThrowException(new BookmarkNotFoundException()) - ; - - $this->container->sessionManager - ->expects(static::once()) - ->method('setSessionParameter') - ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 123 could not be found.']) - ; - - $result = $this->controller->pinBookmark($request, $response, ['id' => (string) $id]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); - } -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php b/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php deleted file mode 100644 index 1adeef5a..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/SaveBookmarkTest.php +++ /dev/null @@ -1,369 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Test save a new bookmark - */ - public function testSaveBookmark(): void - { - $id = 21; - $parameters = [ - 'lf_url' => 'http://url.tld/other?part=3#hash', - 'lf_title' => 'Provided Title', - 'lf_description' => 'Provided description.', - 'lf_tags' => 'abc def', - 'lf_private' => '1', - 'returnurl' => 'http://shaarli/subfolder/admin/add-shaare' - ]; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $checkBookmark = function (Bookmark $bookmark) use ($parameters) { - static::assertSame($parameters['lf_url'], $bookmark->getUrl()); - static::assertSame($parameters['lf_title'], $bookmark->getTitle()); - static::assertSame($parameters['lf_description'], $bookmark->getDescription()); - static::assertSame($parameters['lf_tags'], $bookmark->getTagsString()); - static::assertTrue($bookmark->isPrivate()); - }; - - $this->container->bookmarkService - ->expects(static::once()) - ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { - static::assertFalse($save); - - $checkBookmark($bookmark); - - $bookmark->setId($id); - - return $bookmark; - }) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('set') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { - static::assertTrue($save); - - $checkBookmark($bookmark); - - static::assertSame($id, $bookmark->getId()); - - return $bookmark; - }) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::atLeastOnce()) - ->method('executeHooks') - ->withConsecutive(['save_link']) - ->willReturnCallback(function (string $hook, array $data) use ($parameters, $id): array { - if ('save_link' === $hook) { - static::assertSame($id, $data['id']); - static::assertSame($parameters['lf_url'], $data['url']); - static::assertSame($parameters['lf_title'], $data['title']); - static::assertSame($parameters['lf_description'], $data['description']); - static::assertSame($parameters['lf_tags'], $data['tags']); - static::assertTrue($data['private']); - } - - return $data; - }) - ; - - $result = $this->controller->save($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertRegExp('@/subfolder/#[\w\-]{6}@', $result->getHeader('location')[0]); - } - - - /** - * Test save an existing bookmark - */ - public function testSaveExistingBookmark(): void - { - $id = 21; - $parameters = [ - 'lf_id' => (string) $id, - 'lf_url' => 'http://url.tld/other?part=3#hash', - 'lf_title' => 'Provided Title', - 'lf_description' => 'Provided description.', - 'lf_tags' => 'abc def', - 'lf_private' => '1', - 'returnurl' => 'http://shaarli/subfolder/?page=2' - ]; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $checkBookmark = function (Bookmark $bookmark) use ($parameters, $id) { - static::assertSame($id, $bookmark->getId()); - static::assertSame($parameters['lf_url'], $bookmark->getUrl()); - static::assertSame($parameters['lf_title'], $bookmark->getTitle()); - static::assertSame($parameters['lf_description'], $bookmark->getDescription()); - static::assertSame($parameters['lf_tags'], $bookmark->getTagsString()); - static::assertTrue($bookmark->isPrivate()); - }; - - $this->container->bookmarkService->expects(static::atLeastOnce())->method('exists')->willReturn(true); - $this->container->bookmarkService - ->expects(static::once()) - ->method('get') - ->willReturn((new Bookmark())->setId($id)->setUrl('http://other.url')) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { - static::assertFalse($save); - - $checkBookmark($bookmark); - - return $bookmark; - }) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('set') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { - static::assertTrue($save); - - $checkBookmark($bookmark); - - static::assertSame($id, $bookmark->getId()); - - return $bookmark; - }) - ; - - // Make sure that PluginManager hook is triggered - $this->container->pluginManager - ->expects(static::atLeastOnce()) - ->method('executeHooks') - ->withConsecutive(['save_link']) - ->willReturnCallback(function (string $hook, array $data) use ($parameters, $id): array { - if ('save_link' === $hook) { - static::assertSame($id, $data['id']); - static::assertSame($parameters['lf_url'], $data['url']); - static::assertSame($parameters['lf_title'], $data['title']); - static::assertSame($parameters['lf_description'], $data['description']); - static::assertSame($parameters['lf_tags'], $data['tags']); - static::assertTrue($data['private']); - } - - return $data; - }) - ; - - $result = $this->controller->save($request, $response); - - static::assertSame(302, $result->getStatusCode()); - static::assertRegExp('@/subfolder/\?page=2#[\w\-]{6}@', $result->getHeader('location')[0]); - } - - /** - * Test save a bookmark - try to retrieve the thumbnail - */ - public function testSaveBookmarkWithThumbnailSync(): void - { - $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->conf = $this->createMock(ConfigManager::class); - $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { - if ($key === 'thumbnails.mode') { - return Thumbnailer::MODE_ALL; - } elseif ($key === 'general.enable_async_metadata') { - return false; - } - - return $default; - }); - - $this->container->thumbnailer = $this->createMock(Thumbnailer::class); - $this->container->thumbnailer - ->expects(static::once()) - ->method('get') - ->with($parameters['lf_url']) - ->willReturn($thumb = 'http://thumb.url') - ; - - $this->container->bookmarkService - ->expects(static::once()) - ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): Bookmark { - static::assertSame($thumb, $bookmark->getThumbnail()); - - return $bookmark; - }) - ; - - $result = $this->controller->save($request, $response); - - static::assertSame(302, $result->getStatusCode()); - } - - /** - * Test save a bookmark - with ID #0 - */ - public function testSaveBookmarkWithIdZero(): void - { - $parameters = ['lf_id' => '0']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->bookmarkService->expects(static::once())->method('exists')->with(0)->willReturn(true); - $this->container->bookmarkService->expects(static::once())->method('get')->with(0)->willReturn(new Bookmark()); - - $result = $this->controller->save($request, $response); - - static::assertSame(302, $result->getStatusCode()); - } - - /** - * Test save a bookmark - do not attempt to retrieve thumbnails if async mode is enabled. - */ - public function testSaveBookmarkWithThumbnailAsync(): void - { - $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $this->container->conf = $this->createMock(ConfigManager::class); - $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { - if ($key === 'thumbnails.mode') { - return Thumbnailer::MODE_ALL; - } elseif ($key === 'general.enable_async_metadata') { - return true; - } - - return $default; - }); - - $this->container->thumbnailer = $this->createMock(Thumbnailer::class); - $this->container->thumbnailer->expects(static::never())->method('get'); - - $this->container->bookmarkService - ->expects(static::once()) - ->method('addOrSet') - ->willReturnCallback(function (Bookmark $bookmark): Bookmark { - static::assertNull($bookmark->getThumbnail()); - - return $bookmark; - }) - ; - - $result = $this->controller->save($request, $response); - - static::assertSame(302, $result->getStatusCode()); - } - - /** - * Change the password with a wrong existing password - */ - public function testSaveBookmarkFromBookmarklet(): void - { - $parameters = ['source' => 'bookmarklet']; - - $request = $this->createMock(Request::class); - $request - ->method('getParam') - ->willReturnCallback(function (string $key) use ($parameters): ?string { - return $parameters[$key] ?? null; - }) - ; - $response = new Response(); - - $result = $this->controller->save($request, $response); - - static::assertSame(200, $result->getStatusCode()); - static::assertSame('', (string) $result->getBody()); - } - - /** - * Change the password with a wrong existing password - */ - public function testSaveBookmarkWrongToken(): void - { - $this->container->sessionManager = $this->createMock(SessionManager::class); - $this->container->sessionManager->method('checkToken')->willReturn(false); - - $this->container->bookmarkService->expects(static::never())->method('addOrSet'); - $this->container->bookmarkService->expects(static::never())->method('set'); - - $request = $this->createMock(Request::class); - $response = new Response(); - - $this->expectException(WrongTokenException::class); - - $this->controller->save($request, $response); - } - -} diff --git a/tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php b/tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php deleted file mode 100644 index 1e7877c7..00000000 --- a/tests/front/controller/admin/ManageShaareControllerTest/SharePrivateTest.php +++ /dev/null @@ -1,139 +0,0 @@ -createContainer(); - - $this->container->httpAccess = $this->createMock(HttpAccess::class); - $this->controller = new ManageShaareController($this->container); - } - - /** - * Test shaare private with a private bookmark which does not have a key yet. - */ - public function testSharePrivateWithNewPrivateBookmark(): void - { - $hash = 'abcdcef'; - $request = $this->createMock(Request::class); - $response = new Response(); - - $bookmark = (new Bookmark()) - ->setId(123) - ->setUrl('http://domain.tld') - ->setTitle('Title 123') - ->setPrivate(true) - ; - - $this->container->bookmarkService - ->expects(static::once()) - ->method('findByHash') - ->with($hash) - ->willReturn($bookmark) - ; - $this->container->bookmarkService - ->expects(static::once()) - ->method('set') - ->with($bookmark, true) - ->willReturnCallback(function (Bookmark $bookmark): Bookmark { - static::assertSame(32, strlen($bookmark->getAdditionalContentEntry('private_key'))); - - return $bookmark; - }) - ; - - $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); - - static::assertSame(302, $result->getStatusCode()); - static::assertRegExp('#/subfolder/shaare/' . $hash . '\?key=\w{32}#', $result->getHeaderLine('Location')); - } - - /** - * Test shaare private with a private bookmark which does already have a key. - */ - public function testSharePrivateWithExistingPrivateBookmark(): void - { - $hash = 'abcdcef'; - $existingKey = 'this is a private key'; - $request = $this->createMock(Request::class); - $response = new Response(); - - $bookmark = (new Bookmark()) - ->setId(123) - ->setUrl('http://domain.tld') - ->setTitle('Title 123') - ->setPrivate(true) - ->addAdditionalContentEntry('private_key', $existingKey) - ; - - $this->container->bookmarkService - ->expects(static::once()) - ->method('findByHash') - ->with($hash) - ->willReturn($bookmark) - ; - $this->container->bookmarkService - ->expects(static::never()) - ->method('set') - ; - - $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame('/subfolder/shaare/' . $hash . '?key=' . $existingKey, $result->getHeaderLine('Location')); - } - - /** - * Test shaare private with a public bookmark. - */ - public function testSharePrivateWithPublicBookmark(): void - { - $hash = 'abcdcef'; - $request = $this->createMock(Request::class); - $response = new Response(); - - $bookmark = (new Bookmark()) - ->setId(123) - ->setUrl('http://domain.tld') - ->setTitle('Title 123') - ->setPrivate(false) - ; - - $this->container->bookmarkService - ->expects(static::once()) - ->method('findByHash') - ->with($hash) - ->willReturn($bookmark) - ; - $this->container->bookmarkService - ->expects(static::never()) - ->method('set') - ; - - $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); - - static::assertSame(302, $result->getStatusCode()); - static::assertSame('/subfolder/shaare/' . $hash, $result->getHeaderLine('Location')); - } -} diff --git a/tests/front/controller/admin/ShaareAddControllerTest.php b/tests/front/controller/admin/ShaareAddControllerTest.php new file mode 100644 index 00000000..a27ebe64 --- /dev/null +++ b/tests/front/controller/admin/ShaareAddControllerTest.php @@ -0,0 +1,97 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaareAddController($this->container); + } + + /** + * Test displaying add link page + */ + public function testAddShaare(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $request = $this->createMock(Request::class); + $response = new Response(); + + $expectedTags = [ + 'tag1' => 32, + 'tag2' => 24, + 'tag3' => 1, + ]; + $this->container->bookmarkService + ->expects(static::once()) + ->method('bookmarksCountPerTag') + ->willReturn($expectedTags) + ; + $expectedTags = array_merge($expectedTags, [BookmarkMarkdownFormatter::NO_MD_TAG => 1]); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { + return $key === 'formatter' ? 'markdown' : $default; + }); + + $result = $this->controller->addShaare($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('addlink', (string) $result->getBody()); + + static::assertSame('Shaare a new link - Shaarli', $assignedVariables['pagetitle']); + static::assertFalse($assignedVariables['default_private_links']); + static::assertTrue($assignedVariables['async_metadata']); + static::assertSame($expectedTags, $assignedVariables['tags']); + } + + /** + * Test displaying add link page + */ + public function testAddShaareWithoutMd(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $request = $this->createMock(Request::class); + $response = new Response(); + + $expectedTags = [ + 'tag1' => 32, + 'tag2' => 24, + 'tag3' => 1, + ]; + $this->container->bookmarkService + ->expects(static::once()) + ->method('bookmarksCountPerTag') + ->willReturn($expectedTags) + ; + + $result = $this->controller->addShaare($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('addlink', (string) $result->getBody()); + + static::assertSame($expectedTags, $assignedVariables['tags']); + } +} diff --git a/tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php new file mode 100644 index 00000000..28b1c023 --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/ChangeVisibilityBookmarkTest.php @@ -0,0 +1,418 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaareManageController($this->container); + } + + /** + * Change bookmark visibility - Set private - Single public bookmark with valid parameters + */ + public function testSetSingleBookmarkPrivate(): void + { + $parameters = ['id' => '123', 'newVisibility' => 'private']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(false); + + static::assertFalse($bookmark->isPrivate()); + + $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); + $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturnCallback(function () use ($bookmark): BookmarkFormatter { + return new BookmarkRawFormatter($this->container->conf, true); + }) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::once()) + ->method('executeHooks') + ->with('save_link') + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertTrue($bookmark->isPrivate()); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Set public - Single private bookmark with valid parameters + */ + public function testSetSingleBookmarkPublic(): void + { + $parameters = ['id' => '123', 'newVisibility' => 'public']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true); + + static::assertTrue($bookmark->isPrivate()); + + $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); + $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::once()) + ->method('executeHooks') + ->with('save_link') + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertFalse($bookmark->isPrivate()); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Set private on single already private bookmark + */ + public function testSetSinglePrivateBookmarkPrivate(): void + { + $parameters = ['id' => '123', 'newVisibility' => 'private']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true); + + static::assertTrue($bookmark->isPrivate()); + + $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); + $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, false); + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::once()) + ->method('executeHooks') + ->with('save_link') + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertTrue($bookmark->isPrivate()); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Set multiple bookmarks private + */ + public function testSetMultipleBookmarksPrivate(): void + { + $parameters = ['id' => '123 456 789', 'newVisibility' => 'private']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmarks = [ + (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(false), + (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456')->setPrivate(true), + (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789')->setPrivate(false), + ]; + + $this->container->bookmarkService + ->expects(static::exactly(3)) + ->method('get') + ->withConsecutive([123], [456], [789]) + ->willReturnOnConsecutiveCalls(...$bookmarks) + ; + $this->container->bookmarkService + ->expects(static::exactly(3)) + ->method('set') + ->withConsecutive(...array_map(function (Bookmark $bookmark): array { + return [$bookmark, false]; + }, $bookmarks)) + ; + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::exactly(3)) + ->method('executeHooks') + ->with('save_link') + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertTrue($bookmarks[0]->isPrivate()); + static::assertTrue($bookmarks[1]->isPrivate()); + static::assertTrue($bookmarks[2]->isPrivate()); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Single bookmark not found. + */ + public function testChangeVisibilitySingleBookmarkNotFound(): void + { + $parameters = ['id' => '123', 'newVisibility' => 'private']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('get') + ->willThrowException(new BookmarkNotFoundException()) + ; + $this->container->bookmarkService->expects(static::never())->method('set'); + $this->container->bookmarkService->expects(static::never())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturn(new BookmarkRawFormatter($this->container->conf, true)) + ; + + // Make sure that PluginManager hook is not triggered + $this->container->pluginManager + ->expects(static::never()) + ->method('executeHooks') + ->with('save_link') + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Multiple bookmarks with one not found. + */ + public function testChangeVisibilityMultipleBookmarksOneNotFound(): void + { + $parameters = ['id' => '123 456 789', 'newVisibility' => 'public']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmarks = [ + (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123')->setPrivate(true), + (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789')->setPrivate(false), + ]; + + $this->container->bookmarkService + ->expects(static::exactly(3)) + ->method('get') + ->withConsecutive([123], [456], [789]) + ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark { + if ($id === 123) { + return $bookmarks[0]; + } + if ($id === 789) { + return $bookmarks[1]; + } + throw new BookmarkNotFoundException(); + }) + ; + $this->container->bookmarkService + ->expects(static::exactly(2)) + ->method('set') + ->withConsecutive(...array_map(function (Bookmark $bookmark): array { + return [$bookmark, false]; + }, $bookmarks)) + ; + $this->container->bookmarkService->expects(static::once())->method('save'); + + // Make sure that PluginManager hook is not triggered + $this->container->pluginManager + ->expects(static::exactly(2)) + ->method('executeHooks') + ->with('save_link') + ; + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.']) + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Invalid ID + */ + public function testChangeVisibilityInvalidId(): void + { + $parameters = ['id' => 'nope not an ID', 'newVisibility' => 'private']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - Empty ID + */ + public function testChangeVisibilityEmptyId(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Change bookmark visibility - with invalid visibility + */ + public function testChangeVisibilityWithInvalidVisibility(): void + { + $parameters = ['id' => '123', 'newVisibility' => 'invalid']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid visibility provided.']) + ; + + $result = $this->controller->changeVisibility($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } +} diff --git a/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php new file mode 100644 index 00000000..770a16d7 --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php @@ -0,0 +1,380 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaareManageController($this->container); + } + + /** + * Delete bookmark - Single bookmark with valid parameters + */ + public function testDeleteSingleBookmark(): void + { + $parameters = ['id' => '123']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmark = (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'); + + $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); + $this->container->bookmarkService->expects(static::once())->method('remove')->with($bookmark, false); + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturnCallback(function () use ($bookmark): BookmarkFormatter { + $formatter = $this->createMock(BookmarkFormatter::class); + $formatter + ->expects(static::once()) + ->method('format') + ->with($bookmark) + ->willReturn(['formatted' => $bookmark]) + ; + + return $formatter; + }) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::once()) + ->method('executeHooks') + ->with('delete_link', ['formatted' => $bookmark]) + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Delete bookmark - Multiple bookmarks with valid parameters + */ + public function testDeleteMultipleBookmarks(): void + { + $parameters = ['id' => '123 456 789']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmarks = [ + (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'), + (new Bookmark())->setId(456)->setUrl('http://domain.tld')->setTitle('Title 456'), + (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'), + ]; + + $this->container->bookmarkService + ->expects(static::exactly(3)) + ->method('get') + ->withConsecutive([123], [456], [789]) + ->willReturnOnConsecutiveCalls(...$bookmarks) + ; + $this->container->bookmarkService + ->expects(static::exactly(3)) + ->method('remove') + ->withConsecutive(...array_map(function (Bookmark $bookmark): array { + return [$bookmark, false]; + }, $bookmarks)) + ; + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter { + $formatter = $this->createMock(BookmarkFormatter::class); + + $formatter + ->expects(static::exactly(3)) + ->method('format') + ->withConsecutive(...array_map(function (Bookmark $bookmark): array { + return [$bookmark]; + }, $bookmarks)) + ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array { + return ['formatted' => $bookmark]; + }, $bookmarks)) + ; + + return $formatter; + }) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::exactly(3)) + ->method('executeHooks') + ->with('delete_link') + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Delete bookmark - Single bookmark not found in the data store + */ + public function testDeleteSingleBookmarkNotFound(): void + { + $parameters = ['id' => '123']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('get') + ->willThrowException(new BookmarkNotFoundException()) + ; + $this->container->bookmarkService->expects(static::never())->method('remove'); + $this->container->bookmarkService->expects(static::never())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturnCallback(function (): BookmarkFormatter { + $formatter = $this->createMock(BookmarkFormatter::class); + + $formatter->expects(static::never())->method('format'); + + return $formatter; + }) + ; + // Make sure that PluginManager hook is not triggered + $this->container->pluginManager + ->expects(static::never()) + ->method('executeHooks') + ->with('delete_link') + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Delete bookmark - Multiple bookmarks with one not found in the data store + */ + public function testDeleteMultipleBookmarksOneNotFound(): void + { + $parameters = ['id' => '123 456 789']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $bookmarks = [ + (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123'), + (new Bookmark())->setId(789)->setUrl('http://domain.tld')->setTitle('Title 789'), + ]; + + $this->container->bookmarkService + ->expects(static::exactly(3)) + ->method('get') + ->withConsecutive([123], [456], [789]) + ->willReturnCallback(function (int $id) use ($bookmarks): Bookmark { + if ($id === 123) { + return $bookmarks[0]; + } + if ($id === 789) { + return $bookmarks[1]; + } + throw new BookmarkNotFoundException(); + }) + ; + $this->container->bookmarkService + ->expects(static::exactly(2)) + ->method('remove') + ->withConsecutive(...array_map(function (Bookmark $bookmark): array { + return [$bookmark, false]; + }, $bookmarks)) + ; + $this->container->bookmarkService->expects(static::once())->method('save'); + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->with('raw') + ->willReturnCallback(function () use ($bookmarks): BookmarkFormatter { + $formatter = $this->createMock(BookmarkFormatter::class); + + $formatter + ->expects(static::exactly(2)) + ->method('format') + ->withConsecutive(...array_map(function (Bookmark $bookmark): array { + return [$bookmark]; + }, $bookmarks)) + ->willReturnOnConsecutiveCalls(...array_map(function (Bookmark $bookmark): array { + return ['formatted' => $bookmark]; + }, $bookmarks)) + ; + + return $formatter; + }) + ; + + // Make sure that PluginManager hook is not triggered + $this->container->pluginManager + ->expects(static::exactly(2)) + ->method('executeHooks') + ->with('delete_link') + ; + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 456 could not be found.']) + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Delete bookmark - Invalid ID + */ + public function testDeleteInvalidId(): void + { + $parameters = ['id' => 'nope not an ID']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Delete bookmark - Empty ID + */ + public function testDeleteEmptyId(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Invalid bookmark ID provided.']) + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Delete bookmark - from bookmarklet + */ + public function testDeleteBookmarkFromBookmarklet(): void + { + $parameters = [ + 'id' => '123', + 'source' => 'bookmarklet', + ]; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->bookmarkService->method('get')->with('123')->willReturn( + (new Bookmark())->setId(123)->setUrl('http://domain.tld')->setTitle('Title 123') + ); + + $this->container->formatterFactory = $this->createMock(FormatterFactory::class); + $this->container->formatterFactory + ->expects(static::once()) + ->method('getFormatter') + ->willReturnCallback(function (): BookmarkFormatter { + $formatter = $this->createMock(BookmarkFormatter::class); + $formatter->method('format')->willReturn(['formatted']); + + return $formatter; + }) + ; + + $result = $this->controller->deleteBookmark($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('', (string) $result->getBody('location')); + } +} diff --git a/tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php new file mode 100644 index 00000000..b89206ce --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/PinBookmarkTest.php @@ -0,0 +1,145 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaareManageController($this->container); + } + + /** + * Test pin bookmark - with valid input + * + * @dataProvider initialStickyValuesProvider() + */ + public function testPinBookmarkIsStickyNull(?bool $sticky, bool $expectedValue): void + { + $id = 123; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setSticky($sticky) + ; + + $this->container->bookmarkService->expects(static::once())->method('get')->with(123)->willReturn($bookmark); + $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, true); + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::once()) + ->method('executeHooks') + ->with('save_link') + ; + + $result = $this->controller->pinBookmark($request, $response, ['id' => (string) $id]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + + static::assertSame($expectedValue, $bookmark->isSticky()); + } + + public function initialStickyValuesProvider(): array + { + // [initialStickyState, isStickyAfterPin] + return [[null, true], [false, true], [true, false]]; + } + + /** + * Test pin bookmark - invalid bookmark ID + */ + public function testDisplayEditFormInvalidId(): void + { + $id = 'invalid'; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier invalid could not be found.']) + ; + + $result = $this->controller->pinBookmark($request, $response, ['id' => $id]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Test pin bookmark - Bookmark ID not provided + */ + public function testDisplayEditFormIdNotProvided(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier could not be found.']) + ; + + $result = $this->controller->pinBookmark($request, $response, []); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Test pin bookmark - bookmark not found + */ + public function testDisplayEditFormBookmarkNotFound(): void + { + $id = 123; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('get') + ->with($id) + ->willThrowException(new BookmarkNotFoundException()) + ; + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 123 could not be found.']) + ; + + $result = $this->controller->pinBookmark($request, $response, ['id' => (string) $id]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } +} diff --git a/tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php b/tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php new file mode 100644 index 00000000..ae61dfb7 --- /dev/null +++ b/tests/front/controller/admin/ShaareManageControllerTest/SharePrivateTest.php @@ -0,0 +1,139 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaareManageController($this->container); + } + + /** + * Test shaare private with a private bookmark which does not have a key yet. + */ + public function testSharePrivateWithNewPrivateBookmark(): void + { + $hash = 'abcdcef'; + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setPrivate(true) + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash) + ->willReturn($bookmark) + ; + $this->container->bookmarkService + ->expects(static::once()) + ->method('set') + ->with($bookmark, true) + ->willReturnCallback(function (Bookmark $bookmark): Bookmark { + static::assertSame(32, strlen($bookmark->getAdditionalContentEntry('private_key'))); + + return $bookmark; + }) + ; + + $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); + + static::assertSame(302, $result->getStatusCode()); + static::assertRegExp('#/subfolder/shaare/' . $hash . '\?key=\w{32}#', $result->getHeaderLine('Location')); + } + + /** + * Test shaare private with a private bookmark which does already have a key. + */ + public function testSharePrivateWithExistingPrivateBookmark(): void + { + $hash = 'abcdcef'; + $existingKey = 'this is a private key'; + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setPrivate(true) + ->addAdditionalContentEntry('private_key', $existingKey) + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash) + ->willReturn($bookmark) + ; + $this->container->bookmarkService + ->expects(static::never()) + ->method('set') + ; + + $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame('/subfolder/shaare/' . $hash . '?key=' . $existingKey, $result->getHeaderLine('Location')); + } + + /** + * Test shaare private with a public bookmark. + */ + public function testSharePrivateWithPublicBookmark(): void + { + $hash = 'abcdcef'; + $request = $this->createMock(Request::class); + $response = new Response(); + + $bookmark = (new Bookmark()) + ->setId(123) + ->setUrl('http://domain.tld') + ->setTitle('Title 123') + ->setPrivate(false) + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByHash') + ->with($hash) + ->willReturn($bookmark) + ; + $this->container->bookmarkService + ->expects(static::never()) + ->method('set') + ; + + $result = $this->controller->sharePrivate($request, $response, ['hash' => $hash]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame('/subfolder/shaare/' . $hash, $result->getHeaderLine('Location')); + } +} diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php new file mode 100644 index 00000000..34547120 --- /dev/null +++ b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php @@ -0,0 +1,62 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->container->metadataRetriever = $this->createMock(MetadataRetriever::class); + $this->controller = new ShaarePublishController($this->container); + } + + /** + * TODO + */ + public function testDisplayCreateFormBatch(): void + { + $urls = [ + 'https://domain1.tld/url1', + 'https://domain2.tld/url2', + 'https://domain3.tld/url3', + ]; + + $request = $this->createMock(Request::class); + $request->method('getParam')->willReturnCallback(function (string $key) use ($urls): ?string { + return $key === 'urls' ? implode(PHP_EOL, $urls) : null; + }); + $response = new Response(); + + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $result = $this->controller->displayCreateBatchForms($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink.batch', (string) $result->getBody()); + + static::assertTrue($assignedVariables['batch_mode']); + static::assertCount(3, $assignedVariables['links']); + static::assertSame($urls[0], $assignedVariables['links'][0]['link']['url']); + static::assertSame($urls[1], $assignedVariables['links'][1]['link']['url']); + static::assertSame($urls[2], $assignedVariables['links'][2]['link']['url']); + } +} diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php new file mode 100644 index 00000000..f20b1def --- /dev/null +++ b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php @@ -0,0 +1,367 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->container->metadataRetriever = $this->createMock(MetadataRetriever::class); + $this->controller = new ShaarePublishController($this->container); + } + + /** + * Test displaying bookmark create form + * Ensure that every step of the standard workflow works properly. + */ + public function testDisplayCreateFormWithUrlAndWithMetadataRetrieval(): void + { + $this->container->environment = [ + 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' + ]; + + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; + $expectedUrl = str_replace('&utm_ad=pay', '', $url); + $remoteTitle = 'Remote Title'; + $remoteDesc = 'Sometimes the meta description is relevant.'; + $remoteTags = 'abc def'; + + $request = $this->createMock(Request::class); + $request->method('getParam')->willReturnCallback(function (string $key) use ($url): ?string { + return $key === 'post' ? $url : null; + }); + $response = new Response(); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $param, $default) { + if ($param === 'general.enable_async_metadata') { + return false; + } + + return $default; + }); + + $this->container->metadataRetriever->expects(static::once())->method('retrieve')->willReturn([ + 'title' => $remoteTitle, + 'description' => $remoteDesc, + 'tags' => $remoteTags, + ]); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('bookmarksCountPerTag') + ->willReturn($tags = ['tag1' => 2, 'tag2' => 1]) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::atLeastOnce()) + ->method('executeHooks') + ->withConsecutive(['render_editlink'], ['render_includes']) + ->willReturnCallback(function (string $hook, array $data) use ($remoteTitle, $remoteDesc): array { + if ('render_editlink' === $hook) { + static::assertSame($remoteTitle, $data['link']['title']); + static::assertSame($remoteDesc, $data['link']['description']); + } + + return $data; + }) + ; + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + + static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); + + static::assertSame($expectedUrl, $assignedVariables['link']['url']); + static::assertSame($remoteTitle, $assignedVariables['link']['title']); + static::assertSame($remoteDesc, $assignedVariables['link']['description']); + static::assertSame($remoteTags, $assignedVariables['link']['tags']); + static::assertFalse($assignedVariables['link']['private']); + + static::assertTrue($assignedVariables['link_is_new']); + static::assertSame($referer, $assignedVariables['http_referer']); + static::assertSame($tags, $assignedVariables['tags']); + static::assertArrayHasKey('source', $assignedVariables); + static::assertArrayHasKey('default_private_links', $assignedVariables); + static::assertArrayHasKey('async_metadata', $assignedVariables); + static::assertArrayHasKey('retrieve_description', $assignedVariables); + } + + /** + * Test displaying bookmark create form without any external metadata retrieval attempt + */ + public function testDisplayCreateFormWithUrlAndWithoutMetadata(): void + { + $this->container->environment = [ + 'HTTP_REFERER' => $referer = 'http://shaarli/subfolder/controller/?searchtag=abc' + ]; + + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; + $expectedUrl = str_replace('&utm_ad=pay', '', $url); + + $request = $this->createMock(Request::class); + $request->method('getParam')->willReturnCallback(function (string $key) use ($url): ?string { + return $key === 'post' ? $url : null; + }); + $response = new Response(); + + $this->container->metadataRetriever->expects(static::never())->method('retrieve'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('bookmarksCountPerTag') + ->willReturn($tags = ['tag1' => 2, 'tag2' => 1]) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::atLeastOnce()) + ->method('executeHooks') + ->withConsecutive(['render_editlink'], ['render_includes']) + ->willReturnCallback(function (string $hook, array $data): array { + if ('render_editlink' === $hook) { + static::assertSame('', $data['link']['title']); + static::assertSame('', $data['link']['description']); + } + + return $data; + }) + ; + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + + static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); + + static::assertSame($expectedUrl, $assignedVariables['link']['url']); + static::assertSame('', $assignedVariables['link']['title']); + static::assertSame('', $assignedVariables['link']['description']); + static::assertSame('', $assignedVariables['link']['tags']); + static::assertFalse($assignedVariables['link']['private']); + + static::assertTrue($assignedVariables['link_is_new']); + static::assertSame($referer, $assignedVariables['http_referer']); + static::assertSame($tags, $assignedVariables['tags']); + static::assertArrayHasKey('source', $assignedVariables); + static::assertArrayHasKey('default_private_links', $assignedVariables); + static::assertArrayHasKey('async_metadata', $assignedVariables); + static::assertArrayHasKey('retrieve_description', $assignedVariables); + } + + /** + * Test displaying bookmark create form + * Ensure all available query parameters are handled properly. + */ + public function testDisplayCreateFormWithFullParameters(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $parameters = [ + 'post' => 'http://url.tld/other?part=3&utm_ad=pay#hash', + 'title' => 'Provided Title', + 'description' => 'Provided description.', + 'tags' => 'abc def', + 'private' => '1', + 'source' => 'apps', + ]; + $expectedUrl = str_replace('&utm_ad=pay', '', $parameters['post']); + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }); + $response = new Response(); + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + + static::assertSame('Shaare - Shaarli', $assignedVariables['pagetitle']); + + static::assertSame($expectedUrl, $assignedVariables['link']['url']); + static::assertSame($parameters['title'], $assignedVariables['link']['title']); + static::assertSame($parameters['description'], $assignedVariables['link']['description']); + static::assertSame($parameters['tags'], $assignedVariables['link']['tags']); + static::assertTrue($assignedVariables['link']['private']); + static::assertTrue($assignedVariables['link_is_new']); + static::assertSame($parameters['source'], $assignedVariables['source']); + } + + /** + * Test displaying bookmark create form + * Without any parameter. + */ + public function testDisplayCreateFormEmpty(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); + $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + static::assertSame('', $assignedVariables['link']['url']); + static::assertSame('Note: ', $assignedVariables['link']['title']); + static::assertSame('', $assignedVariables['link']['description']); + static::assertSame('', $assignedVariables['link']['tags']); + static::assertFalse($assignedVariables['link']['private']); + static::assertTrue($assignedVariables['link_is_new']); + } + + /** + * Test displaying bookmark create form + * URL not using HTTP protocol: do not try to retrieve the title + */ + public function testDisplayCreateFormNotHttp(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $url = 'magnet://kubuntu.torrent'; + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($url): ?string { + return $key === 'post' ? $url : null; + }); + $response = new Response(); + + $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); + $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + static::assertSame($url, $assignedVariables['link']['url']); + static::assertTrue($assignedVariables['link_is_new']); + } + + /** + * Test displaying bookmark create form + * When markdown formatter is enabled, the no markdown tag should be added to existing tags. + */ + public function testDisplayCreateFormWithMarkdownEnabled(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf + ->expects(static::atLeastOnce()) + ->method('get')->willReturnCallback(function (string $key): ?string { + if ($key === 'formatter') { + return 'markdown'; + } + + return $key; + }) + ; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + static::assertSame(['nomarkdown' => 1], $assignedVariables['tags']); + } + + /** + * Test displaying bookmark create form + * When an existing URL is submitted, we want to edit the existing link. + */ + public function testDisplayCreateFormWithExistingUrl(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $url = 'http://url.tld/other?part=3&utm_ad=pay#hash'; + $expectedUrl = str_replace('&utm_ad=pay', '', $url); + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($url): ?string { + return $key === 'post' ? $url : null; + }); + $response = new Response(); + + $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); + $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('findByUrl') + ->with($expectedUrl) + ->willReturn( + (new Bookmark()) + ->setId($id = 23) + ->setUrl($expectedUrl) + ->setTitle($title = 'Bookmark Title') + ->setDescription($description = 'Bookmark description.') + ->setTags($tags = ['abc', 'def']) + ->setPrivate(true) + ->setCreated($createdAt = new \DateTime('2020-06-10 18:45:44')) + ) + ; + + $result = $this->controller->displayCreateForm($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + + static::assertSame('Edit Shaare - Shaarli', $assignedVariables['pagetitle']); + static::assertFalse($assignedVariables['link_is_new']); + + static::assertSame($id, $assignedVariables['link']['id']); + static::assertSame($expectedUrl, $assignedVariables['link']['url']); + static::assertSame($title, $assignedVariables['link']['title']); + static::assertSame($description, $assignedVariables['link']['description']); + static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); + static::assertTrue($assignedVariables['link']['private']); + static::assertSame($createdAt, $assignedVariables['link']['created']); + } +} diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php new file mode 100644 index 00000000..da393e49 --- /dev/null +++ b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php @@ -0,0 +1,155 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaarePublishController($this->container); + } + + /** + * Test displaying bookmark edit form + * When an existing ID is provided, ensure that default workflow works properly. + */ + public function testDisplayEditFormDefault(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $id = 11; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->httpAccess->expects(static::never())->method('getHttpResponse'); + $this->container->httpAccess->expects(static::never())->method('getCurlDownloadCallback'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('get') + ->with($id) + ->willReturn( + (new Bookmark()) + ->setId($id) + ->setUrl($url = 'http://domain.tld') + ->setTitle($title = 'Bookmark Title') + ->setDescription($description = 'Bookmark description.') + ->setTags($tags = ['abc', 'def']) + ->setPrivate(true) + ->setCreated($createdAt = new \DateTime('2020-06-10 18:45:44')) + ) + ; + + $result = $this->controller->displayEditForm($request, $response, ['id' => (string) $id]); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('editlink', (string) $result->getBody()); + + static::assertSame('Edit Shaare - Shaarli', $assignedVariables['pagetitle']); + static::assertFalse($assignedVariables['link_is_new']); + + static::assertSame($id, $assignedVariables['link']['id']); + static::assertSame($url, $assignedVariables['link']['url']); + static::assertSame($title, $assignedVariables['link']['title']); + static::assertSame($description, $assignedVariables['link']['description']); + static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); + static::assertTrue($assignedVariables['link']['private']); + static::assertSame($createdAt, $assignedVariables['link']['created']); + } + + /** + * Test displaying bookmark edit form + * Invalid ID provided. + */ + public function testDisplayEditFormInvalidId(): void + { + $id = 'invalid'; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier invalid could not be found.']) + ; + + $result = $this->controller->displayEditForm($request, $response, ['id' => $id]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Test displaying bookmark edit form + * ID not provided. + */ + public function testDisplayEditFormIdNotProvided(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier could not be found.']) + ; + + $result = $this->controller->displayEditForm($request, $response, []); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } + + /** + * Test displaying bookmark edit form + * Bookmark not found. + */ + public function testDisplayEditFormBookmarkNotFound(): void + { + $id = 123; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('get') + ->with($id) + ->willThrowException(new BookmarkNotFoundException()) + ; + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_ERROR_MESSAGES, ['Bookmark with identifier 123 could not be found.']) + ; + + $result = $this->controller->displayEditForm($request, $response, ['id' => (string) $id]); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/'], $result->getHeader('location')); + } +} diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/SaveBookmarkTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/SaveBookmarkTest.php new file mode 100644 index 00000000..b6a861bc --- /dev/null +++ b/tests/front/controller/admin/ShaarePublishControllerTest/SaveBookmarkTest.php @@ -0,0 +1,369 @@ +createContainer(); + + $this->container->httpAccess = $this->createMock(HttpAccess::class); + $this->controller = new ShaarePublishController($this->container); + } + + /** + * Test save a new bookmark + */ + public function testSaveBookmark(): void + { + $id = 21; + $parameters = [ + 'lf_url' => 'http://url.tld/other?part=3#hash', + 'lf_title' => 'Provided Title', + 'lf_description' => 'Provided description.', + 'lf_tags' => 'abc def', + 'lf_private' => '1', + 'returnurl' => 'http://shaarli/subfolder/admin/add-shaare' + ]; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $checkBookmark = function (Bookmark $bookmark) use ($parameters) { + static::assertSame($parameters['lf_url'], $bookmark->getUrl()); + static::assertSame($parameters['lf_title'], $bookmark->getTitle()); + static::assertSame($parameters['lf_description'], $bookmark->getDescription()); + static::assertSame($parameters['lf_tags'], $bookmark->getTagsString()); + static::assertTrue($bookmark->isPrivate()); + }; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('addOrSet') + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { + static::assertFalse($save); + + $checkBookmark($bookmark); + + $bookmark->setId($id); + + return $bookmark; + }) + ; + $this->container->bookmarkService + ->expects(static::once()) + ->method('set') + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { + static::assertTrue($save); + + $checkBookmark($bookmark); + + static::assertSame($id, $bookmark->getId()); + + return $bookmark; + }) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::atLeastOnce()) + ->method('executeHooks') + ->withConsecutive(['save_link']) + ->willReturnCallback(function (string $hook, array $data) use ($parameters, $id): array { + if ('save_link' === $hook) { + static::assertSame($id, $data['id']); + static::assertSame($parameters['lf_url'], $data['url']); + static::assertSame($parameters['lf_title'], $data['title']); + static::assertSame($parameters['lf_description'], $data['description']); + static::assertSame($parameters['lf_tags'], $data['tags']); + static::assertTrue($data['private']); + } + + return $data; + }) + ; + + $result = $this->controller->save($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertRegExp('@/subfolder/#[\w\-]{6}@', $result->getHeader('location')[0]); + } + + + /** + * Test save an existing bookmark + */ + public function testSaveExistingBookmark(): void + { + $id = 21; + $parameters = [ + 'lf_id' => (string) $id, + 'lf_url' => 'http://url.tld/other?part=3#hash', + 'lf_title' => 'Provided Title', + 'lf_description' => 'Provided description.', + 'lf_tags' => 'abc def', + 'lf_private' => '1', + 'returnurl' => 'http://shaarli/subfolder/?page=2' + ]; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $checkBookmark = function (Bookmark $bookmark) use ($parameters, $id) { + static::assertSame($id, $bookmark->getId()); + static::assertSame($parameters['lf_url'], $bookmark->getUrl()); + static::assertSame($parameters['lf_title'], $bookmark->getTitle()); + static::assertSame($parameters['lf_description'], $bookmark->getDescription()); + static::assertSame($parameters['lf_tags'], $bookmark->getTagsString()); + static::assertTrue($bookmark->isPrivate()); + }; + + $this->container->bookmarkService->expects(static::atLeastOnce())->method('exists')->willReturn(true); + $this->container->bookmarkService + ->expects(static::once()) + ->method('get') + ->willReturn((new Bookmark())->setId($id)->setUrl('http://other.url')) + ; + $this->container->bookmarkService + ->expects(static::once()) + ->method('addOrSet') + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { + static::assertFalse($save); + + $checkBookmark($bookmark); + + return $bookmark; + }) + ; + $this->container->bookmarkService + ->expects(static::once()) + ->method('set') + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($checkBookmark, $id): Bookmark { + static::assertTrue($save); + + $checkBookmark($bookmark); + + static::assertSame($id, $bookmark->getId()); + + return $bookmark; + }) + ; + + // Make sure that PluginManager hook is triggered + $this->container->pluginManager + ->expects(static::atLeastOnce()) + ->method('executeHooks') + ->withConsecutive(['save_link']) + ->willReturnCallback(function (string $hook, array $data) use ($parameters, $id): array { + if ('save_link' === $hook) { + static::assertSame($id, $data['id']); + static::assertSame($parameters['lf_url'], $data['url']); + static::assertSame($parameters['lf_title'], $data['title']); + static::assertSame($parameters['lf_description'], $data['description']); + static::assertSame($parameters['lf_tags'], $data['tags']); + static::assertTrue($data['private']); + } + + return $data; + }) + ; + + $result = $this->controller->save($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertRegExp('@/subfolder/\?page=2#[\w\-]{6}@', $result->getHeader('location')[0]); + } + + /** + * Test save a bookmark - try to retrieve the thumbnail + */ + public function testSaveBookmarkWithThumbnailSync(): void + { + $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return false; + } + + return $default; + }); + + $this->container->thumbnailer = $this->createMock(Thumbnailer::class); + $this->container->thumbnailer + ->expects(static::once()) + ->method('get') + ->with($parameters['lf_url']) + ->willReturn($thumb = 'http://thumb.url') + ; + + $this->container->bookmarkService + ->expects(static::once()) + ->method('addOrSet') + ->willReturnCallback(function (Bookmark $bookmark, bool $save) use ($thumb): Bookmark { + static::assertSame($thumb, $bookmark->getThumbnail()); + + return $bookmark; + }) + ; + + $result = $this->controller->save($request, $response); + + static::assertSame(302, $result->getStatusCode()); + } + + /** + * Test save a bookmark - with ID #0 + */ + public function testSaveBookmarkWithIdZero(): void + { + $parameters = ['lf_id' => '0']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->bookmarkService->expects(static::once())->method('exists')->with(0)->willReturn(true); + $this->container->bookmarkService->expects(static::once())->method('get')->with(0)->willReturn(new Bookmark()); + + $result = $this->controller->save($request, $response); + + static::assertSame(302, $result->getStatusCode()); + } + + /** + * Test save a bookmark - do not attempt to retrieve thumbnails if async mode is enabled. + */ + public function testSaveBookmarkWithThumbnailAsync(): void + { + $parameters = ['lf_url' => 'http://url.tld/other?part=3#hash']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key, $default) { + if ($key === 'thumbnails.mode') { + return Thumbnailer::MODE_ALL; + } elseif ($key === 'general.enable_async_metadata') { + return true; + } + + return $default; + }); + + $this->container->thumbnailer = $this->createMock(Thumbnailer::class); + $this->container->thumbnailer->expects(static::never())->method('get'); + + $this->container->bookmarkService + ->expects(static::once()) + ->method('addOrSet') + ->willReturnCallback(function (Bookmark $bookmark): Bookmark { + static::assertNull($bookmark->getThumbnail()); + + return $bookmark; + }) + ; + + $result = $this->controller->save($request, $response); + + static::assertSame(302, $result->getStatusCode()); + } + + /** + * Change the password with a wrong existing password + */ + public function testSaveBookmarkFromBookmarklet(): void + { + $parameters = ['source' => 'bookmarklet']; + + $request = $this->createMock(Request::class); + $request + ->method('getParam') + ->willReturnCallback(function (string $key) use ($parameters): ?string { + return $parameters[$key] ?? null; + }) + ; + $response = new Response(); + + $result = $this->controller->save($request, $response); + + static::assertSame(200, $result->getStatusCode()); + static::assertSame('', (string) $result->getBody()); + } + + /** + * Change the password with a wrong existing password + */ + public function testSaveBookmarkWrongToken(): void + { + $this->container->sessionManager = $this->createMock(SessionManager::class); + $this->container->sessionManager->method('checkToken')->willReturn(false); + + $this->container->bookmarkService->expects(static::never())->method('addOrSet'); + $this->container->bookmarkService->expects(static::never())->method('set'); + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->expectException(WrongTokenException::class); + + $this->controller->save($request, $response); + } + +} -- cgit v1.2.3 From 34c8f558e595d4f90e46e3753c8455b0b515771a Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 23 Oct 2020 13:28:02 +0200 Subject: Bulk creation: ignore blank lines --- .../admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php index 34547120..ce8e112b 100644 --- a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php +++ b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateBatchFormTest.php @@ -36,6 +36,7 @@ class DisplayCreateBatchFormTest extends TestCase $urls = [ 'https://domain1.tld/url1', 'https://domain2.tld/url2', + ' ', 'https://domain3.tld/url3', ]; @@ -57,6 +58,6 @@ class DisplayCreateBatchFormTest extends TestCase static::assertCount(3, $assignedVariables['links']); static::assertSame($urls[0], $assignedVariables['links'][0]['link']['url']); static::assertSame($urls[1], $assignedVariables['links'][1]['link']['url']); - static::assertSame($urls[2], $assignedVariables['links'][2]['link']['url']); + static::assertSame($urls[3], $assignedVariables['links'][2]['link']['url']); } } -- cgit v1.2.3 From b862705947ff14f54023ba6d1cbead3435d0f234 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Mon, 2 Nov 2020 19:22:50 +0100 Subject: UT: fix formatting issue when the current day has a single digit --- tests/front/controller/visitor/DailyControllerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/front') diff --git a/tests/front/controller/visitor/DailyControllerTest.php b/tests/front/controller/visitor/DailyControllerTest.php index 758e7219..70fbce54 100644 --- a/tests/front/controller/visitor/DailyControllerTest.php +++ b/tests/front/controller/visitor/DailyControllerTest.php @@ -327,7 +327,7 @@ class DailyControllerTest extends TestCase static::assertSame(200, $result->getStatusCode()); static::assertSame('daily', (string) $result->getBody()); static::assertCount(0, $assignedVariables['linksToDisplay']); - static::assertSame('Today - ' . (new \DateTime())->format('F d, Y'), $assignedVariables['dayDesc']); + static::assertSame('Today - ' . (new \DateTime())->format('F j, Y'), $assignedVariables['dayDesc']); static::assertEquals((new \DateTime())->setTime(0, 0)->getTimestamp(), $assignedVariables['day']); static::assertEquals((new \DateTime())->setTime(0, 0), $assignedVariables['dayDate']); } -- cgit v1.2.3 From 330ac859fb13a3a15875f185a611bfaa6c5f5587 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 5 Nov 2020 16:14:22 +0100 Subject: Fix: redirect to referrer after bookmark deletion Except if the referer points to a permalink (which has been deleted). Fixes #1622 --- .../admin/ShaareManageControllerTest/DeleteBookmarkTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php index 770a16d7..a276d988 100644 --- a/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php +++ b/tests/front/controller/admin/ShaareManageControllerTest/DeleteBookmarkTest.php @@ -38,6 +38,8 @@ class DeleteBookmarkTest extends TestCase { $parameters = ['id' => '123']; + $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/shaare/abcdef'; + $request = $this->createMock(Request::class); $request ->method('getParam') @@ -90,6 +92,8 @@ class DeleteBookmarkTest extends TestCase { $parameters = ['id' => '123 456 789']; + $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/?searchtags=abcdef'; + $request = $this->createMock(Request::class); $request ->method('getParam') @@ -152,7 +156,7 @@ class DeleteBookmarkTest extends TestCase $result = $this->controller->deleteBookmark($request, $response); static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/subfolder/'], $result->getHeader('location')); + static::assertSame(['/subfolder/?searchtags=abcdef'], $result->getHeader('location')); } /** -- cgit v1.2.3 From b3bd8c3e8d367975980043e772f7cd78b7f96bc6 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 22 Oct 2020 16:21:03 +0200 Subject: Feature: support any tag separator So it allows to have multiple words tags. Breaking change: commas ',' are no longer a default separator. Fixes #594 --- .../controller/admin/ManageTagControllerTest.php | 136 +++++++++++++++++++++ .../DisplayCreateFormTest.php | 8 +- .../DisplayEditFormTest.php | 2 +- .../visitor/BookmarkListControllerTest.php | 6 +- .../visitor/FrontControllerMockHelper.php | 4 + .../controller/visitor/TagCloudControllerTest.php | 12 +- .../front/controller/visitor/TagControllerTest.php | 6 +- 7 files changed, 157 insertions(+), 17 deletions(-) (limited to 'tests/front') diff --git a/tests/front/controller/admin/ManageTagControllerTest.php b/tests/front/controller/admin/ManageTagControllerTest.php index 8a0ff7a9..af6f273f 100644 --- a/tests/front/controller/admin/ManageTagControllerTest.php +++ b/tests/front/controller/admin/ManageTagControllerTest.php @@ -6,6 +6,7 @@ namespace Shaarli\Front\Controller\Admin; use Shaarli\Bookmark\Bookmark; use Shaarli\Bookmark\BookmarkFilter; +use Shaarli\Config\ConfigManager; use Shaarli\Front\Exception\WrongTokenException; use Shaarli\Security\SessionManager; use Shaarli\TestCase; @@ -44,9 +45,32 @@ class ManageTagControllerTest extends TestCase static::assertSame('changetag', (string) $result->getBody()); static::assertSame('fromtag', $assignedVariables['fromtag']); + static::assertSame('@', $assignedVariables['tags_separator']); static::assertSame('Manage tags - Shaarli', $assignedVariables['pagetitle']); } + /** + * Test displaying manage tag page + */ + public function testIndexWhitespaceSeparator(): void + { + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $this->container->conf = $this->createMock(ConfigManager::class); + $this->container->conf->method('get')->willReturnCallback(function (string $key) { + return $key === 'general.tags_separator' ? ' ' : $key; + }); + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->controller->index($request, $response); + + static::assertSame(' ', $assignedVariables['tags_separator']); + static::assertSame('whitespace', $assignedVariables['tags_separator_desc']); + } + /** * Test posting a tag update - rename tag - valid info provided. */ @@ -269,4 +293,116 @@ class ManageTagControllerTest extends TestCase static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session); static::assertSame(['Invalid tags provided.'], $session[SessionManager::KEY_WARNING_MESSAGES]); } + + /** + * Test changeSeparator to '#': redirection + success message. + */ + public function testChangeSeparatorValid(): void + { + $toSeparator = '#'; + + $session = []; + $this->assignSessionVars($session); + + $request = $this->createMock(Request::class); + $request + ->expects(static::atLeastOnce()) + ->method('getParam') + ->willReturnCallback(function (string $key) use ($toSeparator): ?string { + return $key === 'separator' ? $toSeparator : $key; + }) + ; + $response = new Response(); + + $this->container->conf + ->expects(static::once()) + ->method('set') + ->with('general.tags_separator', $toSeparator, true, true) + ; + + $result = $this->controller->changeSeparator($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location')); + + static::assertArrayNotHasKey(SessionManager::KEY_ERROR_MESSAGES, $session); + static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session); + static::assertArrayHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session); + static::assertSame( + ['Your tags separator setting has been updated!'], + $session[SessionManager::KEY_SUCCESS_MESSAGES] + ); + } + + /** + * Test changeSeparator to '#@' (too long): redirection + error message. + */ + public function testChangeSeparatorInvalidTooLong(): void + { + $toSeparator = '#@'; + + $session = []; + $this->assignSessionVars($session); + + $request = $this->createMock(Request::class); + $request + ->expects(static::atLeastOnce()) + ->method('getParam') + ->willReturnCallback(function (string $key) use ($toSeparator): ?string { + return $key === 'separator' ? $toSeparator : $key; + }) + ; + $response = new Response(); + + $this->container->conf->expects(static::never())->method('set'); + + $result = $this->controller->changeSeparator($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location')); + + static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session); + static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session); + static::assertArrayHasKey(SessionManager::KEY_ERROR_MESSAGES, $session); + static::assertSame( + ['Tags separator must be a single character.'], + $session[SessionManager::KEY_ERROR_MESSAGES] + ); + } + + /** + * Test changeSeparator to '#@' (too long): redirection + error message. + */ + public function testChangeSeparatorInvalidReservedCharacter(): void + { + $toSeparator = '*'; + + $session = []; + $this->assignSessionVars($session); + + $request = $this->createMock(Request::class); + $request + ->expects(static::atLeastOnce()) + ->method('getParam') + ->willReturnCallback(function (string $key) use ($toSeparator): ?string { + return $key === 'separator' ? $toSeparator : $key; + }) + ; + $response = new Response(); + + $this->container->conf->expects(static::never())->method('set'); + + $result = $this->controller->changeSeparator($request, $response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/admin/tags'], $result->getHeader('location')); + + static::assertArrayNotHasKey(SessionManager::KEY_SUCCESS_MESSAGES, $session); + static::assertArrayNotHasKey(SessionManager::KEY_WARNING_MESSAGES, $session); + static::assertArrayHasKey(SessionManager::KEY_ERROR_MESSAGES, $session); + static::assertStringStartsWith( + 'These characters are reserved and can\'t be used as tags separator', + $session[SessionManager::KEY_ERROR_MESSAGES][0] + ); + } } diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php index f20b1def..964773da 100644 --- a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php +++ b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayCreateFormTest.php @@ -101,7 +101,7 @@ class DisplayCreateFormTest extends TestCase static::assertSame($expectedUrl, $assignedVariables['link']['url']); static::assertSame($remoteTitle, $assignedVariables['link']['title']); static::assertSame($remoteDesc, $assignedVariables['link']['description']); - static::assertSame($remoteTags, $assignedVariables['link']['tags']); + static::assertSame($remoteTags . ' ', $assignedVariables['link']['tags']); static::assertFalse($assignedVariables['link']['private']); static::assertTrue($assignedVariables['link_is_new']); @@ -192,7 +192,7 @@ class DisplayCreateFormTest extends TestCase 'post' => 'http://url.tld/other?part=3&utm_ad=pay#hash', 'title' => 'Provided Title', 'description' => 'Provided description.', - 'tags' => 'abc def', + 'tags' => 'abc@def', 'private' => '1', 'source' => 'apps', ]; @@ -216,7 +216,7 @@ class DisplayCreateFormTest extends TestCase static::assertSame($expectedUrl, $assignedVariables['link']['url']); static::assertSame($parameters['title'], $assignedVariables['link']['title']); static::assertSame($parameters['description'], $assignedVariables['link']['description']); - static::assertSame($parameters['tags'], $assignedVariables['link']['tags']); + static::assertSame($parameters['tags'] . '@', $assignedVariables['link']['tags']); static::assertTrue($assignedVariables['link']['private']); static::assertTrue($assignedVariables['link_is_new']); static::assertSame($parameters['source'], $assignedVariables['source']); @@ -360,7 +360,7 @@ class DisplayCreateFormTest extends TestCase static::assertSame($expectedUrl, $assignedVariables['link']['url']); static::assertSame($title, $assignedVariables['link']['title']); static::assertSame($description, $assignedVariables['link']['description']); - static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); + static::assertSame(implode('@', $tags) . '@', $assignedVariables['link']['tags']); static::assertTrue($assignedVariables['link']['private']); static::assertSame($createdAt, $assignedVariables['link']['created']); } diff --git a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php index da393e49..738cea12 100644 --- a/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php +++ b/tests/front/controller/admin/ShaarePublishControllerTest/DisplayEditFormTest.php @@ -74,7 +74,7 @@ class DisplayEditFormTest extends TestCase static::assertSame($url, $assignedVariables['link']['url']); static::assertSame($title, $assignedVariables['link']['title']); static::assertSame($description, $assignedVariables['link']['description']); - static::assertSame(implode(' ', $tags), $assignedVariables['link']['tags']); + static::assertSame(implode('@', $tags) . '@', $assignedVariables['link']['tags']); static::assertTrue($assignedVariables['link']['private']); static::assertSame($createdAt, $assignedVariables['link']['created']); } diff --git a/tests/front/controller/visitor/BookmarkListControllerTest.php b/tests/front/controller/visitor/BookmarkListControllerTest.php index 5cbc8c73..dec938f2 100644 --- a/tests/front/controller/visitor/BookmarkListControllerTest.php +++ b/tests/front/controller/visitor/BookmarkListControllerTest.php @@ -173,7 +173,7 @@ class BookmarkListControllerTest extends TestCase $request = $this->createMock(Request::class); $request->method('getParam')->willReturnCallback(function (string $key) { if ('searchtags' === $key) { - return 'abc def'; + return 'abc@def'; } if ('searchterm' === $key) { return 'ghi jkl'; @@ -204,7 +204,7 @@ class BookmarkListControllerTest extends TestCase ->expects(static::once()) ->method('search') ->with( - ['searchtags' => 'abc def', 'searchterm' => 'ghi jkl'], + ['searchtags' => 'abc@def', 'searchterm' => 'ghi jkl'], 'private', false, true @@ -222,7 +222,7 @@ class BookmarkListControllerTest extends TestCase static::assertSame('linklist', (string) $result->getBody()); static::assertSame('Search: ghi jkl [abc] [def] - Shaarli', $assignedVariables['pagetitle']); - static::assertSame('?page=2&searchterm=ghi+jkl&searchtags=abc+def', $assignedVariables['previous_page_url']); + static::assertSame('?page=2&searchterm=ghi+jkl&searchtags=abc%40def', $assignedVariables['previous_page_url']); } /** diff --git a/tests/front/controller/visitor/FrontControllerMockHelper.php b/tests/front/controller/visitor/FrontControllerMockHelper.php index fc0bb7d1..02229f68 100644 --- a/tests/front/controller/visitor/FrontControllerMockHelper.php +++ b/tests/front/controller/visitor/FrontControllerMockHelper.php @@ -41,6 +41,10 @@ trait FrontControllerMockHelper // Config $this->container->conf = $this->createMock(ConfigManager::class); $this->container->conf->method('get')->willReturnCallback(function (string $parameter, $default) { + if ($parameter === 'general.tags_separator') { + return '@'; + } + return $default === null ? $parameter : $default; }); diff --git a/tests/front/controller/visitor/TagCloudControllerTest.php b/tests/front/controller/visitor/TagCloudControllerTest.php index 9305612e..4915573d 100644 --- a/tests/front/controller/visitor/TagCloudControllerTest.php +++ b/tests/front/controller/visitor/TagCloudControllerTest.php @@ -100,7 +100,7 @@ class TagCloudControllerTest extends TestCase ->with() ->willReturnCallback(function (string $key): ?string { if ('searchtags' === $key) { - return 'ghi def'; + return 'ghi@def'; } return null; @@ -131,7 +131,7 @@ class TagCloudControllerTest extends TestCase ->withConsecutive(['render_tagcloud']) ->willReturnCallback(function (string $hook, array $data, array $param): array { if ('render_tagcloud' === $hook) { - static::assertSame('ghi def', $data['search_tags']); + static::assertSame('ghi@def@', $data['search_tags']); static::assertCount(1, $data['tags']); static::assertArrayHasKey('loggedin', $param); @@ -147,7 +147,7 @@ class TagCloudControllerTest extends TestCase static::assertSame('tag.cloud', (string) $result->getBody()); static::assertSame('ghi def - Tag cloud - Shaarli', $assignedVariables['pagetitle']); - static::assertSame('ghi def', $assignedVariables['search_tags']); + static::assertSame('ghi@def@', $assignedVariables['search_tags']); static::assertCount(1, $assignedVariables['tags']); static::assertArrayHasKey('abc', $assignedVariables['tags']); @@ -277,7 +277,7 @@ class TagCloudControllerTest extends TestCase ->with() ->willReturnCallback(function (string $key): ?string { if ('searchtags' === $key) { - return 'ghi def'; + return 'ghi@def'; } elseif ('sort' === $key) { return 'alpha'; } @@ -310,7 +310,7 @@ class TagCloudControllerTest extends TestCase ->withConsecutive(['render_taglist']) ->willReturnCallback(function (string $hook, array $data, array $param): array { if ('render_taglist' === $hook) { - static::assertSame('ghi def', $data['search_tags']); + static::assertSame('ghi@def@', $data['search_tags']); static::assertCount(1, $data['tags']); static::assertArrayHasKey('loggedin', $param); @@ -326,7 +326,7 @@ class TagCloudControllerTest extends TestCase static::assertSame('tag.list', (string) $result->getBody()); static::assertSame('ghi def - Tag list - Shaarli', $assignedVariables['pagetitle']); - static::assertSame('ghi def', $assignedVariables['search_tags']); + static::assertSame('ghi@def@', $assignedVariables['search_tags']); static::assertCount(1, $assignedVariables['tags']); static::assertSame(3, $assignedVariables['tags']['abc']); } diff --git a/tests/front/controller/visitor/TagControllerTest.php b/tests/front/controller/visitor/TagControllerTest.php index 750ea02d..5a556c6d 100644 --- a/tests/front/controller/visitor/TagControllerTest.php +++ b/tests/front/controller/visitor/TagControllerTest.php @@ -50,7 +50,7 @@ class TagControllerTest extends TestCase static::assertInstanceOf(Response::class, $result); static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/controller/?searchtags=def+abc'], $result->getHeader('location')); + static::assertSame(['/controller/?searchtags=def%40abc'], $result->getHeader('location')); } public function testAddTagWithoutRefererAndExistingSearch(): void @@ -80,7 +80,7 @@ class TagControllerTest extends TestCase static::assertInstanceOf(Response::class, $result); static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/controller/?searchtags=def+abc'], $result->getHeader('location')); + static::assertSame(['/controller/?searchtags=def%40abc'], $result->getHeader('location')); } public function testAddTagResetPagination(): void @@ -96,7 +96,7 @@ class TagControllerTest extends TestCase static::assertInstanceOf(Response::class, $result); static::assertSame(302, $result->getStatusCode()); - static::assertSame(['/controller/?searchtags=def+abc'], $result->getHeader('location')); + static::assertSame(['/controller/?searchtags=def%40abc'], $result->getHeader('location')); } public function testAddTagWithRefererAndEmptySearch(): void -- cgit v1.2.3 From cfdd2094407e61f371c02117c8c66916a6d1d807 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 5 Nov 2020 19:45:41 +0100 Subject: Display error details even with dev.debug set to false It makes more sense to display the error even if it's unexpected. Only for logged in users. Fixes #1606 --- .../controller/visitor/ErrorControllerTest.php | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'tests/front') diff --git a/tests/front/controller/visitor/ErrorControllerTest.php b/tests/front/controller/visitor/ErrorControllerTest.php index 75408cf4..e18a6fa2 100644 --- a/tests/front/controller/visitor/ErrorControllerTest.php +++ b/tests/front/controller/visitor/ErrorControllerTest.php @@ -50,7 +50,31 @@ class ErrorControllerTest extends TestCase } /** - * Test displaying error with any exception (no debug): only display an error occurred with HTTP 500. + * Test displaying error with any exception (no debug) while logged in: + * display full error details + */ + public function testDisplayAnyExceptionErrorNoDebugLoggedIn(): void + { + $request = $this->createMock(Request::class); + $response = new Response(); + + // Save RainTPL assigned variables + $assignedVariables = []; + $this->assignTemplateVars($assignedVariables); + + $this->container->loginManager->method('isLoggedIn')->willReturn(true); + + $result = ($this->controller)($request, $response, new \Exception('abc')); + + static::assertSame(500, $result->getStatusCode()); + static::assertSame('Error: abc', $assignedVariables['message']); + static::assertContainsPolyfill('Please report it on Github', $assignedVariables['text']); + static::assertArrayHasKey('stacktrace', $assignedVariables); + } + + /** + * Test displaying error with any exception (no debug) while logged out: + * display standard error without detail */ public function testDisplayAnyExceptionErrorNoDebug(): void { @@ -61,10 +85,13 @@ class ErrorControllerTest extends TestCase $assignedVariables = []; $this->assignTemplateVars($assignedVariables); + $this->container->loginManager->method('isLoggedIn')->willReturn(false); + $result = ($this->controller)($request, $response, new \Exception('abc')); static::assertSame(500, $result->getStatusCode()); static::assertSame('An unexpected error occurred.', $assignedVariables['message']); + static::assertArrayNotHasKey('text', $assignedVariables); static::assertArrayNotHasKey('stacktrace', $assignedVariables); } } -- cgit v1.2.3