Skip to content

Commit 48eec93

Browse files
updated relationship tests for the batch transaction update of parent + relationships
1 parent b92b7aa commit 48eec93

4 files changed

Lines changed: 333 additions & 0 deletions

File tree

tests/e2e/Adapter/Scopes/Relationships/ManyToManyTests.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Utopia\Database\Database;
77
use Utopia\Database\Document;
88
use Utopia\Database\Exception\Restricted as RestrictedException;
9+
use Utopia\Database\Exception\Structure;
910
use Utopia\Database\Helpers\ID;
1011
use Utopia\Database\Helpers\Permission;
1112
use Utopia\Database\Helpers\Role;
@@ -1595,4 +1596,89 @@ public function testDeleteBulkDocumentsManyToManyRelationship(): void
15951596
$this->getDatabase()->deleteDocuments('bulk_delete_person_m2m');
15961597
$this->assertCount(0, $this->getDatabase()->find('bulk_delete_person_m2m'));
15971598
}
1599+
public function testUpdateParentAndChild_ManyToMany(): void
1600+
{
1601+
/** @var Database $database */
1602+
$database = static::getDatabase();
1603+
1604+
if (
1605+
!$database->getAdapter()->getSupportForRelationships() ||
1606+
!$database->getAdapter()->getSupportForBatchOperations()
1607+
) {
1608+
$this->expectNotToPerformAssertions();
1609+
return;
1610+
}
1611+
1612+
$parentCollection = 'parent_combined_m2m';
1613+
$childCollection = 'child_combined_m2m';
1614+
1615+
$database->createCollection($parentCollection);
1616+
$database->createCollection($childCollection);
1617+
1618+
$database->createAttribute($parentCollection, 'name', Database::VAR_STRING, 255, true);
1619+
$database->createAttribute($childCollection, 'name', Database::VAR_STRING, 255, true);
1620+
$database->createAttribute($childCollection, 'parentNumber', Database::VAR_INTEGER, 0, false);
1621+
1622+
1623+
$database->createRelationship(
1624+
collection: $parentCollection,
1625+
relatedCollection: $childCollection,
1626+
type: Database::RELATION_MANY_TO_MANY,
1627+
id: 'parentNumber'
1628+
);
1629+
1630+
$database->createDocument($parentCollection, new Document([
1631+
'$id' => 'parent1',
1632+
'$permissions' => [
1633+
Permission::read(Role::any()),
1634+
Permission::update(Role::any()),
1635+
Permission::delete(Role::any()),
1636+
],
1637+
'name' => 'Parent 1',
1638+
]));
1639+
1640+
$database->createDocument($childCollection, new Document([
1641+
'$id' => 'child1',
1642+
'$permissions' => [
1643+
Permission::read(Role::any()),
1644+
Permission::update(Role::any()),
1645+
Permission::delete(Role::any()),
1646+
],
1647+
'name' => 'Child 1',
1648+
'parentNumber' => null,
1649+
]));
1650+
1651+
$database->updateDocuments(
1652+
$parentCollection,
1653+
new Document(['name' => 'Parent 1 Updated']),
1654+
[Query::equal('$id', ['parent1'])]
1655+
);
1656+
1657+
$parentDoc = $database->getDocument($parentCollection, 'parent1');
1658+
$this->assertEquals('Parent 1 Updated', $parentDoc->getAttribute('name'), 'Parent should be updated');
1659+
1660+
$childDoc = $database->getDocument($childCollection, 'child1');
1661+
$this->assertEquals('Child 1', $childDoc->getAttribute('name'), 'Child should remain unchanged');
1662+
1663+
// invalid update to child
1664+
try {
1665+
$database->updateDocuments(
1666+
$childCollection,
1667+
new Document(['parentNumber' => 'not-a-number']),
1668+
[Query::equal('$id', ['child1'])]
1669+
);
1670+
$this->fail('Expected exception was not thrown for invalid parentNumber type');
1671+
} catch (\Throwable $e) {
1672+
$this->assertInstanceOf(Structure::class, $e);
1673+
}
1674+
1675+
// parent remains unaffected
1676+
$parentDocAfter = $database->getDocument($parentCollection, 'parent1');
1677+
$this->assertEquals('Parent 1 Updated', $parentDocAfter->getAttribute('name'), 'Parent should not be affected by failed child update');
1678+
1679+
$database->deleteCollection($parentCollection);
1680+
$database->deleteCollection($childCollection);
1681+
}
1682+
1683+
15981684
}

