From 5769f8dcbea29bdf1698eddafac1650dc3f14069 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Mon, 4 Sep 2023 16:28:19 +0530 Subject: [PATCH 1/3] fixes missing keys when updating doc --- src/Database/Database.php | 8 + tests/Database/Base.php | 301 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 309 insertions(+) diff --git a/src/Database/Database.php b/src/Database/Database.php index 3c4d8d932..52ff65ad5 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -3111,6 +3111,14 @@ private function updateDocumentRelationships(Document $collection, Document $old $side = (string) $relationship['options']['side']; if ($oldValue == $value) { + if ( + ($relationType === Database::RELATION_ONE_TO_ONE || + ($relationType === DATABASE::RELATION_MANY_TO_ONE && $side === DATABASE::RELATION_SIDE_PARENT)) && + $value instanceof Document + ) { + $document->setAttribute($key,$value->getId()); + continue; + } $document->removeAttribute($key); continue; } diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 021894901..18cbe7292 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -11960,6 +11960,307 @@ public function testCreateRelationDocumentWithoutUpdatePermission(): void static::getDatabase()->deleteCollection('childRelationTest'); } + public function testUpdateDocumentWithRelationships(): void { + if (!static::getDatabase()->getAdapter()->getSupportForRelationships()) { + $this->expectNotToPerformAssertions(); + return; + } + static::getDatabase()->createCollection('userProfiles', [ + new Document([ + '$id' => ID::custom('username'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('links', [ + new Document([ + '$id' => ID::custom('title'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('videos', [ + new Document([ + '$id' => ID::custom('title'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('products', [ + new Document([ + '$id' => ID::custom('title'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('settings', [ + new Document([ + '$id' => ID::custom('metaTitle'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('appearance', [ + new Document([ + '$id' => ID::custom('metaTitle'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('group', [ + new Document([ + '$id' => ID::custom('name'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + static::getDatabase()->createCollection('community', [ + new Document([ + '$id' => ID::custom('name'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 700, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ]), + ], [], [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()) + ]); + + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'links', + type: Database::RELATION_ONE_TO_MANY, + id: 'links' + ); + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'videos', + type: Database::RELATION_ONE_TO_MANY, + id: 'videos' + ); + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'products', + type: Database::RELATION_ONE_TO_MANY, + twoWay: true, + id: 'products', + twoWayKey: 'userProfile', + ); + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'settings', + type: Database::RELATION_ONE_TO_ONE, + id: 'settings' + ); + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'appearance', + type: Database::RELATION_ONE_TO_ONE, + id: 'appearance' + ); + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'group', + type: Database::RELATION_MANY_TO_ONE, + id: 'group' + ); + + static::getDatabase()->createRelationship( + collection: 'userProfiles', + relatedCollection: 'community', + type: Database::RELATION_MANY_TO_ONE, + id: 'community' + ); + + $profile = static::getDatabase()->createDocument('userProfiles', new Document([ + '$id' => '1', + 'username' => 'user1', + 'links' => [ + [ + '$id' => 'link1', + 'title' => 'Link 1', + ], + ], + 'videos' => [ + [ + '$id' => 'video1', + 'title' => 'Video 1', + ], + ], + 'products' => [ + [ + '$id' => 'product1', + 'title' => 'Product 1', + ], + ], + 'settings' => [ + '$id' => 'settings1', + 'metaTitle' => 'Meta Title', + ], + 'appearance' => [ + '$id' => 'appearance1', + 'metaTitle' => 'Meta Title', + ], + 'group' => [ + '$id' => 'group1', + 'name' => 'Group 1', + ], + 'community' => [ + '$id' => 'community1', + 'name' => 'Community 1', + ], + ])); + $this->assertEquals('link1', $profile->getAttribute('links')[0]->getId()); + $this->assertEquals('settings1', $profile->getAttribute('settings')->getId()); + $this->assertEquals('group1', $profile->getAttribute('group')->getId()); + $this->assertEquals('community1', $profile->getAttribute('community')->getId()); + $this->assertEquals('video1', $profile->getAttribute('videos')[0]->getId()); + $this->assertEquals('product1', $profile->getAttribute('products')[0]->getId()); + $this->assertEquals('appearance1', $profile->getAttribute('appearance')->getId()); + + + $profile->setAttribute('links', [ + [ + '$id' => 'link1', + 'title' => 'New Link Value', + ], + ]); + + $profile->setAttribute('settings', [ + '$id' => 'settings1', + 'metaTitle' => 'New Meta Title', + ]); + + $profile->setAttribute('group', [ + '$id' => 'group1', + 'name' => 'New Group Name', + ]); + + $updatedProfile = static::getDatabase()->updateDocument('userProfiles', '1', $profile); + + $this->assertEquals('New Link Value', $updatedProfile->getAttribute('links')[0]->getAttribute('title')); + $this->assertEquals('New Meta Title', $updatedProfile->getAttribute('settings')->getAttribute('metaTitle')); + $this->assertEquals('New Group Name', $updatedProfile->getAttribute('group')->getAttribute('name')); + + // This is the point of test, related documents should be present if they are not updated + $this->assertEquals('Video 1', $updatedProfile->getAttribute('videos')[0]->getAttribute('title')); + $this->assertEquals('Product 1', $updatedProfile->getAttribute('products')[0]->getAttribute('title')); + $this->assertEquals('Meta Title', $updatedProfile->getAttribute('appearance')->getAttribute('metaTitle')); + $this->assertEquals('Community 1', $updatedProfile->getAttribute('community')->getAttribute('name')); + + + // updating document using two way key in one to many relationship + $product = static::getDatabase()->getDocument('products', 'product1'); + $product->setAttribute('userProfile', [ + '$id' => '1', + 'username' => 'updated user value', + ]); + $updatedProduct = static::getDatabase()->updateDocument('products', 'product1', $product); + $this->assertEquals('updated user value', $updatedProduct->getAttribute('userProfile')->getAttribute('username')); + $this->assertEquals('Product 1', $updatedProduct->getAttribute('title')); + $this->assertEquals('product1', $updatedProduct->getId()); + $this->assertEquals('1', $updatedProduct->getAttribute('userProfile')->getId()); + + static::getDatabase()->deleteCollection('userProfiles'); + static::getDatabase()->deleteCollection('links'); + static::getDatabase()->deleteCollection('settings'); + static::getDatabase()->deleteCollection('group'); + static::getDatabase()->deleteCollection('community'); + static::getDatabase()->deleteCollection('videos'); + static::getDatabase()->deleteCollection('products'); + static::getDatabase()->deleteCollection('appearance'); + } + public function testLabels(): void { $this->assertInstanceOf('Utopia\Database\Document', static::getDatabase()->createCollection( From 77e0a9610b1d9f5b56627f07b59a5e6c1ab8f2b8 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Mon, 4 Sep 2023 16:36:05 +0530 Subject: [PATCH 2/3] lint fix --- src/Database/Database.php | 6 +++--- tests/Database/Base.php | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index 52ff65ad5..7f7986c40 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -3112,11 +3112,11 @@ private function updateDocumentRelationships(Document $collection, Document $old if ($oldValue == $value) { if ( - ($relationType === Database::RELATION_ONE_TO_ONE || - ($relationType === DATABASE::RELATION_MANY_TO_ONE && $side === DATABASE::RELATION_SIDE_PARENT)) && + ($relationType === Database::RELATION_ONE_TO_ONE || + ($relationType === DATABASE::RELATION_MANY_TO_ONE && $side === DATABASE::RELATION_SIDE_PARENT)) && $value instanceof Document ) { - $document->setAttribute($key,$value->getId()); + $document->setAttribute($key, $value->getId()); continue; } $document->removeAttribute($key); diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 18cbe7292..738a801f0 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -11960,7 +11960,8 @@ public function testCreateRelationDocumentWithoutUpdatePermission(): void static::getDatabase()->deleteCollection('childRelationTest'); } - public function testUpdateDocumentWithRelationships(): void { + public function testUpdateDocumentWithRelationships(): void + { if (!static::getDatabase()->getAdapter()->getSupportForRelationships()) { $this->expectNotToPerformAssertions(); return; @@ -12110,7 +12111,6 @@ public function testUpdateDocumentWithRelationships(): void { Permission::delete(Role::any()) ]); - static::getDatabase()->createRelationship( collection: 'userProfiles', relatedCollection: 'links', @@ -12208,7 +12208,6 @@ public function testUpdateDocumentWithRelationships(): void { $this->assertEquals('product1', $profile->getAttribute('products')[0]->getId()); $this->assertEquals('appearance1', $profile->getAttribute('appearance')->getId()); - $profile->setAttribute('links', [ [ '$id' => 'link1', @@ -12238,7 +12237,6 @@ public function testUpdateDocumentWithRelationships(): void { $this->assertEquals('Meta Title', $updatedProfile->getAttribute('appearance')->getAttribute('metaTitle')); $this->assertEquals('Community 1', $updatedProfile->getAttribute('community')->getAttribute('name')); - // updating document using two way key in one to many relationship $product = static::getDatabase()->getDocument('products', 'product1'); $product->setAttribute('userProfile', [ @@ -12250,7 +12248,7 @@ public function testUpdateDocumentWithRelationships(): void { $this->assertEquals('Product 1', $updatedProduct->getAttribute('title')); $this->assertEquals('product1', $updatedProduct->getId()); $this->assertEquals('1', $updatedProduct->getAttribute('userProfile')->getId()); - + static::getDatabase()->deleteCollection('userProfiles'); static::getDatabase()->deleteCollection('links'); static::getDatabase()->deleteCollection('settings'); From 275f876adace36b7a529dcdf97ff8de209b22871 Mon Sep 17 00:00:00 2001 From: prateek banga Date: Mon, 4 Sep 2023 16:38:28 +0530 Subject: [PATCH 3/3] lint fix --- src/Database/Database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index 7f7986c40..8292bf6bf 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -3113,7 +3113,7 @@ private function updateDocumentRelationships(Document $collection, Document $old if ($oldValue == $value) { if ( ($relationType === Database::RELATION_ONE_TO_ONE || - ($relationType === DATABASE::RELATION_MANY_TO_ONE && $side === DATABASE::RELATION_SIDE_PARENT)) && + ($relationType === Database::RELATION_MANY_TO_ONE && $side === Database::RELATION_SIDE_PARENT)) && $value instanceof Document ) { $document->setAttribute($key, $value->getId());