From 33c56abcf441f001612400272ce323671b7863b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Nabia=C5=82ek?= Date: Thu, 24 Aug 2017 21:15:21 +0200 Subject: [PATCH] [5.5] Add whereIn and whereNotIn constraints to DatabaseRule (#20691) * Add whereIn and whereNotIn constraints to DatabaseRule * Add integration tests for whereIn and whereNotIn rules for DatabaseRule * Apply StyleCI patch --- .../Validation/Rules/DatabaseRule.php | 38 +++- tests/Validation/ValidationExistsRuleTest.php | 166 +++++++++++++++++- 2 files changed, 197 insertions(+), 7 deletions(-) diff --git a/src/Illuminate/Validation/Rules/DatabaseRule.php b/src/Illuminate/Validation/Rules/DatabaseRule.php index c1fe9c8bc2d1..f18bcbf5e111 100644 --- a/src/Illuminate/Validation/Rules/DatabaseRule.php +++ b/src/Illuminate/Validation/Rules/DatabaseRule.php @@ -28,11 +28,11 @@ trait DatabaseRule protected $wheres = []; /** - * The custom query callback. + * The array of custom query callbacks. * - * @var \Closure|null + * @var array */ - protected $using; + protected $using = []; /** * Create a new rule instance. @@ -99,6 +99,34 @@ public function whereNotNull($column) return $this->where($column, 'NOT_NULL'); } + /** + * Set a "where in" constraint on the query. + * + * @param string $column + * @param array $values + * @return $this + */ + public function whereIn($column, array $values) + { + return $this->where(function ($query) use ($column, $values) { + $query->whereIn($column, $values); + }); + } + + /** + * Set a "where not in" constraint on the query. + * + * @param string $column + * @param array $values + * @return $this + */ + public function whereNotIn($column, array $values) + { + return $this->where(function ($query) use ($column, $values) { + $query->whereNotIn($column, $values); + }); + } + /** * Register a custom query callback. * @@ -107,7 +135,7 @@ public function whereNotNull($column) */ public function using(Closure $callback) { - $this->using = $callback; + $this->using[] = $callback; return $this; } @@ -119,7 +147,7 @@ public function using(Closure $callback) */ public function queryCallbacks() { - return $this->using ? [$this->using] : []; + return $this->using; } /** diff --git a/tests/Validation/ValidationExistsRuleTest.php b/tests/Validation/ValidationExistsRuleTest.php index 07a999c04ed5..329831d8a153 100644 --- a/tests/Validation/ValidationExistsRuleTest.php +++ b/tests/Validation/ValidationExistsRuleTest.php @@ -3,17 +3,179 @@ namespace Illuminate\Tests\Validation; use PHPUnit\Framework\TestCase; +use Illuminate\Validation\Validator; +use Illuminate\Validation\Rules\Exists; +use Illuminate\Database\Capsule\Manager as DB; +use Illuminate\Database\Eloquent\Model as Eloquent; +use Illuminate\Validation\DatabasePresenceVerifier; class ValidationExistsRuleTest extends TestCase { + /** + * Setup the database schema. + * + * @return void + */ + public function setUp() + { + $db = new DB; + + $db->addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + $db->bootEloquent(); + $db->setAsGlobal(); + + $this->createSchema(); + } + public function testItCorrectlyFormatsAStringVersionOfTheRule() { - $rule = new \Illuminate\Validation\Rules\Exists('table'); + $rule = new Exists('table'); $rule->where('foo', 'bar'); $this->assertEquals('exists:table,NULL,foo,bar', (string) $rule); - $rule = new \Illuminate\Validation\Rules\Exists('table', 'column'); + $rule = new Exists('table', 'column'); $rule->where('foo', 'bar'); $this->assertEquals('exists:table,column,foo,bar', (string) $rule); } + + public function testItChoosesValidRecordsUsingWhereInRule() + { + $rule = new Exists('users', 'id'); + $rule->whereIn('type', ['foo', 'bar']); + + EloquentTestUser::create(['id' => '1', 'type' => 'foo']); + EloquentTestUser::create(['id' => '2', 'type' => 'bar']); + EloquentTestUser::create(['id' => '3', 'type' => 'baz']); + EloquentTestUser::create(['id' => '4', 'type' => 'other']); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, [], ['id' => $rule]); + $v->setPresenceVerifier(new DatabasePresenceVerifier(Eloquent::getConnectionResolver())); + + $v->setData(['id' => 1]); + $this->assertTrue($v->passes()); + $v->setData(['id' => 2]); + $this->assertTrue($v->passes()); + $v->setData(['id' => 3]); + $this->assertFalse($v->passes()); + $v->setData(['id' => 4]); + $this->assertFalse($v->passes()); + } + + public function testItChoosesValidRecordsUsingWhereNotInRule() + { + $rule = new Exists('users', 'id'); + $rule->whereNotIn('type', ['foo', 'bar']); + + EloquentTestUser::create(['id' => '1', 'type' => 'foo']); + EloquentTestUser::create(['id' => '2', 'type' => 'bar']); + EloquentTestUser::create(['id' => '3', 'type' => 'baz']); + EloquentTestUser::create(['id' => '4', 'type' => 'other']); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, [], ['id' => $rule]); + $v->setPresenceVerifier(new DatabasePresenceVerifier(Eloquent::getConnectionResolver())); + + $v->setData(['id' => 1]); + $this->assertFalse($v->passes()); + $v->setData(['id' => 2]); + $this->assertFalse($v->passes()); + $v->setData(['id' => 3]); + $this->assertTrue($v->passes()); + $v->setData(['id' => 4]); + $this->assertTrue($v->passes()); + } + + public function testItChoosesValidRecordsUsingWhereNotInAndWhereNotInRulesTogether() + { + $rule = new Exists('users', 'id'); + $rule->whereIn('type', ['foo', 'bar', 'baz'])->whereNotIn('type', ['foo', 'bar']); + + EloquentTestUser::create(['id' => '1', 'type' => 'foo']); + EloquentTestUser::create(['id' => '2', 'type' => 'bar']); + EloquentTestUser::create(['id' => '3', 'type' => 'baz']); + EloquentTestUser::create(['id' => '4', 'type' => 'other']); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, [], ['id' => $rule]); + $v->setPresenceVerifier(new DatabasePresenceVerifier(Eloquent::getConnectionResolver())); + + $v->setData(['id' => 1]); + $this->assertFalse($v->passes()); + $v->setData(['id' => 2]); + $this->assertFalse($v->passes()); + $v->setData(['id' => 3]); + $this->assertTrue($v->passes()); + $v->setData(['id' => 4]); + $this->assertFalse($v->passes()); + } + + protected function createSchema() + { + $this->schema('default')->create('users', function ($table) { + $table->unsignedInteger('id'); + $table->string('type'); + }); + } + + /** + * Get a schema builder instance. + * + * @return \Illuminate\Database\Schema\Builder + */ + protected function schema($connection = 'default') + { + return $this->connection($connection)->getSchemaBuilder(); + } + + /** + * Get a database connection instance. + * + * @return \Illuminate\Database\Connection + */ + protected function connection($connection = 'default') + { + return $this->getConnectionResolver()->connection($connection); + } + + /** + * Get connection resolver. + * + * @return \Illuminate\Database\ConnectionResolverInterface + */ + protected function getConnectionResolver() + { + return Eloquent::getConnectionResolver(); + } + + /** + * Tear down the database schema. + * + * @return void + */ + public function tearDown() + { + $this->schema('default')->drop('users'); + } + + public function getIlluminateArrayTranslator() + { + return new \Illuminate\Translation\Translator( + new \Illuminate\Translation\ArrayLoader, 'en' + ); + } +} + +/** + * Eloquent Models. + */ +class EloquentTestUser extends Eloquent +{ + protected $table = 'users'; + protected $guarded = []; + public $timestamps = false; }