tests/e2e/Adapter/Scopes/Relationships/ManyToOneTests.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Utopia\Database\Database;
77
use Utopia\Database\Document;
88
use Utopia\Database\Exception\Restricted as RestrictedException;
9+
use Utopia\Database\Exception\Structure;
910
use Utopia\Database\Helpers\ID;
1011
use Utopia\Database\Helpers\Permission;
1112
use Utopia\Database\Helpers\Role;
@@ -1677,4 +1678,85 @@ public function testDeleteBulkDocumentsManyToOneRelationship(): void
16771678
$this->getDatabase()->deleteDocuments('bulk_delete_person_m2o');
16781679
$this->assertCount(0, $this->getDatabase()->find('bulk_delete_person_m2o'));
16791680
}
1681+
public function testUpdateParentAndChild_ManyToOne(): void
1682+
{
1683+
/** @var Database $database */
1684+
$database = static::getDatabase();
1685+
1686+
if (
1687+
!$database->getAdapter()->getSupportForRelationships() ||
1688+
!$database->getAdapter()->getSupportForBatchOperations()
1689+
) {
1690+
$this->expectNotToPerformAssertions();
1691+
return;
1692+
}
1693+
1694+
$parentCollection = 'parent_combined_m2o';
1695+
$childCollection = 'child_combined_m2o';
1696+
1697+
$database->createCollection($parentCollection);
1698+
$database->createCollection($childCollection);
1699+
1700+
$database->createAttribute($parentCollection, 'name', Database::VAR_STRING, 255, true);
1701+
$database->createAttribute($childCollection, 'name', Database::VAR_STRING, 255, true);
1702+
$database->createAttribute($childCollection, 'parentNumber', Database::VAR_INTEGER, 0, false);
1703+
1704+
$database->createRelationship(
1705+
collection: $childCollection,
1706+
relatedCollection: $parentCollection,
1707+
type: Database::RELATION_MANY_TO_ONE,
1708+
);
1709+
1710+
$database->createDocument($parentCollection, new Document([
1711+
'$id' => 'parent1',
1712+
'$permissions' => [
1713+
Permission::read(Role::any()),
1714+
Permission::update(Role::any()),
1715+
Permission::delete(Role::any()),
1716+
],
1717+
'name' => 'Parent 1',
1718+
]));
1719+
1720+
$database->createDocument($childCollection, new Document([
1721+
'$id' => 'child1',
1722+
'$permissions' => [
1723+
Permission::read(Role::any()),
1724+
Permission::update(Role::any()),
1725+
Permission::delete(Role::any()),
1726+
],
1727+
'name' => 'Child 1',
1728+
'parentNumber' => null,
1729+
]));
1730+
1731+
$database->updateDocuments(
1732+
$parentCollection,
1733+
new Document(['name' => 'Parent 1 Updated']),
1734+
[Query::equal('$id', ['parent1'])]
1735+
);
1736+
1737+
$parentDoc = $database->getDocument($parentCollection, 'parent1');
1738+
$this->assertEquals('Parent 1 Updated', $parentDoc->getAttribute('name'), 'Parent should be updated');
1739+
1740+
$childDoc = $database->getDocument($childCollection, 'child1');
1741+
$this->assertEquals('Child 1', $childDoc->getAttribute('name'), 'Child should remain unchanged');
1742+
1743+
// invalid update to child
1744+
try {
1745+
$database->updateDocuments(
1746+
$childCollection,
1747+
new Document(['parentNumber' => 'not-a-number']),
1748+
[Query::equal('$id', ['child1'])]
1749+
);
1750+
$this->fail('Expected exception was not thrown for invalid parentNumber type');
1751+
} catch (\Throwable $e) {
1752+
$this->assertInstanceOf(Structure::class, $e);
1753+
}
1754+
1755+
// parent remains unaffected
1756+
$parentDocAfter = $database->getDocument($parentCollection, 'parent1');
1757+
$this->assertEquals('Parent 1 Updated', $parentDocAfter->getAttribute('name'), 'Parent should not be affected by failed child update');
1758+
1759+
$database->deleteCollection($parentCollection);
1760+
$database->deleteCollection($childCollection);
1761+
}
16801762
}

