Skip to content

Commit 7a58be1

Browse files
committed
create mixed atomic actions tests
1 parent 0cb202a commit 7a58be1

File tree

2 files changed

+220
-3
lines changed

2 files changed

+220
-3
lines changed

tests/schemas.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,18 @@ class ChildSchema(ChildInSchema):
262262
id: int
263263

264264

265-
class ComputerBaseSchema(BaseModel):
266-
"""Computer base schema."""
267-
265+
class ComputerAttributesBaseSchema(BaseModel):
268266
class Config:
269267
"""Pydantic schema config."""
270268

271269
orm_mode = True
272270

273271
name: str
272+
273+
274+
class ComputerBaseSchema(ComputerAttributesBaseSchema):
275+
"""Computer base schema."""
276+
274277
user: Optional["UserSchema"] = Field(
275278
relationship=RelationshipInfo(
276279
resource_type="user",
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import logging
2+
3+
from httpx import AsyncClient
4+
from pytest import mark # noqa
5+
from sqlalchemy import select
6+
from sqlalchemy.ext.asyncio import AsyncSession
7+
from sqlalchemy.sql.functions import count
8+
from starlette import status
9+
10+
from tests.misc.utils import fake
11+
from tests.models import Computer, User, UserBio
12+
from tests.schemas import ComputerAttributesBaseSchema, UserAttributesBaseSchema, UserBioBaseSchema
13+
14+
pytestmark = mark.asyncio
15+
16+
logging.basicConfig(level=logging.DEBUG)
17+
18+
19+
class TestAtomicMixedActions:
20+
async def test_create_and_update_atomic_success(
21+
self,
22+
client: AsyncClient,
23+
async_session: AsyncSession,
24+
user_1: User,
25+
user_1_bio: UserBio,
26+
):
27+
"""
28+
Create computer for user
29+
Update user's Bio
30+
Update user
31+
32+
:param client:
33+
:param async_session:
34+
:param user_1:
35+
:param user_1_bio:
36+
:return:
37+
"""
38+
user_data = UserAttributesBaseSchema.from_orm(user_1)
39+
user_bio_data = UserBioBaseSchema.from_orm(user_1_bio)
40+
user_data.name = fake.name()
41+
user_bio_data.favourite_movies = fake.sentence()
42+
assert user_1.name != user_data.name
43+
assert user_1_bio.favourite_movies != user_bio_data.favourite_movies
44+
new_computer = ComputerAttributesBaseSchema(
45+
name=fake.user_name(),
46+
)
47+
data_atomic_request = {
48+
"atomic:operations": [
49+
{
50+
"op": "add",
51+
"data": {
52+
"type": "computer",
53+
"attributes": new_computer.dict(),
54+
"relationships": {
55+
"user": {
56+
"data": {
57+
"id": user_1.id,
58+
"type": "user",
59+
},
60+
},
61+
},
62+
},
63+
},
64+
{
65+
"op": "update",
66+
"data": {
67+
"id": str(user_1_bio.id),
68+
"type": "user_bio",
69+
"attributes": user_bio_data.dict(),
70+
},
71+
},
72+
{
73+
"op": "update",
74+
"data": {
75+
"id": str(user_1.id),
76+
"type": "user",
77+
"attributes": user_data.dict(),
78+
},
79+
},
80+
],
81+
}
82+
response = await client.post("/operations", json=data_atomic_request)
83+
assert response.status_code == status.HTTP_200_OK, response.text
84+
response_data = response.json()
85+
assert "atomic:results" in response_data, response_data
86+
results = response_data["atomic:results"]
87+
assert results
88+
await async_session.refresh(user_1)
89+
await async_session.refresh(user_1_bio)
90+
assert user_1.name == user_data.name
91+
assert user_1_bio.favourite_movies == user_bio_data.favourite_movies
92+
computer: Computer = await async_session.scalar(select(Computer).where(Computer.user_id == user_1.id))
93+
assert results == [
94+
{
95+
"data": {
96+
"id": str(computer.id),
97+
"type": "computer",
98+
"attributes": new_computer.dict(),
99+
},
100+
"meta": None,
101+
},
102+
{
103+
"data": {
104+
"id": str(user_1_bio.id),
105+
"type": "user_bio",
106+
"attributes": user_bio_data.dict(),
107+
},
108+
"meta": None,
109+
},
110+
{
111+
"data": {
112+
"id": str(user_1.id),
113+
"type": "user",
114+
"attributes": user_data.dict(),
115+
},
116+
"meta": None,
117+
},
118+
]
119+
120+
async def test_create_and_update_atomic_rollback(
121+
self,
122+
client: AsyncClient,
123+
async_session: AsyncSession,
124+
user_1: User,
125+
user_2: User,
126+
user_1_bio: UserBio,
127+
):
128+
"""
129+
130+
- create computer (ok)
131+
- update user bio (ok)
132+
- update username (not ok, error, rollback)
133+
134+
:param client:
135+
:param async_session:
136+
:param user_1:
137+
:param user_2:
138+
:param user_1_bio:
139+
:return:
140+
"""
141+
user_data = UserAttributesBaseSchema.from_orm(user_1)
142+
user_bio_data = UserBioBaseSchema.from_orm(user_1_bio)
143+
user_bio_data.favourite_movies = fake.sentence()
144+
assert user_1_bio.favourite_movies != user_bio_data.favourite_movies
145+
user_data.name = user_2.name
146+
user_1_name: str = user_1.name
147+
user_bio_movies: str = user_1_bio.favourite_movies
148+
assert user_data.name != user_1.name
149+
new_computer = ComputerAttributesBaseSchema(
150+
name=fake.user_name(),
151+
)
152+
data_atomic_request = {
153+
"atomic:operations": [
154+
{
155+
"op": "add",
156+
"data": {
157+
"type": "computer",
158+
"attributes": new_computer.dict(),
159+
"relationships": {
160+
"user": {
161+
"data": {
162+
"id": user_1.id,
163+
"type": "user",
164+
},
165+
},
166+
},
167+
},
168+
},
169+
{
170+
"op": "update",
171+
"data": {
172+
"id": str(user_1_bio.id),
173+
"type": "user_bio",
174+
"attributes": user_bio_data.dict(),
175+
},
176+
},
177+
{
178+
"op": "update",
179+
"data": {
180+
"id": str(user_1.id),
181+
"type": "user",
182+
"attributes": user_data.dict(),
183+
},
184+
},
185+
],
186+
}
187+
response = await client.post("/operations", json=data_atomic_request)
188+
assert response.status_code == status.HTTP_400_BAD_REQUEST, response.text
189+
response_data = response.json()
190+
assert "errors" in response_data, response_data
191+
errors = response_data["errors"]
192+
assert errors
193+
await async_session.refresh(user_1)
194+
await async_session.refresh(user_1_bio)
195+
assert user_1.name != user_data.name
196+
assert user_1.name == user_1_name
197+
assert user_1_bio.favourite_movies != user_bio_data.favourite_movies
198+
assert user_1_bio.favourite_movies == user_bio_movies
199+
200+
stmt = select(count(Computer.id)).where(Computer.user_id == user_1.id)
201+
cnt = await async_session.scalar(stmt)
202+
assert cnt == 0, "no computers have to be created"
203+
assert errors == [
204+
{
205+
"detail": "Object update error",
206+
"source": {"pointer": "/data"},
207+
"status_code": status.HTTP_400_BAD_REQUEST,
208+
"title": "Bad Request",
209+
"meta": {
210+
"id": str(user_1.id),
211+
"type": "user",
212+
},
213+
},
214+
]

0 commit comments

Comments
 (0)