fix(editor): auto-default article metadata and de-duplicate SEO panels
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / ci (pull_request) Failing after 1m33s
CI / pr-e2e (pull_request) Successful in 1m35s

This commit is contained in:
codex_a
2026-03-04 22:32:14 +00:00
parent 93d3e4703b
commit 521075cf04
2 changed files with 220 additions and 5 deletions

View File

@@ -1,10 +1,11 @@
from datetime import timedelta
from types import SimpleNamespace
import pytest
from django.test import override_settings
from django.utils import timezone
from apps.blog.models import ArticleIndexPage, ArticlePage
from apps.blog.models import ArticleIndexPage, ArticlePage, ArticlePageAdminForm, Category
from apps.blog.tests.factories import AuthorFactory
@@ -273,3 +274,107 @@ def test_article_search_fields_include_summary():
f.field_name for f in ArticlePage.search_fields if hasattr(f, "field_name")
]
assert "summary" in field_names
@pytest.mark.django_db
def test_article_admin_form_relaxes_initial_required_fields(article_index, django_user_model):
"""Slug/author/category/summary should not block initial draft validation."""
user = django_user_model.objects.create_user(
username="writer",
email="writer@example.com",
password="writer-pass",
)
form_class = ArticlePage.get_edit_handler().get_form_class()
form = form_class(parent_page=article_index, for_user=user)
assert form.fields["slug"].required is False
assert form.fields["author"].required is False
assert form.fields["category"].required is False
assert form.fields["summary"].required is False
@pytest.mark.django_db
def test_article_admin_form_clean_applies_defaults(article_index, django_user_model, monkeypatch):
"""Form clean should auto-fill slug/author/category/summary when omitted."""
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="code", value=SimpleNamespace(raw_code="print('ignore')")),
SimpleNamespace(block_type="rich_text", value=SimpleNamespace(source="<p>Hello world body text.</p>")),
]
def fake_super_clean(_self):
_self.cleaned_data = {
"title": "Auto Defaults Title",
"slug": "",
"author": None,
"category": None,
"summary": "",
"body": body,
}
return _self.cleaned_data
mro = form.__class__.__mro__
super_form_class = mro[mro.index(ArticlePageAdminForm) + 1]
monkeypatch.setattr(super_form_class, "clean", fake_super_clean)
cleaned = form.clean()
assert cleaned["slug"] == "auto-defaults-title"
assert cleaned["author"] is not None
assert cleaned["author"].user_id == user.id
assert cleaned["category"] is not None
assert cleaned["category"].slug == "general"
assert cleaned["summary"] == "Hello world body text."
@pytest.mark.django_db
def test_article_seo_tab_fields_not_duplicated():
"""SEO tab should include each promote/SEO field only once."""
handler = ArticlePage.get_edit_handler()
seo_tab = next(panel for panel in handler.children if panel.heading == "SEO")
def flatten_field_names(panel):
names = []
for child in panel.children:
if hasattr(child, "field_name"):
names.append(child.field_name)
else:
names.extend(flatten_field_names(child))
return names
field_names = flatten_field_names(seo_tab)
assert field_names.count("slug") == 1
assert field_names.count("seo_title") == 1
assert field_names.count("search_description") == 1
assert field_names.count("show_in_menus") == 1
@pytest.mark.django_db
def test_article_save_autogenerates_summary_when_missing(article_index):
"""Model save fallback should generate summary from prose blocks."""
category = Category.objects.create(name="Guides", slug="guides")
author = AuthorFactory()
article = ArticlePage(
title="Summary Auto",
slug="summary-auto",
author=author,
category=category,
summary="",
body=[
("code", {"language": "python", "filename": "", "raw_code": "print('skip')"}),
("rich_text", "<p>This should become the summary text.</p>"),
],
)
article_index.add_child(instance=article)
article.save()
assert article.summary == "This should become the summary text."