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

Add use case for getting the groups a user is in with tests

Also update some places I was not using ISO compliant timestamp
parent 05ee55b8
......@@ -5,6 +5,7 @@ namespace Source\Gateways\GroupUser;
use Source\Gateways\Users\UsersRepository;
use Source\Gateways\Groups\GroupsRepository;
use Source\Exceptions\EntityNotFoundException;
class InMemoryGroupUserRepository implements GroupUserRepository
{
......@@ -36,6 +37,10 @@ class InMemoryGroupUserRepository implements GroupUserRepository
*/
public function getGroupsForUser(string $userId): array
{
if (!$this->users->exists($userId)) {
throw new EntityNotFoundException();
}
if (!isset($this->groupMap[$userId])) {
return [];
}
......
......@@ -65,9 +65,9 @@ abstract class BasePresenter
'display_name' => $user->getDisplayName(),
'emplid' => $user->getEmplid(),
'email' => $user->getEmail(),
'expires_at' => $this->formatDate($user->getExpiresAt()),
'created_at' => $this->formatDate($user->getCreatedAt()),
'updated_at' => $this->formatDate($user->getUpdatedAt()),
'expires_at' => $this->formatDateTime($user->getExpiresAt()),
'created_at' => $this->formatDateTime($user->getCreatedAt()),
'updated_at' => $this->formatDateTime($user->getUpdatedAt()),
];
}
......
<?php
namespace Source\UseCases\GroupUser\GetUserGroups;
use Source\Entities\Group;
use Source\UseCases\BasePresenter;
class APIPresenter extends BasePresenter implements Presenter
{
protected array $viewModel = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$this->viewModel['groups'] = array_map(static function (Group $group) {
return [
'id' => $group->getId(),
'title' => $group->getTitle(),
'description' => $group->getDescription(),
];
}, $responseModel->getGroups());
}
/** @inheritDoc */
public function getViewModel(): array
{
return $this->viewModel;
}
}
<?php
namespace Source\UseCases\GroupUser\GetUserGroups;
use Source\Gateways\GroupUser\GroupUserRepository;
class GetUserGroups implements GetUserGroupsUseCase
{
/**
* @var \Source\Gateways\GroupUser\GroupUserRepository
*/
protected GroupUserRepository $repository;
public function __construct(GroupUserRepository $repository)
{
$this->repository = $repository;
}
/**
* @inheritDoc
*/
public function getGroupsForUser(string $userId, Presenter $presenter): void
{
$groups = $this->repository->getGroupsForUser($userId);
$response = new ResponseModel($groups);
$presenter->present($response);
}
}
<?php
namespace Source\UseCases\GroupUser\GetUserGroups;
interface GetUserGroupsUseCase
{
/**
* @param string $userId
* @param \Source\UseCases\GroupUser\GetUserGroups\Presenter $presenter
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function getGroupsForUser(string $userId, Presenter $presenter): void;
}
<?php
namespace Source\UseCases\GroupUser\GetUserGroups;
use Illuminate\Contracts\Foundation\Application;
use Source\Gateways\GroupUser\GroupUserRepository;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class GetUserGroupsUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(GetUserGroupsUseCase::class, static function (Application $app) {
return new GetUserGroups($app->make(GroupUserRepository::class));
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [GetUserGroupsUseCase::class];
}
}
<?php
namespace Source\UseCases\GroupUser\GetUserGroups;
interface Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public function present(ResponseModel $responseModel): void;
/**
* @return array
*/
public function getViewModel(): array;
}
<?php
namespace Source\UseCases\GroupUser\GetUserGroups;
class ResponseModel
{
/**
* @var \Source\Entities\Group[]
*/
protected array $groups;
public function __construct(array $groups)
{
$this->groups = $groups;
}
/**
* @return \Source\Entities\Group[]
*/
public function getGroups(): array
{
return $this->groups;
}
}
<?php
namespace Tests\Unit\Source\UseCases\GroupUser\GetUserGroups;
use Source\UseCases\GroupUser\GetUserGroups\Presenter;
use Source\UseCases\GroupUser\GetUserGroups\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\GroupUser\GetUserGroups;
use Source\Entities\Group;
use PHPUnit\Framework\TestCase;
use Source\UseCases\GroupUser\GetUserGroups\APIPresenter;
use Source\UseCases\GroupUser\GetUserGroups\ResponseModel;
class PresenterTest extends TestCase
{
protected APIPresenter $presenter;
protected ResponseModel $model;
protected array $response;
public function setUp(): void
{
parent::setUp();
$this->presenter = new APIPresenter();
}
/**
* @param \Source\Entities\Group[] $groups
*/
public function handleTest(array $groups): void
{
$this->model = new ResponseModel($groups);
$this->presenter->present($this->model);
$this->response = $this->presenter->getViewModel();
}
/**
* @test
*/
public function it_formats_groups_when_empty(): void
{
$this->handleTest([]);
$this->assertEquals(['groups' => []], $this->response);
}
/** @test */
public function it_formats_a_group(): void
{
$groups = [
new Group(1, 't1', 'd1'),
new Group(2, 't2', 'd2'),
];
$this->handleTest($groups);
$this->assertCount(2, $this->response['groups']);
$this->assertEquals([
'groups' => [
[
'id' => 1,
'title' => 't1',
'description' => 'd1',
],
[
'id' => 2,
'title' => 't2',
'description' => 'd2',
],
]], $this->response);
}
}
<?php
namespace Tests\Unit\Source\UseCases\GroupUser\GetUserGroups;
use Source\Entities\User;
use Source\Entities\Group;
use PHPUnit\Framework\TestCase;
use Source\Gateways\Users\UsersRepository;
use Source\Gateways\Groups\GroupsRepository;
use Source\Exceptions\EntityNotFoundException;
use Source\Gateways\GroupUser\GroupUserRepository;
use Source\Gateways\Users\InMemoryUsersRepository;
use Source\Gateways\Groups\InMemoryGroupsRepository;
use Source\Gateways\GroupUser\InMemoryGroupUserRepository;
use Source\UseCases\GroupUser\GetUserGroups\ResponseModel;
use Source\UseCases\GroupUser\GetUserGroups\GetUserGroups;
class UseCaseTest extends TestCase
{
protected ResponseModel $response;
protected PresenterStub $presenter;
protected GroupUserRepository $repository;
protected GetUserGroups $useCase;
protected UsersRepository $users;
protected GroupsRepository $groups;
public function setUp(): void
{
parent::setUp();
$this->users = new InMemoryUsersRepository();
$this->groups = new InMemoryGroupsRepository();
$this->repository = new InMemoryGroupUserRepository($this->users, $this->groups);
$this->useCase = new GetUserGroups($this->repository);
$this->presenter = new PresenterStub();
}
/**
* @param string $userId
* @throws \Source\Exceptions\EntityNotFoundException
*/
protected function handleTest(string $userId): void
{
$this->useCase->getGroupsForUser($userId, $this->presenter);
$this->response = $this->presenter->response;
}
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_cannot_get_groups_for_non_existient_user(): void
{
$this->expectException(EntityNotFoundException::class);
$this->handleTest('asdf');
}
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_gets_groups_for_a_user(): void
{
$user = $this->users->create(new User(
0,
'',
'',
'',
'',
'',
'',
''
));
$group = $this->groups->create(new Group(
0,
'',
''
));
$this->repository->addUserToGroup($user->getId(), $group->getId());
$this->handleTest($user->getId());
$this->assertEquals([$group], $this->response->getGroups());
}
}
......@@ -60,7 +60,7 @@ class PresenterTest extends TestCase
'display_name' => 'display',
'emplid' => 'emplid',
'email' => 'email',
'expires_at' => 'Feb 2, 2020',
'expires_at' => '2020-02-02T00:00:00+00:00',
'created_at' => null,
'updated_at' => null,
],
......
......@@ -61,7 +61,7 @@ class PresenterTest extends TestCase
'display_name' => 'display',
'emplid' => 'emplid',
'email' => 'email',
'expires_at' => 'Feb 2, 2020',
'expires_at' => '2020-02-02T00:00:00+00:00',
'created_at' => null,
'updated_at' => null,
],
......
......@@ -61,7 +61,7 @@ class PresenterTest extends TestCase
'display_name' => 'display',
'emplid' => 'emplid',
'email' => 'email',
'expires_at' => 'Feb 2, 2020',
'expires_at' => '2020-02-02T00:00:00+00:00',
'created_at' => null,
'updated_at' => null,
],
......
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