Skip to content
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

Refactor AbstractQueryCacheAttribute & expanded test suite #8

Merged
merged 12 commits into from
Feb 9, 2021
Merged
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ All notable changes to `datum` will be documented in this file
## 0.5.0 - 2021-02-08
- cut PublicStatusFilter class
- refactor Sfneal\Filters\FilterListString to Sfneal\Filters\AbstractFilter


## 0.6.0 - 2021-02-09
- refactor Sfneal\Queries\AbstractQueryCacheAttribute to Sfneal\Queries\CacheModel & expanded functionality
- add tests for evaluating AbstractQueryWithFilter functionality
2 changes: 2 additions & 0 deletions src/Queries/AbstractQueryWithFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

abstract class AbstractQueryWithFilter extends AbstractQuery implements DynamicQuery
{
// todo: add protected execute method with default functionality

// Uses Filter classes for applying queries
use ApplyFilter;

Expand Down
2 changes: 2 additions & 0 deletions src/Queries/AbstractQueryWithFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ abstract class AbstractQueryWithFilters extends AbstractQuery implements Dynamic
{
use ApplyFilter;

// todo: add protected execute method with default functionality

/**
* Array of attribute/form input name keys and Filter class values.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Sfneal\Caching\Traits\Cacheable;
use Sfneal\Helpers\Redis\RedisCache;

abstract class AbstractQueryCacheAttribute extends AbstractQuery
class CacheModelQuery extends AbstractQuery
{
/**
* Inherit cache methods.
Expand Down Expand Up @@ -38,20 +38,35 @@ abstract class AbstractQueryCacheAttribute extends AbstractQuery
* QueryCacheAttribute constructor.
*
* @param int $model_key
* @param string|null $model
* @param string|null $attribute
*/
public function __construct(int $model_key)
public function __construct(int $model_key, string $model = null, string $attribute = null)
{
$this->model_key = $model_key;
$this->model = $this->model ?? $model;
$this->attribute = $this->attribute ?? $attribute;
}

/**
* Retrieve a Service's title.
*
* @return string
* @return Model|string
*/
public function execute(): string
public function execute()
{
return $this->model::query()->find($this->model_key)->getAttribute($this->attribute);
// Retrieve the model
$model = $this->model::query()->find($this->model_key);

// Return the entire model if no attribute is set
if (is_null($this->attribute)) {
return $model;
}

// Return a specific model
else {
return $model->getAttribute($this->attribute);
}
}

/**
Expand All @@ -62,8 +77,9 @@ public function execute(): string
public function cacheKey(): string
{
$table = (new $this->model)->getTable();
$key = "{$table}:{$this->model_key}";

return "{$table}:{$this->model_key}:{$this->attribute}";
return $key.(is_null($this->attribute) ? '' : ":{$this->attribute}");
}

/**
Expand Down
112 changes: 112 additions & 0 deletions tests/CacheModelQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

namespace Sfneal\Datum\Tests;

use Sfneal\Datum\Tests\Models\People;
use Sfneal\Datum\Tests\Queries\CachePeopleEmailQuery;
use Sfneal\Datum\Tests\Queries\CachePeopleQuery;
use Sfneal\Queries\CacheModelQuery;

class CacheModelQueryTest extends TestCase
{
/**
* @var int
*/
private $id;

/**
* Setup the test environment.
*
* @return void
*/
public function setUp(): void
{
parent::setUp();
$this->id = People::query()->get()->shuffle()->first()->getKey();
}

private function getExpectedResult(): string
{
return People::query()->find($this->id)->email;
}

public function test_attribute_results_properties()
{
$result = (new CachePeopleEmailQuery($this->id))->fetch();

$this->assertIsString($result);
$this->assertSame($this->getExpectedResult(), $result);
}

public function test_attribute_result_is_cached_properties()
{
$query = (new CachePeopleEmailQuery($this->id));
$result = $query->fetch();

$this->assertTrue($query->isCached());
}

public function test_attribute_results_constructed()
{
$result = (new CacheModelQuery($this->id, People::class, 'email'))->fetch();

$this->assertIsString($result);
$this->assertSame($this->getExpectedResult(), $result);
}

public function test_attribute_result_is_cached_constructed()
{
$query = (new CacheModelQuery($this->id, People::class, 'email'));
$result = $query->fetch();

$this->assertTrue($query->isCached());
}

public function test_attribute_cache_keys_are_same()
{
$cacheKey1 = (new CacheModelQuery($this->id, People::class, 'email'))->cacheKey();
$cacheKey2 = (new CachePeopleEmailQuery($this->id))->cacheKey();

$this->assertSame($cacheKey1, $cacheKey2);
}

public function test_model_results_properties()
{
$result = (new CachePeopleQuery($this->id))->fetch();

$this->assertInstanceOf(People::class, $result);
$this->assertEquals(People::query()->find($this->id), $result);
}

public function test_model_result_is_cached_properties()
{
$query = (new CachePeopleQuery($this->id));
$result = $query->fetch();

$this->assertTrue($query->isCached());
}

public function test_model_results_constructed()
{
$result = (new CacheModelQuery($this->id, People::class))->fetch();

$this->assertInstanceOf(People::class, $result);
$this->assertEquals(People::query()->find($this->id), $result);
}

public function test_model_result_is_cached_constructed()
{
$query = (new CacheModelQuery($this->id, People::class));
$result = $query->fetch();

$this->assertTrue($query->isCached());
}

public function test_model_cache_keys_are_same()
{
$cacheKey1 = (new CacheModelQuery($this->id, People::class))->cacheKey();
$cacheKey2 = (new CachePeopleQuery($this->id))->cacheKey();

$this->assertSame($cacheKey1, $cacheKey2);
}
}
4 changes: 2 additions & 2 deletions tests/FilterInterfaceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function test_city_filter_single()
'city' => 'Franklin',
];

