From af290059d10319e76d1e7d78b592cab99c26d91a Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 22 May 2020 11:02:56 +0200 Subject: Process session filters through Slim controllers Including: - visibility - links per page - untagged only --- .../controller/SessionFilterControllerTest.php | 290 +++++++++++++++++++++ tests/front/controller/ShaarliControllerTest.php | 131 ++++++++++ 2 files changed, 421 insertions(+) create mode 100644 tests/front/controller/SessionFilterControllerTest.php (limited to 'tests/front') diff --git a/tests/front/controller/SessionFilterControllerTest.php b/tests/front/controller/SessionFilterControllerTest.php new file mode 100644 index 00000000..f541de03 --- /dev/null +++ b/tests/front/controller/SessionFilterControllerTest.php @@ -0,0 +1,290 @@ +createContainer(); + + $this->controller = new SessionFilterController($this->container); + } + + /** + * Link per page - Default call with valid parameter and a referer. + */ + public function testLinksPerPage(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $request = $this->createMock(Request::class); + $request->method('getParam')->with('nb')->willReturn('8'); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_LINKS_PER_PAGE, 8) + ; + + $result = $this->controller->linksPerPage($request, $response); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } + + /** + * Link per page - Invalid value, should use default value (20) + */ + public function testLinksPerPageNotValid(): void + { + $this->createValidContainerMockSet(); + + $request = $this->createMock(Request::class); + $request->method('getParam')->with('nb')->willReturn('test'); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_LINKS_PER_PAGE, 20) + ; + + $result = $this->controller->linksPerPage($request, $response); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['./'], $result->getHeader('location')); + } + + /** + * Visibility - Default call for private filter while logged in without current value + */ + public function testVisibility(): void + { + $this->createValidContainerMockSet(); + + $arg = ['visibility' => 'private']; + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $this->container->loginManager->method('isLoggedIn')->willReturn(true); + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_VISIBILITY, 'private') + ; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $result = $this->controller->visibility($request, $response, $arg); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } + + /** + * Visibility - Toggle off private visibility + */ + public function testVisibilityToggleOff(): void + { + $this->createValidContainerMockSet(); + + $arg = ['visibility' => 'private']; + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $this->container->loginManager->method('isLoggedIn')->willReturn(true); + $this->container->sessionManager + ->method('getSessionParameter') + ->with(SessionManager::KEY_VISIBILITY) + ->willReturn('private') + ; + $this->container->sessionManager + ->expects(static::never()) + ->method('setSessionParameter') + ; + $this->container->sessionManager + ->expects(static::once()) + ->method('deleteSessionParameter') + ->with(SessionManager::KEY_VISIBILITY) + ; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $result = $this->controller->visibility($request, $response, $arg); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } + + /** + * Visibility - Change private to public + */ + public function testVisibilitySwitch(): void + { + $this->createValidContainerMockSet(); + + $arg = ['visibility' => 'private']; + + $this->container->loginManager->method('isLoggedIn')->willReturn(true); + $this->container->sessionManager + ->method('getSessionParameter') + ->with(SessionManager::KEY_VISIBILITY) + ->willReturn('public') + ; + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_VISIBILITY, 'private') + ; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $result = $this->controller->visibility($request, $response, $arg); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['./'], $result->getHeader('location')); + } + + /** + * Visibility - With invalid value - should remove any visibility setting + */ + public function testVisibilityInvalidValue(): void + { + $this->createValidContainerMockSet(); + + $arg = ['visibility' => 'test']; + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $this->container->loginManager->method('isLoggedIn')->willReturn(true); + $this->container->sessionManager + ->expects(static::never()) + ->method('setSessionParameter') + ; + $this->container->sessionManager + ->expects(static::once()) + ->method('deleteSessionParameter') + ->with(SessionManager::KEY_VISIBILITY) + ; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $result = $this->controller->visibility($request, $response, $arg); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } + + /** + * Visibility - Try to change visibility while logged out + */ + public function testVisibilityLoggedOut(): void + { + $this->createValidContainerMockSet(); + + $arg = ['visibility' => 'test']; + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $this->container->loginManager->method('isLoggedIn')->willReturn(false); + $this->container->sessionManager + ->expects(static::never()) + ->method('setSessionParameter') + ; + $this->container->sessionManager + ->expects(static::never()) + ->method('deleteSessionParameter') + ->with(SessionManager::KEY_VISIBILITY) + ; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $result = $this->controller->visibility($request, $response, $arg); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } + + /** + * Untagged only - valid call + */ + public function testUntaggedOnly(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_UNTAGGED_ONLY, true) + ; + + $result = $this->controller->untaggedOnly($request, $response); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } + + /** + * Untagged only - toggle off + */ + public function testUntaggedOnlyToggleOff(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; + + $request = $this->createMock(Request::class); + $response = new Response(); + + $this->container->sessionManager + ->method('getSessionParameter') + ->with(SessionManager::KEY_UNTAGGED_ONLY) + ->willReturn(true) + ; + $this->container->sessionManager + ->expects(static::once()) + ->method('setSessionParameter') + ->with(SessionManager::KEY_UNTAGGED_ONLY, false) + ; + + $result = $this->controller->untaggedOnly($request, $response); + + static::assertInstanceOf(Response::class, $result); + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller/?searchtag=abc'], $result->getHeader('location')); + } +} diff --git a/tests/front/controller/ShaarliControllerTest.php b/tests/front/controller/ShaarliControllerTest.php index 3efe4d95..a6011b49 100644 --- a/tests/front/controller/ShaarliControllerTest.php +++ b/tests/front/controller/ShaarliControllerTest.php @@ -6,6 +6,7 @@ namespace Shaarli\Front\Controller; use PHPUnit\Framework\TestCase; use Shaarli\Bookmark\BookmarkFilter; +use Slim\Http\Response; /** * Class ShaarliControllerTest @@ -38,6 +39,14 @@ class ShaarliControllerTest extends TestCase { return parent::render($template); } + + public function redirectFromReferer( + Response $response, + array $loopTerms = [], + array $clearParams = [] + ): Response { + return parent::redirectFromReferer($response, $loopTerms, $clearParams); + } }; $this->assignedValues = []; } @@ -91,4 +100,126 @@ class ShaarliControllerTest extends TestCase static::assertSame('templateName', $this->assignedValues['plugins_footer']['render_footer']['target']); static::assertTrue($this->assignedValues['plugins_footer']['render_footer']['loggedin']); } + + /** + * Test redirectFromReferer() - Default behaviour + */ + public function testRedirectFromRefererDefault(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); + } + + /** + * Test redirectFromReferer() - With a loop term not matched in the referer + */ + public function testRedirectFromRefererWithUnmatchedLoopTerm(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response, ['nope']); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); + } + + /** + * Test redirectFromReferer() - With a loop term matching the referer in its path -> redirect to default + */ + public function testRedirectFromRefererWithMatchingLoopTermInPath(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response, ['nope', 'controller']); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['./'], $result->getHeader('location')); + } + + /** + * Test redirectFromReferer() - With a loop term matching the referer in its query parameters -> redirect to default + */ + public function testRedirectFromRefererWithMatchingLoopTermInQueryParam(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response, ['nope', 'other']); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['./'], $result->getHeader('location')); + } + + /** + * Test redirectFromReferer() - With a loop term matching the referer in its query value + * -> we do not block redirection for query parameter values. + */ + public function testRedirectFromRefererWithMatchingLoopTermInQueryValue(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response, ['nope', 'param']); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); + } + + /** + * Test redirectFromReferer() - With a loop term matching the referer in its domain name + * -> we do not block redirection for shaarli's hosts + */ + public function testRedirectFromRefererWithLoopTermInDomain(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response, ['shaarli']); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); + } + + /** + * Test redirectFromReferer() - With a loop term matching a query parameter AND clear this query param + * -> the param should be cleared before checking if it matches the redir loop terms + */ + public function testRedirectFromRefererWithMatchingClearedParam(): void + { + $this->createValidContainerMockSet(); + + $this->container->environment['HTTP_REFERER'] = 'http://shaarli.tld/subfolder/controller?query=param&other=2'; + + $response = new Response(); + + $result = $this->controller->redirectFromReferer($response, ['query'], ['query']); + + static::assertSame(302, $result->getStatusCode()); + static::assertSame(['/subfolder/controller?other=2'], $result->getHeader('location')); + } } -- cgit v1.2.3