From a96134e69684dc246f7c7f6fc64eadd197964b7e Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Wed, 16 Aug 2023 20:43:22 -0400 Subject: [PATCH 1/4] Add test for invalid keys --- tests/Database/Base.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 75030e84c..d37e302dc 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -4415,6 +4415,47 @@ public function testWritePermissions(): void $this->assertEquals('newCat', $docs[0]['type']); } + public function testNoInvalidKeys(): void + { + static::getDatabase()->createCollection('species'); + static::getDatabase()->createCollection('animals'); + + static::getDatabase()->createAttribute('species', 'name', Database::VAR_STRING, 255, true); + static::getDatabase()->createAttribute('animals', 'name', Database::VAR_STRING, 255, true); + + static::getDatabase()->createRelationship( + collection: 'species', + relatedCollection: 'animals', + type: Database::RELATION_ONE_TO_ONE, + twoWay: true, + id: 'animal', + ); + + $species = static::getDatabase()->createDocument('species', new Document([ + '$id' => ID::unique(), + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + 'name' => 'Canine', + 'animal' => [ + '$id' => ID::unique(), + '$permissions' => [ + Permission::read(Role::any()), + ], + 'name' => 'Dog', + ] + ])); + + $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_createdAt', '')); + $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_updatedAt', '')); + + $species = static::getDatabase()->updateDocument('species', $species->getId(), $species->setAttribute('name', 'Tiger')); + + $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_createdAt', '')); + $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_updatedAt', '')); + } + // Relationships public function testOneToOneOneWayRelationship(): void { From 947f43b4d1efe409782830e2a5cb5d35a23856e4 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Thu, 17 Aug 2023 23:24:49 +0530 Subject: [PATCH 2/4] fix no invalid keys --- src/Database/Database.php | 5 +++ tests/Database/Base.php | 70 +++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index 6524abee6..f7fa6249f 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -2920,6 +2920,11 @@ public function updateDocument(string $collection, string $id, Document $documen $time = DateTime::now(); $old = Authorization::skip(fn () => $this->silent(fn () => $this->getDocument($collection, $id))); // Skip ensures user does not need read permission for this + $document = \array_merge($old->getArrayCopy(), $document->getArrayCopy()); + $document['$collection'] = $old->getAttribute('$collection'); // Make sure user doesn't switch collectionID + $document['$createdAt'] = $old->getCreatedAt(); // Make sure user doesn't switch createdAt + $document['$id'] = $old->getId(); + $document = new Document($document); $collection = $this->silent(fn () => $this->getCollection($collection)); $relationships = \array_filter($collection->getAttribute('attributes', []), function ($attribute) { diff --git a/tests/Database/Base.php b/tests/Database/Base.php index d37e302dc..fc294a62d 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -23,7 +23,6 @@ use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Index; -use Utopia\Database\Validator\Query\Filter; use Utopia\Database\Validator\Structure; use Utopia\Validator\Range; use Utopia\Database\Exception\Structure as StructureException; @@ -4415,45 +4414,74 @@ public function testWritePermissions(): void $this->assertEquals('newCat', $docs[0]['type']); } - public function testNoInvalidKeys(): void + public function testNoInvalidKeysWithRelationships(): void { + if (!static::getDatabase()->getAdapter()->getSupportForRelationships()) { + $this->expectNotToPerformAssertions(); + return; + } static::getDatabase()->createCollection('species'); - static::getDatabase()->createCollection('animals'); + static::getDatabase()->createCollection('creatures'); + static::getDatabase()->createCollection('characterstics'); static::getDatabase()->createAttribute('species', 'name', Database::VAR_STRING, 255, true); - static::getDatabase()->createAttribute('animals', 'name', Database::VAR_STRING, 255, true); + static::getDatabase()->createAttribute('creatures', 'name', Database::VAR_STRING, 255, true); + static::getDatabase()->createAttribute('characterstics', 'name', Database::VAR_STRING, 255, true); static::getDatabase()->createRelationship( collection: 'species', - relatedCollection: 'animals', + relatedCollection: 'creatures', + type: Database::RELATION_ONE_TO_ONE, + twoWay: true, + id: 'creature', + twoWayKey:'species' + ); + static::getDatabase()->createRelationship( + collection: 'creatures', + relatedCollection: 'characterstics', type: Database::RELATION_ONE_TO_ONE, twoWay: true, - id: 'animal', + id: 'characterstic', + twoWayKey:'creature' ); $species = static::getDatabase()->createDocument('species', new Document([ - '$id' => ID::unique(), + '$id' => ID::custom('1'), '$permissions' => [ Permission::read(Role::any()), - Permission::update(Role::any()), ], 'name' => 'Canine', - 'animal' => [ - '$id' => ID::unique(), + 'creature' => [ + '$id' => ID::custom('1'), '$permissions' => [ Permission::read(Role::any()), ], 'name' => 'Dog', + 'characterstic' => [ + '$id' => ID::custom('1'), + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + 'name' => 'active', + ] ] ])); - - $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_createdAt', '')); - $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_updatedAt', '')); - - $species = static::getDatabase()->updateDocument('species', $species->getId(), $species->setAttribute('name', 'Tiger')); - - $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_createdAt', '')); - $this->assertEquals('', $species->getAttribute('animal')->getAttribute('_updatedAt', '')); + static::getDatabase()->updateDocument('species', $species->getId(), new Document([ + '$id' => ID::custom('1'), + '$collection' => 'species', + 'creature' => [ + '$id' => ID::custom('1'), + '$collection' => 'creatures', + 'characterstic' => [ + '$id' => ID::custom('1'), + 'name' => 'active', + '$collection' => 'characterstics', + ] + ] + ])); + $updatedSpecies = static::getDatabase()->getDocument('species', $species->getId()); + $this->assertEquals($species, $updatedSpecies); } // Relationships @@ -4953,14 +4981,12 @@ public function testOneToOneTwoWayRelationship(): void $country1 = static::getDatabase()->getDocument('country', 'country1'); $this->assertEquals('London', $country1->getAttribute('city')->getAttribute('name')); - // Update a document with non existing related document. It should not get added to the list. - static::getDatabase()->updateDocument('country', 'country1', $doc->setAttribute('city', 'no-city')); + static::getDatabase()->updateDocument('country', 'country1', (new Document($doc->getArrayCopy()))->setAttribute('city', 'no-city')); $country1Document = static::getDatabase()->getDocument('country', 'country1'); // Assert document does not contain non existing relation document. $this->assertEquals(null, $country1Document->getAttribute('city')); - static::getDatabase()->updateDocument('country', 'country1', $doc->setAttribute('city', 'city1')); - try { + static::getDatabase()->updateDocument('country', 'country1', (new Document($doc->getArrayCopy()))->setAttribute('city','city1')); try { static::getDatabase()->deleteDocument('country', 'country1'); $this->fail('Failed to throw exception'); } catch (Exception $e) { From 6d1a62171f1de1967264ebe72fba84033a3db39c Mon Sep 17 00:00:00 2001 From: prateek banga Date: Thu, 17 Aug 2023 23:25:18 +0530 Subject: [PATCH 3/4] lint fix --- src/Database/Database.php | 2 +- tests/Database/Base.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index f7fa6249f..48c2968b9 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -2923,7 +2923,7 @@ public function updateDocument(string $collection, string $id, Document $documen $document = \array_merge($old->getArrayCopy(), $document->getArrayCopy()); $document['$collection'] = $old->getAttribute('$collection'); // Make sure user doesn't switch collectionID $document['$createdAt'] = $old->getCreatedAt(); // Make sure user doesn't switch createdAt - $document['$id'] = $old->getId(); + $document['$id'] = $old->getId(); $document = new Document($document); $collection = $this->silent(fn () => $this->getCollection($collection)); diff --git a/tests/Database/Base.php b/tests/Database/Base.php index fc294a62d..a9f4ca766 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -4481,7 +4481,7 @@ public function testNoInvalidKeysWithRelationships(): void ] ])); $updatedSpecies = static::getDatabase()->getDocument('species', $species->getId()); - $this->assertEquals($species, $updatedSpecies); + $this->assertEquals($species, $updatedSpecies); } // Relationships @@ -4986,7 +4986,8 @@ public function testOneToOneTwoWayRelationship(): void $country1Document = static::getDatabase()->getDocument('country', 'country1'); // Assert document does not contain non existing relation document. $this->assertEquals(null, $country1Document->getAttribute('city')); - static::getDatabase()->updateDocument('country', 'country1', (new Document($doc->getArrayCopy()))->setAttribute('city','city1')); try { + static::getDatabase()->updateDocument('country', 'country1', (new Document($doc->getArrayCopy()))->setAttribute('city', 'city1')); + try { static::getDatabase()->deleteDocument('country', 'country1'); $this->fail('Failed to throw exception'); } catch (Exception $e) { From 6c53a71da86524a106ae762439aa473242f0d172 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Thu, 17 Aug 2023 23:33:55 +0530 Subject: [PATCH 4/4] adds missing comment back --- tests/Database/Base.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Database/Base.php b/tests/Database/Base.php index a9f4ca766..593e2adbe 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -4981,6 +4981,7 @@ public function testOneToOneTwoWayRelationship(): void $country1 = static::getDatabase()->getDocument('country', 'country1'); $this->assertEquals('London', $country1->getAttribute('city')->getAttribute('name')); + // Update a document with non existing related document. It should not get added to the list. static::getDatabase()->updateDocument('country', 'country1', (new Document($doc->getArrayCopy()))->setAttribute('city', 'no-city')); $country1Document = static::getDatabase()->getDocument('country', 'country1');