"""End-to-end tests for post likes via web UI. Tests the like/unlike toggle flow, multi-user like isolation, and guest authentication redirect. """ from __future__ import annotations import uuid import pytest from playwright.sync_api import Page, expect from pytfm.generators import PostDataGenerator from tests.e2e.pages import HomePage, PostDetailPage, PostFormPage def _unique_title(base: str) -> str: """Append a short UUID to a title to avoid slug collisions.""" return f"{base} {uuid.uuid4().hex[:8]}" @pytest.mark.e2e def test_like_unlike_flow( user_page: Page, base_url: str, ) -> None: """Test like/unlike toggle through the web UI. Steps: 1. Create and publish a post. 2. Verify initial like count is 0. 3. Click the like button. 4. Verify like count becomes 1. 5. Click the like button again. 6. Verify like count returns to 0. Args: user_page: Playwright page authenticated as regular user. base_url: Application base URL. """ generator = PostDataGenerator() post_data = generator.generate_post() title = _unique_title(str(post_data["title"])) content = str(post_data["content"]) tags = ", ".join(post_data["tags"]) home = HomePage(user_page, base_url) home.open() home.create_post() form = PostFormPage(user_page, base_url) form.fill_form(title, content, tags) with user_page.expect_navigation(wait_until="networkidle"): form.publish() current_url = user_page.url assert "new" not in current_url, f"Still on form page: {current_url}" slug = current_url.rstrip("/").split("/")[-1] user_page.wait_for_selector('[data-testid="post-detail-title"]') detail = PostDetailPage(user_page, base_url, slug) assert detail.get_title() == title # Initial like count should be 0 for a new post assert detail.get_like_count() == 0 # Like the post detail.click_like() expect(user_page.locator("#like-count")).to_have_text("1", timeout=15000) # Unlike the post detail.click_like() expect(user_page.locator("#like-count")).to_have_text("0", timeout=15000) @pytest.mark.e2e def test_multiple_users_can_like( user_page: Page, user2_page: Page, base_url: str, ) -> None: """Test that two users can independently like the same post. Steps: 1. User creates and publishes a post. 2. User likes the post (count becomes 1). 3. User2 opens the same post (sees count=1). 4. User2 clicks like (count becomes 2). Args: user_page: Playwright page authenticated as first regular user. user2_page: Playwright page authenticated as second regular user. base_url: Application base URL. """ generator = PostDataGenerator() post_data = generator.generate_post() title = _unique_title(str(post_data["title"])) content = str(post_data["content"]) tags = ", ".join(post_data["tags"]) home = HomePage(user_page, base_url) home.open() home.create_post() form = PostFormPage(user_page, base_url) form.fill_form(title, content, tags) with user_page.expect_navigation(wait_until="networkidle"): form.publish() current_url = user_page.url assert "new" not in current_url, f"Still on form page: {current_url}" slug = current_url.rstrip("/").split("/")[-1] user_page.wait_for_selector('[data-testid="post-detail-title"]') detail = PostDetailPage(user_page, base_url, slug) assert detail.get_title() == title # User likes the post assert detail.get_like_count() == 0 detail.click_like() expect(user_page.locator("#like-count")).to_have_text("1", timeout=15000) # Verify like_count persists after page reload user_page.reload(wait_until="networkidle") user_page.wait_for_selector('[data-testid="post-detail-title"]') assert detail.get_like_count() == 1 # User2 opens same post and likes user2_detail = PostDetailPage(user2_page, base_url, slug) user2_detail.open() user2_page.wait_for_selector('[data-testid="post-detail-title"]') assert user2_detail.get_like_count() == 1 user2_detail.click_like() expect(user2_page.locator("#like-count")).to_have_text("2", timeout=15000) @pytest.mark.e2e def test_guest_redirect_on_like( user_page: Page, guest_page: Page, base_url: str, ) -> None: """Test that unauthenticated guests are redirected to login when liking. Steps: 1. User creates and publishes a post. 2. Guest opens the post detail page. 3. Guest clicks the like button. 4. Guest is redirected to the development login page. Args: user_page: Playwright page authenticated as regular user. guest_page: Unauthenticated Playwright page. base_url: Application base URL. """ generator = PostDataGenerator() post_data = generator.generate_post() title = _unique_title(str(post_data["title"])) content = str(post_data["content"]) tags = ", ".join(post_data["tags"]) home = HomePage(user_page, base_url) home.open() home.create_post() form = PostFormPage(user_page, base_url) form.fill_form(title, content, tags) with user_page.expect_navigation(wait_until="networkidle"): form.publish() current_url = user_page.url assert "new" not in current_url, f"Still on form page: {current_url}" slug = current_url.rstrip("/").split("/")[-1] # Guest opens the published post guest_detail = PostDetailPage(guest_page, base_url, slug) guest_detail.open() guest_page.wait_for_selector('[data-testid="post-detail-title"]') # Guest clicks like -> should be redirected to dev login page with guest_page.expect_navigation(wait_until="networkidle", timeout=15000): guest_detail.click_like() assert "dev-login" in guest_page.url