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

Refactor groups api to include a search as well as pagination

parent 0962866d
......@@ -6,14 +6,14 @@ use Illuminate\Http\JsonResponse;
use Source\Authorization\Permissions;
use Source\Exceptions\DeleteFailedException;
use Source\UseCases\Groups\GetGroup\GetGroupUseCase;
use Source\UseCases\Groups\GetGroups\GetGroupsUseCase;
use Source\UseCases\Groups\CreateGroup\CreateGroupUseCase;
use Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCase;
use Source\UseCases\Groups\UpdateGroup\UpdateGroupUseCase;
use Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCase;
use Source\UseCases\DoorGroup\GetGroupDoors\GetGroupDoorsUseCase;
use Source\UseCases\GroupUser\GetGroupUsers\GetGroupUsersUseCase;
use Source\UseCases\Groups\GetGroup\APIPresenter as GetGroupAPIPresenter;
use Source\UseCases\Groups\GetAllGroups\APIPresenter as AllGroupsAPIPresenter;
use Source\UseCases\Groups\GetGroups\APIPresenter as AllGroupsAPIPresenter;
use Source\UseCases\Groups\CreateGroup\APIPresenter as CreateGroupAPIPresenter;
use Source\UseCases\Groups\DeleteGroup\APIPresenter as DeleteGroupAPIPresenter;
use Source\UseCases\Groups\UpdateGroup\APIPresenter as UpdateGroupAPIPresenter;
......@@ -69,20 +69,27 @@ class GroupsController extends ApiController
}
/**
* @param \Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCase $useCase
* @param \Source\UseCases\Groups\GetGroups\GetGroupsUseCase $useCase
* @return \Illuminate\Http\JsonResponse
* @throws \Source\Exceptions\AuthorizationException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Illuminate\Validation\ValidationException
*/
public function index(GetAllGroupsUseCase $useCase): JsonResponse
public function index(GetGroupsUseCase $useCase): JsonResponse
{
$this->authorizer->protectOne([Permissions::MANAGE_GROUPS, Permissions::MANAGE_USERS]);
$this->validate($this->request, [
'query' => 'string',
]);
$presenter = new AllGroupsAPIPresenter();
$useCase->all($presenter);
$useCase->search($this->request->input('query'), $presenter);
return $this->respondWithData($presenter->getViewModel());
return $this->respondWithData($presenter->getViewModel([
'query' => $this->request->input('query'),
]));
}
/**
......
......@@ -43,7 +43,7 @@ use Source\UseCases\Tokens\CreateToken\CreateTokenUseCaseServiceProvider;
use Source\UseCases\Tokens\ExpireToken\ExpireTokenUseCaseServiceProvider;
use Source\UseCases\Tokens\UpdateToken\UpdateTokenUseCaseServiceProvider;
use Source\UseCases\Attempts\GetAttempts\GetAttemptsUseCaseServiceProvider;
use Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCaseServiceProvider;
use Source\UseCases\Groups\GetGroups\GetGroupsUseCaseServiceProvider;
use Source\UseCases\Overrides\OverrideGet\OverrideGetUseCaseServiceProvider;
use Source\UseCases\Schedules\ScheduleGet\ScheduleGetUseCaseServiceProvider;
use Source\UseCases\Door\StatusResponse\StatusResponseUseCaseServiceProvider;
......@@ -111,7 +111,7 @@ class AppServiceProvider extends ServiceProvider
CreateGroupUseCaseServiceProvider::class,
DeleteGroupUseCaseServiceProvider::class,
UpdateGroupUseCaseServiceProvider::class,
GetAllGroupsUseCaseServiceProvider::class,
GetGroupsUseCaseServiceProvider::class,
// GroupUser
GetUserGroupsUseCaseServiceProvider::class,
......
......@@ -14,7 +14,7 @@ class GroupsSeeder extends Seeder
*/
public function run(DatabaseGroupsRepository $groups): void
{
if ($groups->all()) {
if ($groups->search(null)) {
throw new RuntimeException('Cannot seed database as it is not empty.');
}
......
......@@ -43,9 +43,18 @@ class DatabaseGroupsRepository implements GroupsRepository
/**
* @inheritDoc
*/
public function all(): array
public function search(?string $query): array
{
$groups = \App\Group::all()->values()->all();
$groups = [];
if ($query) {
$groups = \App\Group::query()
->where('title', 'LIKE', "%$query%")
->orWhere('description', 'LIKE', "%$query%")
->get()->values()->all();
} else {
$groups = \App\Group::all()->values()->all();
}
return array_map(function (\App\Group $group) {
return $this->makeGroupFromDbGroup($group);
......
......@@ -14,9 +14,12 @@ interface GroupsRepository
public function get(string $groupId): ?Group;
/**
* Will return all groups if the given query is null or empty
*
* @param string|null $query
* @return Group[]
*/
public function all(): array;
public function search(?string $query): array;
/**
* It is the callers responsibility to check the exists function first to make sure it does not exist.
......
......@@ -20,9 +20,16 @@ class InMemoryGroupsRepository implements GroupsRepository
/**
* @inheritDoc
*/
public function all(): array
public function search(?string $query): array
{
return $this->groups;
if (!$query) {
return $this->groups;
}
return array_filter($this->groups, static function (Group $group) use ($query) {
return strpos($group->getTitle(), $query) !== false ||
strpos($group->getDescription(), $query) !== false;
});
}
/**
......
<?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;
namespace Source\UseCases\Groups\GetGroups;
use Source\Entities\Group;
use Source\Sanitize\Paginates;
use Source\UseCases\BasePresenter;
class APIPresenter extends BasePresenter implements Presenter
{
protected array $viewModel = [];
use Paginates;
protected array $groups = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$this->viewModel['groups'] = array_map(function (Group $group) {
$this->groups = array_map(function (Group $group) {
return $this->formatGroup($group);
}, $responseModel->getGroups());
}
/** @inheritDoc */
public function getViewModel(): array
public function getViewModel(array $appends = []): array
{
return $this->paginate($this->groups, $appends);
}
public function raw(): array
{
return $this->viewModel;
return ['groups' => $this->groups];
}
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
namespace Source\UseCases\Groups\GetGroups;
use Source\Gateways\Groups\GroupsRepository;
class GetAllGroups implements GetAllGroupsUseCase
class GetGroups implements GetGroupsUseCase
{
/**
* @var \Source\Gateways\Groups\GroupsRepository
......@@ -19,11 +19,11 @@ class GetAllGroups implements GetAllGroupsUseCase
/**
* @inheritDoc
*/
public function all(Presenter $presenter): void
public function search(?string $query, Presenter $presenter): void
{
$response = new ResponseModel();
foreach ($this->groups->all() as $group) {
foreach ($this->groups->search($query) as $group) {
$response->addGroup($group);
}
......
<?php
namespace Source\UseCases\Groups\GetGroups;
interface GetGroupsUseCase
{
/**
* @param string|null $query
* @param \Source\UseCases\Groups\GetGroups\Presenter $presenter
*/
public function search(?string $query, Presenter $presenter): void;
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
namespace Source\UseCases\Groups\GetGroups;
use Illuminate\Support\ServiceProvider;
use Source\Gateways\Groups\GroupsRepository;
......@@ -11,7 +11,7 @@ use Illuminate\Contracts\Support\DeferrableProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class GetAllGroupsUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
class GetGroupsUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
......@@ -20,8 +20,8 @@ class GetAllGroupsUseCaseServiceProvider extends ServiceProvider implements Defe
*/
public function register()
{
$this->app->bind(GetAllGroupsUseCase::class, static function (Application $app) {
return new GetAllGroups($app->make(GroupsRepository::class));
$this->app->bind(GetGroupsUseCase::class, static function (Application $app) {
return new GetGroups($app->make(GroupsRepository::class));
});
}
......@@ -39,6 +39,6 @@ class GetAllGroupsUseCaseServiceProvider extends ServiceProvider implements Defe
*/
public function provides()
{
return [GetAllGroupsUseCase::class];
return [GetGroupsUseCase::class];
}
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
namespace Source\UseCases\Groups\GetGroups;
interface Presenter
{
......@@ -11,7 +11,8 @@ interface Presenter
public function present(ResponseModel $responseModel): void;
/**
* @param array $appends
* @return array
*/
public function getViewModel(): array;
public function getViewModel(array $appends = []): array;
}
<?php
namespace Source\UseCases\Groups\GetAllGroups;
namespace Source\UseCases\Groups\GetGroups;
use Source\Entities\Group;
......
......@@ -26,14 +26,14 @@ class GroupDatabaseTest extends DatabaseTestCase
*/
public function it_gets_all_groups(): void
{
$all = $this->groups->all();
$all = $this->groups->search(null);
$this->assertEquals([], $all);
$this->groups->create(new Group(0, 't1', ''));
$this->groups->create(new Group(0, 't2', ''));
$all = $this->groups->all();
$all = $this->groups->search(null);
$this->assertCount(2, $all);
}
......
......@@ -29,9 +29,10 @@ class InMemoryGroupsRepositoryStub implements GroupsRepository
}
/**
* @param string|null $query
* @return array
*/
public function all(): array
public function search(?string $query): array
{
return [];
}
......
......@@ -114,6 +114,6 @@ class CreateGroupApiTest extends AuthenticatesWithApplicationTestCase
'description' => 'desc',
]);
$this->assertCount(1, $this->groups->all());
$this->assertCount(1, $this->groups->search(null));
}
}
......@@ -98,7 +98,7 @@ class DeleteGroupApiTest extends AuthenticatesWithApplicationTestCase
'code' => 200,
]);
$this->assertCount(0, $this->groups->all());
$this->assertCount(0, $this->groups->search(null));
}
/**
......
......@@ -85,7 +85,7 @@ class GetAllGroupsApiTest extends AuthenticatesWithApplicationTestCase
$this->handleTest();
$this->response->assertStatus(200);
$this->response->assertJsonCount(2, 'groups');
$this->response->assertJsonCount(2, 'data');
$this->response->assertJson(['status' => 'success']);
}
}
......@@ -78,7 +78,7 @@ class UseCaseTest extends TestCase
$this->assertEquals($group->getTitle(), $this->response->getGroup()->getTitle());
$this->assertEquals($group->getDescription(), $this->response->getGroup()->getDescription());
$this->assertCount(1, $this->groupsRepository->all());
$this->assertCount(1, $this->groupsRepository->search(null));
}
/**
......
......@@ -82,7 +82,7 @@ class UseCaseTest extends TestCase
$this->handleTest('69');
$this->assertCount(1, $this->groupsRepository->all());
$this->assertCount(1, $this->groupsRepository->search(null));
$this->assertEquals('420', $this->groupsRepository->get('420')->getId());
}
......
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