Auto slug, auto summary/SEO, and deterministic tag colours
Issue #61: Strengthen auto-generation for slug, summary, and SEO fields. - ArticlePage.save() now auto-generates slug from title when empty - ArticlePage.save() auto-populates search_description from summary - Admin form also auto-populates search_description from summary Issue #63: Replace manual TagMetadata colour assignment with deterministic hash-based auto-colour. Tags get a consistent colour from a 12-entry palette without needing a TagMetadata snippet. TagMetadata still works as an explicit override. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -411,6 +411,73 @@ def test_snippet_category_listing_shows_categories(client, django_user_model):
|
||||
assert "Tutorials" in content
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_article_admin_form_clean_auto_populates_search_description(article_index, django_user_model, monkeypatch):
|
||||
"""Form clean should auto-populate search_description from summary."""
|
||||
user = django_user_model.objects.create_user(
|
||||
username="writer",
|
||||
email="writer@example.com",
|
||||
password="writer-pass",
|
||||
first_name="Writer",
|
||||
last_name="User",
|
||||
)
|
||||
form_class = ArticlePage.get_edit_handler().get_form_class()
|
||||
form = form_class(parent_page=article_index, for_user=user)
|
||||
|
||||
body = [
|
||||
SimpleNamespace(block_type="rich_text", value=SimpleNamespace(source="<p>Article body text.</p>")),
|
||||
]
|
||||
form.cleaned_data = {
|
||||
"title": "SEO Test",
|
||||
"slug": "",
|
||||
"author": None,
|
||||
"category": None,
|
||||
"summary": "",
|
||||
"search_description": "",
|
||||
"body": body,
|
||||
}
|
||||
|
||||
mro = form.__class__.__mro__
|
||||
super_form_class = mro[mro.index(ArticlePageAdminForm) + 1]
|
||||
monkeypatch.setattr(super_form_class, "clean", lambda _self: _self.cleaned_data)
|
||||
cleaned = form.clean()
|
||||
|
||||
assert cleaned["summary"] == "Article body text."
|
||||
assert cleaned["search_description"] == "Article body text."
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_article_admin_form_preserves_explicit_search_description(article_index, django_user_model, monkeypatch):
|
||||
"""Form clean should not overwrite an explicit search_description."""
|
||||
user = django_user_model.objects.create_user(
|
||||
username="writer2",
|
||||
email="writer2@example.com",
|
||||
password="writer-pass",
|
||||
)
|
||||
form_class = ArticlePage.get_edit_handler().get_form_class()
|
||||
form = form_class(parent_page=article_index, for_user=user)
|
||||
|
||||
body = [
|
||||
SimpleNamespace(block_type="rich_text", value=SimpleNamespace(source="<p>Body.</p>")),
|
||||
]
|
||||
form.cleaned_data = {
|
||||
"title": "SEO Explicit Test",
|
||||
"slug": "seo-explicit-test",
|
||||
"author": None,
|
||||
"category": None,
|
||||
"summary": "My summary.",
|
||||
"search_description": "Custom SEO text.",
|
||||
"body": body,
|
||||
}
|
||||
|
||||
mro = form.__class__.__mro__
|
||||
super_form_class = mro[mro.index(ArticlePageAdminForm) + 1]
|
||||
monkeypatch.setattr(super_form_class, "clean", lambda _self: _self.cleaned_data)
|
||||
cleaned = form.clean()
|
||||
|
||||
assert cleaned["search_description"] == "Custom SEO text."
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_article_page_omits_admin_messages_on_frontend(article_page, rf):
|
||||
"""Frontend templates should not render admin session messages."""
|
||||
|
||||
Reference in New Issue
Block a user