Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -3589,7 +3589,8 @@ public function createRelationship(
}

if (
$attribute->getAttribute('type') === self::VAR_RELATIONSHIP
$twoWay
&& $attribute->getAttribute('type') === self::VAR_RELATIONSHIP
&& \strtolower($attribute->getAttribute('options')['twoWayKey']) === \strtolower($twoWayKey)
&& $attribute->getAttribute('options')['relatedCollection'] === $relatedCollection->getId()
Comment thread
coderabbitai[bot] marked this conversation as resolved.
) {
Expand Down
58 changes: 24 additions & 34 deletions tests/e2e/Adapter/Scopes/Relationships/OneToOneTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -1024,26 +1024,37 @@ public function testIdenticalTwoWayKeyRelationship(): void
id: 'child1'
);

$result = $database->createRelationship(
collection: 'parent',
relatedCollection: 'child',
type: Database::RELATION_ONE_TO_MANY,
id: 'children',
);
$this->assertTrue($result);

$result = $database->createRelationship(
collection: 'parent',
relatedCollection: 'child',
type: Database::RELATION_ONE_TO_MANY,
id: 'childrenById',
twoWayKey: 'parent_id'
);
$this->assertTrue($result);

try {
$database->createRelationship(
collection: 'parent',
relatedCollection: 'child',
type: Database::RELATION_ONE_TO_MANY,
id: 'children',
twoWay: true,
id: 'twoWayChildren',
twoWayKey: 'parent_id'
);
$this->fail('Failed to throw Exception');
} catch (Exception $e) {
$this->assertEquals('Related attribute already exists', $e->getMessage());
}
Comment on lines 1044 to 1056
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Exception asserted against a one-way relationship's metadata

The DuplicateException is thrown here because childrenById (a one-way relationship) happens to carry the same twoWayKey value in its stored options. Since one-way relationships do not create a real reverse attribute in the related collection, the error message 'Related attribute already exists' is misleading — the attribute does not actually exist at the schema level.

More importantly, this test does not exercise the core guard: a genuine two-way vs two-way reverse-key collision, where the reverse attribute was actually created in the related collection. A stronger coverage would first create a twoWay: true relationship, then attempt to create a second twoWay: true relationship pointing at the same relatedCollection with an identical reverse key, and assert DuplicateException is thrown. Without that scenario, a future change could accidentally weaken the guard for real two-way key conflicts and the test suite would not catch the regression.


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

$collection = $database->getCollection('parent');
$attributes = $collection->getAttribute('attributes', []);
foreach ($attributes as $attribute) {
Expand All @@ -1052,35 +1063,14 @@ public function testIdenticalTwoWayKeyRelationship(): void
}

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

if ($attribute['key'] === 'childrenById') {
$this->assertEquals('parent_id', $attribute['options']['twoWayKey']);
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
}

$database->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 = $database->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 {
$database->updateRelationship(
collection: 'parent',
Expand Down
Loading