Commit 767417a6 authored by Jacob Priddy's avatar Jacob Priddy 👌
Browse files

Get Group Endpoint

parent d39f2fb5
......@@ -5,12 +5,14 @@ namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Source\Authorization\Permissions;
use Source\Exceptions\DeleteFailedException;
use Source\UseCases\Groups\GetAllGroups\APIPresenter as AllGroupsAPIPresenter;
use Source\UseCases\Groups\GetGroup\APIPresenter as GetGroupAPIPresenter;
use Source\UseCases\Groups\GetGroup\GetGroupUseCase;
use Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCase;
use Source\UseCases\Groups\CreateGroup\CreateGroupUseCase;
use Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCase;
use Source\UseCases\Groups\GetAllGroups\APIPresenter as AllGroupsAPIPresenter;
use Source\UseCases\Groups\DeleteGroup\APIPresenter as DeleteGroupAPIPresenter;
use Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCase;
use Source\UseCases\Groups\CreateGroup\APIPresenter as CreateGroupAPIPresenter;
use Source\UseCases\Groups\CreateGroup\CreateGroupUseCase;
class GroupsController extends ApiController
{
......@@ -28,7 +30,7 @@ class GroupsController extends ApiController
$this->validate($this->request, [
'title' => 'required|string|max:255',
'description' => 'required|string'
'description' => 'required|string',
]);
$presenter = new CreateGroupAPIPresenter();
......@@ -68,7 +70,7 @@ class GroupsController extends ApiController
*/
public function index(GetAllGroupsUseCase $useCase): JsonResponse
{
$this->authorizer->protectAll([Permissions::MANAGE_GROUPS]);
$this->authorizer->protectOne([Permissions::MANAGE_GROUPS, Permissions::MANAGE_USERS]);
$presenter = new AllGroupsAPIPresenter();
......@@ -76,4 +78,22 @@ class GroupsController extends ApiController
return $this->respondWithData($presenter->getViewModel());
}
/**
* @param \Source\UseCases\Groups\GetGroup\GetGroupUseCase $useCase
* @param string $groupId
* @return \Illuminate\Http\JsonResponse
* @throws \Source\Exceptions\AuthorizationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function get(GetGroupUseCase $useCase, string $groupId): JsonResponse
{
$this->authorizer->protectOne([Permissions::MANAGE_GROUPS, Permissions::MANAGE_USERS]);
$presenter = new GetGroupAPIPresenter();
$useCase->get($groupId, $presenter);
return $this->respondWithData($presenter->getViewModel());
}
}
......@@ -11,6 +11,7 @@ use Source\Gateways\Groups\GroupsRepositoryServiceProvider;
use Source\Gateways\Tokens\TokensRepositoryServiceProvider;
use Source\UseCases\Users\GetUser\GetUserUseCaseServiceProvider;
use Source\Gateways\GroupUser\GroupUserRepositoryServiceProvider;
use Source\UseCases\Groups\GetGroup\GetGroupUseCaseServiceProvider;
use Source\UseCases\Users\CreateUser\CreateUserUseCaseServiceProvider;
use Source\UseCases\Users\DeleteUser\DeleteUserUseCaseServiceProvider;
use Source\UseCases\Users\UpdateUser\UpdateUserUseCaseServiceProvider;
......@@ -49,6 +50,7 @@ class AppServiceProvider extends ServiceProvider
GetAllUsersUseCaseServiceProvider::class,
// Groups
GetGroupUseCaseServiceProvider::class,
CreateGroupUseCaseServiceProvider::class,
DeleteGroupUseCaseServiceProvider::class,
GetAllGroupsUseCaseServiceProvider::class,
......
<?php
namespace Source\UseCases\Groups\GetGroup;
use Source\UseCases\BasePresenter;
class APIPresenter extends BasePresenter implements Presenter
{
protected array $viewModel = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$this->viewModel['group'] = $this->formatGroup($responseModel->getGroup());
}
/** @inheritDoc */
public function getViewModel(): array
{
return $this->viewModel;
}
}
<?php
namespace Source\UseCases\Groups\GetGroup;
use Source\Gateways\Groups\GroupsRepository;
use Source\Exceptions\EntityNotFoundException;
class GetGroup implements GetGroupUseCase
{
/**
* @var \Source\Gateways\Groups\GroupsRepository
*/
protected GroupsRepository $groups;
public function __construct(GroupsRepository $groups)
{
$this->groups = $groups;
}
/**
* @inheritDoc
*/
public function get(string $groupId, Presenter $presenter): void
{
$group = $this->groups->get($groupId);
if (!$group) {
throw new EntityNotFoundException();
}
$response = new ResponseModel($group);
$presenter->present($response);
}
}
<?php
namespace Source\UseCases\Groups\GetGroup;
use Source\Exceptions\EntityNotFoundException;
interface GetGroupUseCase
{
/**
* @param string $groupId
* @param Presenter $presenter
* @throws EntityNotFoundException
*/
public function get(string $groupId, Presenter $presenter): void;
}
<?php
namespace Source\UseCases\Groups\GetGroup;
use Source\Gateways\Groups\GroupsRepository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class GetGroupUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(GetGroupUseCase::class, static function (Application $app) {
return new GetGroup($app->make(GroupsRepository::class));
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [GetGroupUseCase::class];
}
}
<?php
namespace Source\UseCases\Groups\GetGroup;
interface Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public function present(ResponseModel $responseModel): void;
/**
* @return array
*/
public function getViewModel(): array;
}
<?php
namespace Source\UseCases\Groups\GetGroup;
use Source\Entities\Group;
class ResponseModel
{
/**
* @var \Source\Entities\Group
*/
protected Group $group;
public function __construct(Group $group)
{
$this->group = $group;
}
/**
* @return \Source\Entities\Group
*/
public function getGroup(): Group
{
return $this->group;
}
}
<?php
namespace Tests\Feature\Api\Groups;
use Source\Entities\Group;
use Source\Gateways\Groups\GroupsRepository;
use Illuminate\Foundation\Testing\TestResponse;
use Source\Gateways\Groups\InMemoryGroupsRepository;
use Tests\Feature\AuthenticatesWithApplicationTestCase;
class GetGroupApiTest extends AuthenticatesWithApplicationTestCase
{
/**
* @var \Illuminate\Foundation\Testing\TestResponse
*/
protected TestResponse $response;
protected InMemoryGroupsRepository $groups;
public function setUp(): void
{
parent::setUp();
$this->groups = $this->app->make(GroupsRepository::class);
}
protected function handleTest(string $groupId): void
{
$this->response = $this->getJson('/groups/' . $groupId . '?api_token=' . $this->authToken);
}
/**
* @test
*/
public function it_denies_unauthorized(): void
{
$this->handleTest('asdf');
$this->response->assertStatus(401);
}
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_protects_the_route(): void
{
$this->authorize(false);
$this->handleTest('asdf');
$this->response->assertStatus(403);
}
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_returns_404_on_non_existent_group(): void
{
$this->authenticate();
$this->handleTest('asdfasdfasdfasd');
$this->response->assertStatus(404);
$this->response->assertExactJson(
[
'status' => 'error',
'code' => 404,
'message' => 'Entity not found',
]
);
}
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_returns_a_group(): void
{
$this->authenticate();
$group = new Group(69, '', '');
$this->groups->create($group);
$this->handleTest('69');
$this->response->assertStatus(200);
$this->response->assertJson(['status' => 'success']);
}
}
<?php
namespace Tests\Unit\Source\UseCases\Groups\GetGroup;
use Source\UseCases\Groups\GetGroup\Presenter;
use Source\UseCases\Groups\GetGroup\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 Unit\Source\UseCases\Groups\GetGroup;
use Carbon\Carbon;
use Source\Entities\Group;
use PHPUnit\Framework\TestCase;
use Source\UseCases\Groups\GetGroup\APIPresenter;
use Source\UseCases\Groups\GetGroup\ResponseModel;
class PresenterTest extends TestCase
{
protected APIPresenter $presenter;
protected ResponseModel $model;
protected array $response;
public function setUp(): void
{
parent::setUp();
$this->presenter = new APIPresenter();
}
public function handleTest(Group $user): void
{
$this->model = new ResponseModel($user);
$this->presenter->present($this->model);
$this->response = $this->presenter->getViewModel();
}
/** @test */
public function it_formats_a_user(): void
{
$user = new Group(
0,
'title',
'desc',
new Carbon('2020-03-02 00:17:55'),
);
$this->handleTest($user);
$this->assertEquals(
[
'group' => [
'id' => 0,
'title' => 'title',
'description' => 'desc',
'created_at' => '2020-03-02T00:17:55+00:00',
'updated_at' => null,
],
],
$this->response
);
}
}
<?php
namespace Tests\Unit\Source\UseCases\Groups\GetGroup;
use Source\Entities\Group;
use PHPUnit\Framework\TestCase;
use Source\UseCases\Groups\GetGroup\GetGroup;
use Source\Exceptions\EntityNotFoundException;
use Source\UseCases\Groups\GetGroup\ResponseModel;
use Source\Gateways\Groups\InMemoryGroupsRepository;
class UseCaseTest extends TestCase
{
protected InMemoryGroupsRepository $groups;
protected GetGroup $useCase;
protected ResponseModel $response;
protected PresenterStub $presenter;
public function setUp(): void
{
parent::setUp();
$this->groups = new InMemoryGroupsRepository();
$this->useCase = new GetGroup($this->groups);
$this->presenter = new PresenterStub();
}
/**
* @param string $groupId
* @throws EntityNotFoundException
*/
public function handleTest(string $groupId): void
{
$this->useCase->get($groupId, $this->presenter);
$this->response = $this->presenter->response;
}
/** @test */
/**
* @test
* @throws EntityNotFoundException
*/
public function presenter_was_called(): void
{
$this->groups->create(new Group(1, '', ''));
$this->handleTest('1');
$this->assertTrue($this->presenter->wasPresenterCalled());
}
/**
* @test
* @throws EntityNotFoundException
*/
public function it_throws_an_exception_when_a_group_does_not_exist(): void
{
$this->groups->create(new Group(0, '', ''));
$this->expectException(EntityNotFoundException::class);
$this->handleTest('adf');
}
/**
* @test
* @throws EntityNotFoundException
*/
public function it_gets_a_group(): void
{
$group = new Group(15, '', '');
$this->groups->create($group);
$this->handleTest('15');
$this->assertEquals($group, $this->response->getGroup());
}
}
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