createContainer(); $this->controller = new class($this->container) extends ShaarliVisitorController { public function assignView(string $key, $value): ShaarliVisitorController { return parent::assignView($key, $value); } public function render(string $template): string { return parent::render($template); } public function redirectFromReferer( Request $request, Response $response, array $loopTerms = [], array $clearParams = [], string $anchor = null ): Response { return parent::redirectFromReferer($request, $response, $loopTerms, $clearParams, $anchor); } }; $this->assignedValues = []; $this->request = $this->createMock(Request::class); } public function testAssignView(): void { $this->assignTemplateVars($this->assignedValues); $self = $this->controller->assignView('variableName', 'variableValue'); static::assertInstanceOf(ShaarliVisitorController::class, $self); static::assertSame('variableValue', $this->assignedValues['variableName']); } public function testRender(): void { $this->assignTemplateVars($this->assignedValues); $this->container->bookmarkService ->method('count') ->willReturnCallback(function (string $visibility): int { return $visibility === BookmarkFilter::$PRIVATE ? 5 : 10; }) ; $this->container->pluginManager ->method('executeHooks') ->willReturnCallback(function (string $hook, array &$data, array $params): array { return $data[$hook] = $params; }); $this->container->pluginManager->method('getErrors')->willReturn(['error']); $this->container->loginManager->method('isLoggedIn')->willReturn(true); $render = $this->controller->render('templateName'); static::assertSame('templateName', $render); static::assertSame('templateName', $this->assignedValues['_PAGE_']); static::assertSame('templateName', $this->assignedValues['template']); static::assertSame(10, $this->assignedValues['linkcount']); static::assertSame(5, $this->assignedValues['privateLinkcount']); static::assertSame(['error'], $this->assignedValues['plugin_errors']); static::assertSame('templateName', $this->assignedValues['plugins_includes']['render_includes']['target']); static::assertTrue($this->assignedValues['plugins_includes']['render_includes']['loggedin']); static::assertSame('templateName', $this->assignedValues['plugins_header']['render_header']['target']); static::assertTrue($this->assignedValues['plugins_header']['render_header']['loggedin']); 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->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $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->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $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->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $response, ['nope', 'controller']); static::assertSame(302, $result->getStatusCode()); static::assertSame(['/subfolder/'], $result->getHeader('location')); } /** * Test redirectFromReferer() - With a loop term matching the referer in its query parameters -> redirect to default */ public function testRedirectFromRefererWithMatchingLoopTermInQueryParam(): void { $this->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $response, ['nope', 'other']); static::assertSame(302, $result->getStatusCode()); static::assertSame(['/subfolder/'], $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->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $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->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $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->container->environment['HTTP_REFERER'] = 'http://shaarli/subfolder/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $response, ['query'], ['query']); static::assertSame(302, $result->getStatusCode()); static::assertSame(['/subfolder/controller?other=2'], $result->getHeader('location')); } /** * Test redirectFromReferer() - From another domain -> we ignore the given referrer. */ public function testRedirectExternalReferer(): void { $this->container->environment['HTTP_REFERER'] = 'http://other.domain.tld/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $response, ['query'], ['query']); static::assertSame(302, $result->getStatusCode()); static::assertSame(['/subfolder/'], $result->getHeader('location')); } /** * Test redirectFromReferer() - From another domain -> we ignore the given referrer. */ public function testRedirectExternalRefererExplicitDomainName(): void { $this->container->environment['SERVER_NAME'] = 'my.shaarli.tld'; $this->container->environment['HTTP_REFERER'] = 'http://your.shaarli.tld/controller?query=param&other=2'; $response = new Response(); $result = $this->controller->redirectFromReferer($this->request, $response, ['query'], ['query']); static::assertSame(302, $result->getStatusCode()); static::assertSame(['/subfolder/'], $result->getHeader('location')); } }