163 lines
7.2 KiB
Python
163 lines
7.2 KiB
Python
import pytest
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import Permission
|
|
from django.core.exceptions import ValidationError
|
|
from django.test import Client
|
|
from django.urls import reverse
|
|
from wagtail.models import Page, Site
|
|
|
|
from apps.core.models import ContactPage, NavigationMenu, NavigationMenuItem, SimpleContentPage, SiteSettings
|
|
from apps.core.site_setup import setup_company_site
|
|
from apps.core.wagtail_hooks import register_company_setup_menu
|
|
from apps.forms.models import FormDefinition
|
|
from apps.home.models import HomePage
|
|
from apps.products.models import ProductIndexPage
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
@pytest.fixture
|
|
def company_data():
|
|
return {"company_name": "测试软件公司", "contact_phone": "010-12345678", "contact_email": "hello@example.com", "address": "测试地址", "icp_number": ""}
|
|
|
|
|
|
@pytest.fixture
|
|
def admin_user():
|
|
return get_user_model().objects.create_superuser("site-admin", "admin@example.com", "test-password")
|
|
|
|
|
|
def test_setup_creates_full_site_and_public_api(client, company_data):
|
|
created = setup_company_site(company_data, create_demo=True)
|
|
site = Site.objects.get(is_default_site=True)
|
|
assert isinstance(site.root_page.specific, HomePage)
|
|
assert len(created) == 13
|
|
assert set(site.root_page.get_children().values_list("slug", flat=True)) == {
|
|
"products", "solutions", "cases", "blog", "about", "contact", "privacy-policy",
|
|
}
|
|
assert SiteSettings.for_site(site).company_name == company_data["company_name"]
|
|
assert site.site_name == company_data["company_name"]
|
|
assert NavigationMenu.objects.get(name="main").items.count() == 7
|
|
assert NavigationMenu.objects.get(name="footer").items.count() == 3
|
|
assert FormDefinition.objects.get(name="官网项目咨询").notification_email == company_data["contact_email"]
|
|
for type_name, slug in [("core.SimpleContentPage", "about"), ("products.ProductPage", "content-platform"), ("core.ContactPage", "contact")]:
|
|
response = client.get("/api/v2/pages/", {"type": type_name, "slug": slug, "fields": "body"})
|
|
assert response.status_code == 200
|
|
assert response.json()["meta"]["total_count"] == 1
|
|
assert "虚构" in Page.objects.get(slug="demo-content-project").title
|
|
|
|
|
|
def test_setup_is_idempotent_and_preserves_edits(company_data):
|
|
setup_company_site(company_data, True)
|
|
page = SimpleContentPage.objects.get(slug="about")
|
|
page.title = "客户自己的介绍"
|
|
page.body = "<p>客户自己的内容</p>"
|
|
page.save_revision().publish()
|
|
count = Page.objects.count()
|
|
forms = FormDefinition.objects.count()
|
|
assert setup_company_site(company_data, True) == []
|
|
page.refresh_from_db()
|
|
assert page.title == "客户自己的介绍"
|
|
assert str(page.body) == "<p>客户自己的内容</p>"
|
|
assert Page.objects.count() == count
|
|
assert FormDefinition.objects.count() == forms
|
|
|
|
|
|
def test_existing_home_contact_menu_and_draft_are_preserved(home_page, company_data):
|
|
site = Site.objects.get(is_default_site=True)
|
|
site.root_page = home_page
|
|
site.save()
|
|
original_body = home_page.body.get_prep_value()
|
|
contact = home_page.add_child(instance=ContactPage(title="原有联系页", slug="contact", body=[("richtext", "<p>自定义</p>")]))
|
|
contact.save_revision().publish()
|
|
products = home_page.add_child(instance=ProductIndexPage(title="草稿栏目", slug="products", live=False))
|
|
products.save_revision()
|
|
menu = NavigationMenu.objects.create(name="main")
|
|
NavigationMenuItem.objects.create(menu=menu, label="原有菜单", link_url="/custom/")
|
|
setup_company_site(company_data, True)
|
|
home_page.refresh_from_db()
|
|
contact.refresh_from_db()
|
|
products.refresh_from_db()
|
|
assert home_page.body.get_prep_value() == original_body
|
|
assert contact.title == "原有联系页"
|
|
assert "自定义" in str(contact.body)
|
|
assert not products.live
|
|
assert menu.items.count() == 1
|
|
assert menu.items.first().label == "原有菜单"
|
|
assert FormDefinition.objects.count() == 0
|
|
|
|
|
|
def test_company_only_does_not_create_pages_or_forms(company_data):
|
|
before = Page.objects.count()
|
|
setup_company_site(company_data)
|
|
assert Page.objects.count() == before
|
|
assert FormDefinition.objects.count() == 0
|
|
assert NavigationMenu.objects.count() == 0
|
|
|
|
|
|
def test_conflict_rolls_back_all_changes(home_page, company_data):
|
|
site = Site.objects.get(is_default_site=True)
|
|
site.root_page = home_page
|
|
site.save()
|
|
home_page.add_child(instance=SimpleContentPage(title="路径冲突", slug="solutions"))
|
|
before = Page.objects.count()
|
|
with pytest.raises(ValidationError, match="solutions"):
|
|
setup_company_site(company_data, True)
|
|
assert Page.objects.count() == before
|
|
assert not SiteSettings.objects.filter(company_name=company_data["company_name"]).exists()
|
|
site.refresh_from_db()
|
|
assert site.site_name != company_data["company_name"]
|
|
|
|
|
|
def test_incompatible_root_is_not_replaced(company_data):
|
|
site = Site.objects.get(is_default_site=True)
|
|
site.root_page.slug = "existing-business"
|
|
site.root_page.save()
|
|
with pytest.raises(ValidationError, match="根页面"):
|
|
setup_company_site(company_data, True)
|
|
site.refresh_from_db()
|
|
assert site.root_page.slug == "existing-business"
|
|
|
|
|
|
def test_company_html_is_escaped(company_data):
|
|
company_data["company_name"] = '<script>alert("test")</script>'
|
|
setup_company_site(company_data, True)
|
|
assert "<script>" not in str(SimpleContentPage.objects.get(slug="about").body)
|
|
|
|
|
|
def test_wizard_get_and_post(client, admin_user, company_data):
|
|
client.force_login(admin_user)
|
|
url = reverse("company_site_setup")
|
|
response = client.get(url)
|
|
assert response.status_code == 200
|
|
assert "新建页面会立即公开发布" in response.content.decode()
|
|
before = Page.objects.count()
|
|
assert client.post(url, company_data).status_code == 302
|
|
assert Page.objects.count() == before
|
|
response = client.post(url, {**company_data, "create_demo": "on"}, follow=True)
|
|
assert response.status_code == 200
|
|
assert "新增 13 个页面" in response.content.decode()
|
|
|
|
|
|
def test_wizard_requires_superuser_and_csrf(client, admin_user, company_data):
|
|
url = reverse("company_site_setup")
|
|
assert client.get(url).status_code == 302
|
|
user = get_user_model().objects.create_user("editor", password="test-password", is_staff=True)
|
|
user.user_permissions.add(Permission.objects.get(content_type__app_label="wagtailadmin", codename="access_admin"))
|
|
client.force_login(user)
|
|
assert client.post(url, {**company_data, "create_demo": "on"}).status_code == 403
|
|
item = register_company_setup_menu()
|
|
request = type("Request", (), {"user": user})()
|
|
assert not item.is_shown(request)
|
|
csrf_client = Client(enforce_csrf_checks=True)
|
|
csrf_client.force_login(admin_user)
|
|
assert csrf_client.post(url, company_data).status_code == 403
|
|
|
|
|
|
def test_invalid_form_does_not_write(client, admin_user, company_data):
|
|
client.force_login(admin_user)
|
|
before = Page.objects.count()
|
|
response = client.post(reverse("company_site_setup"), {**company_data, "company_name": "", "contact_email": "invalid", "create_demo": "on"})
|
|
assert response.status_code == 200
|
|
assert response.context["form"].errors
|
|
assert Page.objects.count() == before
|