tests/e2e/Adapter/Scopes/Relationships/OneToManyTests.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Utopia\Database\Database;
77
use Utopia\Database\Document;
88
use Utopia\Database\Exception\Restricted as RestrictedException;
9+
use Utopia\Database\Exception\Structure;
910
use Utopia\Database\Helpers\ID;
1011
use Utopia\Database\Helpers\Permission;
1112
use Utopia\Database\Helpers\Role;
@@ -2072,4 +2073,86 @@ public function testOneToManyAndManyToOneDeleteRelationship(): void
20722073
$this->assertCount(0, $relation2->getAttribute('attributes'));
20732074
$this->assertCount(0, $relation2->getAttribute('indexes'));
20742075
}
2076+
public function testUpdateParentAndChild_OneToMany(): void
2077+
{
2078+
/** @var Database $database */
2079+
$database = static::getDatabase();
2080+
2081+
if (
2082+
!$database->getAdapter()->getSupportForRelationships() ||
2083+
!$database->getAdapter()->getSupportForBatchOperations()
2084+
) {
2085+
$this->expectNotToPerformAssertions();
2086+
return;
2087+
}
2088+
2089+
$parentCollection = 'parent_combined_o2m';
2090+
$childCollection = 'child_combined_o2m';
2091+
2092+
$database->createCollection($parentCollection);
2093+
$database->createCollection($childCollection);
2094+
2095+
$database->createAttribute($parentCollection, 'name', Database::VAR_STRING, 255, true);
2096+
$database->createAttribute($childCollection, 'name', Database::VAR_STRING, 255, true);
2097+
$database->createAttribute($childCollection, 'parentNumber', Database::VAR_INTEGER, 0, false);
2098+
2099+
$database->createRelationship(
2100+
collection: $parentCollection,
2101+
relatedCollection: $childCollection,
2102+
type: Database::RELATION_ONE_TO_MANY,
2103+
id: 'parentNumber'
2104+
);
2105+
2106+
$database->createDocument($parentCollection, new Document([
2107+
'$id' => 'parent1',
2108+
'$permissions' => [
2109+
Permission::read(Role::any()),
2110+
Permission::update(Role::any()),
2111+
Permission::delete(Role::any()),
2112+
],
2113+
'name' => 'Parent 1',
2114+
]));
2115+
2116+
$database->createDocument($childCollection, new Document([
2117+
'$id' => 'child1',
2118+
'$permissions' => [
2119+
Permission::read(Role::any()),
2120+
Permission::update(Role::any()),
2121+
Permission::delete(Role::any()),
2122+
],
2123+
'name' => 'Child 1',
2124+
'parentNumber' => null,
2125+
]));
2126+
2127+
$database->updateDocuments(
2128+
$parentCollection,
2129+
new Document(['name' => 'Parent 1 Updated']),
2130+
[Query::equal('$id', ['parent1'])]
2131+
);
2132+
2133+
$parentDoc = $database->getDocument($parentCollection, 'parent1');
2134+
$this->assertEquals('Parent 1 Updated', $parentDoc->getAttribute('name'), 'Parent should be updated');
2135+
2136+
$childDoc = $database->getDocument($childCollection, 'child1');
2137+
$this->assertEquals('Child 1', $childDoc->getAttribute('name'), 'Child should remain unchanged');
2138+
2139+
// invalid update to child
2140+
try {
2141+
$database->updateDocuments(
2142+
$childCollection,
2143+
new Document(['parentNumber' => 'not-a-number']),
2144+
[Query::equal('$id', ['child1'])]
2145+
);
2146+
$this->fail('Expected exception was not thrown for invalid parentNumber type');
2147+
} catch (\Throwable $e) {
2148+
$this->assertInstanceOf(Structure::class, $e);
2149+
}
2150+
2151+
// parent remains unaffected
2152+
$parentDocAfter = $database->getDocument($parentCollection, 'parent1');
2153+
$this->assertEquals('Parent 1 Updated', $parentDocAfter->getAttribute('name'), 'Parent should not be affected by failed child update');
2154+
2155+
$database->deleteCollection($parentCollection);
2156+
$database->deleteCollection($childCollection);
2157+
}
20752158
}

