feat: 新增Snippet全局内容模型(TeamMember/Testimonial/Partner/NavigationMenu/SiteSettings)
- 新增 apps.core.TeamMember/Testimonial/Partner:简单 register_snippet,含 order 排序字段
- 新增 apps.core.NavigationMenu+NavigationMenuItem:ClusterableModel+Orderable+InlinePanel,
支持内部页面或外部链接二选一
- 新增 apps.core.SiteSettings:接入 wagtail.contrib.settings + BaseSiteSetting,
存放公司信息/ICP备案号/社交账号等全局配置
- 新增只读 API:/api/v1/custom/core/{team,testimonials,partners,navigation,site-settings}/
- 补充 apps/core/tests.py 单元测试,pytest 用例由 11 个增至 24 个,全部通过
- 更新设计文档 §2.16 Phase 1 进度清单
This commit is contained in:
+121
-1
@@ -1,8 +1,17 @@
|
||||
"""apps.core 基础单元测试:SEOablePage 抽象基类字段与公共 Block。"""
|
||||
import pytest
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from apps.core.blocks import FormBlock
|
||||
from apps.core.models import SimpleContentPage
|
||||
from apps.core.models import (
|
||||
NavigationMenu,
|
||||
NavigationMenuItem,
|
||||
Partner,
|
||||
SimpleContentPage,
|
||||
SiteSettings,
|
||||
TeamMember,
|
||||
Testimonial,
|
||||
)
|
||||
from apps.forms.models import FormDefinition, FormDefinitionField
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
@@ -75,3 +84,114 @@ def test_simple_content_page_can_be_created_under_home(home_page):
|
||||
page.refresh_from_db()
|
||||
assert SimpleContentPage.objects.live().descendant_of(home_page).count() == 1
|
||||
assert "个人信息保护" in page.body
|
||||
|
||||
|
||||
def test_team_member_default_ordering():
|
||||
"""团队成员应按 order 字段升序排列。"""
|
||||
TeamMember.objects.create(name="李四", order=2)
|
||||
TeamMember.objects.create(name="张三", order=1)
|
||||
names = list(TeamMember.objects.values_list("name", flat=True))
|
||||
assert names == ["张三", "李四"]
|
||||
|
||||
|
||||
def test_testimonial_str_includes_author_and_quote():
|
||||
testimonial = Testimonial.objects.create(
|
||||
quote="非常专业的服务,效果超出预期。", author_name="王经理"
|
||||
)
|
||||
assert "王经理" in str(testimonial)
|
||||
|
||||
|
||||
def test_partner_str_returns_name():
|
||||
partner = Partner.objects.create(name="示例合作伙伴")
|
||||
assert str(partner) == "示例合作伙伴"
|
||||
|
||||
|
||||
def test_navigation_menu_item_url_prefers_external_link_over_page(home_page):
|
||||
menu = NavigationMenu.objects.create(name="main")
|
||||
item = NavigationMenuItem.objects.create(
|
||||
menu=menu, label="首页", link_page=home_page, link_url="https://example.com"
|
||||
)
|
||||
assert item.url == "https://example.com"
|
||||
|
||||
|
||||
def test_navigation_menu_item_url_falls_back_to_page_url(home_page):
|
||||
menu = NavigationMenu.objects.create(name="main")
|
||||
item = NavigationMenuItem.objects.create(menu=menu, label="首页", link_page=home_page)
|
||||
assert item.url == home_page.url
|
||||
|
||||
|
||||
def test_navigation_menu_item_url_defaults_to_hash_when_empty():
|
||||
menu = NavigationMenu.objects.create(name="main")
|
||||
item = NavigationMenuItem.objects.create(menu=menu, label="占位")
|
||||
assert item.url == "#"
|
||||
|
||||
|
||||
def test_site_settings_for_site_creates_singleton_with_defaults():
|
||||
from wagtail.models import Site
|
||||
|
||||
site = Site.objects.get(is_default_site=True)
|
||||
settings_obj = SiteSettings.for_site(site)
|
||||
assert settings_obj.icp_url == "https://beian.miit.gov.cn/"
|
||||
# 再次获取应复用同一条记录而非重复创建
|
||||
assert SiteSettings.for_site(site).pk == settings_obj.pk
|
||||
|
||||
|
||||
def test_team_api_returns_ordered_members():
|
||||
TeamMember.objects.create(name="李四", role="工程师", order=2)
|
||||
TeamMember.objects.create(name="张三", role="总经理", order=1)
|
||||
|
||||
client = APIClient()
|
||||
response = client.get("/api/v1/custom/core/team/")
|
||||
|
||||
assert response.status_code == 200
|
||||
items = response.data["items"]
|
||||
assert [item["name"] for item in items] == ["张三", "李四"]
|
||||
assert items[0]["role"] == "总经理"
|
||||
|
||||
|
||||
def test_testimonial_api_returns_list():
|
||||
Testimonial.objects.create(quote="效果很好", author_name="客户A")
|
||||
|
||||
client = APIClient()
|
||||
response = client.get("/api/v1/custom/core/testimonials/")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.data["items"][0]["author_name"] == "客户A"
|
||||
|
||||
|
||||
def test_partner_api_returns_list():
|
||||
Partner.objects.create(name="伙伴A", website_url="https://partner-a.example.com")
|
||||
|
||||
client = APIClient()
|
||||
response = client.get("/api/v1/custom/core/partners/")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.data["items"][0]["name"] == "伙伴A"
|
||||
|
||||
|
||||
def test_navigation_menu_api_returns_items_by_name(home_page):
|
||||
menu = NavigationMenu.objects.create(name="main")
|
||||
NavigationMenuItem.objects.create(menu=menu, label="首页", link_page=home_page, sort_order=0)
|
||||
NavigationMenuItem.objects.create(menu=menu, label="外部链接", link_url="https://example.com", sort_order=1)
|
||||
|
||||
client = APIClient()
|
||||
response = client.get("/api/v1/custom/core/navigation/?name=main")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.data["name"] == "main"
|
||||
assert len(response.data["items"]) == 2
|
||||
assert response.data["items"][1]["url"] == "https://example.com"
|
||||
|
||||
|
||||
def test_navigation_menu_api_404_when_missing():
|
||||
client = APIClient()
|
||||
response = client.get("/api/v1/custom/core/navigation/?name=does-not-exist")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_site_settings_api_returns_defaults():
|
||||
client = APIClient()
|
||||
response = client.get("/api/v1/custom/core/site-settings/")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.data["icp_url"] == "https://beian.miit.gov.cn/"
|
||||
|
||||
Reference in New Issue
Block a user