diff --git a/composer.json b/composer.json index 874ee51..7bc3835 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "illuminate/console": "^5.2" }, "require-dev": { - "mockery/mockery": "dev-master@dev" + "mockery/mockery": "dev-master@dev", + "phpunit/phpunit": "6.*" }, "autoload": { "psr-4": { diff --git a/src/Bosnadev/Repositories/Contracts/RepositoryInterface.php b/src/Bosnadev/Repositories/Contracts/RepositoryInterface.php index 74a3652..9ad7d25 100644 --- a/src/Bosnadev/Repositories/Contracts/RepositoryInterface.php +++ b/src/Bosnadev/Repositories/Contracts/RepositoryInterface.php @@ -74,4 +74,18 @@ public function findAllBy($field, $value, $columns = array('*')); */ public function findWhere($where, $columns = array('*')); + /** + * @param $id + * @param array $columns + * @return mixed + */ + public function findOrFail($id, $columns = array('*')); + + /** + * @param $attribute + * @param $value + * @param array $columns + * @return mixed + */ + public function findByOrFail($attribute, $value, $columns = array('*')); } diff --git a/src/Bosnadev/Repositories/Eloquent/Repository.php b/src/Bosnadev/Repositories/Eloquent/Repository.php index 303fe46..50fa657 100644 --- a/src/Bosnadev/Repositories/Eloquent/Repository.php +++ b/src/Bosnadev/Repositories/Eloquent/Repository.php @@ -244,6 +244,35 @@ public function findWhere($where, $columns = ['*'], $or = false) return $model->get($columns); } + /** + * @param $id + * @param array $columns + * @return mixed + */ + public function findOrFail($id, $columns = array('*')) + { + $model = $this->find($id, $columns); + if (!$model) { + throw new \Illuminate\Database\Eloquent\ModelNotFoundException(sprintf('Nothing found for %d', $id)); + } + return $model; + } + + /** + * @param $attribute + * @param $value + * @param array $columns + * @return mixed + */ + public function findByOrFail($attribute, $value, $columns = array('*')) + { + $model = $this->findBy($attribute, $value, $columns); + if (!$model) { + throw new \Illuminate\Database\Eloquent\ModelNotFoundException(sprintf('Nothing found for %s==%s', $attribute, $value)); + } + return $model; + } + /** * @return \Illuminate\Database\Eloquent\Builder * @throws RepositoryException diff --git a/tests/FindOrFailTest.php b/tests/FindOrFailTest.php new file mode 100644 index 0000000..93eb227 --- /dev/null +++ b/tests/FindOrFailTest.php @@ -0,0 +1,124 @@ + 10, 'data' => 'abc']]; + $this->reinitMocks(collect($items)); + + /** @var RepositoryInterface $sut */ + $sut = $this->getMockForAbstractClass( + Repository::class, + [$this->containerMock, collect($items)] + ); + + $result = $sut->findOrFail(10); + + $this->assertEquals($result->count(), count($items)); + $this->assertEquals($result->all(), $items); + } + + protected function reinitMocks($collection = null) + { + $this->modelMock = m::mock('Illuminate\Database\Eloquent\Model') + ->shouldReceive([ + 'find' => $collection, + 'first' => $collection, + ]) + ->getMock(); + + $this->modelMock = $this->modelMock + ->shouldReceive('where') + ->andReturn($this->modelMock) + ->getMock(); + + $this->containerMock = m::mock(Container::class) + ->expects('make') + ->andReturn($this->modelMock) + ->getMock(); + } + + /** + * @expectedException \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function testFindOrFailNothingFound() + { + $this->reinitMocks(); + + /** @var RepositoryInterface $sut */ + $sut = $this->getMockForAbstractClass( + Repository::class, + [$this->containerMock, collect([])] + ); + + $sut->findOrFail(10); + } + + public function testFindByOrFail() + { + $items = [['id' => 10, 'hash' => 'abc']]; + $this->reinitMocks(collect($items)); + + /** @var RepositoryInterface $sut */ + $sut = $this->getMockForAbstractClass( + Repository::class, + [$this->containerMock, collect($items)] + ); + + $result = $sut->findByOrFail('id', 10); + $this->assertEquals($result->count(), count($items)); + $this->assertEquals($result->all(), $items); + + $result = $sut->findByOrFail('hash', 'abc'); + $this->assertEquals($result->count(), count($items)); + $this->assertEquals($result->all(), $items); + } + + /** + * @expectedException \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function testFindByOrFailNothingFound() + { + $this->reinitMocks(); + + /** @var RepositoryInterface $sut */ + $sut = $this->getMockForAbstractClass( + Repository::class, + [$this->containerMock, collect([])] + ); + + $sut->findByOrFail('id', 10); + } +} diff --git a/tests/RepositoryTest.php b/tests/RepositoryTest.php index 7718f6b..73eb112 100644 --- a/tests/RepositoryTest.php +++ b/tests/RepositoryTest.php @@ -3,7 +3,7 @@ namespace Bosnadev\Tests\Repositories; use \Mockery as m; -use \PHPUnit_Framework_TestCase as TestCase; +use PHPUnit\Framework\TestCase; class RepositoryTest extends TestCase {