Skip to content

Commit 8913e7b

Browse files
committed
Merge repository operation_isolation tests
1 parent 7409238 commit 8913e7b

File tree

3 files changed

+124
-212
lines changed

3 files changed

+124
-212
lines changed

tests/repository/async_/test_operation_isolation.py

Lines changed: 0 additions & 106 deletions
This file was deleted.

tests/repository/sync/test_operation_isolation.py

Lines changed: 0 additions & 106 deletions
This file was deleted.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from unittest.mock import AsyncMock, MagicMock, patch
2+
3+
from sqlalchemy_bind_manager._bind_manager import SQLAlchemyAsyncBind
4+
from sqlalchemy_bind_manager._transaction_handler import (
5+
AsyncSessionHandler,
6+
SessionHandler,
7+
)
8+
9+
10+
async def test_repository_instance_returns_always_different_models(
11+
repository_class, model_class, sa_bind, sync_async_wrapper
12+
):
13+
repo1 = repository_class(bind=sa_bind, model_class=model_class)
14+
15+
# Populate a database entry to be used for tests using first repo
16+
model_1 = model_class(
17+
name="Someone",
18+
)
19+
await sync_async_wrapper(repo1.save(model_1))
20+
assert model_1.model_id is not None
21+
22+
# Retrieve the model using multiple repos
23+
retrieved_model_1 = await sync_async_wrapper(repo1.get(model_1.model_id))
24+
retrieved_model_2 = await sync_async_wrapper(repo1.get(model_1.model_id))
25+
assert retrieved_model_1 is not model_1
26+
assert retrieved_model_2 is not model_1
27+
assert retrieved_model_1.model_id == model_1.model_id
28+
assert retrieved_model_2.model_id == model_1.model_id
29+
30+
31+
async def test_update_model_doesnt_update_other_models_from_same_repo(
32+
repository_class, model_class, sa_bind, sync_async_wrapper
33+
):
34+
repo = repository_class(bind=sa_bind, model_class=model_class)
35+
36+
# Populate a database entry to be used for tests
37+
model1 = model_class(
38+
name="Someone",
39+
)
40+
model2 = model_class(
41+
name="SomeoneElse",
42+
)
43+
await sync_async_wrapper(repo.save_many([model1, model2]))
44+
assert model1.model_id is not None
45+
assert model2.model_id is not None
46+
47+
# Retrieve the models
48+
new_model1 = await sync_async_wrapper(repo.get(model1.model_id))
49+
new_model2 = await sync_async_wrapper(repo.get(model2.model_id))
50+
51+
# Update both models but save only model 1
52+
new_model1.name = "StillSomeoneElse"
53+
new_model2.name = "IsThisSomeoneElse?"
54+
await sync_async_wrapper(repo.save(new_model1))
55+
56+
# Check model1 has been updated
57+
updated_model1 = await sync_async_wrapper(repo.get(model1.model_id))
58+
assert updated_model1.name == "StillSomeoneElse"
59+
60+
# Check model2 has not been updated
61+
updated_model2 = await sync_async_wrapper(repo.get(model2.model_id))
62+
assert updated_model2.name == "SomeoneElse"
63+
64+
65+
async def test_update_model_updates_models_retrieved_by_other_repos(
66+
repository_class, model_class, sa_bind, sync_async_wrapper
67+
):
68+
repo = repository_class(bind=sa_bind, model_class=model_class)
69+
repo2 = repository_class(bind=sa_bind, model_class=model_class)
70+
71+
# Populate a database entry to be used for tests
72+
model1 = model_class(
73+
name="Someone",
74+
)
75+
await sync_async_wrapper(repo.save(model1))
76+
assert model1.model_id is not None
77+
78+
# Retrieve the models
79+
new_model1 = await sync_async_wrapper(repo.get(model1.model_id))
80+
81+
# Update the model with another repository instance
82+
new_model1.name = "StillSomeoneElse"
83+
await sync_async_wrapper(repo2.save(new_model1))
84+
85+
# Check model1 has been updated
86+
updated_model1 = await sync_async_wrapper(repo2.get(model1.model_id))
87+
assert updated_model1.name == "StillSomeoneElse"
88+
89+
# Check model1 has been updated
90+
updated_model1b = await sync_async_wrapper(repo.get(model1.model_id))
91+
assert updated_model1b.name == "StillSomeoneElse"
92+
93+
94+
async def test_commit_triggers_once_per_operation_using_internal_uow(
95+
repository_class, model_class, sa_bind, sync_async_wrapper
96+
):
97+
# Populate a database entry to be used for tests
98+
model1 = model_class(
99+
name="Someone",
100+
)
101+
model2 = model_class(
102+
name="SomeoneElse",
103+
)
104+
105+
session_handler_class = (
106+
AsyncSessionHandler
107+
if isinstance(sa_bind, SQLAlchemyAsyncBind)
108+
else SessionHandler
109+
)
110+
session_handler_mock = (
111+
AsyncMock if isinstance(sa_bind, SQLAlchemyAsyncBind) else MagicMock
112+
)
113+
114+
with patch.object(
115+
session_handler_class,
116+
"commit",
117+
new_callable=session_handler_mock,
118+
return_value=None,
119+
) as mocked_uow_commit:
120+
repo1 = repository_class(bind=sa_bind, model_class=model_class)
121+
repo2 = repository_class(bind=sa_bind, model_class=model_class)
122+
await sync_async_wrapper(repo1.save(model1))
123+
await sync_async_wrapper(repo2.save(model2))
124+
assert mocked_uow_commit.call_count == 2

0 commit comments

Comments
 (0)