From d230e5fc2d3af0273d2e9db7dc2f3c9a17d186b8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 17 Jan 2024 17:56:17 +0200 Subject: [PATCH 1/5] Datetime queries --- phpunit.xml | 2 +- src/Database/Database.php | 4 ++++ src/Database/DateTime.php | 2 ++ tests/e2e/Adapter/Base.php | 47 ++++++++++++++++++++++++++++++-------- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index ccdaa969e..783265d80 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false"> + stopOnFailure="true"> ./tests/unit diff --git a/src/Database/Database.php b/src/Database/Database.php index ca7920ac1..15af9fa46 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -5166,6 +5166,10 @@ public static function convertQueries(Document $collection, array $queries): arr foreach ($attributes as $attribute) { if ($attribute->getAttribute('type') == Database::VAR_DATETIME) { + + var_dump('dsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsds'); + + foreach ($queries as $index => $query) { if ($query->getAttribute() === $attribute->getId()) { $values = $query->getValues(); diff --git a/src/Database/DateTime.php b/src/Database/DateTime.php index b85e9f0b3..501a3aafa 100644 --- a/src/Database/DateTime.php +++ b/src/Database/DateTime.php @@ -62,6 +62,8 @@ public static function setTimezone(string $datetime): string $value->setTimezone(new \DateTimeZone(date_default_timezone_get())); return DateTime::format($value); } catch (\Exception $e) { + var_dump($e->getMessage()); + var_dump($e->getCode()); throw new DatabaseException($e->getMessage(), $e->getCode(), $e); } } diff --git a/tests/e2e/Adapter/Base.php b/tests/e2e/Adapter/Base.php index 6eb5f4f37..578a294b9 100644 --- a/tests/e2e/Adapter/Base.php +++ b/tests/e2e/Adapter/Base.php @@ -4537,15 +4537,44 @@ public function testCreateDatetime(): void $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" - ])); + + + 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); + } + + + 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); + } + + + $documents = static::getDatabase()->find('datetime', [ + Query::equal('date', ['1975-12-06 00:00:61']) + ]); + + $this->assertEquals(true, false); + var_dump($documents); + + + $documents = static::getDatabase()->find('datetime', [ + Query::equal('date', ['2023-10-2515:09:09.966399Z']) + ]); + + var_dump($documents); + + + } public function testCreateDateTimeAttributeFailure(): void From 7f8a1840a8913c0762c37d456247f0a3dadf1b6f Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 18 Jan 2024 13:21:48 +0200 Subject: [PATCH 2/5] Change validations --- phpunit.xml | 2 +- src/Database/Database.php | 4 --- src/Database/DateTime.php | 2 -- src/Database/Validator/Query/Filter.php | 45 ++++++++++++++++++++----- tests/e2e/Adapter/Base.php | 35 +++++++++---------- 5 files changed, 56 insertions(+), 32 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 783265d80..ccdaa969e 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="true"> + stopOnFailure="false"> ./tests/unit diff --git a/src/Database/Database.php b/src/Database/Database.php index 15af9fa46..ca7920ac1 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -5166,10 +5166,6 @@ public static function convertQueries(Document $collection, array $queries): arr foreach ($attributes as $attribute) { if ($attribute->getAttribute('type') == Database::VAR_DATETIME) { - - var_dump('dsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsds'); - - foreach ($queries as $index => $query) { if ($query->getAttribute() === $attribute->getId()) { $values = $query->getValues(); diff --git a/src/Database/DateTime.php b/src/Database/DateTime.php index 501a3aafa..b85e9f0b3 100644 --- a/src/Database/DateTime.php +++ b/src/Database/DateTime.php @@ -62,8 +62,6 @@ public static function setTimezone(string $datetime): string $value->setTimezone(new \DateTimeZone(date_default_timezone_get())); return DateTime::format($value); } catch (\Exception $e) { - var_dump($e->getMessage()); - var_dump($e->getCode()); throw new DatabaseException($e->getMessage(), $e->getCode(), $e); } } diff --git a/src/Database/Validator/Query/Filter.php b/src/Database/Validator/Query/Filter.php index 7b576136c..fa51cd5fe 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,14 +93,38 @@ 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) { + + $validator = null; + + switch ($attributeType) { + case Database::VAR_STRING: + $validator = new Text(9999, 0); // todo: how long can a value be? + 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 type does not match expected: ' . $attributeType; return false; } diff --git a/tests/e2e/Adapter/Base.php b/tests/e2e/Adapter/Base.php index 578a294b9..1abef8ef9 100644 --- a/tests/e2e/Adapter/Base.php +++ b/tests/e2e/Adapter/Base.php @@ -4534,11 +4534,8 @@ 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)); - - try { static::getDatabase()->createDocument('datetime', new Document([ 'date' => "1975-12-06 00:00:61" // 61 seconds is invalid @@ -4548,7 +4545,6 @@ public function testCreateDatetime(): void $this->assertInstanceOf(StructureException::class, $e); } - try { static::getDatabase()->createDocument('datetime', new Document([ 'date' => '1975-12-06 00:00:61' // 61 seconds is invalid @@ -4558,23 +4554,28 @@ public function testCreateDatetime(): void $this->assertInstanceOf(StructureException::class, $e); } + try { + static::getDatabase()->find('datetime', [ + Query::equal('date', ['1975-12-06 00:00:61']) + ]); + $this->fail('Failed to throw exception'); + } catch (Exception $e) { + $this->assertEquals('Invalid query: Query type does not match expected: datetime', $e->getMessage()); + } - $documents = static::getDatabase()->find('datetime', [ - Query::equal('date', ['1975-12-06 00:00:61']) - ]); - - $this->assertEquals(true, false); - var_dump($documents); - + try { + static::getDatabase()->find('datetime', [ + Query::equal('date', ['16/01/2024 12:00:00AM']) + ]); + $this->fail('Failed to throw exception'); + } catch (Exception $e) { + $this->assertEquals('Invalid query: Query type does not match expected: datetime', $e->getMessage()); + } $documents = static::getDatabase()->find('datetime', [ - Query::equal('date', ['2023-10-2515:09:09.966399Z']) + Query::greaterThan('$createdAt', '1975-12-06 11:00:00.000'), ]); - - var_dump($documents); - - - + $this->assertCount(1, $documents); } public function testCreateDateTimeAttributeFailure(): void From 1d07cb7e597947c575351a9a6f29293436a9862d Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 18 Jan 2024 16:32:39 +0200 Subject: [PATCH 3/5] Remove redundant tests --- tests/e2e/Adapter/Base.php | 47 +++++++++++++++----------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/tests/e2e/Adapter/Base.php b/tests/e2e/Adapter/Base.php index 1abef8ef9..b091486aa 100644 --- a/tests/e2e/Adapter/Base.php +++ b/tests/e2e/Adapter/Base.php @@ -4536,46 +4536,35 @@ public function testCreateDatetime(): void ]); $this->assertEquals(1, count($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); - } + $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 + '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); } - try { - static::getDatabase()->find('datetime', [ - Query::equal('date', ['1975-12-06 00:00:61']) - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertEquals('Invalid query: Query type does not match expected: datetime', $e->getMessage()); - } + $invalidDates = [ + '1975-12-06 00:00:61', + '16/01/2024 12:00:00AM' + ]; - try { - static::getDatabase()->find('datetime', [ - Query::equal('date', ['16/01/2024 12:00:00AM']) - ]); - $this->fail('Failed to throw exception'); - } catch (Exception $e) { - $this->assertEquals('Invalid query: Query type does not match expected: datetime', $e->getMessage()); + 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 type does not match expected: datetime', $e->getMessage()); + } } - - $documents = static::getDatabase()->find('datetime', [ - Query::greaterThan('$createdAt', '1975-12-06 11:00:00.000'), - ]); - $this->assertCount(1, $documents); } public function testCreateDateTimeAttributeFailure(): void From 4f104ee95bd1a0aee5d8d9f75aefca5a5a94aed8 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 19 Jan 2024 18:05:45 +1300 Subject: [PATCH 4/5] Apply suggestions from code review --- src/Database/Validator/Query/Filter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Validator/Query/Filter.php b/src/Database/Validator/Query/Filter.php index fa51cd5fe..de3281f00 100644 --- a/src/Database/Validator/Query/Filter.php +++ b/src/Database/Validator/Query/Filter.php @@ -98,7 +98,7 @@ protected function isValidAttributeAndValues(string $attribute, array $values): switch ($attributeType) { case Database::VAR_STRING: - $validator = new Text(9999, 0); // todo: how long can a value be? + $validator = new Text(0, 0); break; case Database::VAR_INTEGER: @@ -125,7 +125,7 @@ protected function isValidAttributeAndValues(string $attribute, array $values): } if (!is_null($validator) && !$validator->isValid($value)) { - $this->message = 'Query type does not match expected: ' . $attributeType; + $this->message = 'Query value invalid for attribute "' . $attribute . '": ' . $validator->getDescription(); return false; } } From 77a60984bec862b573a5366e8eba28b966a6d4e0 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 19 Jan 2024 19:16:42 +1300 Subject: [PATCH 5/5] Update query value validation failure message --- src/Database/Validator/Query/Filter.php | 4 ++-- tests/e2e/Adapter/Base.php | 2 +- tests/unit/Validator/QueryTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Database/Validator/Query/Filter.php b/src/Database/Validator/Query/Filter.php index de3281f00..e2d73c722 100644 --- a/src/Database/Validator/Query/Filter.php +++ b/src/Database/Validator/Query/Filter.php @@ -124,8 +124,8 @@ protected function isValidAttributeAndValues(string $attribute, array $values): return false; } - if (!is_null($validator) && !$validator->isValid($value)) { - $this->message = 'Query value invalid for attribute "' . $attribute . '": ' . $validator->getDescription(); + 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 b091486aa..52e6bfd95 100644 --- a/tests/e2e/Adapter/Base.php +++ b/tests/e2e/Adapter/Base.php @@ -4562,7 +4562,7 @@ public function testCreateDatetime(): void ]); $this->fail('Failed to throw exception'); } catch (Exception $e) { - $this->assertEquals('Invalid query: Query type does not match expected: datetime', $e->getMessage()); + $this->assertEquals('Invalid query: Query value is invalid for attribute "date"', $e->getMessage()); } } } 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()); } /**