feat: trade-pro skeleton theme package (Phase 2)

Fifth built-in theme: English-first international B2B skeleton registered
via manifest discovery, builds real sites end-to-end. pro.html derives
from industrial with lang=en, href-set value-comparison English fallback
nav (header + footer), sf-tp-* button classes and hard-coded #0b3d91
theme-color until the map entry lands. pages/ ships all 14 kinds; macro
library is an English passthrough copy pending the Phase 3 cms port.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-22 18:19:30 +08:00
parent 702253f387
commit 5797638caf
25 changed files with 456 additions and 0 deletions
+21
View File
@@ -2,6 +2,7 @@
import json
from pathlib import Path
from app import core, theme_pro, theme_store
from test_factory_v2 import factory, site # noqa: F401 -- fixture + helper reused by trade-pro tests
ROOT = Path(core.__file__).resolve().parent.parent
@@ -92,6 +93,26 @@ def test_env_for_degraded_branch_not_cached_and_single_path(tmp_path, monkeypatc
finally:
core.THEMES = core.discover_themes()
def test_trade_pro_registered_and_compatible():
assert 'trade-pro' in core.THEMES
result = theme_store.compatibility('trade-pro')
assert result['valid'], result['errors']
assert not result['errors']
def test_trade_pro_builds_real_site(factory):
sid = site(factory)
assert factory.post(f'/api/factory/sites/{sid}/bootstrap').status_code == 200
selected = factory.put(f'/api/factory/sites/{sid}/theme', json={'theme': 'trade-pro', 'version': '1.0.0'})
assert selected.status_code == 200, selected.text
result = factory.post(f'/api/sites/{sid}/builds', json={})
assert result.status_code == 200, result.text
bid = result.json()['version']
home = factory.get(f'/preview/{sid}/{bid}/')
assert home.status_code == 200, home.text[:400]
assert 'lang="en"' in home.text
assert '>首页<' not in home.text
assert '<meta name="theme-color" content="#0b3d91"' in home.text
def test_theme_blocks_css_overrides_platform(tmp_path):
from app import builder
dist = tmp_path / 'assets'; dist.mkdir()