Skip to content

Commit

Permalink
Prevent running tests when no code was changed
Browse files Browse the repository at this point in the history
  • Loading branch information
stloyd committed Feb 22, 2024
1 parent 8b9787b commit 5f785a9
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 169 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/ci.yaml
Expand Up @@ -4,7 +4,16 @@ on:
push:
branches:
- master
paths-ignore:
- '**.md'
pull_request:
paths:
- '.github/workflows/**'
- 'src/**'
- 'tests/**'
- 'phpstan.neon'
- 'phpunit.xml.dist'
- 'composer.json'

# See https://stackoverflow.com/a/72408109
concurrency:
Expand Down
68 changes: 7 additions & 61 deletions src/Controller/LoginController.php
Expand Up @@ -11,14 +11,8 @@

namespace HWI\Bundle\OAuthBundle\Controller;

use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
Expand All @@ -31,63 +25,28 @@
*/
final class LoginController
{
private bool $connect;
private string $grantRule;
private AuthenticationUtils $authenticationUtils;
private RouterInterface $router;
private AuthorizationCheckerInterface $authorizationChecker;
private RequestStack $requestStack;
private Environment $twig;

public function __construct(
AuthenticationUtils $authenticationUtils,
RouterInterface $router,
AuthorizationCheckerInterface $authorizationChecker,
RequestStack $requestStack,
Environment $twig,
bool $connect,
string $grantRule
private readonly AuthenticationUtils $authenticationUtils,
private readonly AuthorizationCheckerInterface $authorizationChecker,
private readonly Environment $twig,
private readonly string $grantRule
) {
$this->authenticationUtils = $authenticationUtils;
$this->router = $router;
$this->authorizationChecker = $authorizationChecker;
$this->requestStack = $requestStack;
$this->twig = $twig;
$this->connect = $connect;
$this->grantRule = $grantRule;
}

/**
* Action that handles the login 'form'. If connecting is enabled the
* user will be redirected to the appropriate login urls or registration forms.
*
* @throws \LogicException
*/
public function connectAction(Request $request): Response
{
try {
$hasUser = $this->authorizationChecker->isGranted($this->grantRule);
} catch (AuthenticationCredentialsNotFoundException $exception) {
$hasUser = false;
$this->authorizationChecker->isGranted($this->grantRule);
} catch (AuthenticationCredentialsNotFoundException) {
// no-op
}

$error = $this->authenticationUtils->getLastAuthenticationError();

// if connecting is enabled and there is no user, redirect to the registration form
if ($this->connect && !$hasUser && $error instanceof AccountNotLinkedException) {
$key = time();
$session = $request->hasSession() ? $request->getSession() : $this->getSession();
if ($session) {
if (!$session->isStarted()) {
$session->start();
}

$session->set('_hwi_oauth.registration_error.'.$key, $error);
}

return new RedirectResponse($this->router->generate('hwi_oauth_connect_registration', ['key' => $key], UrlGeneratorInterface::ABSOLUTE_PATH));
}

if (null !== $error) {
$error = $error->getMessageKey();
}
Expand All @@ -96,17 +55,4 @@ public function connectAction(Request $request): Response
$this->twig->render('@HWIOAuth/Connect/login.html.twig', ['error' => $error])
);
}

private function getSession(): ?SessionInterface
{
if (method_exists($this->requestStack, 'getSession')) {
return $this->requestStack->getSession();
}

if ((null !== $request = $this->requestStack->getCurrentRequest()) && $request->hasSession()) {
return $request->getSession();
}

return null;
}
}
3 changes: 0 additions & 3 deletions src/Resources/config/controller.php
Expand Up @@ -58,11 +58,8 @@
->public()
->args([
service('security.authentication_utils'),
service('router'),
service('security.authorization_checker'),
service('request_stack'),
service('twig'),
'%hwi_oauth.connect%',
'%hwi_oauth.grant_rule%',
]);

Expand Down
92 changes: 5 additions & 87 deletions tests/Controller/LoginControllerTest.php
Expand Up @@ -12,15 +12,12 @@
namespace HWI\Bundle\OAuthBundle\Tests\Controller;

