diff --git a/src/Database/Validator/Query/Filter.php b/src/Database/Validator/Query/Filter.php index 7b576136c..e2d73c722 100644 --- a/src/Database/Validator/Query/Filter.php +++ b/src/Database/Validator/Query/Filter.php @@ -5,6 +5,11 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; +use Utopia\Database\Validator\Datetime as DatetimeValidator; +use Utopia\Validator\Boolean; +use Utopia\Validator\FloatValidator; +use Utopia\Validator\Integer; +use Utopia\Validator\Text; class Filter extends Base { @@ -88,15 +93,39 @@ protected function isValidAttributeAndValues(string $attribute, array $values): $attributeType = $attributeSchema['type']; foreach ($values as $value) { - $condition = match ($attributeType) { - Database::VAR_RELATIONSHIP => true, - Database::VAR_DATETIME => gettype($value) === Database::VAR_STRING, - Database::VAR_FLOAT => (gettype($value) === Database::VAR_FLOAT || gettype($value) === Database::VAR_INTEGER), - default => gettype($value) === $attributeType - }; - - if (!$condition) { - $this->message = 'Query type does not match expected: ' . $attributeType; + + $validator = null; + + switch ($attributeType) { + case Database::VAR_STRING: + $validator = new Text(0, 0); + break; + + case Database::VAR_INTEGER: + $validator = new Integer(); + break; + + case Database::VAR_FLOAT: + $validator = new FloatValidator(); + break; + + case Database::VAR_BOOLEAN: + $validator = new Boolean(); + break; + + case Database::VAR_DATETIME: + $validator = new DatetimeValidator(); + break; + + case Database::VAR_RELATIONSHIP: + break; + default: + $this->message = 'Unknown Data type'; + return false; + } + + if (!\is_null($validator) && !$validator->isValid($value)) { + $this->message = 'Query value is invalid for attribute "' . $attribute . '"'; return false; } } diff --git a/tests/e2e/Adapter/Base.php b/tests/e2e/Adapter/Base.php index 6eb5f4f37..52e6bfd95 100644 --- a/tests/e2e/Adapter/Base.php +++ b/tests/e2e/Adapter/Base.php @@ -4534,18 +4534,37 @@ public function testCreateDatetime(): void Query::greaterThan('date', '1975-12-06 10:00:00+01:00'), Query::lessThan('date', '2030-12-06 10:00:00-01:00'), ]); - $this->assertEquals(1, count($documents)); - $this->expectException(StructureException::class); - static::getDatabase()->createDocument('datetime', new Document([ - '$permissions' => [ - Permission::create(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), - ], - 'date' => "1975-12-06 00:00:61" - ])); + $documents = static::getDatabase()->find('datetime', [ + Query::greaterThan('$createdAt', '1975-12-06 11:00:00.000'), + ]); + $this->assertCount(1, $documents); + + try { + static::getDatabase()->createDocument('datetime', new Document([ + 'date' => "1975-12-06 00:00:61" // 61 seconds is invalid + ])); + $this->fail('Failed to throw exception'); + } catch (Exception $e) { + $this->assertInstanceOf(StructureException::class, $e); + } + + $invalidDates = [ + '1975-12-06 00:00:61', + '16/01/2024 12:00:00AM' + ]; + + foreach ($invalidDates as $date) { + try { + static::getDatabase()->find('datetime', [ + Query::equal('date', [$date]) + ]); + $this->fail('Failed to throw exception'); + } catch (Exception $e) { + $this->assertEquals('Invalid query: Query value is invalid for attribute "date"', $e->getMessage()); + } + } } public function testCreateDateTimeAttributeFailure(): void diff --git a/tests/unit/Validator/QueryTest.php b/tests/unit/Validator/QueryTest.php index b1aaf6c8b..df89fc3b8 100644 --- a/tests/unit/Validator/QueryTest.php +++ b/tests/unit/Validator/QueryTest.php @@ -158,7 +158,7 @@ public function testAttributeWrongType(): void $response = $validator->isValid([Query::equal('title', [1776])]); $this->assertEquals(false, $response); - $this->assertEquals('Invalid query: Query type does not match expected: string', $validator->getDescription()); + $this->assertEquals('Invalid query: Query value is invalid for attribute "title"', $validator->getDescription()); } /**