Skip to content

(feat)easier repository definition #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 7 additions & 18 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ OldPeopleFilter.php

declare(strict_types=1);

use Illuminate\Database\Query\Builder;
use DevMakerLab\LaravelFilters\AbstractFilter;
use ...

class OldPeopleFilter extends AbstractFilter
{
Expand All @@ -66,27 +65,17 @@ PeopleRepository.php

declare(strict_types=1);

use DevMakerLab\LaravelFilters\AbstractFilterableRepository;
use ...

class PeopleRepository extends AbstractFilterableRepository
class PeopleRepository extends AbstractFilterableRepository
{
private DatabaseManager $databaseManager;
protected string $table = 'people';
protected array $attributes = ['firstname', 'lastname', 'age', 'gender'];
protected bool $shouldTransform = true;

public function __construct(DatabaseManager $databaseManager)
{
$this->databaseManager = $databaseManager;
}

public function get(array $args): array
{
$queryBuilder = $this->databaseManager->table('people')
->select(['firstname', 'lastname', 'age', 'gender']);

$this->applyFilters($queryBuilder, $args);

$people = $queryBuilder->get();

return $this->transform($people);
parent::__construct($databaseManager);
}

public function transform(Collection $people): array
Expand Down
31 changes: 30 additions & 1 deletion src/AbstractFilterableRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@
namespace DevMakerLab\LaravelFilters;

use Illuminate\Database\Query\Builder;
use Illuminate\Database\DatabaseManager;

abstract class AbstractFilterableRepository
{
protected string $table;
protected array $attributes = [];
protected ?int $limit = null;
protected array $filters = [];

protected ?int $limit = null;
protected DatabaseManager $databaseManager;

public function __construct(DatabaseManager $databaseManager)
{
$this->databaseManager = $databaseManager;
}

/**
* @throws FilterClassNotFound
Expand Down Expand Up @@ -52,6 +61,26 @@ public function resetLimit(): self
return $this;
}

public function get(array $args = []): iterable
{
$queryBuilder = $this->databaseManager->table($this->table)
->select($this->attributes);

$this->applyFilters($queryBuilder, $args);

$result = $queryBuilder->get();

if (property_exists($this, 'shouldTransform') && $this->shouldTransform === true) {
if (method_exists($this, 'transform')) {
return $this->transform($result);
} else {
throw new TransformMethodNotImplementedException(static::class);
}
}

return $result;
}

public function applyFilters(Builder &$builder, array $args): self
{
foreach ($this->filters as $filter) {
Expand Down
15 changes: 15 additions & 0 deletions src/TransformMethodNotImplementedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace DevMakerLab\LaravelFilters;

use Exception;

class TransformMethodNotImplementedException extends Exception
{
public function __construct(string $class)
{
parent::__construct(sprintf('Class `%s` does not implement transform function although property `$shouldTransform` is set to true.', $class));
}
}
24 changes: 8 additions & 16 deletions tests/Example/PeopleRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,24 @@

namespace Tests\Example;

use Illuminate\Support\Collection;
use Tests\Example\Entities\PeopleEntity;
use Illuminate\Database\DatabaseManager;
use Tests\Example\Entities\PeopleEntityList;
use DevMakerLab\LaravelFilters\AbstractFilterableRepository;

class PeopleRepository extends AbstractFilterableRepository
{
private \Illuminate\Database\DatabaseManager $databaseManager;
protected string $table = 'people';
protected array $attributes = ['firstname', 'lastname', 'age', 'gender'];
protected bool $shouldTransform = true;

public function __construct(\Illuminate\Database\DatabaseManager $databaseManager)
public function __construct(DatabaseManager $databaseManager)
{
$this->databaseManager = $databaseManager;
parent::__construct($databaseManager);
}

public function get(array $args): PeopleEntityList
{
$queryBuilder = $this->databaseManager->table('people')
->select(['firstname', 'lastname', 'age', 'gender']);

$this->applyFilters($queryBuilder, $args);

$people = $queryBuilder->get();

return $this->transform($people);
}

public function transform(\Illuminate\Support\Collection $people): PeopleEntityList
public function transform(Collection $people): PeopleEntityList
{
$people->transform(function ($person) {
return new PeopleEntity([
Expand Down
2 changes: 2 additions & 0 deletions tests/Feature/PeopleRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

declare(strict_types=1);

namespace Tests\Feature;

use Tests\TestCase;
use Tests\Example\Filters\OldPeopleFilter;
use Tests\Example\Entities\PeopleEntityList;
Expand Down
42 changes: 42 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@

namespace Tests;

use Illuminate\Support\Collection;
use Tests\Example\PeopleRepository;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\Schema\Blueprint;
use DevMakerLab\LaravelFilters\AbstractFilterableRepository;

class TestCase extends \Orchestra\Testbench\TestCase
{
Expand Down Expand Up @@ -36,4 +40,42 @@ public function createPeople(array $peoples): void
->table('people')
->insert($peoples);
}

public function getAbstractRepository(bool $shouldTransform = true): AbstractFilterableRepository
{
$db = $this->partialMock(DatabaseManager::class);
$queryBuilder = $this->partialMock(Builder::class);
$db->shouldReceive('table')
->andReturn($queryBuilder);
$db->shouldReceive('select')
->andReturn($queryBuilder);

$queryBuilder->shouldReceive('get')
->andReturn(new Collection([
0 => 'first item',
1 => 'second item',
]));

return new class($db, $shouldTransform) extends AbstractFilterableRepository {
protected string $table = 'table';
protected array $attributes = [];
protected bool $shouldTransform;

public function __construct(DatabaseManager $databaseManager, bool $shouldTransform)
{
parent::__construct($databaseManager);
$this->shouldTransform = $shouldTransform;
}

public function getFilters(): array
{
return $this->filters;
}

public function getLimit(): ?int
{
return $this->limit;
}
};
}
}
69 changes: 36 additions & 33 deletions tests/Unit/AbstractFilterableRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,78 @@

declare(strict_types=1);

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Support\Collection;
use DevMakerLab\LaravelFilters\AbstractFilter;
use DevMakerLab\LaravelFilters\FilterClassNotFound;
use DevMakerLab\LaravelFilters\IncorrectFilterException;
use DevMakerLab\LaravelFilters\AbstractFilterableRepository;
use DevMakerLab\LaravelFilters\TransformMethodNotImplementedException;

class AbstractFilterableRepositoryTest extends TestCase
{
public function testExceptionThrownWhenAskedForTransformWithoutDefiningTransformMethod(): void
{
$abstractRepository = $this->getAbstractRepository();

$this->expectException(TransformMethodNotImplementedException::class);
$abstractRepository->get();
}

public function testCanGet(): void
{
$abstractRepository = $this->getAbstractRepository(false);

$result = $abstractRepository->get();
$this->assertInstanceOf(Collection::class, $result);
$this->assertCount(2, $result);
$this->assertSame([
'first item',
'second item',
], $result->toArray());
}

public function testExceptionThrownWhenAddingNonExistingFilter(): void
{
$abstractRepository = new class extends AbstractFilterableRepository {
};
$abstractRepository = $this->getAbstractRepository();

$this->expectException(FilterClassNotFound::class);
$abstractRepository->addFilter(FooFilter::class);
}

public function testExceptionThrownWhenAddingFilterWhichIsNotExtendingAbstractFilter(): void
{
$abstractRepository = new class extends AbstractFilterableRepository {
};
$abstractRepository = $this->getAbstractRepository();

$filter = new class {
};

$this->expectException(IncorrectFilterException::class);
$abstractRepository->addFilter(get_class($filter));
$abstractRepository->addFilter(\get_class($filter));
}

public function testCanAddFilter(): void
{
$abstractRepository = new class extends AbstractFilterableRepository {
public function getFilters(): array
{
return $this->filters;
}
};
$abstractRepository = $this->getAbstractRepository();

$filter = new class extends AbstractFilter {
};

$abstractRepository->addFilter(get_class($filter));
$abstractRepository->addFilter(\get_class($filter));

$this->assertCount(1, $abstractRepository->getFilters());
$this->assertSame(get_class($filter), $abstractRepository->getFilters()[0]);
$this->assertSame(\get_class($filter), $abstractRepository->getFilters()[0]);
}

public function testCanResetFilters(): void
{
$abstractRepository = new class extends AbstractFilterableRepository {
public function getFilters(): array
{
return $this->filters;
}
};
$abstractRepository = $this->getAbstractRepository();

$filter = new class extends AbstractFilter {
};

$abstractRepository->addFilter(get_class($filter));
$abstractRepository->addFilter(\get_class($filter));
$this->assertCount(1, $abstractRepository->getFilters());

$abstractRepository->resetFilters();
Expand All @@ -69,12 +82,7 @@ public function getFilters(): array

public function testCanSpecifyLimit(): void
{
$abstractRepository = new class extends AbstractFilterableRepository {
public function getLimit(): ?int
{
return $this->limit;
}
};
$abstractRepository = $this->getAbstractRepository();

$this->assertNull($abstractRepository->getLimit());

Expand All @@ -84,12 +92,7 @@ public function getLimit(): ?int

public function testCanResetLimit(): void
{
$abstractRepository = new class extends AbstractFilterableRepository {
public function getLimit(): ?int
{
return $this->limit;
}
};
$abstractRepository = $this->getAbstractRepository();

$this->assertNull($abstractRepository->getLimit());

Expand Down