tests/e2e/Adapter/Scopes/Relationships/OneToOneTests.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,4 +2289,86 @@ public function testDeleteTwoWayRelationshipFromChild(): void
22892289

22902290
$this->assertEquals(true, $junction->isEmpty());
22912291
}
2292+
public function testUpdateParentAndChild_OneToOne(): void
2293+
{
2294+
/** @var Database $database */
2295+
$database = static::getDatabase();
2296+
2297+
if (
2298+
!$database->getAdapter()->getSupportForRelationships() ||
2299+
!$database->getAdapter()->getSupportForBatchOperations()
2300+
) {
2301+
$this->expectNotToPerformAssertions();
2302+
return;
2303+
}
2304+
2305+
$parentCollection = 'parent_combined_o2o';
2306+
$childCollection = 'child_combined_o2o';
2307+
2308+
$database->createCollection($parentCollection);
2309+
$database->createCollection($childCollection);
2310+
2311+
$database->createAttribute($parentCollection, 'name', Database::VAR_STRING, 255, true);
2312+
$database->createAttribute($childCollection, 'name', Database::VAR_STRING, 255, true);
2313+
$database->createAttribute($childCollection, 'parentNumber', Database::VAR_INTEGER, 0, false);
2314+
2315+
$database->createRelationship(
2316+
collection: $parentCollection,
2317+
relatedCollection: $childCollection,
2318+
type: Database::RELATION_ONE_TO_ONE,
2319+
id: 'parentNumber'
2320+
);
2321+
2322+
$database->createDocument($parentCollection, new Document([
2323+
'$id' => 'parent1',
2324+
'$permissions' => [
2325+
Permission::read(Role::any()),
2326+
Permission::update(Role::any()),
2327+
Permission::delete(Role::any()),
2328+
],
2329+
'name' => 'Parent 1',
2330+
]));
2331+
2332+
$database->createDocument($childCollection, new Document([
2333+
'$id' => 'child1',
2334+
'$permissions' => [
2335+
Permission::read(Role::any()),
2336+
Permission::update(Role::any()),
2337+
Permission::delete(Role::any()),
2338+
],
2339+
'name' => 'Child 1',
2340+
'parentNumber' => null,
2341+
]));
2342+
2343+
$database->updateDocuments(
2344+
$parentCollection,
2345+
new Document(['name' => 'Parent 1 Updated']),
2346+
[Query::equal('$id', ['parent1'])]
2347+
);
2348+
2349+
$parentDoc = $database->getDocument($parentCollection, 'parent1');
2350+
$this->assertEquals('Parent 1 Updated', $parentDoc->getAttribute('name'), 'Parent should be updated');
2351+
2352+
$childDoc = $database->getDocument($childCollection, 'child1');
2353+
$this->assertEquals('Child 1', $childDoc->getAttribute('name'), 'Child should remain unchanged');
2354+
2355+
// invalid update to child
2356+
try {
2357+
$database->updateDocuments(
2358+
$childCollection,
2359+
new Document(['parentNumber' => 'not-a-number']),
2360+
[Query::equal('$id', ['child1'])]
2361+
);
2362+
$this->fail('Expected exception was not thrown for invalid parentNumber type');
2363+
} catch (\Throwable $e) {
2364+
$this->assertInstanceOf(StructureException::class, $e);
2365+
}
2366+
2367+
// parent remains unaffected
2368+
$parentDocAfter = $database->getDocument($parentCollection, 'parent1');
2369+
$this->assertEquals('Parent 1 Updated', $parentDocAfter->getAttribute('name'), 'Parent should not be affected by failed child update');
2370+
2371+
$database->deleteCollection($parentCollection);
2372+
$database->deleteCollection($childCollection);
2373+
}
22922374
}

0 commit comments

Comments
 (0)