Files
blog.pyaqa.ru/app/application/use_cases/get_post.py
Sergey Vanyushkin 30d9e287a7
All checks were successful
ci/woodpecker/pr/pipeline Pipeline was successful
feat: add e2e tests for likes and fix like_count propagation in DTO mapping
- Write 3 e2e tests (TC-E2E-106-108): like/unlike flow, multi-user like, guest redirect
- Add get_like_count() and click_like() to PostDetailPage object
- Fix _map_to_dto in 5 use cases (create, get, list, publish, update) to include like_count
- Fix pre-existing mypy issues in page object (evaluate returns Any)
- Update FEATURE_LIKES.md with verified E2E status
2026-05-10 21:11:28 +03:00

101 lines
2.9 KiB
Python

"""Get post use case.
This module implements the use case for retrieving blog posts.
Supports lookup by both ID and slug.
"""
from uuid import UUID
from app.application.dtos.post import PostResponseDTO
from app.application.interfaces import TransactionManager
from app.domain.entities import Post
from app.domain.exceptions import NotFoundException
from app.domain.repositories import PostRepository
class GetPostUseCase:
"""Use case for retrieving a post by ID or slug.
Provides methods to fetch posts using different identifiers.
Handles not-found scenarios with appropriate exceptions.
Attributes:
_post_repo: Repository for post data access.
_tx_manager: Transaction manager for transaction control.
Example:
>>> use_case = GetPostUseCase(post_repo, tx_manager)
>>> post = await use_case.by_id(post_id)
>>> post = await use_case.by_slug("my-post")
"""
def __init__(
self,
post_repo: PostRepository,
tx_manager: TransactionManager,
) -> None:
"""Initialize use case with dependencies.
Args:
post_repo: Repository for post operations.
tx_manager: Transaction manager instance.
"""
self._post_repo = post_repo
self._tx_manager = tx_manager
async def by_id(self, post_id: UUID) -> PostResponseDTO:
"""Get post by ID.
Args:
post_id: Unique identifier of the post.
Returns:
PostResponseDTO with complete post data.
Raises:
NotFoundException: If post with given ID does not exist.
"""
post = await self._post_repo.get_by_id(post_id)
if not post:
raise NotFoundException(f"Post with id '{post_id}' not found")
return self._map_to_dto(post)
async def by_slug(self, slug: str) -> PostResponseDTO:
"""Get post by slug.
Args:
slug: URL-friendly slug identifier.
Returns:
PostResponseDTO with complete post data.
Raises:
NotFoundException: If post with given slug does not exist.
"""
post = await self._post_repo.get_by_slug(slug)
if not post:
raise NotFoundException(f"Post with slug '{slug}' not found")
return self._map_to_dto(post)
def _map_to_dto(self, post: Post) -> PostResponseDTO:
"""Map domain entity to response DTO.
Args:
post: Domain post entity.
Returns:
PostResponseDTO with all post attributes.
"""
return PostResponseDTO(
id=post.id,
title=post.title.value,
content=post.content.value,
slug=post.slug.value,
author_id=post.author_id,
published=post.published,
like_count=post.like_count,
tags=post.tags.copy(),
created_at=post.created_at,
updated_at=post.updated_at,
)