$this->assertEquals(2, (new PeopleQueryWithFilters($filters))->execute()->count());
$this->assertEquals(3, (new PeopleQueryWithFilters($filters))->execute()->count());
}

public function test_city_filter_array()
Expand All @@ -32,7 +32,7 @@ public function test_city_filter_array()
],
];

$this->assertEquals(3, (new PeopleQueryWithFilters($filters))->execute()->count());
$this->assertEquals(4, (new PeopleQueryWithFilters($filters))->execute()->count());
}

public function test_name_last_filter_single()
Expand Down
25 changes: 25 additions & 0 deletions tests/Filters/FranklinFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Sfneal\Datum\Tests\Filters;

use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\FilterInterface;

class FranklinFilter implements FilterInterface
{
/**
* Apply a given search value to the builder instance.
*
* @param Builder $query
* @param mixed $value
* @return Builder $query
*/
public function apply(Builder $query, $value)
{
$query
->where('city', '=', 'Franklin')
->where('state', '=', 'MA');

return $query;
}
}
39 changes: 39 additions & 0 deletions tests/Filters/GoatFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Sfneal\Datum\Tests\Filters;

use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\FilterInterface;

class GoatFilter implements FilterInterface
{
/**
* Apply a given search value to the builder instance.
*
* @param Builder $query
* @param mixed $value
* @return Builder $query
*/
public function apply(Builder $query, $value)
{
$query->orWhere(function (Builder $builder) {
$builder
->where('name_first', '=', 'Tahm')
->where('name_last', '=', 'Brady');
});

$query->orWhere(function (Builder $builder) {
$builder
->where('name_first', '=', 'Michael')
->where('name_last', '=', 'Jordan');
});

$query->orWhere(function (Builder $builder) {
$builder
->where('name_first', '=', 'Jon')
->where('name_last', '=', 'Jones');
});

return $query;
}
}
23 changes: 23 additions & 0 deletions tests/Filters/MassFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Sfneal\Datum\Tests\Filters;

use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\FilterInterface;

class MassFilter implements FilterInterface
{
/**
* Apply a given search value to the builder instance.
*
* @param Builder $query
* @param mixed $value
* @return Builder $query
*/
public function apply(Builder $query, $value)
{
$query->where('state', '=', 'MA');

return $query;
}
}
23 changes: 23 additions & 0 deletions tests/Filters/NealFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Sfneal\Datum\Tests\Filters;

use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\FilterInterface;

class NealFilter implements FilterInterface
{
/**
* Apply a given search value to the builder instance.
*
* @param Builder $query
* @param mixed $value
* @return Builder $query
*/
public function apply(Builder $query, $value)
{
$query->where('name_last', '=', 'Neal');

return $query;
}
}
4 changes: 2 additions & 2 deletions tests/Models/People.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
namespace Sfneal\Datum\Tests\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Sfneal\Datum\Tests\Factories\PeopleFactory;
use Sfneal\Models\AbstractModel;

class People extends Model
class People extends AbstractModel
{
use HasFactory;

Expand Down
50 changes: 50 additions & 0 deletions tests/NextOrPreviousModelQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Sfneal\Datum\Tests;

use Sfneal\Datum\Tests\Models\People;
use Sfneal\Queries\NextOrPreviousModelQuery;

class NextOrPreviousModelQueryTest extends TestCase
{
/**
* @var People
*/
private $model;

/**
* Setup the test environment.
*
* @return void
*/
public function setUp(): void
{
parent::setUp();

// Retrieve a random model that is not the first or last
$this->model = People::query()
->where('person_id', '!=', People::query()->min('person_id'))
->where('person_id', '!=', People::query()->max('person_id'))
->get()
->shuffle()
->first();
}

public function test_next_model()
{
$next = (new NextOrPreviousModelQuery(People::class, $this->model->getKey()))
->next()
->execute();

$this->assertTrue($next->getKey() > $this->model->getKey());
}

public function test_previous_model()
{
$next = (new NextOrPreviousModelQuery(People::class, $this->model->getKey()))
->previous()
->execute();

$this->assertTrue($next->getKey() < $this->model->getKey());
}
}
Loading