Files

121 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""批次 C3 · 营销官网测试。
覆盖:页面可达、SEO meta/结构化数据、价格页数据与 Plan 同源、行业页只写已实现特性
("不写纸面功能")、移动端 viewport。
"""
import pytest
from django.test import Client
from apps.billing.models import Plan, seed_plans
@pytest.fixture
def site(db):
seed_plans()
return Client()
PAGES = [
("/site/", "AI 开单"),
("/site/pricing/", "价格与功能对比"),
("/site/industry/food/", "食品饮料"),
("/site/industry/hardware/", "五金建材"),
("/site/industry/autoparts/", "汽配"),
]
@pytest.mark.parametrize("url,needle", PAGES)
def test_pages_reachable(site, url, needle):
resp = site.get(url)
assert resp.status_code == 200, url
html = resp.content.decode("utf-8")
assert needle in html
@pytest.mark.parametrize("url,_needle", PAGES)
def test_pages_have_seo_meta(site, url, _needle):
"""每页都要有 title / description / canonical / 结构化数据 / viewport。"""
html = site.get(url).content.decode("utf-8")
assert "<title>" in html
assert 'name="description"' in html
assert 'rel="canonical"' in html
assert 'application/ld+json' in html
assert 'name="viewport"' in html
assert "width=device-width" in html
def test_pricing_reads_plan_limits(site):
"""价格页的额度数字必须来自 Plan.limits(与系统校验同源)。"""
html = site.get("/site/pricing/").content.decode("utf-8")
free = Plan.objects.get(code="free")
basic = Plan.objects.get(code="basic")
pro = Plan.objects.get(code="pro")
assert free.name in html and basic.name in html and pro.name in html
assert "998" in html and "4800" in html
# 免费版 100 商品 / 基础版 3000 商品
assert f"{free.limits['products']:,}" in html
assert f"{basic.limits['products']:,}" in html
# 专业版不限项展示为"不限"
assert "不限" in html
def test_pricing_flag_row_uses_checkmark(site):
html = site.get("/site/pricing/").content.decode("utf-8")
assert "✓" in html # 支持的项打勾
assert "—" in html # 不支持的项破折号(free 无订货商城)
def test_home_lists_three_ai_sellpoints(site):
html = site.get("/site/").content.decode("utf-8")
assert "AI 应收风险预警" in html
assert "AI 录单" in html
assert "AI 经营问答" in html
# 独家卖点有标注
assert "独家" in html
def test_home_lists_six_roles(site):
html = site.get("/site/").content.decode("utf-8")
for role in ["老板", "财务", "销售", "仓管", "采购", "运营"]:
assert role in html, role
def test_food_page_claims_only_shipped_features(site):
"""食品页卖点必须都是已交付的:批次/FEFO/临期预警/多单位/信用额度。"""
html = site.get("/site/industry/food/").content.decode("utf-8")
for kw in ["批次账", "FEFO", "临期自动预警", "多单位换算", "信用额度"]:
assert kw in html, kw
def test_hardware_page_claims_only_shipped_features(site):
html = site.get("/site/industry/hardware/").content.decode("utf-8")
for kw in ["换算率", "三档抹零", "最低售价管控", "价格历史参考"]:
assert kw in html, kw
def test_autoparts_page_marks_unshipped_as_planned(site):
"""未交付的 SN 追溯必须明确标注"规划中",不得写成已有功能。"""
html = site.get("/site/industry/autoparts/").content.decode("utf-8")
assert "规划中" in html
assert "序列号" in html
# 明确说明尚未交付
assert "尚未交付" in html or "路线图" in html
def test_demo_cta_links_present(site):
"""每页都要有试用入口(转化路径)。"""
for url, _ in PAGES:
html = site.get(url).content.decode("utf-8")
assert "免费试用" in html or "免注册体验" in html, url
def test_site_does_not_shadow_spa(site):
"""官网挂在 /site/ 下,不能抢掉 SPA 的根路径。"""
resp = site.get("/")
assert resp.status_code == 200
# 根路径返回 SPA(FileResponse 流式返回 index.html),不含官网导航
body = b"".join(resp.streaming_content).decode("utf-8", errors="ignore")
assert "site/pricing" not in body