use HWI\Bundle\OAuthBundle\Controller\LoginController;
use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
Expand All @@ -41,47 +38,20 @@ final class LoginControllerTest extends TestCase
*/
private $twig;

/**
* @var MockObject&RouterInterface
*/
private $router;

/**
* @var AuthenticationUtils
*/
private $authenticationUtils;

/**
* @var MockObject&SessionInterface
*/
private $session;

/**
* @var MockObject&RequestStack
*/
private $requestStack;

/**
* @var Request
*/
private $request;
private AuthenticationUtils $authenticationUtils;
private Request $request;

protected function setUp(): void
{
parent::setUp();

$this->authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
$this->twig = $this->createMock(Environment::class);
$this->router = $this->createMock(RouterInterface::class);
$this->session = $this->createMock(SessionInterface::class);
$this->request = Request::create('/');
$this->request->setSession($this->session);

$this->requestStack = $this->createMock(RequestStack::class);
$this->requestStack->push($this->request);

$requestStack = new RequestStack();
$requestStack->push($this->request);

$this->authenticationUtils = new AuthenticationUtils($requestStack);
}

Expand Down Expand Up @@ -117,27 +87,6 @@ public function testLoginPageWithoutToken(): void
$controller->connectAction($this->request);
}

public function testRegistrationRedirect(): void
{
$this->request->attributes = new ParameterBag(
[
$this->getSecurityErrorKey() => new AccountNotLinkedException(),
]
);

$this->mockAuthorizationCheck(false);

$this->router->expects($this->once())
->method('generate')
->with('hwi_oauth_connect_registration')
->willReturn('/')
;

$controller = $this->createController();

$controller->connectAction($this->request);
}

public function testRequestError(): void
{
$this->mockAuthorizationCheck();
Expand All @@ -160,52 +109,21 @@ public function testRequestError(): void
$controller->connectAction($this->request);
}

public function testSessionError(): void
{
$this->mockAuthorizationCheck();

$this->session->expects($this->once())
->method('has')
->with($this->getSecurityErrorKey())
->willReturn(true)
;

$authenticationException = new AuthenticationException();

$this->session->expects($this->once())
->method('get')
->with($this->getSecurityErrorKey())
->willReturn($authenticationException)
;

$this->twig->expects($this->once())
->method('render')
->with('@HWIOAuth/Connect/login.html.twig', ['error' => $authenticationException->getMessageKey()])
;

$controller = $this->createController();

$controller->connectAction($this->request);
}

private function mockAuthorizationCheck(bool $granted = true): void
private function mockAuthorizationCheck(): void
{
$this->authorizationChecker->expects($this->once())
->method('isGranted')
->with('IS_AUTHENTICATED_REMEMBERED')
->willReturn($granted)
->willReturn(true)
;
}

private function createController(): LoginController
{
return new LoginController(
$this->authenticationUtils,
$this->router,
$this->authorizationChecker,
$this->requestStack,
$this->twig,
true,
'IS_AUTHENTICATED_REMEMBERED'
);
}
Expand Down
18 changes: 0 additions & 18 deletions tests/Functional/Controller/LoginControllerTest.php
Expand Up @@ -13,7 +13,6 @@

namespace HWI\Bundle\OAuthBundle\Tests\Functional\Controller;

use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException;
use HWI\Bundle\OAuthBundle\Tests\Functional\AuthenticationHelperTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Bundle\SecurityBundle\Security;
Expand Down Expand Up @@ -44,23 +43,6 @@ public function testLoginPage(): void
$this->assertSame('custom', $crawler->filter('a:nth-child(9)')->text(), $response->getContent());
}

public function testRedirectingToRegistrationFormWithError(): void
{
$client = self::createClient();

$session = $this->getSession($client);
$session->set($this->getSecurityErrorKey(), new AccountNotLinkedException());

$this->saveSession($client, $session);

$client->request('GET', '/login_hwi/');

$response = $client->getResponse();

$this->assertSame(302, $response->getStatusCode(), $response->getContent());
$this->assertSame(0, strpos($response->headers->get('Location'), '/connect/registration/'), $response->headers->get('Location'));
}

public function testLoginPageWithError(): void
{
$httpClient = new MockHttpClient();
Expand Down

0 comments on commit 5f785a9

Please sign in to comment.