createContainer(); $this->controller = new BookmarkListController($this->container); } /** * Test rendering list of bookmarks with default parameters (first page). */ public function testIndexDefaultFirstPage(): void { $assignedVariables = []; $this->assignTemplateVars($assignedVariables); $request = $this->createMock(Request::class); $response = new Response(); $this->container->bookmarkService ->expects(static::once()) ->method('search') ->with( ['searchtags' => '', 'searchterm' => ''], null, false, false, false, ['offset' => 0, 'limit' => 2] ) ->willReturn(SearchResult::getSearchResult([ (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), ], 0, 2) ); $this->container->sessionManager ->method('getSessionParameter') ->willReturnCallback(function (string $parameter, $default = null) { if ('LINKS_PER_PAGE' === $parameter) { return 2; } return $default; }) ; $result = $this->controller->index($request, $response); static::assertSame(200, $result->getStatusCode()); static::assertSame('linklist', (string) $result->getBody()); static::assertSame('Shaarli', $assignedVariables['pagetitle']); static::assertSame('?page=2', $assignedVariables['previous_page_url']); static::assertSame('', $assignedVariables['next_page_url']); static::assertSame(2, $assignedVariables['page_max']); static::assertSame('', $assignedVariables['search_tags']); static::assertSame(3, $assignedVariables['result_count']); static::assertSame(1, $assignedVariables['page_current']); static::assertSame('', $assignedVariables['search_term']); static::assertNull($assignedVariables['visibility']); static::assertCount(2, $assignedVariables['links']); $link = $assignedVariables['links'][0]; static::assertSame(1, $link['id']); static::assertSame('http://url1.tld', $link['url']); static::assertSame('Title 1', $link['title']); $link = $assignedVariables['links'][1]; static::assertSame(2, $link['id']); static::assertSame('http://url2.tld', $link['url']); static::assertSame('Title 2', $link['title']); } /** * Test rendering list of bookmarks with default parameters (second page). */ public function testIndexDefaultSecondPage(): void { $assignedVariables = []; $this->assignTemplateVars($assignedVariables); $request = $this->createMock(Request::class); $request->method('getParam')->willReturnCallback(function (string $key) { if ('page' === $key) { return '2'; } return null; }); $response = new Response(); $this->container->bookmarkService ->expects(static::once()) ->method('search') ->with( ['searchtags' => '', 'searchterm' => ''], null, false, false, false, ['offset' => 2, 'limit' => 2] ) ->willReturn(SearchResult::getSearchResult([ (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), ], 2, 2)) ; $this->container->sessionManager ->method('getSessionParameter') ->willReturnCallback(function (string $parameter, $default = null) { if ('LINKS_PER_PAGE' === $parameter) { return 2; } return $default; }) ; $result = $this->controller->index($request, $response); static::assertSame(200, $result->getStatusCode()); static::assertSame('linklist', (string) $result->getBody()); static::assertSame('Shaarli', $assignedVariables['pagetitle']); static::assertSame('', $assignedVariables['previous_page_url']); static::assertSame('?page=1', $assignedVariables['next_page_url']); static::assertSame(2, $assignedVariables['page_max']); static::assertSame('', $assignedVariables['search_tags']); static::assertSame(3, $assignedVariables['result_count']); static::assertSame(2, $assignedVariables['page_current']); static::assertSame('', $assignedVariables['search_term']); static::assertNull($assignedVariables['visibility']); static::assertCount(1, $assignedVariables['links']); $link = $assignedVariables['links'][2]; static::assertSame(3, $link['id']); static::assertSame('http://url3.tld', $link['url']); static::assertSame('Title 3', $link['title']); } /** * Test rendering list of bookmarks with filters. */ public function testIndexDefaultWithFilters(): void { $assignedVariables = []; $this->assignTemplateVars($assignedVariables); $request = $this->createMock(Request::class); $request->method('getParam')->willReturnCallback(function (string $key) { if ('searchtags' === $key) { return 'abc@def'; } if ('searchterm' === $key) { return 'ghi jkl'; } return null; }); $response = new Response(); $this->container->sessionManager ->method('getSessionParameter') ->willReturnCallback(function (string $key, $default) { if ('LINKS_PER_PAGE' === $key) { return 2; } if ('visibility' === $key) { return 'private'; } if ('untaggedonly' === $key) { return true; } return $default; }) ; $this->container->bookmarkService ->expects(static::once()) ->method('search') ->with( ['searchtags' => 'abc@def', 'searchterm' => 'ghi jkl'], 'private', false, true, false, ['offset' => 0, 'limit' => 2] ) ->willReturn(SearchResult::getSearchResult([ (new Bookmark())->setId(1)->setUrl('http://url1.tld')->setTitle('Title 1'), (new Bookmark())->setId(2)->setUrl('http://url2.tld')->setTitle('Title 2'), (new Bookmark())->setId(3)->setUrl('http://url3.tld')->setTitle('Title 3'), ], 0, 2)) ; $result = $this->controller->index($request, $response); static::assertSame(200, $result->getStatusCode()); 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%40def', $assignedVariables['previous_page_url']); } /** * Test displaying a permalink with valid parameters */ public function testPermalinkValid(): void { $hash = 'abcdef'; $assignedVariables = []; $this->assignTemplateVars($assignedVariables); $request = $this->createMock(Request::class); $response = new Response(); $this->container->bookmarkService ->expects(static::once()) ->method('findByHash') ->with($hash) ->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::assertSame('Title 1 - Shaarli', $assignedVariables['pagetitle']); static::assertCount(1, $assignedVariables['links']); $link = $assignedVariables['links'][0]; static::assertSame(123, $link['id']); static::assertSame('http://url1.tld', $link['url']); static::assertSame('Title 1', $link['title']); } /** * Test displaying a permalink with an unknown small hash : renders a 404 template error */ public function testPermalinkNotFound(): void { $hash = 'abcdef'; $assignedVariables = []; $this->assignTemplateVars($assignedVariables); $request = $this->createMock(Request::class); $response = new Response(); $this->container->bookmarkService ->expects(static::once()) ->method('findByHash') ->with($hash) ->willThrowException(new BookmarkNotFoundException()) ; $result = $this->controller->permalink($request, $response, ['hash' => $hash]); static::assertSame(200, $result->getStatusCode()); static::assertSame('404', (string) $result->getBody()); static::assertSame( 'The link you are trying to reach does not exist or has been deleted.', $assignedVariables['error_message'] ); } /** * 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 */ public function testThumbnailUpdateFromLinkList(): 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 false; } return $default; }) ; $this->container->thumbnailer = $this->createMock(Thumbnailer::class); $this->container->thumbnailer ->expects(static::exactly(2)) ->method('get') ->withConsecutive(['https://url2.tld'], ['https://url4.tld']) ; $this->container->bookmarkService ->expects(static::once()) ->method('search') ->willReturn(SearchResult::getSearchResult([ (new Bookmark())->setId(1)->setUrl('https://url1.tld')->setTitle('Title 1')->setThumbnail(false), $b1 = (new Bookmark())->setId(2)->setUrl('https://url2.tld')->setTitle('Title 2'), (new Bookmark())->setId(3)->setUrl('https://url3.tld')->setTitle('Title 3')->setThumbnail(false), $b2 = (new Bookmark())->setId(2)->setUrl('https://url4.tld')->setTitle('Title 4'), (new Bookmark())->setId(2)->setUrl('ftp://url5.tld', ['ftp'])->setTitle('Title 5'), ])) ; $this->container->bookmarkService ->expects(static::exactly(2)) ->method('set') ->withConsecutive([$b1, false], [$b2, false]) ; $this->container->bookmarkService->expects(static::once())->method('save'); $result = $this->controller->index($request, $response); static::assertSame(200, $result->getStatusCode()); static::assertSame('linklist', (string) $result->getBody()); } /** * Test getting a permalink with thumbnail update. */ public function testThumbnailUpdateFromPermalink(): 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 false; } return $default; }) ; $this->container->thumbnailer = $this->createMock(Thumbnailer::class); $this->container->thumbnailer->expects(static::once())->method('get')->withConsecutive(['https://url.tld']); $this->container->bookmarkService ->expects(static::once()) ->method('findByHash') ->willReturn($bookmark = (new Bookmark())->setId(2)->setUrl('https://url.tld')->setTitle('Title 1')) ; $this->container->bookmarkService->expects(static::once())->method('set')->with($bookmark, true); $this->container->bookmarkService->expects(static::never())->method('save'); $result = $this->controller->permalink($request, $response, ['hash' => 'abc']); static::assertSame(200, $result->getStatusCode()); 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 */ public function testLegacyControllerPermalink(): void { $hash = 'abcdef'; $this->container->environment['QUERY_STRING'] = $hash; $request = $this->createMock(Request::class); $response = new Response(); $result = $this->controller->index($request, $response); static::assertSame(302, $result->getStatusCode()); static::assertSame('/subfolder/shaare/' . $hash, $result->getHeader('location')[0]); } /** * Trigger legacy controller in link list controller: ?do= query parameter */ public function testLegacyControllerDoPage(): void { $request = $this->createMock(Request::class); $request->method('getQueryParam')->with('do')->willReturn('picwall'); $response = new Response(); $result = $this->controller->index($request, $response); static::assertSame(302, $result->getStatusCode()); static::assertSame('/subfolder/picture-wall', $result->getHeader('location')[0]); } /** * Trigger legacy controller in link list controller: ?do= query parameter with unknown legacy route */ public function testLegacyControllerUnknownDoPage(): void { $request = $this->createMock(Request::class); $request->method('getQueryParam')->with('do')->willReturn('nope'); $response = new Response(); $result = $this->controller->index($request, $response); static::assertSame(200, $result->getStatusCode()); static::assertSame('linklist', (string) $result->getBody()); } /** * Trigger legacy controller in link list controller: other GET route (e.g. ?post) */ public function testLegacyControllerGetParameter(): void { $request = $this->createMock(Request::class); $request->method('getQueryParams')->willReturn(['post' => $url = 'http://url.tld']); $response = new Response(); $this->container->loginManager = $this->createMock(LoginManager::class); $this->container->loginManager->method('isLoggedIn')->willReturn(true); $result = $this->controller->index($request, $response); static::assertSame(302, $result->getStatusCode()); static::assertSame( '/subfolder/admin/shaare?post=' . urlencode($url), $result->getHeader('location')[0] ); } }