Commit b49c6662 authored by Jacob Priddy's avatar Jacob Priddy 👌
Browse files

Implement authentication usecase test for attempting local auth

parent 4bc3f161
......@@ -30,6 +30,7 @@
<exclude>
<directory suffix=".php">./app/Console</directory>
<directory suffix="ServiceProvider.php">./src</directory>
<directory prefix="Local" suffix="Repository.php">./src</directory>
</exclude>
</whitelist>
</filter>
......
......@@ -24,6 +24,14 @@ class InMemoryTokensRepository implements TokensRepository
return $token;
}
/**
* @return Token[]
*/
public function all(): array
{
return $this->tokens;
}
/** @inheritDoc */
public function findValidToken(string $tokenToMatch): ?Token
......
......@@ -13,12 +13,26 @@ use Source\Exceptions\AuthenticationException;
class Authenticate implements AuthenticateUseCase
{
/**
* @var \Source\Gateways\Users\UsersRepository
*/
protected UsersRepository $users;
/**
* @var \Source\Gateways\Tokens\TokensRepository
*/
protected TokensRepository $tokens;
/**
* @var \Source\Gateways\Saml\SamlRepository
*/
protected SamlRepository $saml;
/**
* @param \Source\Gateways\Users\UsersRepository $users
* @param \Source\Gateways\Saml\SamlRepository $saml
* @param \Source\Gateways\Tokens\TokensRepository $tokens
*/
public function __construct(UsersRepository $users, SamlRepository $saml, TokensRepository $tokens)
{
$this->saml = $saml;
......@@ -59,6 +73,9 @@ class Authenticate implements AuthenticateUseCase
$presenter->present($response);
}
/**
* @inheritDoc
*/
public function handToSaml(array $options = []): string
{
return $this->saml->login($options);
......
<?php
namespace Tests\Unit\Source\UseCases\Users\Authenticate;
use Carbon\Carbon;
use Source\Entities\User;
use Source\Exceptions\AuthenticationException;
class AttemptUseCaseTest extends UseCaseBaseTest
{
protected const VALID_EMAIL = 'email';
protected const VALID_PASS = 'password';
/**
* @param array $credentials
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
protected function handleTest(
array $credentials = [
'email' => self::VALID_EMAIL,
'password' => self::VALID_PASS,
]
): void {
$this->useCase->attempt($this->presenter, $credentials);
$this->response = $this->presenter->response;
}
/**
* @return \Source\Entities\User
*/
protected function createUser(): User
{
return $this->users->create(new User(0, '', '', '', '', self::VALID_EMAIL, self::VALID_PASS, ''));
}
/**
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_calls_present_on_presenter(): void
{
$this->createUser();
$this->handleTest([
'email' => self::VALID_EMAIL,
'password' => self::VALID_PASS,
]);
$this->assertTrue($this->presenter->wasPresenterCalled());
}
public function attemptAuthenticationProvider(): array
{
return [
[[]],
[['email' => 'eem',]],
[['password' => 'pass']],
[['email' => self::VALID_EMAIL, 'password' => 'ree']],
[['email' => 'non-existent', 'password' => self::VALID_PASS]],
];
}
/**
* @test
* @dataProvider attemptAuthenticationProvider
* @param array $credentials
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_cannot_find_users_for_invalid_input(array $credentials): void
{
$this->createUser();
$this->expectException(AuthenticationException::class);
$this->handleTest($credentials);
}
/**
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_creates_a_token_for_the_user(): void
{
$user = $this->createUser();
$this->handleTest();
$this->assertCount(1, $this->tokens->all());
$token = $this->tokens->all()[0];
$this->assertLessThan(Carbon::now()->addDays(2), $token->getExpiresAt());
$this->assertGreaterThan(Carbon::now()->addDays(1), $token->getExpiresAt());
$this->assertEquals($user->getId(), $token->getUserId());
$this->assertEquals(60, strlen($token->getTokenString()));
$this->assertEquals($token, $this->response->getToken());
}
/**
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_authenticates_a_user(): void
{
$user = $this->createUser();
$this->handleTest();
$this->assertEquals($user, $this->response->getUser());
}
}
<?php
namespace Tests\Unit\Source\UseCases\Users\Authenticate;
use Source\UseCases\Users\Authenticate\Presenter;
use Source\UseCases\Users\Authenticate\ResponseModel;
class PresenterStub implements Presenter
{
public ResponseModel $response;
protected bool $presenterCalled = false;
public function present(ResponseModel $responseModel): void
{
$this->presenterCalled = true;
$this->response = $responseModel;
}
public function wasPresenterCalled(): bool
{
return $this->presenterCalled;
}
public function getViewModel(): array
{
return [];
}
}
<?php
namespace Tests\Unit\Source\UseCases\Users\Authenticate;
use Carbon\Carbon;
use Source\Entities\User;
use Source\Entities\Token;
use PHPUnit\Framework\TestCase;
use Source\UseCases\Users\Authenticate\APIPresenter;
use Source\UseCases\Users\Authenticate\ResponseModel;
class PresenterTest extends TestCase
{
/**
* @var \Source\UseCases\Users\Authenticate\APIPresenter
*/
protected APIPresenter $presenter;
/**
* @var \Source\UseCases\Users\Authenticate\ResponseModel
*/
protected ResponseModel $model;
/**
* @var array
*/
protected array $response;
public function setUp(): void
{
parent::setUp();
$this->presenter = new APIPresenter();
}
/**
* @param \Source\Entities\User $user
* @param \Source\Entities\Token $token
*/
public function handleTest(User $user, Token $token): void
{
$this->model = new ResponseModel($user, $token);
$this->presenter->present($this->model);
$this->response = $this->presenter->getViewModel();
}
/**
* @test
* @throws \Exception
*/
public function it_presents_the_token(): void
{
$expires = new Carbon('2020-03-04');
$user = new User(
0,
'first',
'last',
'display',
'emplid',
'email',
'password',
'doorcode',
$expires,
null,
null
);
$token = new Token(0, 0, 'token', 'nomen', $expires);
$this->handleTest($user, $token);
$minutes = $expires->diffInMinutes(Carbon::now());
$this->assertEquals([
'value' => 'token',
'expires_at' => '2020-03-04T00:00:00+00:00',
'minutes' => $minutes,
], $this->response['token']);
}
/**
* @test
*/
public function it_presents_the_token_with_no_expire(): void
{
$expires = null;
$user = new User(
0,
'first',
'last',
'display',
'emplid',
'email',
'password',
'doorcode',
$expires,
null,
null
);
$token = new Token(0, 0, 'token', 'nomen', $expires);
$this->handleTest($user, $token);
$this->assertEquals([
'value' => 'token',
'expires_at' => null,
'minutes' => 0,
], $this->response['token']);
}
/** @test */
public function it_formats_a_user(): void
{
$user = new User(
0,
'first',
'last',
'display',
'emplid',
'email',
'password',
'doorcode',
new Carbon('2020-02-02'),
null,
null
);
$token = new Token(0, 0, 'token', 'nomen', new Carbon('2020-03-04'));
$this->handleTest($user, $token);
$this->assertEquals([
'id' => 0,
'first_name' => 'first',
'last_name' => 'last',
'display_name' => 'display',
'emplid' => 'emplid',
'email' => 'email',
'expires_at' => '2020-02-02T00:00:00+00:00',
'created_at' => null,
'updated_at' => null,
], $this->response['user']);
}
}
<?php
namespace Tests\Unit\Source\UseCases\Users\Authenticate;
use PHPUnit\Framework\TestCase;
use Source\Gateways\Saml\InMemorySamlRepository;
use Source\UseCases\Users\Authenticate\Authenticate;
use Source\Gateways\Users\InMemoryUsersRepository;
use Source\Gateways\Tokens\InMemoryTokensRepository;
use Source\UseCases\Users\Authenticate\ResponseModel;
abstract class UseCaseBaseTest extends TestCase
{
/**
* @var \Source\Gateways\Users\InMemoryUsersRepository
*/
protected InMemoryUsersRepository $users;
/**
* @var \Source\Gateways\Tokens\InMemoryTokensRepository
*/
protected InMemoryTokensRepository $tokens;
/**
* @var \Source\Gateways\Saml\InMemorySamlRepository
*/
protected InMemorySamlRepository $saml;
/**
* @var \Source\UseCases\Users\Authenticate\Authenticate
*/
protected Authenticate $useCase;
/**
* @var \Source\UseCases\Users\Authenticate\ResponseModel
*/
protected ResponseModel $response;
/**
* @var \Tests\Unit\Source\UseCases\Users\Authenticate\PresenterStub
*/
protected PresenterStub $presenter;
/**
* @var string
*/
protected string $loginUrl = 'login url';
/**
* @var string
*/
protected string $logoutUrl = 'logout url';
public function setUp(): void
{
parent::setUp();
$this->users = new InMemoryUsersRepository();
$this->tokens = new InMemoryTokensRepository();
$this->saml = new InMemorySamlRepository($this->loginUrl, $this->logoutUrl);
$this->useCase = new Authenticate($this->users, $this->saml, $this->tokens);
$this->presenter = new PresenterStub();
}
}
......@@ -11,10 +11,19 @@ use Source\UseCases\Users\GetUser\ResponseModel;
class PresenterTest extends TestCase
{
/**
* @var \Source\UseCases\Users\GetUser\APIPresenter
*/
protected APIPresenter $presenter;
/**
* @var \Source\UseCases\Users\GetUser\ResponseModel
*/
protected ResponseModel $model;
/**
* @var array
*/
protected array $response;
public function setUp(): void
......@@ -52,8 +61,7 @@ class PresenterTest extends TestCase
$this->handleTest($user);
$this->assertEquals(
[
$this->assertEquals([
'user' => [
'id' => 0,
'first_name' => 'first',
......@@ -65,8 +73,6 @@ class PresenterTest extends TestCase
'created_at' => null,
'updated_at' => null,
],
],
$this->response
);
], $this->response);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment