Skip to content

Commit bedcc82

Browse files
Fix PUT News endpoint by sending News data in body
1 parent 8ec45ae commit bedcc82

File tree

5 files changed

+48
-59
lines changed

5 files changed

+48
-59
lines changed

app/routers/news/routes.py

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import app.services.database.orm.news as orm_news
1010
from app.routers.authentication import get_current_active_community
11-
from app.schemas import News, NewsPublishStatus
11+
from app.schemas import News, NewsWithPublishStatus
1212
from app.services.database.models import Community as DBCommunity
1313
from app.services.limiter import limiter
1414

@@ -39,10 +39,10 @@ def encode_email(email: str) -> str:
3939

4040

4141
def setup():
42-
router = APIRouter(prefix="/news", tags=["news"])
42+
router: APIRouter = APIRouter(prefix="/news", tags=["news"])
4343

4444
@router.post(
45-
"",
45+
path="",
4646
response_model=NewsCreateResponse,
4747
status_code=status.HTTP_200_OK,
4848
summary="News endpoint",
@@ -98,44 +98,29 @@ async def get_news(
9898
return NewsGetResponse(news_list=news_list)
9999

100100
@router.put(
101-
"",
102-
response_model=NewsGetResponse,
101+
path="/{news_id}",
103102
status_code=status.HTTP_200_OK,
104103
summary="PUT News",
105-
description="Updates news by query params and set publish value",
104+
description="Updates news and sets publish value",
106105
)
107-
@limiter.limit("60/minute")
106+
@limiter.limit(limit_value="60/minute")
108107
async def put_news(
109108
request: Request,
110109
current_community: Annotated[
111110
DBCommunity, Depends(get_current_active_community)
112111
],
113-
publish_status: NewsPublishStatus,
114-
id: str | None = None,
115-
title: str | None = None,
116-
content: str | None = None,
117-
category: str | None = None,
118-
user_email: str = str(Header(..., alias="user-email")),
119-
source_url: str | None = None,
120-
tags: str | None = None,
121-
social_media_url: str | None = None,
112+
news_id: str,
113+
news: NewsWithPublishStatus,
114+
user_email: str = Header(..., alias="user-email"),
122115
):
123116
"""
124117
Get News endpoint that retrieves news filtered by user and query params.
125118
"""
126-
news: dict = {
127-
"id": id,
128-
"title": title,
129-
"content": content,
130-
"category": category,
131-
"user_email": user_email,
132-
"source_url": source_url,
133-
"tags": tags,
134-
"social_media_url": social_media_url,
135-
"publish": publish_status.publish,
136-
}
137119
await orm_news.update_news(
138-
session=request.app.db_session_factory, news=news
120+
session=request.app.db_session_factory,
121+
news=news.__dict__,
122+
news_id=news_id,
123+
user_email=user_email,
139124
)
140125
return NewsUpdateResponse()
141126

@@ -146,11 +131,11 @@ async def put_news(
146131
summary="News like endpoint",
147132
description="Allows user to like a news item",
148133
)
149-
@limiter.limit("60/minute")
134+
@limiter.limit(limit_value="60/minute")
150135
async def post_like(
151136
request: Request,
152137
current_community: Annotated[
153-
DBCommunity, Depends(get_current_active_community)
138+
DBCommunity, Depends(dependency=get_current_active_community)
154139
],
155140
news_id: str,
156141
user_email: str = Header(..., alias="user-email"),
@@ -173,7 +158,7 @@ async def post_like(
173158
summary="News undo like endpoint",
174159
description="Allows user to undo a like to a news item",
175160
)
176-
@limiter.limit("60/minute")
161+
@limiter.limit(limit_value="60/minute")
177162
async def delete_like(
178163
request: Request,
179164
current_community: Annotated[

app/schemas.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,12 @@ class News(BaseModel):
4848
title: str
4949
content: str
5050
category: str
51-
tags: str | None = None
5251
source_url: str
52+
tags: str | None = None
5353
social_media_url: str | None = None
54-
likes: int = 0
5554

5655

57-
class NewsPublishStatus(BaseModel):
56+
class NewsWithPublishStatus(News):
5857
publish: bool = False
5958

6059

app/services/database/models/news.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class News(SQLModel, table=True):
2626
for this news.
2727
likes (int): Number of likes this news article has received.
2828
Defaults to 0.
29+
publish (bool): Indicates whether the news is published or not.
30+
Defaults to False.
2931
3032
community_id (Optional[int]): Foreign key to the associated community
3133
(communities.id).

app/services/database/orm/news.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ async def create_news(session: AsyncSession, news: dict) -> None:
1616
source_url=news["source_url"],
1717
tags=news["tags"] or "",
1818
social_media_url=news["social_media_url"] or "",
19-
likes=news["likes"],
2019
)
2120
session.add(_news)
2221
await session.commit()
@@ -45,8 +44,15 @@ async def get_news_by_query_params(
4544
return list(results.all())
4645

4746

48-
async def update_news(session: AsyncSession, news: dict) -> None:
49-
statement = select(News).where(News.id == news["id"])
47+
async def update_news(
48+
session: AsyncSession,
49+
news: dict,
50+
news_id: str,
51+
user_email: str,
52+
) -> None:
53+
statement = select(News).where(
54+
News.id == news_id and News.user_email == user_email
55+
)
5056
results = await session.exec(statement)
5157
news_item = results.first()
5258
if news_item:

tests/test_news.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pytest
55
import pytest_asyncio
66
from fastapi import status
7-
from httpx import AsyncClient
7+
from httpx import AsyncClient, Response
88
from sqlmodel import select
99
from sqlmodel.ext.asyncio.session import AsyncSession
1010

@@ -101,8 +101,8 @@ async def test_post_news_endpoint(
101101
"category": "test_category",
102102
"source_url": "https://example.com/test-news",
103103
}
104-
response = await async_client.post(
105-
"/api/news", headers=valid_auth_headers, json=news_data
104+
response: Response = await async_client.post(
105+
url="/api/news", headers=valid_auth_headers, json=news_data
106106
)
107107
assert response.status_code == status.HTTP_200_OK
108108
assert response.json() == {"status": "News Criada"}
@@ -310,26 +310,23 @@ async def test_put_news_endpoint(
310310
"title": "updated title",
311311
"content": "updated content",
312312
"category": "updated_category",
313-
"user_email": "updated_email@test.com",
314313
"source_url": "https://updated_url.com",
315314
"tags": "test_tag_updated",
316315
"social_media_url": "https://updated_social_media_url.com",
317316
}
318317

319-
response = await async_client.put(
320-
"/api/news",
321-
params={
322-
"id": stored_news.id,
318+
response: Response = await async_client.put(
319+
url=f"/api/news/{stored_news.id}",
320+
headers=valid_auth_headers,
321+
json={
323322
"title": data["title"],
324323
"content": data["content"],
325324
"category": data["category"],
326-
"user_email": data["user_email"],
327325
"source_url": data["source_url"],
328326
"tags": data["tags"],
329327
"social_media_url": data["social_media_url"],
328+
"publish": True,
330329
},
331-
headers=valid_auth_headers,
332-
json={"publish": True},
333330
)
334331
assert response.status_code == status.HTTP_200_OK
335332

@@ -339,7 +336,7 @@ async def test_put_news_endpoint(
339336
assert stored_news is not None
340337
assert stored_news.content == data["content"]
341338
assert stored_news.category == data["category"]
342-
assert stored_news.user_email == data["user_email"]
339+
assert stored_news.user_email == valid_auth_headers["user-email"]
343340
assert stored_news.source_url == data["source_url"]
344341
assert stored_news.tags == data["tags"]
345342
assert stored_news.social_media_url == data["social_media_url"]
@@ -361,8 +358,8 @@ async def test_news_likes_endpoint(
361358
"source_url": "https://example.com/test-news",
362359
"social_media_url": "https://test.com/test_news",
363360
}
364-
response = await async_client.post(
365-
"/api/news", json=news_data, headers=valid_auth_headers
361+
response: Response = await async_client.post(
362+
url="/api/news", json=news_data, headers=valid_auth_headers
366363
)
367364
assert response.status_code == status.HTTP_200_OK
368365
statement = select(News).where(News.title == news_data["title"])
@@ -374,8 +371,8 @@ async def test_news_likes_endpoint(
374371
emails = ["like@test.com", "like2@test.com"]
375372

376373
# Add likes
377-
response = await async_client.post(
378-
f"/api/news/{stored_news.id}/like",
374+
response: Response = await async_client.post(
375+
url=f"/api/news/{stored_news.id}/like",
379376
json={"email": emails[0]},
380377
headers={**valid_auth_headers, "user-email": emails[0]},
381378
)
@@ -387,8 +384,8 @@ async def test_news_likes_endpoint(
387384
assert stored_news.likes == 1
388385
assert stored_news.user_email_list == f"['{encode_email(emails[0])}']"
389386

390-
response = await async_client.post(
391-
f"/api/news/{stored_news.id}/like",
387+
response: Response = await async_client.post(
388+
url=f"/api/news/{stored_news.id}/like",
392389
headers={**valid_auth_headers, "user-email": emails[1]},
393390
)
394391
assert response.status_code == status.HTTP_200_OK
@@ -403,8 +400,8 @@ async def test_news_likes_endpoint(
403400
)
404401

405402
# Remove likes
406-
response = await async_client.delete(
407-
f"/api/news/{stored_news.id}/like",
403+
response: Response = await async_client.delete(
404+
url=f"/api/news/{stored_news.id}/like",
408405
headers={**valid_auth_headers, "user-email": emails[0]},
409406
)
410407
assert response.status_code == status.HTTP_200_OK
@@ -415,8 +412,8 @@ async def test_news_likes_endpoint(
415412
assert stored_news.likes == 1
416413
assert stored_news.user_email_list == f"['{encode_email(emails[1])}']"
417414

418-
response = await async_client.delete(
419-
f"/api/news/{stored_news.id}/like",
415+
response: Response = await async_client.delete(
416+
url=f"/api/news/{stored_news.id}/like",
420417
headers={**valid_auth_headers, "user-email": emails[1]},
421418
)
422419
assert response.status_code == status.HTTP_200_OK

0 commit comments

Comments
 (0)