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

Get all groups endpoint

parent c1790119
......@@ -5,6 +5,8 @@ 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\GetAllGroups\GetAllGroupsUseCase;
use Source\UseCases\Groups\DeleteGroup\APIPresenter as DeleteGroupAPIPresenter;
use Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCase;
use Source\UseCases\Groups\CreateGroup\APIPresenter as CreateGroupAPIPresenter;
......@@ -36,6 +38,13 @@ class GroupsController extends ApiController
return $this->respondWithData($presenter->getViewModel());
}
/**
* @param \Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCase $useCase
* @param string $groupId
* @return \Illuminate\Http\JsonResponse
* @throws \Source\Exceptions\AuthorizationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function delete(DeleteGroupUseCase $useCase, string $groupId): JsonResponse
{
$this->authorizer->protectAll([Permissions::MANAGE_GROUPS]);
......@@ -50,4 +59,21 @@ class GroupsController extends ApiController
return $this->respondWithData($presenter->getViewModel());
}
/**
* @param \Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCase $useCase
* @return \Illuminate\Http\JsonResponse
* @throws \Source\Exceptions\AuthorizationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function index(GetAllGroupsUseCase $useCase): JsonResponse
{
$this->authorizer->protectAll([Permissions::MANAGE_GROUPS]);
$presenter = new AllGroupsAPIPresenter();
$useCase->all($presenter);
return $this->respondWithData($presenter->getViewModel());
}
}
......@@ -18,6 +18,7 @@ use Source\UseCases\Users\GetAllUsers\GetAllUsersUseCaseServiceProvider;
use Source\UseCases\Groups\CreateGroup\CreateGroupUseCaseServiceProvider;
use Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCaseServiceProvider;
use Source\UseCases\Token\Authenticate\AuthenticateUseCaseServiceProvider;
use Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCaseServiceProvider;
use Source\UseCases\Doors\Authenticate\AuthenticateUseCaseServiceProvider as DoorAuthenticateUseCaseServiceProvider;
use Source\UseCases\Users\Authenticate\AuthenticateUseCaseServiceProvider as UserAuthenticateUseCaseServiceProvider;
......@@ -50,6 +51,7 @@ class AppServiceProvider extends ServiceProvider
// Groups
CreateGroupUseCaseServiceProvider::class,
DeleteGroupUseCaseServiceProvider::class,
GetAllGroupsUseCaseServiceProvider::class,
// Doors
AuthenticateUseCaseServiceProvider::class,
......
<?php
namespace Source\UseCases\Groups\GetAllGroups;
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(function (Group $group) {
return $this->formatGroup($group);
}, $responseModel->getGroups());
}
/** @inheritDoc */
public function getViewModel(): array
{
return $this->viewModel;
}
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
use Source\Gateways\Groups\GroupsRepository;
class GetAllGroups implements GetAllGroupsUseCase
{
/**
* @var \Source\Gateways\Groups\GroupsRepository
*/
protected GroupsRepository $groups;
public function __construct(GroupsRepository $groups)
{
$this->groups = $groups;
}
/**
* @inheritDoc
*/
public function all(Presenter $presenter): void
{
$response = new ResponseModel();
foreach ($this->groups->all() as $group) {
$response->addGroup($group);
}
$presenter->present($response);
}
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
interface GetAllGroupsUseCase
{
/**
* @param \Source\UseCases\Groups\GetAllGroups\Presenter $presenter
*/
public function all(Presenter $presenter): void;
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
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 GetAllGroupsUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(GetAllGroupsUseCase::class, static function (Application $app) {
return new GetAllGroups($app->make(GroupsRepository::class));
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [GetAllGroupsUseCase::class];
}
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
interface Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public function present(ResponseModel $responseModel): void;
/**
* @return array
*/
public function getViewModel(): array;
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
use Source\Entities\Group;
class ResponseModel
{
/**
* @var \Source\Entities\Group[]
*/
protected array $groups = [];
/**
* @param \Source\Entities\Group $group
*/
public function addGroup(Group $group): void
{
$this->groups[] = $group;
}
/**
* @return \Source\Entities\Group[]
*/
public function getGroups(): array
{
return $this->groups;
}
}
......@@ -6,7 +6,7 @@ namespace Source\UseCases\Users\GetAllUsers;
interface GetAllUsersUseCase
{
/**
* @param Presenter $presenter
* @param \Source\UseCases\Users\GetAllUsers\Presenter $presenter
*/
public function all(Presenter $presenter): void;
}
<?php
namespace Tests\Feature\Api\Groups;
use Source\Entities\Group;
use Source\Gateways\Groups\GroupsRepository;
use Source\Exceptions\EntityNotFoundException;
use Illuminate\Foundation\Testing\TestResponse;
use Tests\Feature\AuthenticatesWithApplicationTestCase;
class GetAllGroupsApiTest extends AuthenticatesWithApplicationTestCase
{
/**
* @var \Illuminate\Foundation\Testing\TestResponse
*/
protected TestResponse $response;
/**
* @var mixed|\Source\Gateways\Groups\GroupsRepository
*/
protected GroupsRepository $groups;
public function setUp(): void
{
parent::setUp();
$this->groups = $this->app->make(GroupsRepository::class);
}
protected function handleTest(): void
{
$this->response = $this->getJson('/groups?api_token=' . $this->authToken);
}
/**
* @test
*/
public function it_denies_unauthorized(): void
{
$this->handleTest();
$this->response->assertStatus(401);
}
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function it_protects_the_route(): void
{
$this->authorize(false);
$this->handleTest();
$this->response->assertStatus(403);
}
/**
* @test
* @throws EntityNotFoundException
*/
public function it_returns_empty_when_no_groups_are_added(): void
{
$this->authenticate();
$this->handleTest();
$this->response->assertStatus(200);
$this->response->assertJson([
'status' => 'success',
'code' => 200,
]);
}
/**
* @test
* @throws EntityNotFoundException
*/
public function it_returns_groups_in_the_repository(): void
{
$this->authenticate();
$this->groups->create(new Group(69, '', ''));
$this->groups->create(new Group(420, '', ''));
$this->handleTest();
$this->response->assertStatus(200);
$this->response->assertJsonCount(2, 'groups');
$this->response->assertJson(['status' => 'success']);
}
}
<?php
namespace Tests\Unit\Source\UseCases\Groups\GetAllGroups;
use Source\UseCases\Groups\GetAllGroups\Presenter;
use Source\UseCases\Groups\GetAllGroups\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\Groups\GetAllGroups;
use Carbon\Carbon;
use Source\Entities\Group;
use PHPUnit\Framework\TestCase;
use Source\UseCases\Groups\GetAllGroups\APIPresenter;
use Source\UseCases\Groups\GetAllGroups\ResponseModel;
class PresenterTest extends TestCase
{
protected APIPresenter $presenter;
protected ResponseModel $model;
protected array $response;
public function setUp(): void
{
parent::setUp();
$this->model = new ResponseModel();
$this->presenter = new APIPresenter();
}
public function handleTest(): void
{
$this->presenter->present($this->model);
$this->response = $this->presenter->getViewModel();
}
/** @test */
public function it_formats_no_groups(): void
{
$this->handleTest();
$this->assertEquals(
[
'groups' => [],
],
$this->response
);
}
/** @test */
public function it_formats_a_group(): void
{
$this->model->addGroup(
new Group(
0,
'title',
'desc',
new Carbon('2020-02-02 20:50:49'),
)
);
$this->handleTest();
$this->assertEquals(
[
'groups' => [
[
'id' => 0,
'title' => 'title',
'description' => 'desc',
'created_at' => '2020-02-02T20:50:49+00:00',
'updated_at' => null,
],
],
],
$this->response
);
}
}
<?php
namespace Tests\Unit\Source\UseCases\Groups\GetAllGroups;
use Source\Entities\Group;
use PHPUnit\Framework\TestCase;
use Source\Gateways\Groups\InMemoryGroupsRepository;
use Source\UseCases\Groups\GetAllGroups\GetAllGroups;
use Source\UseCases\Groups\GetAllGroups\ResponseModel;
class UseCaseTest extends TestCase
{
/**
* @var \Source\Gateways\Groups\InMemoryGroupsRepository
*/
protected InMemoryGroupsRepository $groupsRepository;
/**
* @var \Source\UseCases\Groups\GetAllGroups\GetAllGroups
*/
protected GetAllGroups $useCase;
/**
* @var \Source\UseCases\Groups\GetAllGroups\ResponseModel
*/
protected ResponseModel $response;
/**
* @var \Tests\Unit\Source\UseCases\Groups\GetAllGroups\PresenterStub
*/
protected PresenterStub $presenter;
public function setUp(): void
{
parent::setUp();
$this->groupsRepository = new InMemoryGroupsRepository();
$this->useCase = new GetAllGroups($this->groupsRepository);
$this->presenter = new PresenterStub();
}
public function handleTest(): void
{
$this->useCase->all($this->presenter);
$this->response = $this->presenter->response;
}
/** @test */
public function presenter_was_called(): void
{
$this->handleTest();
$this->assertTrue($this->presenter->wasPresenterCalled());
}
/** @test */
public function it_works_when_no_groups_are_added(): void
{
$this->handleTest();
$this->assertEquals([], $this->response->getGroups());
}
/** @test */
public function it_sees_groups(): void
{
$this->groupsRepository->create(new Group(0, '', ''));
$this->groupsRepository->create(new Group(0, '', ''));
$this->handleTest();
$this->assertCount(2, $this->response->getGroups());
}
}
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