Skip to content

Commit

Permalink
Merge pull request #273 from utopia-php/bug_double_relation
Browse files Browse the repository at this point in the history
Identical twoWayKey
  • Loading branch information
abnegate authored May 26, 2023
2 parents 3e7c866 + 9540fa7 commit ba3dcda
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 32 deletions.
60 changes: 30 additions & 30 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,13 @@ public function createRelationship(
if (\strtolower($attribute->getId()) === \strtolower($id)) {
throw new DuplicateException('Attribute already exists');
}

if ($attribute->getAttribute('type') === self::VAR_RELATIONSHIP
&& \strtolower($attribute->getAttribute('options')['twoWayKey']) === \strtolower($twoWayKey)
&& $attribute->getAttribute('options')['relatedCollection'] === $relatedCollection->getId()
) {
throw new DuplicateException('Related attribute already exists');
}
}

if (
Expand Down Expand Up @@ -1663,7 +1670,7 @@ public function updateRelationship(
!\is_null($newTwoWayKey)
&& \in_array($newTwoWayKey, \array_map(fn ($attribute) => $attribute['key'], $relatedAttributes))
) {
throw new DuplicateException('Attribute already exists');
throw new DuplicateException('Related attribute already exists');
}

$type = $attribute['options']['relationType'];
Expand Down
99 changes: 98 additions & 1 deletion tests/Database/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -4733,6 +4733,103 @@ public function testOneToOneTwoWayRelationship(): void
$this->assertEquals(null, $country);
}

public function testIdenticalTwoWayKeyRelationship(): void
{
if (!static::getDatabase()->getAdapter()->getSupportForRelationships()) {
$this->expectNotToPerformAssertions();
return;
}

static::getDatabase()->createCollection('parent');
static::getDatabase()->createCollection('child');

static::getDatabase()->createRelationship(
collection: 'parent',
relatedCollection: 'child',
type: Database::RELATION_ONE_TO_ONE,
id: 'child1'
);

try {
static::getDatabase()->createRelationship(
collection: 'parent',
relatedCollection: 'child',
type: Database::RELATION_ONE_TO_MANY,
id: 'children',
);
$this->fail('Failed to throw Exception');
} catch (Exception $e) {
$this->assertEquals('Related attribute already exists', $e->getMessage());
}

static::getDatabase()->createRelationship(
collection: 'parent',
relatedCollection: 'child',
type: Database::RELATION_ONE_TO_MANY,
id: 'children',
twoWayKey: 'parent_id'
);

$collection = static::getDatabase()->getCollection('parent');
$attributes = $collection->getAttribute('attributes', []);
foreach ($attributes as $attribute) {
if ($attribute['key'] === 'child1') {
$this->assertEquals('parent', $attribute['options']['twoWayKey']);
}

if ($attribute['key'] === 'children') {
$this->assertEquals('parent_id', $attribute['options']['twoWayKey']);
}
}

static::getDatabase()->createDocument('parent', new Document([
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'child1' => [
'$id' => 'foo',
'$permissions' => [Permission::read(Role::any())],
],
'children' => [
[
'$id' => 'bar',
'$permissions' => [Permission::read(Role::any())],
],
],
]));

$documents = static::getDatabase()->find('parent', []);
$document = array_pop($documents);
$this->assertArrayHasKey('child1', $document);
$this->assertEquals('foo', $document->getAttribute('child1')->getId());
$this->assertArrayHasKey('children', $document);
$this->assertEquals('bar', $document->getAttribute('children')[0]->getId());

try {
static::getDatabase()->updateRelationship(
collection: 'parent',
id: 'children',
newKey: 'child1'
);
$this->fail('Failed to throw Exception');
} catch (Exception $e) {
$this->assertEquals('Attribute already exists', $e->getMessage());
}

try {
static::getDatabase()->updateRelationship(
collection: 'parent',
id: 'children',
newTwoWayKey: 'parent'
);
$this->fail('Failed to throw Exception');
} catch (Exception $e) {
$this->assertEquals('Related attribute already exists', $e->getMessage());
}
}

public function testOneToManyOneWayRelationship(): void
{
if (!static::getDatabase()->getAdapter()->getSupportForRelationships()) {
Expand Down Expand Up @@ -10164,7 +10261,7 @@ public function testUpdateRelationshipToExistingKey(): void
static::getDatabase()->updateRelationship('ovens', 'cakes', newTwoWayKey: 'height');
$this->fail('Failed to throw exception');
} catch (DuplicateException $e) {
$this->assertEquals('Attribute already exists', $e->getMessage());
$this->assertEquals('Related attribute already exists', $e->getMessage());
}
}

Expand Down

0 comments on commit ba3dcda

Please sign in to comment.