2026-05-12 12:45:52 +02:00
|
|
|
import pytest
|
|
|
|
|
from uuid import uuid4
|
2026-06-05 05:36:18 +02:00
|
|
|
from datetime import datetime, timedelta, timezone
|
2026-05-23 03:21:55 +02:00
|
|
|
from tests.conftest import BASE_URL, assert_share_copies
|
2026-05-12 12:45:52 +02:00
|
|
|
from devplacepy.database import get_table
|
|
|
|
|
from devplacepy.utils import make_combined_slug
|
|
|
|
|
|
|
|
|
|
|
2026-06-05 05:36:18 +02:00
|
|
|
def _seed_news_paginated(count):
|
|
|
|
|
news_table = get_table("news")
|
|
|
|
|
base = datetime.now(timezone.utc)
|
|
|
|
|
marker = uuid4().hex[:8]
|
|
|
|
|
titles = []
|
|
|
|
|
for i in range(count):
|
|
|
|
|
uid = str(uuid4())
|
|
|
|
|
title = f"Pag News {marker} {i:02d}"
|
|
|
|
|
titles.append(title)
|
|
|
|
|
news_table.insert({
|
|
|
|
|
"uid": uid, "slug": make_combined_slug(title, uid), "title": title,
|
|
|
|
|
"external_id": f"pag_{marker}_{i}", "grade": 10,
|
|
|
|
|
"status": "published", "show_on_landing": 0, "source_name": "PagSource",
|
|
|
|
|
"url": "https://example.com", "description": "paginated news",
|
|
|
|
|
"synced_at": (base - timedelta(seconds=i)).isoformat(),
|
|
|
|
|
})
|
|
|
|
|
return titles
|
|
|
|
|
|
|
|
|
|
|
2026-05-23 03:21:55 +02:00
|
|
|
def test_news_detail_share_button(page, news_article):
|
|
|
|
|
slug = news_article.get("slug") or news_article["uid"]
|
|
|
|
|
page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
|
|
|
|
|
assert_share_copies(page, "/news/")
|
|
|
|
|
|
|
|
|
|
|
2026-05-12 12:45:52 +02:00
|
|
|
def seed_news():
|
|
|
|
|
news_table = get_table("news")
|
|
|
|
|
for i in range(3):
|
|
|
|
|
eid = f"test_news_{i}"
|
|
|
|
|
if news_table.find_one(external_id=eid):
|
|
|
|
|
continue
|
|
|
|
|
uid = str(uuid4())
|
|
|
|
|
title = f"News Test Article {i}"
|
|
|
|
|
slug = make_combined_slug(title, uid)
|
|
|
|
|
news_table.insert({
|
|
|
|
|
"uid": uid, "slug": slug, "title": title,
|
|
|
|
|
"external_id": eid, "grade": 8 + i,
|
|
|
|
|
"status": "published", "show_on_landing": 1,
|
|
|
|
|
"source_name": "TestSource",
|
2026-05-14 04:12:19 +02:00
|
|
|
"synced_at": datetime.now(timezone.utc).isoformat(),
|
2026-05-12 12:45:52 +02:00
|
|
|
"description": f"Description for test article {i}.",
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def news_article(app_server):
|
|
|
|
|
seed_news()
|
2026-06-05 05:36:18 +02:00
|
|
|
article = get_table("news").find_one(external_id="test_news_0")
|
2026-05-12 12:45:52 +02:00
|
|
|
return article
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_news_listing_loads(page, app_server):
|
|
|
|
|
seed_news()
|
|
|
|
|
page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
|
|
|
|
|
assert page.is_visible("text=Developer News")
|
|
|
|
|
assert page.is_visible("text=News Test Article")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_news_listing_authenticated(alice):
|
|
|
|
|
page, _ = alice
|
|
|
|
|
seed_news()
|
|
|
|
|
page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
|
|
|
|
|
assert page.is_visible("text=Developer News")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_news_detail_loads(page, news_article):
|
|
|
|
|
slug = news_article.get("slug") or news_article["uid"]
|
|
|
|
|
page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
|
|
|
|
|
assert page.is_visible("text=News Test Article")
|
|
|
|
|
assert page.is_visible("text=Comments")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_news_detail_404(page, app_server):
|
|
|
|
|
page.goto(f"{BASE_URL}/news/nonexistent-article", wait_until="domcontentloaded")
|
|
|
|
|
assert page.is_visible("text=not found", timeout=5000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_news_comment(alice, news_article):
|
|
|
|
|
page, _ = alice
|
|
|
|
|
slug = news_article.get("slug") or news_article["uid"]
|
|
|
|
|
page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
|
|
|
|
|
page.fill("textarea[name='content']", "Test comment on news article")
|
|
|
|
|
page.click("button:has-text('Post')")
|
2026-06-05 19:22:29 +02:00
|
|
|
page.wait_for_url(f"{BASE_URL}/news/{slug}**", wait_until="domcontentloaded")
|
2026-05-12 12:45:52 +02:00
|
|
|
assert page.is_visible("text=Test comment on news article")
|
|
|
|
|
|
|
|
|
|
|
2026-06-05 05:36:18 +02:00
|
|
|
def test_news_pagination_first_page(page, app_server):
|
|
|
|
|
_seed_news_paginated(30)
|
|
|
|
|
page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
|
|
|
|
|
assert page.locator(".news-card").count() == 25
|
|
|
|
|
assert page.is_visible(".load-more-wrap")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_news_pagination_load_more(page, app_server):
|
|
|
|
|
titles = _seed_news_paginated(30)
|
|
|
|
|
page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
|
|
|
|
|
newest = titles[0]
|
|
|
|
|
assert page.is_visible(f".news-card-title:has-text('{newest}')")
|
|
|
|
|
page.click(".load-more-wrap a")
|
|
|
|
|
page.wait_for_url(lambda url: "before=" in url, wait_until="domcontentloaded")
|
|
|
|
|
assert not page.is_visible(f".news-card-title:has-text('{newest}')")
|
|
|
|
|
assert page.locator(".news-card").count() >= 1
|
|
|
|
|
|
|
|
|
|
|
2026-05-12 12:45:52 +02:00
|
|
|
def test_news_detail_guest(page, news_article):
|
|
|
|
|
slug = news_article.get("slug") or news_article["uid"]
|
|
|
|
|
page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
|
|
|
|
|
assert page.is_visible("text=News Test Article")
|
|
|
|
|
assert page.is_visible("text=Comments")
|
|
|
|
|
assert page.is_visible("text=Read on TestSource")
|
|
|
|
|
|