|
3 | 3 | from pytest import raises |
4 | 4 |
|
5 | 5 | from neomodel import ( |
| 6 | + AsyncMutuallyExclusive, |
6 | 7 | AsyncOne, |
7 | 8 | AsyncRelationship, |
8 | 9 | AsyncRelationshipFrom, |
|
14 | 15 | StringProperty, |
15 | 16 | adb, |
16 | 17 | ) |
| 18 | +from neomodel.exceptions import MutualExclusionViolation |
17 | 19 |
|
18 | 20 |
|
19 | 21 | class PersonWithRels(AsyncStructuredNode): |
@@ -207,3 +209,64 @@ async def test_props_relationship(): |
207 | 209 |
|
208 | 210 | with raises(NotImplementedError): |
209 | 211 | await c.inhabitant.connect(u, properties={"city": "Thessaloniki"}) |
| 212 | + |
| 213 | + |
| 214 | +class JealousDog(AsyncStructuredNode): |
| 215 | + name = StringProperty(required=True) |
| 216 | + |
| 217 | + |
| 218 | +class JealousCat(AsyncStructuredNode): |
| 219 | + name = StringProperty(required=True) |
| 220 | + |
| 221 | + |
| 222 | +class ExclusivePerson(AsyncStructuredNode): |
| 223 | + name = StringProperty(required=True) |
| 224 | + |
| 225 | + # Define mutually exclusive relationships |
| 226 | + cat = AsyncRelationshipTo( |
| 227 | + "JealousCat", |
| 228 | + "HAS_PET", |
| 229 | + cardinality=AsyncMutuallyExclusive, |
| 230 | + exclusion_group=["dog"], |
| 231 | + ) |
| 232 | + dog = AsyncRelationshipTo( |
| 233 | + "JealousDog", |
| 234 | + "HAS_PET", |
| 235 | + cardinality=AsyncMutuallyExclusive, |
| 236 | + exclusion_group=["cat"], |
| 237 | + ) |
| 238 | + |
| 239 | + |
| 240 | +@mark_async_test |
| 241 | +async def test_mutually_exclusive_relationships(): |
| 242 | + # Create test nodes |
| 243 | + bob = await ExclusivePerson(name="Bob").save() |
| 244 | + rex = await JealousDog(name="Rex").save() |
| 245 | + whiskers = await JealousCat(name="Whiskers").save() |
| 246 | + |
| 247 | + # Bob can have a dog |
| 248 | + await bob.dog.connect(rex) |
| 249 | + |
| 250 | + # But now Bob can't have a cat because he already has a dog |
| 251 | + with raises(MutualExclusionViolation): |
| 252 | + await bob.cat.connect(whiskers) |
| 253 | + |
| 254 | + # Create another person |
| 255 | + alice = await ExclusivePerson(name="Alice").save() |
| 256 | + |
| 257 | + # Alice can have a cat |
| 258 | + await alice.cat.connect(whiskers) |
| 259 | + |
| 260 | + # But now Alice can't have a dog because she already has a cat |
| 261 | + with raises(MutualExclusionViolation): |
| 262 | + await alice.dog.connect(rex) |
| 263 | + |
| 264 | + # If Alice disconnects her cat, she can then have a dog |
| 265 | + await alice.cat.disconnect(whiskers) |
| 266 | + await alice.dog.connect(rex) |
| 267 | + |
| 268 | + # Verify the connections |
| 269 | + assert len(await bob.dog.all()) == 1 |
| 270 | + assert len(await bob.cat.all()) == 0 |
| 271 | + assert len(await alice.dog.all()) == 1 |
| 272 | + assert len(await alice.cat.all()) == 0 |
0 commit comments