Files
blog.pyaqa.ru/tests/FEATURE_LIKES.md
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

209 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Test Model: Post Likes
Feature: Like/unlike toggle on blog posts with per-user tracking, session-based
guest identification, and anti-bot protection via JS-only POST.
## Unit Test Cases
### TogglePostLikeUseCase
#### TC-UNIT-822: TogglePostLikeUseCase — Like first time
- **Type:** Positive
- **Layer:** Unit
- **File:** `unit/application/test_toggle_like.py::TestTogglePostLikeUseCase::test_like_post_first_time`
- **Preconditions:** Post exists, no existing like for this user
- **Steps:** Execute toggle with valid post_id and liked_by
- **Expected:**
- `add_like` called once
- `remove_like` not called
- Response DTO has `like_count=1`
- **Last Verified:** 2026-05-10
#### TC-UNIT-823: TogglePostLikeUseCase — Unlike (already liked)
- **Type:** Positive
- **Layer:** Unit
- **File:** `unit/application/test_toggle_like.py::TestTogglePostLikeUseCase::test_unlike_post_already_liked`
- **Preconditions:** Post exists, existing like found for this user
- **Steps:** Execute toggle with same post_id and liked_by
- **Expected:**
- `remove_like` called once
- `add_like` not called
- Response DTO has `like_count=0`
- **Last Verified:** 2026-05-10
#### TC-UNIT-824: TogglePostLikeUseCase — Post not found
- **Type:** Negative
- **Layer:** Unit
- **File:** `unit/application/test_toggle_like.py::TestTogglePostLikeUseCase::test_like_post_not_found`
- **Preconditions:** Repository returns None for post lookup
- **Steps:** Execute toggle with non-existent post_id
- **Expected:** `NotFoundException` raised
- **Last Verified:** 2026-05-10
#### TC-UNIT-825: TogglePostLikeUseCase — Guest via device_id
- **Type:** Positive
- **Layer:** Unit
- **File:** `unit/application/test_toggle_like.py::TestTogglePostLikeUseCase::test_like_as_guest_with_device_id`
- **Preconditions:** Post exists, no existing like, liked_by set to device_id
- **Steps:** Execute toggle with device_id instead of user_id
- **Expected:**
- Like created with `liked_by == device_id`
- Response DTO has `like_count=1`
- **Last Verified:** 2026-05-10
#### TC-UNIT-828: TogglePostLikeUseCase — Identity isolation
- **Type:** Positive
- **Layer:** Unit
- **File:** `unit/application/test_toggle_like.py::TestTogglePostLikeUseCase::test_two_users_can_both_like`
- **Preconditions:** Post exists, user1 likes first
- **Steps:** User2 toggles like on same post
- **Expected:**
- User2's like added (separate identity)
- `like_count=2`
- **Last Verified:** 2026-05-10
### Domain Entities
#### TC-UNIT-826: PostLike entity — valid creation
- **Type:** Positive
- **Layer:** Unit
- **File:** `unit/domain/test_like_entity.py::TestPostLikeEntity::test_post_like_creation`
- **Preconditions:** Valid post_id and liked_by values
- **Steps:** Create PostLike instance
- **Expected:**
- `post_id` matches input
- `liked_by` matches input
- `id` is a valid UUID
- `created_at` is set
- **Last Verified:** 2026-05-10
#### TC-UNIT-827: Post entity — like_count default 0
- **Type:** Positive
- **Layer:** Unit
- **File:** `unit/domain/test_post_entity.py::TestPostEntity::test_like_count_defaults_to_zero`
- **Preconditions:** —
- **Steps:** Create Post via `Post.create()`
- **Expected:** `post.like_count == 0`
- **Last Verified:** 2026-05-10
## API Test Cases
#### TC-API-114: Like Post — authenticated toggle on
- **Type:** Positive
- **Layer:** API
- **File:** `api/test_likes.py::TestLikePost::test_like_post_authenticated`
- **Preconditions:** Post exists, user authenticated
- **Steps:** POST `/api/v1/posts/{id}/like` with auth header
- **Expected:**
- Status 200
- `like_count == 1`
- **Last Verified:** 2026-05-10
#### TC-API-115: Like Post — authenticated toggle off
- **Type:** Positive
- **Layer:** API
- **File:** `api/test_likes.py::TestLikePost::test_unlike_post_authenticated`
- **Preconditions:** Post exists, user already liked it
- **Steps:** POST `/api/v1/posts/{id}/like` second time
- **Expected:**
- Status 200
- `like_count == 0`
- **Last Verified:** 2026-05-10
#### TC-API-116: Like Post — guest via device_id
- **Type:** Positive
- **Layer:** API
- **File:** `api/test_likes.py::TestLikePost::test_like_post_as_guest`
- **Preconditions:** Post exists, guest token used
- **Steps:** POST `/api/v1/posts/{id}/like` with guest token
- **Expected:**
- Status 200
- `like_count == 1`
- **Last Verified:** 2026-05-10
#### TC-API-117: Like Post — not found
- **Type:** Negative
- **Layer:** API
- **File:** `api/test_likes.py::TestLikePost::test_like_post_not_found`
- **Preconditions:** Post does not exist
- **Steps:** POST `/api/v1/posts/{id}/like` with auth header
- **Expected:**
- Status 404
- **Last Verified:** 2026-05-10
## Web Test Cases
#### TC-WEB-001: Like count on post list
- **Type:** Positive
- **Layer:** Web
- **File:** `tests/web/test_likes.py::TestLikeDisplay::test_like_count_on_homepage`
- **Preconditions:** Posts exist with known like counts
- **Steps:** GET `/web/`
- **Expected:**
- Each post card shows like count
- `data-testid="like-count-{post.id}"` present
- **Last Verified:** 2026-05-10
#### TC-WEB-002: Like button on post detail
- **Type:** Positive
- **Layer:** Web
- **File:** `tests/web/test_likes.py::TestLikeDisplay::test_like_button_on_detail`
- **Preconditions:** Post exists
- **Steps:** GET `/web/posts/{slug}`
- **Expected:**
- Like count displayed
- `data-testid="like-button"` present
- **Last Verified:** 2026-05-10
#### TC-WEB-003: Like toggle via POST
- **Type:** Positive
- **Layer:** Web
- **File:** `tests/web/test_likes.py::TestLikeToggle::test_like_toggle_via_web`
- **Preconditions:** Post exists
- **Steps:** POST `/web/posts/{slug}/like` redirects back
- **Expected:**
- 303 redirect to post detail
- Like count incremented
- **Last Verified:** 2026-05-10
## E2E Test Cases
#### TC-E2E-106: Like/Unlike flow via web UI
- **Type:** Positive
- **Layer:** E2E
- **File:** `tests/e2e/test_likes.py::test_like_unlike_flow`
- **Scenario:** Create post → like → verify count → unlike → verify count
- **Expected:** Count toggles correctly (0→1→0)
- **Last Verified:** 2026-05-10
#### TC-E2E-107: Separate users can both like
- **Type:** Positive
- **Layer:** E2E
- **File:** `tests/e2e/test_likes.py::test_multiple_users_can_like`
- **Scenario:** User1 likes → count=1 → User2 likes → count=2
- **Expected:** Count increments per user
- **Last Verified:** 2026-05-10
#### TC-E2E-108: Guest redirect on like
- **Type:** Positive
- **Layer:** E2E
- **File:** `tests/e2e/test_likes.py::test_guest_redirect_on_like`
- **Scenario:** Guest opens published post → clicks like → redirected to login
- **Expected:** 401 redirects to `/auth/dev-login`
- **Last Verified:** 2026-05-10
## Coverage Summary
| Component | Cases | Status |
|-----------|-------|--------|
| TogglePostLikeUseCase | 5 | ✅ Verified |
| Domain Entities (PostLike, Post) | 2 | ✅ Verified |
| API Endpoints | 4 | ✅ Verified |
| Web Display | 3 | ⬜ Planned |
| E2E Flows | 3 | ✅ Verified |
## Gaps (Not Yet Covered)
- [ ] Web tests (TC-WEB-001003) — test infrastructure pending
- [ ] Full device_id middleware for guest like support