Skip to content

Commit 798336d

Browse files
Create like endpoint
1 parent efd8b20 commit 798336d

3 files changed

Lines changed: 86 additions & 1 deletion

File tree

app/routers/news/routes.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
from app.routers.authentication import get_current_active_community
88
from app.schemas import News
99
from app.services.database.models import Community as DBCommunity
10-
from app.services.database.orm.news import create_news, get_news_by_query_params
10+
from app.services.database.orm.news import (
11+
create_news,
12+
get_news_by_query_params,
13+
like_news,
14+
)
1115

1216

1317
class NewsPostResponse(BaseModel):
@@ -19,6 +23,10 @@ class NewsGetResponse(BaseModel):
1923
news_list: list = []
2024

2125

26+
class NewsLikeResponse(BaseModel):
27+
total_likes: int | None
28+
29+
2230
def setup():
2331
router = APIRouter(prefix="/news", tags=["news"])
2432

@@ -76,4 +84,29 @@ async def get_news(
7684
)
7785
return NewsGetResponse(news_list=news_list)
7886

87+
@router.post(
88+
path="/{news_id}/like",
89+
response_model=NewsPostResponse,
90+
status_code=status.HTTP_200_OK,
91+
summary="News like endpoint",
92+
description="Allows user to like a news item",
93+
)
94+
async def post_like(
95+
request: Request,
96+
current_community: Annotated[
97+
DBCommunity, Depends(get_current_active_community)
98+
],
99+
news_id,
100+
user_email: str = Header(..., alias="user-email"),
101+
):
102+
"""
103+
News endpoint where user can set like to news item.
104+
"""
105+
total_likes = await like_news(
106+
session=request.app.db_session_factory,
107+
news_id=news_id,
108+
user_email=user_email,
109+
)
110+
return NewsLikeResponse(total_likes=total_likes)
111+
79112
return router

app/services/database/orm/news.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,18 @@ async def get_news_by_query_params(
4242
statement = select(News).where(*filters)
4343
results = await session.exec(statement)
4444
return results.all()
45+
46+
47+
async def like_news(
48+
session: AsyncSession, news_id: str, user_email: str
49+
) -> int | None:
50+
statement = select(News).where(News.id == news_id)
51+
results = await session.exec(statement)
52+
news_item = results.first()
53+
if news_item:
54+
news_item.likes += 1
55+
session.add(news_item)
56+
await session.commit()
57+
await session.refresh(news_item)
58+
return news_item.likes
59+
return None

tests/test_news.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,40 @@ async def test_news_integration(
284284
== news_data["social_media_url"]
285285
)
286286
assert data["news_list"][0]["likes"] == 0
287+
288+
289+
@pytest.mark.asyncio
290+
async def test_insert_news_likes_endpoint(
291+
session: AsyncSession,
292+
async_client: AsyncClient,
293+
community: Community,
294+
valid_auth_headers: Mapping[str, str],
295+
):
296+
news_data = {
297+
"title": "Test News",
298+
"content": "Test news content.",
299+
"category": "test_category",
300+
"tags": "test_tag",
301+
"source_url": "https://example.com/test-news",
302+
"social_media_url": "https://test.com/test_news",
303+
}
304+
response = await async_client.post(
305+
"/api/news", json=news_data, headers=valid_auth_headers
306+
)
307+
assert response.status_code == status.HTTP_200_OK
308+
statement = select(News).where(News.title == news_data["title"])
309+
result = await session.exec(statement)
310+
stored_news = result.first()
311+
assert stored_news is not None
312+
assert stored_news.likes == 0
313+
314+
response = await async_client.post(
315+
f"/api/news/{stored_news.id}/like",
316+
json=news_data,
317+
headers=valid_auth_headers,
318+
)
319+
assert response.status_code == status.HTTP_200_OK
320+
statement = select(News).where(News.title == news_data["title"])
321+
result = await session.exec(statement)
322+
stored_news = result.first()
323+
assert stored_news.likes == 1

0 commit comments

Comments
 (0)