Skip to content

Commit

Permalink
Merge pull request #306 from utopia-php/fix-5404-check-related-doc-id
Browse files Browse the repository at this point in the history
fixes edge case in comparison check
  • Loading branch information
abnegate authored Aug 14, 2023
2 parents 5631f15 + 557c630 commit 9ff69a9
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 31 deletions.
4 changes: 4 additions & 0 deletions src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -2940,6 +2940,10 @@ public function updateDocument(string $collection, string $id, Document $documen
foreach ($document as $key => $value) {
// Skip the nested documents as they will be checked later in recursions.
if (\array_key_exists($key, $relationships)) {
// No need to compare nested documents more than max depth.
if (count($this->relationshipWriteStack) >= Database::RELATION_MAX_DEPTH - 1) {
continue;
}
$relationType = (string) $relationships[$key]['options']['relationType'];
$side = (string) $relationships[$key]['options']['side'];

Expand Down
106 changes: 75 additions & 31 deletions tests/Database/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -3326,49 +3326,93 @@ public function testNoChangeUpdateDocumentWithRelationWithoutPermission(): void
$this->expectNotToPerformAssertions();
return;
}
$attribute = new Document([
'$id' => ID::custom("name"),
'type' => Database::VAR_STRING,
'size' => 100,
'required' => false,
'default' => null,
'signed' => false,
'array' => false,
'filters' => [],
]);

static::getDatabase()->createCollection('parentRelationTest');
static::getDatabase()->createCollection('childRelationTest');

static::getDatabase()->createAttribute('parentRelationTest', 'name', Database::VAR_STRING, 255, false);
static::getDatabase()->createAttribute('childRelationTest', 'name', Database::VAR_STRING, 255, false);
$permissions = [
Permission::read(Role::any()),
Permission::create(Role::any()),
Permission::delete(Role::any()),
];
for ($i=1; $i < 6; $i++) {
static::getDatabase()->createCollection("level{$i}", [$attribute], [], $permissions);
}

static::getDatabase()->createRelationship(
collection: 'parentRelationTest',
relatedCollection: 'childRelationTest',
type: Database::RELATION_ONE_TO_MANY,
id: 'children'
);
for ($i = 1; $i < 5; $i++) {
$collectionId = $i;
$relatedCollectionId = $i+1;
static::getDatabase()->createRelationship(
collection: "level{$collectionId}",
relatedCollection: "level{$relatedCollectionId}",
type: Database::RELATION_ONE_TO_ONE,
id: "level{$relatedCollectionId}"
);
}

// Create document with relationship with nested data
$parent = static::getDatabase()->createDocument('parentRelationTest', new Document([
'$id' => 'parent1',
'$permissions' => [
Permission::read(Role::any()),
],
'name' => 'Parent 1',
'children' => [
[
'$id' => 'child1',
'$permissions' => [
Permission::read(Role::any()),
$level1 = static::getDatabase()->createDocument('level1', new Document([
'$id' => 'level1',
'$permissions' => [],
'name' => 'Level 1',
'level2' => [
'$id' => 'level2',
'$permissions' => [],
'name' => 'Level 2',
'level3' => [
'$id' => 'level3',
'$permissions' => [],
'name' => 'Level 3',
'level4' => [
'$id' => 'level4',
'$permissions' => [],
'name' => 'Level 4',
'level5' => [
'$id' => 'level5',
'$permissions' => [],
'name' => 'Level 5',
]
],
'name' => 'Child 1',
],
],
]));
static::getDatabase()->updateDocument('level1', $level1->getId(), new Document($level1->getArrayCopy()));
$updatedLevel1 = static::getDatabase()->getDocument('level1', $level1->getId());
$this->assertEquals($level1, $updatedLevel1);

$this->assertEquals(1, \count($parent['children']));

$parent->setAttribute('children', ['child1']);
try {
static::getDatabase()->updateDocument('level1', $level1->getId(), $level1->setAttribute('name', 'haha'));
$this->fail('Failed to throw exception');
} catch(Exception $e) {
$this->assertInstanceOf(AuthorizationException::class, $e);
}
$level1->setAttribute('name', 'Level 1');
static::getDatabase()->updateCollection('level3', [
Permission::read(Role::any()),
Permission::create(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
], false);
$level2 = $level1->getAttribute('level2');
$level3 = $level2->getAttribute('level3');

$updatedParent = static::getDatabase()->updateDocument('parentRelationTest', 'parent1', $parent);
$level3->setAttribute('name', 'updated value');
$level2->setAttribute('level3', $level3);
$level1->setAttribute('level2', $level2);

$this->assertEquals($updatedParent->getUpdatedAt(), $parent->getUpdatedAt());
$this->assertEquals($updatedParent->getAttribute('children')[0]->getUpdatedAt(), $parent->getAttribute('children')[0]->getUpdatedAt());
$level1 = static::getDatabase()->updateDocument('level1', $level1->getId(), $level1);
$this->assertEquals('updated value', $level1['level2']['level3']['name']);

static::getDatabase()->deleteCollection('parentRelationTest');
static::getDatabase()->deleteCollection('childRelationTest');
for ($i=1; $i < 6; $i++) {
static::getDatabase()->deleteCollection("level{$i}");
}
}

public function testExceptionAttributeLimit(): void
Expand Down

0 comments on commit 9ff69a9

Please sign in to comment.