- Use datetime.timedelta instead of timezone.timedelta (mypy) - Fix import ordering (ruff I001) - Fix admin sidebar E2E selector: use #wagtail-sidebar (Wagtail 7) - Set deterministic published_date on seeded E2E articles for stable ordering - Fix nightly test strict-mode violation: exact=True for Comments heading Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
235 lines
7.8 KiB
Python
235 lines
7.8 KiB
Python
from datetime import timedelta
|
|
|
|
import pytest
|
|
from django.test import override_settings
|
|
from django.utils import timezone
|
|
|
|
from apps.blog.models import ArticleIndexPage, ArticlePage
|
|
from apps.blog.tests.factories import AuthorFactory
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_published_date_auto_set_on_first_publish(home_page):
|
|
"""published_date should be auto-populated from first_published_at on first publish."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
article = ArticlePage(
|
|
title="Auto Date",
|
|
slug="auto-date",
|
|
author=author,
|
|
summary="summary",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
)
|
|
index.add_child(instance=article)
|
|
article.save_revision().publish()
|
|
article.refresh_from_db()
|
|
assert article.published_date is not None
|
|
assert article.published_date == article.first_published_at
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_published_date_preserved_when_explicitly_set(home_page):
|
|
"""An explicitly set published_date should not be overwritten on save."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
custom_date = timezone.now() - timedelta(days=30)
|
|
article = ArticlePage(
|
|
title="Custom Date",
|
|
slug="custom-date",
|
|
author=author,
|
|
summary="summary",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
published_date=custom_date,
|
|
)
|
|
index.add_child(instance=article)
|
|
article.save_revision().publish()
|
|
article.refresh_from_db()
|
|
assert article.published_date == custom_date
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_homepage_orders_articles_by_published_date(home_page):
|
|
"""HomePage context should list articles ordered by -published_date."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
|
|
older = ArticlePage(
|
|
title="Older",
|
|
slug="older",
|
|
author=author,
|
|
summary="s",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
published_date=timezone.now() - timedelta(days=10),
|
|
)
|
|
index.add_child(instance=older)
|
|
older.save_revision().publish()
|
|
|
|
newer = ArticlePage(
|
|
title="Newer",
|
|
slug="newer",
|
|
author=author,
|
|
summary="s",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
published_date=timezone.now(),
|
|
)
|
|
index.add_child(instance=newer)
|
|
newer.save_revision().publish()
|
|
|
|
ctx = home_page.get_context(type("Req", (), {"GET": {}})())
|
|
titles = [a.title for a in ctx["latest_articles"]]
|
|
assert titles.index("Newer") < titles.index("Older")
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_article_index_orders_by_published_date(home_page, rf):
|
|
"""ArticleIndexPage.get_articles should order by -published_date."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
|
|
old = ArticlePage(
|
|
title="Old",
|
|
slug="old",
|
|
author=author,
|
|
summary="s",
|
|
body=[("rich_text", "<p>b</p>")],
|
|
published_date=timezone.now() - timedelta(days=5),
|
|
)
|
|
index.add_child(instance=old)
|
|
old.save_revision().publish()
|
|
|
|
new = ArticlePage(
|
|
title="New",
|
|
slug="new",
|
|
author=author,
|
|
summary="s",
|
|
body=[("rich_text", "<p>b</p>")],
|
|
published_date=timezone.now(),
|
|
)
|
|
index.add_child(instance=new)
|
|
new.save_revision().publish()
|
|
|
|
articles = list(index.get_articles())
|
|
assert articles[0].title == "New"
|
|
assert articles[1].title == "Old"
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_feed_uses_published_date(article_page):
|
|
"""RSS feed item_pubdate should use published_date."""
|
|
from apps.blog.feeds import AllArticlesFeed
|
|
|
|
feed = AllArticlesFeed()
|
|
assert feed.item_pubdate(article_page) == article_page.published_date
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@override_settings(ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"])
|
|
def test_articles_listing_viewset_loads(client, django_user_model, home_page):
|
|
"""The Articles PageListingViewSet index page should load."""
|
|
admin = django_user_model.objects.create_superuser(
|
|
username="admin", email="admin@example.com", password="admin-pass"
|
|
)
|
|
client.force_login(admin)
|
|
response = client.get("/cms/articles/")
|
|
assert response.status_code == 200
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@override_settings(ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"])
|
|
def test_articles_listing_shows_articles(client, django_user_model, home_page):
|
|
"""The Articles listing should show existing articles."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
article = ArticlePage(
|
|
title="Listed Article",
|
|
slug="listed-article",
|
|
author=author,
|
|
summary="summary",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
)
|
|
index.add_child(instance=article)
|
|
article.save_revision().publish()
|
|
|
|
admin = django_user_model.objects.create_superuser(
|
|
username="admin", email="admin@example.com", password="admin-pass"
|
|
)
|
|
client.force_login(admin)
|
|
response = client.get("/cms/articles/")
|
|
assert response.status_code == 200
|
|
assert "Listed Article" in response.content.decode()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@override_settings(ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"])
|
|
def test_dashboard_panel_renders(client, django_user_model, home_page):
|
|
"""The Wagtail admin dashboard should include the articles summary panel."""
|
|
admin = django_user_model.objects.create_superuser(
|
|
username="admin", email="admin@example.com", password="admin-pass"
|
|
)
|
|
client.force_login(admin)
|
|
response = client.get("/cms/")
|
|
assert response.status_code == 200
|
|
content = response.content.decode()
|
|
assert "Articles overview" in content
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@override_settings(ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"])
|
|
def test_dashboard_panel_shows_drafts(client, django_user_model, home_page):
|
|
"""Dashboard panel should list draft articles."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
draft = ArticlePage(
|
|
title="My Draft Post",
|
|
slug="draft-post",
|
|
author=author,
|
|
summary="summary",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
)
|
|
index.add_child(instance=draft)
|
|
draft.save_revision() # save revision but don't publish
|
|
|
|
admin = django_user_model.objects.create_superuser(
|
|
username="admin", email="admin@example.com", password="admin-pass"
|
|
)
|
|
client.force_login(admin)
|
|
response = client.get("/cms/")
|
|
content = response.content.decode()
|
|
assert "My Draft Post" in content
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@override_settings(ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"])
|
|
def test_article_edit_page_has_tabbed_interface(client, django_user_model, home_page):
|
|
"""ArticlePage editor should have tabbed panels (Content, Metadata, Publishing, SEO)."""
|
|
index = ArticleIndexPage(title="Articles", slug="articles")
|
|
home_page.add_child(instance=index)
|
|
author = AuthorFactory()
|
|
article = ArticlePage(
|
|
title="Tabbed",
|
|
slug="tabbed",
|
|
author=author,
|
|
summary="summary",
|
|
body=[("rich_text", "<p>body</p>")],
|
|
)
|
|
index.add_child(instance=article)
|
|
article.save_revision().publish()
|
|
|
|
admin = django_user_model.objects.create_superuser(
|
|
username="admin", email="admin@example.com", password="admin-pass"
|
|
)
|
|
client.force_login(admin)
|
|
response = client.get(f"/cms/pages/{article.pk}/edit/")
|
|
content = response.content.decode()
|
|
assert response.status_code == 200
|
|
assert "Content" in content
|
|
assert "Metadata" in content
|
|
assert "Publishing" in content
|
|
assert "SEO" in content
|