Skip to content

Commit

Permalink
Merge pull request #320 from utopia-php/fix-keys-missing-in-updating-…
Browse files Browse the repository at this point in the history
…doc-using-relationships

fixes missing keys when updating doc
  • Loading branch information
abnegate authored Sep 7, 2023
2 parents cc0247f + 275f876 commit f2626ac
Show file tree
Hide file tree
Showing 2 changed files with 307 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
299 changes: 299 additions & 0 deletions tests/Database/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -11960,6 +11960,305 @@ 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(
Expand Down

0 comments on commit f2626ac

Please sign in to comment.