Files
cms-SiteForge/tests/test_mobile_tabs_v8213.py
T
浅念 601451f22b upgrade: adopt V8.21.3 (V8.13→8.21.3: P5 SFTP/S3, P6 multilingual, editor overhaul, enterprise hardening)
Overlay ~150 upstream items onto our V8.12 base, preserving trade-pro
theme, registry tests, and design docs. Re-applied our patch set
(discovery/env_for/blocks.css/type-mapping/theme_color/frontend entries,
test_theme_pro_v3 mods) — all anchors survived upstream evolution.

New platform enhancement (fixes upgrade-introduced regression):
multilingual.site_locale now honors settings_json.locale, plus
PUT /api/i18n/sites/{id}/locale — standalone English sites get
<html lang='en'> under the V8.15 locale-rewrite pipeline.

compose: adopt V8.21.3 (image 8.21.3-dev.1, /api/ready probes, MySQL/S3
env) with project name pinned to siteforge-v8-10 (data volumes).

Tests: 356 passed / 11 failed — all 11 confirmed pre-existing in
pristine V8.21.3 on this host (10 upstream Windows env + our build test
now green after locale fix). Patch registry updated in plan doc.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-23 12:31:03 +08:00

84 lines
4.0 KiB
Python

"""V8.21.3 mobile navigation must be optional, safe and theme-independent."""
import copy
import pytest
from tests.test_factory import client, create
from app import site_design_v87, builder, db
def config(tabs=True):
x=copy.deepcopy(site_design_v87.DEFAULTS)
x['mobile_tabs']={'enabled':tabs,'items':[
{'title':'首页','icon':'home','route':'/','action':'link'},
{'title':'产品','icon':'products','route':'/products/','action':'link'},
{'title':'菜单','icon':'menu','route':'/','action':'menu'},
]}
return x
@pytest.mark.parametrize('theme',['automotive','industrial','corporate','minimal'])
def test_all_four_professional_themes_render_optional_bar(client,theme):
sid=create(client,theme)
url=f'/api/sites/{sid}/site-design'
before=builder.build(sid,False)
previous=(db.DATA/'builds'/sid/before['version']/'dist/index.html').read_text()
assert 'data-mobile-tabs' not in previous
payload=config()
stored=client.put(url,json={'config':payload,'expected_revision':0})
assert stored.status_code==200,stored.text
waiting=builder.build(sid,False)
assert 'data-mobile-tabs' not in (db.DATA/'builds'/sid/waiting['version']/'dist/index.html').read_text()
published=client.post(url+'/publish',json={'expected_revision':1})
assert published.status_code==200,published.text
after=builder.build(sid,False)
dist=db.DATA/'builds'/sid/after['version']/'dist'
html=(dist/'index.html').read_text()
css=(dist/'assets/commercial.css').read_text()
js=(dist/'assets/pro.js').read_text()
assert 'data-mobile-tabs' in html and 'data-mobile-open-menu' in html
assert 'aria-current="page"' in html
assert '手机底部快捷导航' in html
assert 'sf-drawer-header' in css and 'sf-drawer-open' in css
assert 'sf-mobile-drawer-backdrop' in js and 'Escape' in js
assert len(html)>2000
def test_tabs_can_be_disabled_while_items_remain(client):
sid=create(client)
url=f'/api/sites/{sid}/site-design'
payload=config(False)
assert client.put(url,json={'config':payload,'expected_revision':0}).status_code==200
assert client.post(url+'/publish',json={'expected_revision':1}).status_code==200
dist=db.DATA/'builds'/sid/builder.build(sid,False)['version']/'dist'
assert 'data-mobile-tabs' not in (dist/'index.html').read_text()
@pytest.mark.parametrize('bad',[{'enabled':True,'items':[]},
{'enabled':'yes','items':[]},
{'enabled':True,'items':[{'title':'Hello','icon':'script','route':'/'}]},
{'enabled':True,'items':[{'title':'测试','icon':'home','route':'javascript:alert(1)'}]},
{'enabled':True,'items':[{'title':'测试','icon':'home','route':'//127.0.0.1'}]},
{'enabled':True,'items':[{'title':'X'*20,'icon':'home','route':'/'}]},
{'enabled':True,'items':[{'title':'1','icon':'home','route':'/'}]*6},
{'enabled':True,'items':[{'title':'ok','icon':'home','action':'eval','route':'/'}]}])
def test_invalid_mobile_tabs_rejected(bad):
payload=config()
payload['mobile_tabs']=bad
with pytest.raises(Exception):site_design_v87.validate(payload)
def test_tab_config_is_normalized_and_legacy_defaults_are_safe():
legacy={'header':{},'responsive':{},'tokens':{},'footer':{},'nav':[]}
assert site_design_v87.validate(legacy)['mobile_tabs']=={'enabled':False,'items':[]}
planned=config()
out=site_design_v87.validate(planned)
assert out['mobile_tabs']['items'][-1]['action']=='menu'
assert out['mobile_tabs']['items'][-1]['route']=='/'
def test_contact_links_are_configurable_but_unsafe_schemes_are_blocked():
for url in ('https://wa.me/12345678','tel:+8613800000000','mailto:hello@example.com'):
v=config();v['mobile_tabs']['items'][1]['route']=url
assert site_design_v87.validate(v)['mobile_tabs']['items'][1]['route']==url
for url in ('http://example.com','javascript:alert(1)','data:text/html,hi','https://user:pass@example.com/','https://bad.example/\nnewline'):
v=config();v['mobile_tabs']['items'][1]['route']=url
with pytest.raises(Exception):site_design_v87.validate(v)