Skip to content

Commit fdc2b92

Browse files
committed
user tests
1 parent e6f4b6f commit fdc2b92

File tree

9 files changed

+133
-29
lines changed

9 files changed

+133
-29
lines changed

src/__init__.py

Whitespace-only changes.

src/app/api/v1/users.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async def write_user(user: UserCreate, db: AsyncSession = Depends(async_get_db))
3131
return await crud_users.create(db=db, object=user_internal)
3232

3333

34-
@router.get("/user", response_model=List[UserRead])
34+
@router.get("/users", response_model=List[UserRead])
3535
async def read_users(db: AsyncSession = Depends(async_get_db)):
3636
users = await crud_users.get_multi(db=db, is_deleted=False)
3737
return users
@@ -44,27 +44,27 @@ async def read_users_me(
4444
return current_user
4545

4646

47-
@router.get("/user/{id}", response_model=UserRead)
48-
async def read_user(id: int, db: AsyncSession = Depends(async_get_db)):
49-
db_user = await crud_users.get(db=db, id=id, is_deleted=False)
47+
@router.get("/user/{username}", response_model=UserRead)
48+
async def read_user(username: str, db: AsyncSession = Depends(async_get_db)):
49+
db_user = await crud_users.get(db=db, username=username, is_deleted=False)
5050
if db_user is None:
5151
raise HTTPException(status_code=404, detail="User not found")
5252

5353
return db_user
5454

5555

56-
@router.patch("/users/{id}", response_model=UserUpdate)
56+
@router.patch("/user/{username}", response_model=UserUpdate)
5757
async def patch_user(
5858
values: UserUpdate,
59-
id: int,
59+
username: str,
6060
current_user: Annotated[UserRead, Depends(get_current_user)],
6161
db: AsyncSession = Depends(async_get_db)
6262
):
63-
db_user = await crud_users.get(db=db, id=id)
63+
db_user = await crud_users.get(db=db, username=username)
6464
if db_user is None:
6565
raise HTTPException(status_code=404, detail="User not found")
6666

67-
if db_user.id != current_user.id:
67+
if db_user.username != current_user.username:
6868
raise privileges_exception
6969

7070
if values.username != db_user.username:
@@ -81,32 +81,32 @@ async def patch_user(
8181
return db_user
8282

8383

84-
@router.delete("/user/{id}")
84+
@router.delete("/user/{username}")
8585
async def erase_user(
86-
id: int,
86+
username: str,
8787
current_user: Annotated[UserRead, Depends(get_current_user)],
8888
db: AsyncSession = Depends(async_get_db)
8989
):
90-
db_user = await crud_users.get(db=db, id=id)
90+
db_user = await crud_users.get(db=db, username=username)
9191
if db_user is None:
9292
raise HTTPException(status_code=404, detail="User not found")
9393

94-
if db_user.id != current_user.id:
94+
if db_user.username != current_user.username:
9595
raise privileges_exception
9696

97-
db_user = await crud_users.delete(db=db, db_object=db_user, id=id)
97+
db_user = await crud_users.delete(db=db, db_object=db_user, username=username)
9898
return db_user
9999

100100

101-
@router.delete("/db_user/{id}")
101+
@router.delete("/db_user/{username}")
102102
async def erase_db_user(
103-
id: int,
103+
username: str,
104104
current_superuser: Annotated[UserRead, Depends(get_current_superuser)],
105105
db: AsyncSession = Depends(async_get_db)
106106
):
107-
db_user = await crud_users.get(db=db, id=id)
107+
db_user = await crud_users.get(db=db, username=username)
108108
if db_user is None:
109109
raise HTTPException(status_code=404, detail="User not found")
110110

111-
db_user = await crud_users.db_delete(db=db, db_object=db_user, id=id)
111+
db_user = await crud_users.db_delete(db=db, db_object=db_user, username=username)
112112
return db_user

src/app/core/models.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ class TokenData(BaseModel):
2424
class UUIDModel(BaseModel):
2525
uuid: uuid_pkg.UUID = Field(
2626
default_factory=uuid_pkg.uuid4,
27-
primary_key=True,
28-
index=True,
29-
nullable=False,
30-
sa_column_kwargs={
27+
json_schema_extra={
3128
"server_default": text("gen_random_uuid()"),
3229
"unique": True
3330
}
@@ -37,16 +34,14 @@ class UUIDModel(BaseModel):
3734
class TimestampModel(BaseModel):
3835
created_at: datetime = Field(
3936
default_factory=datetime.utcnow,
40-
nullable=False,
41-
sa_column_kwargs={
37+
json_schema_extra={
4238
"server_default": text("current_timestamp(0)")
4339
}
4440
)
4541

4642
updated_at: datetime = Field(
4743
default=None,
48-
nullable=True,
49-
sa_column_kwargs={
44+
json_schema_extra={
5045
"server_default": text("current_timestamp(0)"),
5146
"onupdate": text("current_timestamp(0)")
5247
}
@@ -56,8 +51,7 @@ class TimestampModel(BaseModel):
5651
class PersistentDeletion(BaseModel):
5752
deleted_at: datetime | None = Field(
5853
default=None,
59-
nullable=True,
60-
sa_column_kwargs={
54+
json_schema_extra={
6155
"server_default": text("None"),
6256
"ondelete": text("current_timestamp(0)")
6357
}

src/app/crud/crud_base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ async def db_delete(
7272
db_object = db_object or await self.get(db=db, **kwargs)
7373
await db.delete(db_object)
7474
await db.commit()
75+
7576
return db_object
7677

7778
async def delete(

src/app/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ async def create_tables():
1111
await conn.run_sync(Base.metadata.create_all)
1212

1313

14-
def create_applitcation() -> FastAPI:
14+
def create_application() -> FastAPI:
1515
application = FastAPI(
1616
title=settings.APP_NAME,
1717
description=settings.APP_DESCRIPTION,
@@ -25,4 +25,4 @@ def create_applitcation() -> FastAPI:
2525
return application
2626

2727

28-
app = create_applitcation()
28+
app = create_application()

src/tests/__init__.py

Whitespace-only changes.

src/tests/conftest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pytest
2+
from fastapi.testclient import TestClient
3+
4+
from src.app.main import app
5+
6+
@pytest.fixture(scope="session")
7+
def client():
8+
with TestClient(app) as _client:
9+
yield _client

src/tests/helper.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import List
2+
import re
3+
4+
from fastapi.testclient import TestClient
5+
from fastapi.routing import APIRoute
6+
7+
from app.main import app
8+
9+
def _get_token(username: str, password: str, client: TestClient):
10+
return client.post(
11+
"/api/v1/login",
12+
data={
13+
"username": username,
14+
"password": password
15+
},
16+
headers={"content-type": "application/x-www-form-urlencoded"}
17+
)

src/tests/test_user.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
from typing import List
2+
from fastapi.testclient import TestClient
3+
from decouple import config
4+
5+
from src.app.main import app
6+
from tests.helper import _get_token
7+
from app.schemas.user import UserCreate, UserRead, UserUpdate
8+
9+
test_name = config("TEST_NAME")
10+
test_username = config("TEST_USERNAME")
11+
test_email = config("TEST_EMAIL")
12+
test_password = config("TEST_PASSWORD")
13+
14+
admin_username = config("ADMIN_USERNAME")
15+
admin_password = config("ADMIN_PASSWORD")
16+
17+
client = TestClient(app)
18+
19+
def test_post_user(client: TestClient) -> None:
20+
response = client.post(
21+
"/api/v1/user",
22+
json = {
23+
"name": test_name,
24+
"username": test_username,
25+
"email": test_email,
26+
"password": test_password
27+
}
28+
)
29+
assert response.status_code == 201
30+
31+
def test_get_user(client: TestClient) -> None:
32+
response = client.get(
33+
f"/api/v1/user/{test_username}"
34+
)
35+
assert response.status_code == 200
36+
37+
def test_get_multiple_users(client: TestClient) -> None:
38+
response = client.get(
39+
"/api/v1/users"
40+
)
41+
assert response.status_code == 200
42+
43+
def test_update_user(client: TestClient) -> None:
44+
token = _get_token(
45+
username=test_username,
46+
password=test_password,
47+
client=client
48+
)
49+
50+
response = client.patch(
51+
f"/api/v1/user/{test_username}",
52+
json={
53+
"name": f"Updated {test_name}"
54+
},
55+
headers={"Authorization": f'Bearer {token.json()["access_token"]}'}
56+
)
57+
assert response.status_code == 200
58+
59+
def test_delete_user(client: TestClient) -> None:
60+
token = _get_token(
61+
username=test_username,
62+
password=test_password,
63+
client=client
64+
)
65+
66+
response = client.delete(
67+
f"/api/v1/user/{test_username}",
68+
headers={"Authorization": f'Bearer {token.json()["access_token"]}'}
69+
)
70+
assert response.status_code == 200
71+
72+
def test_delete_db_user(client: TestClient) -> None:
73+
token = _get_token(
74+
username=admin_username,
75+
password=admin_password,
76+
client=client
77+
)
78+
79+
response = client.delete(
80+
f"/api/v1/db_user/{test_username}",
81+
headers={"Authorization": f'Bearer {token.json()["access_token"]}'}
82+
)
83+
assert response.status_code == 200

0 commit comments

Comments
 (0)