From ebcfd4f3f45af8214b5e356d912ee8cf01ff2426 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 17 Oct 2023 18:41:24 +0300 Subject: [PATCH 01/12] Invalid chars --- phpunit.xml | 2 +- src/Database/Adapter/Postgres.php | 2 +- src/Database/Adapter/SQL.php | 2 +- tests/Database/Adapter/MariaDBTest.php | 120 +++++++-------- tests/Database/Adapter/MongoDBTest.php | 194 ++++++++++++------------- tests/Database/Base.php | 38 ++++- 6 files changed, 197 insertions(+), 161 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 31b947dd6..3833748e0 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false"> + stopOnFailure="true"> ./tests/ diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index 97b600123..702526b14 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -739,9 +739,9 @@ public function createDocument(string $collection, Document $document): Document $stmtPermissions->execute(); } } catch (Throwable $e) { + $this->getPDO()->rollBack(); switch ($e->getCode()) { case 23505: - $this->getPDO()->rollBack(); throw new Duplicate('Duplicated document: ' . $e->getMessage()); default: diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index 39729e8b6..313904fe3 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -880,7 +880,7 @@ protected function getSQLTable(string $name): string * Returns the current PDO object * @return mixed */ - protected function getPDO(): mixed + protected function getPDO(): PDO { return $this->pdo; } diff --git a/tests/Database/Adapter/MariaDBTest.php b/tests/Database/Adapter/MariaDBTest.php index af616f260..8831aef4c 100644 --- a/tests/Database/Adapter/MariaDBTest.php +++ b/tests/Database/Adapter/MariaDBTest.php @@ -1,61 +1,61 @@ connect('redis', 6379); - $redis->flushAll(); - $cache = new Cache(new RedisAdapter($redis)); - - $database = new Database(new MariaDB($pdo), $cache); - $database->setDefaultDatabase('utopiaTests'); - $database->setNamespace('myapp_'.uniqid()); - - if ($database->exists('utopiaTests')) { - $database->delete('utopiaTests'); - } - - $database->create(); - - return self::$database = $database; - } -} +// +//namespace Utopia\Tests\Adapter; +// +//use PDO; +//use Redis; +//use Utopia\Database\Database; +//use Utopia\Database\Adapter\MariaDB; +//use Utopia\Cache\Cache; +//use Utopia\Cache\Adapter\Redis as RedisAdapter; +//use Utopia\Tests\Base; +// +//class MariaDBTest extends Base +//{ +// public static ?Database $database = null; +// +// // TODO@kodumbeats hacky way to identify adapters for tests +// // Remove once all methods are implemented +// /** +// * Return name of adapter +// * +// * @return string +// */ +// public static function getAdapterName(): string +// { +// return "mariadb"; +// } +// +// /** +// * @return Database +// */ +// public static function getDatabase(): Database +// { +// if (!is_null(self::$database)) { +// return self::$database; +// } +// +// $dbHost = 'mariadb'; +// $dbPort = '3306'; +// $dbUser = 'root'; +// $dbPass = 'password'; +// +// $pdo = new PDO("mysql:host={$dbHost};port={$dbPort};charset=utf8mb4", $dbUser, $dbPass, MariaDB::getPDOAttributes()); +// $redis = new Redis(); +// $redis->connect('redis', 6379); +// $redis->flushAll(); +// $cache = new Cache(new RedisAdapter($redis)); +// +// $database = new Database(new MariaDB($pdo), $cache); +// $database->setDefaultDatabase('utopiaTests'); +// $database->setNamespace('myapp_'.uniqid()); +// +// if ($database->exists('utopiaTests')) { +// $database->delete('utopiaTests'); +// } +// +// $database->create(); +// +// return self::$database = $database; +// } +//} diff --git a/tests/Database/Adapter/MongoDBTest.php b/tests/Database/Adapter/MongoDBTest.php index 62c48ae37..3cfcd753a 100644 --- a/tests/Database/Adapter/MongoDBTest.php +++ b/tests/Database/Adapter/MongoDBTest.php @@ -1,98 +1,98 @@ connect('redis', 6379); - $redis->flushAll(); - $cache = new Cache(new RedisAdapter($redis)); - - $schema = 'utopiaTests'; // same as $this->testDatabase - $client = new Client( - $schema, - 'mongo', - 27017, - 'root', - 'example', - false - ); - - $database = new Database(new Mongo($client), $cache); - $database->setDefaultDatabase($schema); - $database->setNamespace('myapp_' . uniqid()); - - if ($database->exists('utopiaTests')) { - $database->delete('utopiaTests'); - } - - $database->create(); - - return self::$database = $database; - } - - /** - * @throws Exception - */ - public function testCreateExistsDelete(): void - { - // Mongo creates databases on the fly, so exists would always pass. So we override this test to remove the exists check. - $this->assertNotNull(static::getDatabase()->create()); - $this->assertEquals(true, static::getDatabase()->delete($this->testDatabase)); - $this->assertEquals(true, static::getDatabase()->create()); - $this->assertEquals(true, static::getDatabase()->setDefaultDatabase($this->testDatabase)); - } - - public function testRenameAttribute(): void - { - $this->assertTrue(true); - } - - public function testRenameAttributeExisting(): void - { - $this->assertTrue(true); - } - - public function testUpdateAttributeStructure(): void - { - $this->assertTrue(true); - } - - public function testKeywords(): void - { - $this->assertTrue(true); - } -} +// +//namespace Utopia\Tests\Adapter; +// +//use Exception; +//use Redis; +//use Utopia\Cache\Cache; +//use Utopia\Cache\Adapter\Redis as RedisAdapter; +//use Utopia\Database\Adapter\Mongo; +//use Utopia\Database\Database; +//use Utopia\Mongo\Client; +//use Utopia\Tests\Base; +// +//class MongoDBTest extends Base +//{ +// public static ?Database $database = null; +// +// +// /** +// * Return name of adapter +// * +// * @return string +// */ +// public static function getAdapterName(): string +// { +// return "mongodb"; +// } +// +// /** +// * @return Database +// * @throws Exception +// */ +// public static function getDatabase(): Database +// { +// if (!is_null(self::$database)) { +// return self::$database; +// } +// +// $redis = new Redis(); +// $redis->connect('redis', 6379); +// $redis->flushAll(); +// $cache = new Cache(new RedisAdapter($redis)); +// +// $schema = 'utopiaTests'; // same as $this->testDatabase +// $client = new Client( +// $schema, +// 'mongo', +// 27017, +// 'root', +// 'example', +// false +// ); +// +// $database = new Database(new Mongo($client), $cache); +// $database->setDefaultDatabase($schema); +// $database->setNamespace('myapp_' . uniqid()); +// +// if ($database->exists('utopiaTests')) { +// $database->delete('utopiaTests'); +// } +// +// $database->create(); +// +// return self::$database = $database; +// } +// +// /** +// * @throws Exception +// */ +// public function testCreateExistsDelete(): void +// { +// // Mongo creates databases on the fly, so exists would always pass. So we override this test to remove the exists check. +// $this->assertNotNull(static::getDatabase()->create()); +// $this->assertEquals(true, static::getDatabase()->delete($this->testDatabase)); +// $this->assertEquals(true, static::getDatabase()->create()); +// $this->assertEquals(true, static::getDatabase()->setDefaultDatabase($this->testDatabase)); +// } +// +// public function testRenameAttribute(): void +// { +// $this->assertTrue(true); +// } +// +// public function testRenameAttributeExisting(): void +// { +// $this->assertTrue(true); +// } +// +// public function testUpdateAttributeStructure(): void +// { +// $this->assertTrue(true); +// } +// +// public function testKeywords(): void +// { +// $this->assertTrue(true); +// } +//} diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 99e7b41d0..0c6776e14 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -254,7 +254,6 @@ public function testQueryTimeoutUsingStaticTimeout(): void $this->expectNotToPerformAssertions(); } - /** * @depends testCreateExistsDelete */ @@ -1082,6 +1081,43 @@ public function testCreateDocumentDefaults(): void static::getDatabase()->deleteCollection('defaults'); } + public function testInvalidUtfCharacters(): void + { + $collection = 'null_character'; + + static::getDatabase()->createCollection($collection); + static::getDatabase()->createAttribute($collection, 'str', Database::VAR_STRING, 128, true); + + $str = "\x00"; + $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ + 'str' => $str, + ]))); + + $str = "\u0000"; + $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ + 'str' => $str, + ]))); + + $str = "\000"; + $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ + 'str' => $str, + ]))); + + $str = "\xE2\x94"; + try { + $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ + 'str' => $str, + ]))); + $this->fail('Failed to throw Exception'); + } catch (Exception $e) { + $this->assertTrue(true); + } + + $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ + 'str' => mb_convert_encoding($str, 'UTF-8', 'UTF-8'), + ]))); + } + /** * @throws AuthorizationException|LimitException|DuplicateException|StructureException|Exception|Throwable */ From f67097fd32fdf97873705c9445e6e3e8f21d8607 Mon Sep 17 00:00:00 2001 From: fogelito Date: Tue, 17 Oct 2023 18:44:28 +0300 Subject: [PATCH 02/12] remove commment --- tests/Database/Adapter/MariaDBTest.php | 120 +++++++-------- tests/Database/Adapter/MongoDBTest.php | 194 ++++++++++++------------- 2 files changed, 157 insertions(+), 157 deletions(-) diff --git a/tests/Database/Adapter/MariaDBTest.php b/tests/Database/Adapter/MariaDBTest.php index 8831aef4c..af616f260 100644 --- a/tests/Database/Adapter/MariaDBTest.php +++ b/tests/Database/Adapter/MariaDBTest.php @@ -1,61 +1,61 @@ connect('redis', 6379); -// $redis->flushAll(); -// $cache = new Cache(new RedisAdapter($redis)); -// -// $database = new Database(new MariaDB($pdo), $cache); -// $database->setDefaultDatabase('utopiaTests'); -// $database->setNamespace('myapp_'.uniqid()); -// -// if ($database->exists('utopiaTests')) { -// $database->delete('utopiaTests'); -// } -// -// $database->create(); -// -// return self::$database = $database; -// } -//} + +namespace Utopia\Tests\Adapter; + +use PDO; +use Redis; +use Utopia\Database\Database; +use Utopia\Database\Adapter\MariaDB; +use Utopia\Cache\Cache; +use Utopia\Cache\Adapter\Redis as RedisAdapter; +use Utopia\Tests\Base; + +class MariaDBTest extends Base +{ + public static ?Database $database = null; + + // TODO@kodumbeats hacky way to identify adapters for tests + // Remove once all methods are implemented + /** + * Return name of adapter + * + * @return string + */ + public static function getAdapterName(): string + { + return "mariadb"; + } + + /** + * @return Database + */ + public static function getDatabase(): Database + { + if (!is_null(self::$database)) { + return self::$database; + } + + $dbHost = 'mariadb'; + $dbPort = '3306'; + $dbUser = 'root'; + $dbPass = 'password'; + + $pdo = new PDO("mysql:host={$dbHost};port={$dbPort};charset=utf8mb4", $dbUser, $dbPass, MariaDB::getPDOAttributes()); + $redis = new Redis(); + $redis->connect('redis', 6379); + $redis->flushAll(); + $cache = new Cache(new RedisAdapter($redis)); + + $database = new Database(new MariaDB($pdo), $cache); + $database->setDefaultDatabase('utopiaTests'); + $database->setNamespace('myapp_'.uniqid()); + + if ($database->exists('utopiaTests')) { + $database->delete('utopiaTests'); + } + + $database->create(); + + return self::$database = $database; + } +} diff --git a/tests/Database/Adapter/MongoDBTest.php b/tests/Database/Adapter/MongoDBTest.php index 3cfcd753a..62c48ae37 100644 --- a/tests/Database/Adapter/MongoDBTest.php +++ b/tests/Database/Adapter/MongoDBTest.php @@ -1,98 +1,98 @@ connect('redis', 6379); -// $redis->flushAll(); -// $cache = new Cache(new RedisAdapter($redis)); -// -// $schema = 'utopiaTests'; // same as $this->testDatabase -// $client = new Client( -// $schema, -// 'mongo', -// 27017, -// 'root', -// 'example', -// false -// ); -// -// $database = new Database(new Mongo($client), $cache); -// $database->setDefaultDatabase($schema); -// $database->setNamespace('myapp_' . uniqid()); -// -// if ($database->exists('utopiaTests')) { -// $database->delete('utopiaTests'); -// } -// -// $database->create(); -// -// return self::$database = $database; -// } -// -// /** -// * @throws Exception -// */ -// public function testCreateExistsDelete(): void -// { -// // Mongo creates databases on the fly, so exists would always pass. So we override this test to remove the exists check. -// $this->assertNotNull(static::getDatabase()->create()); -// $this->assertEquals(true, static::getDatabase()->delete($this->testDatabase)); -// $this->assertEquals(true, static::getDatabase()->create()); -// $this->assertEquals(true, static::getDatabase()->setDefaultDatabase($this->testDatabase)); -// } -// -// public function testRenameAttribute(): void -// { -// $this->assertTrue(true); -// } -// -// public function testRenameAttributeExisting(): void -// { -// $this->assertTrue(true); -// } -// -// public function testUpdateAttributeStructure(): void -// { -// $this->assertTrue(true); -// } -// -// public function testKeywords(): void -// { -// $this->assertTrue(true); -// } -//} + +namespace Utopia\Tests\Adapter; + +use Exception; +use Redis; +use Utopia\Cache\Cache; +use Utopia\Cache\Adapter\Redis as RedisAdapter; +use Utopia\Database\Adapter\Mongo; +use Utopia\Database\Database; +use Utopia\Mongo\Client; +use Utopia\Tests\Base; + +class MongoDBTest extends Base +{ + public static ?Database $database = null; + + + /** + * Return name of adapter + * + * @return string + */ + public static function getAdapterName(): string + { + return "mongodb"; + } + + /** + * @return Database + * @throws Exception + */ + public static function getDatabase(): Database + { + if (!is_null(self::$database)) { + return self::$database; + } + + $redis = new Redis(); + $redis->connect('redis', 6379); + $redis->flushAll(); + $cache = new Cache(new RedisAdapter($redis)); + + $schema = 'utopiaTests'; // same as $this->testDatabase + $client = new Client( + $schema, + 'mongo', + 27017, + 'root', + 'example', + false + ); + + $database = new Database(new Mongo($client), $cache); + $database->setDefaultDatabase($schema); + $database->setNamespace('myapp_' . uniqid()); + + if ($database->exists('utopiaTests')) { + $database->delete('utopiaTests'); + } + + $database->create(); + + return self::$database = $database; + } + + /** + * @throws Exception + */ + public function testCreateExistsDelete(): void + { + // Mongo creates databases on the fly, so exists would always pass. So we override this test to remove the exists check. + $this->assertNotNull(static::getDatabase()->create()); + $this->assertEquals(true, static::getDatabase()->delete($this->testDatabase)); + $this->assertEquals(true, static::getDatabase()->create()); + $this->assertEquals(true, static::getDatabase()->setDefaultDatabase($this->testDatabase)); + } + + public function testRenameAttribute(): void + { + $this->assertTrue(true); + } + + public function testRenameAttributeExisting(): void + { + $this->assertTrue(true); + } + + public function testUpdateAttributeStructure(): void + { + $this->assertTrue(true); + } + + public function testKeywords(): void + { + $this->assertTrue(true); + } +} From da736cd3c2d46faf3aa966eadbce958451537fb4 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 10:53:15 +0300 Subject: [PATCH 03/12] Add comments --- tests/Database/Base.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 0c6776e14..877394492 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1083,26 +1083,31 @@ public function testCreateDocumentDefaults(): void public function testInvalidUtfCharacters(): void { - $collection = 'null_character'; + // This test is a reminder we can not insert non UTF chars to UTF field + $collection = 'invalid_characters'; static::getDatabase()->createCollection($collection); static::getDatabase()->createAttribute($collection, 'str', Database::VAR_STRING, 128, true); + // Test insert of null $str = "\x00"; $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str, ]))); + // Test insert of null $str = "\u0000"; $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str, ]))); + // Test insert of null $str = "\000"; $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str, ]))); + // Test fail to insert non-utf chars $str = "\xE2\x94"; try { $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ @@ -1113,8 +1118,12 @@ public function testInvalidUtfCharacters(): void $this->assertTrue(true); } + // Suggestion for fix after cleanup non + // Test success to insert non-utf chars after removal of non-utf chars + $str = "\xE2\x94"; + $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ - 'str' => mb_convert_encoding($str, 'UTF-8', 'UTF-8'), + 'str' => $str ]))); } From 8e521ba1247b35ccec850a442c6c8231c6cd9e93 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 10:54:02 +0300 Subject: [PATCH 04/12] Add comments --- tests/Database/Base.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 877394492..7d706fb2a 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1120,7 +1120,6 @@ public function testInvalidUtfCharacters(): void // Suggestion for fix after cleanup non // Test success to insert non-utf chars after removal of non-utf chars - $str = "\xE2\x94"; $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str From c1511c7f210c6a72a8ef6289fe0a962f95d7f8fb Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 10:55:30 +0300 Subject: [PATCH 05/12] stopOnFailure --- phpunit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index 3833748e0..31b947dd6 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="true"> + stopOnFailure="false"> ./tests/ From 72ea44436fff0de0db5d993b07a5f02fd4c9fee1 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 10:56:50 +0300 Subject: [PATCH 06/12] revert PDO --- src/Database/Adapter/SQL.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index 313904fe3..39729e8b6 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -880,7 +880,7 @@ protected function getSQLTable(string $name): string * Returns the current PDO object * @return mixed */ - protected function getPDO(): PDO + protected function getPDO(): mixed { return $this->pdo; } From 891be9e5c4613b2d0c6033305a13af2ad45547c0 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 16:15:55 +0300 Subject: [PATCH 07/12] Messages --- tests/Database/Base.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 7d706fb2a..ef2a50282 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1115,7 +1115,17 @@ public function testInvalidUtfCharacters(): void ]))); $this->fail('Failed to throw Exception'); } catch (Exception $e) { - $this->assertTrue(true); + $messages = [ + 'SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding "UTF8": 0xe2 0x94 0x20', // Postgres + 'SQLSTATE[HY000]: General error: 1366 Incorrect string value: \'\xE2\x94\' for column \'str\' at row 1', // MySQL + 'Detected invalid UTF-8 for field path "documents.0.str": ?', // Mongo + ]; + + $codes = [ + '22007', // MariaDB + ]; + + $this->assertTrue(in_array($e->getMessage(), $messages) || in_array($e->getCode(), $codes)); } // Suggestion for fix after cleanup non @@ -1124,6 +1134,7 @@ public function testInvalidUtfCharacters(): void $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str ]))); + } /** From 55c99d2c0040473bb8a0aeab7b9c8ffad981518d Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 16:20:17 +0300 Subject: [PATCH 08/12] line --- tests/Database/Base.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index ef2a50282..052bd325c 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1134,7 +1134,6 @@ public function testInvalidUtfCharacters(): void $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str ]))); - } /** From 7195031a782e788195b728f8baeb175d41b36f3b Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 16:49:15 +0300 Subject: [PATCH 09/12] Double quoute issue with Mongo --- tests/Database/Base.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 052bd325c..fb683a2c9 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1116,9 +1116,9 @@ public function testInvalidUtfCharacters(): void $this->fail('Failed to throw Exception'); } catch (Exception $e) { $messages = [ - 'SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding "UTF8": 0xe2 0x94 0x20', // Postgres - 'SQLSTATE[HY000]: General error: 1366 Incorrect string value: \'\xE2\x94\' for column \'str\' at row 1', // MySQL - 'Detected invalid UTF-8 for field path "documents.0.str": ?', // Mongo + "SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding \"UTF8\": 0xe2 0x94 0x20", // Postgres + "SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xE2\x94' for column 'str' at row 1", // MySQL + "Detected invalid UTF-8 for field path \"documents.0.str\": \xE2\x94", // Mongo, must use double quotes! ]; $codes = [ From 2d7e4a02a8e7a319c8337ec23031fcb840523cb2 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 18 Oct 2023 18:38:25 +0300 Subject: [PATCH 10/12] Mysql single quotes --- tests/Database/Base.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index fb683a2c9..6725f0366 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1117,8 +1117,8 @@ public function testInvalidUtfCharacters(): void } catch (Exception $e) { $messages = [ "SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding \"UTF8\": 0xe2 0x94 0x20", // Postgres - "SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xE2\x94' for column 'str' at row 1", // MySQL - "Detected invalid UTF-8 for field path \"documents.0.str\": \xE2\x94", // Mongo, must use double quotes! + 'SQLSTATE[HY000]: General error: 1366 Incorrect string value: \'\xE2\x94\' for column \'str\' at row 1', // MySQL // Use single quotes! + "Detected invalid UTF-8 for field path \"documents.0.str\": \xE2\x94", // Mongo, Use double quotes! ]; $codes = [ From 8aeaea3089798c8a5fad05ef20593e38a4832f54 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 19 Oct 2023 13:00:21 +0300 Subject: [PATCH 11/12] Fix utf chars --- phpunit.xml | 2 +- tests/Database/Base.php | 37 ++++++++----------------------------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 31b947dd6..3833748e0 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false"> + stopOnFailure="true"> ./tests/ diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 6725f0366..85158ad83 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -1090,46 +1090,25 @@ public function testInvalidUtfCharacters(): void static::getDatabase()->createAttribute($collection, 'str', Database::VAR_STRING, 128, true); // Test insert of null - $str = "\x00"; + $str = "\x00"; // Use double quotes! $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ - 'str' => $str, + 'str' => $str ]))); // Test insert of null - $str = "\u0000"; + $str = "\u0000"; // Use double quotes! $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ - 'str' => $str, + 'str' => $str ]))); - // Test insert of null - $str = "\000"; + // Test insert of null Use double quotes + $str = "\000"; // Use double quotes! $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str, ]))); - // Test fail to insert non-utf chars - $str = "\xE2\x94"; - try { - $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ - 'str' => $str, - ]))); - $this->fail('Failed to throw Exception'); - } catch (Exception $e) { - $messages = [ - "SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding \"UTF8\": 0xe2 0x94 0x20", // Postgres - 'SQLSTATE[HY000]: General error: 1366 Incorrect string value: \'\xE2\x94\' for column \'str\' at row 1', // MySQL // Use single quotes! - "Detected invalid UTF-8 for field path \"documents.0.str\": \xE2\x94", // Mongo, Use double quotes! - ]; - - $codes = [ - '22007', // MariaDB - ]; - - $this->assertTrue(in_array($e->getMessage(), $messages) || in_array($e->getCode(), $codes)); - } - - // Suggestion for fix after cleanup non - // Test success to insert non-utf chars after removal of non-utf chars + // Suggestion for fix: cleanup non-utf chars + $str = "\xE2\x94"; // Use double quotes! $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createDocument($collection, new Document([ 'str' => $str From 83e25257d9065511a6e54fa8c5d2d2887aa18ca8 Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 19 Oct 2023 13:02:53 +0300 Subject: [PATCH 12/12] stopOnFailure --- phpunit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index 3833748e0..31b947dd6 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="true"> + stopOnFailure="false"> ./tests/