upgrade: adopt V8.31.1 (theme 1.3/1.4 redesigns, editor deep-canvas, guided launch, component library)
Overlay 190 upstream items (V8.22→8.31) preserving trade-pro theme, registry tests, and design docs. Re-applied full patch set on identical anchors (discovery/env_for/blocks.css/type-mapping/locale-override/ theme_color/frontend entries/test_theme_pro_v3 mods) plus compose pins. Verified: theme suites 35/35; dual-baseline full run 415 passed vs pristine 386+29 ours, FAILED-set diff EMPTY (same 10 Windows env fails). Live: container 8.31.1-dev.1 healthy, hesupipe 192 entries intact, trade-pro build 203 pages 0 errors. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""V8.23 nested authoring contract. These checks execute against the real renderer."""
|
||||
from pathlib import Path
|
||||
from bs4 import BeautifulSoup
|
||||
from app import blueprints
|
||||
from tests.test_factory import client,create
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_nested_ids_are_rendered_and_duplicate_ids_rejected():
|
||||
layout=blueprints.new_block('layout')
|
||||
child=blueprints.new_block('image_text',{'title':'Subcomponent editing'})
|
||||
layout['columns'][0]['blocks']=[child]
|
||||
clean=blueprints.validate_blocks([layout]);assert clean[0]['columns'][0]['blocks'][0]['id']==child['id']
|
||||
html=blueprints.render_blocks(clean,{}, {},[])
|
||||
soup=BeautifulSoup(html,'html.parser')
|
||||
assert soup.select_one(f'.sf-layout-grid[data-layout="{layout["id"]}"]')
|
||||
assert soup.select_one(f'.sf-layout-column .sf-section[data-block="{child["id"]}"]')
|
||||
assert 'onload=' not in html
|
||||
layout['columns'][1]['blocks']=[child]
|
||||
import pytest
|
||||
with pytest.raises(ValueError,match='重复'):blueprints.validate_blocks([layout])
|
||||
|
||||
|
||||
def test_nested_view_is_only_in_draft_editor():
|
||||
editor=(ROOT/'app/static/editor.js').read_text(encoding='utf-8')
|
||||
bridge=(ROOT/'app/static/studio-canvas-bridge.js').read_text(encoding='utf-8')
|
||||
helpers=(ROOT/'app/static/editor-helpers.js').read_text(encoding='utf-8')
|
||||
for marker in ('child-select','child-inline-text','child-duplicate','child-delete'):
|
||||
assert marker in bridge and marker in editor
|
||||
assert 'safeNestedCanvasCommand' in helpers
|
||||
assert 'childQuickEditor' in editor and 'setLayoutPreset' in editor
|
||||
assert 'event.source!==frame.contentWindow' in editor
|
||||
assert 'eval(' not in bridge and 'new Function(' not in bridge
|
||||
assert 'studio-canvas-bridge.js' not in (ROOT/'app/builder.py').read_text(encoding='utf-8')
|
||||
|
||||
|
||||
def test_editor_sandbox_keeps_scripts_isolated():
|
||||
soup=BeautifulSoup((ROOT/'app/templates/editor.html').read_text(encoding='utf-8'),'html.parser')
|
||||
assert soup.select_one('#sitePreview')['sandbox']==['allow-scripts']
|
||||
assert soup.select_one('#saveDraftButton')
|
||||
|
||||
|
||||
def test_nested_layout_draft_round_trip(client):
|
||||
sid=create(client)
|
||||
entries=client.get(f'/api/sites/{sid}/entries').json()
|
||||
eid=next(row['id'] for row in entries if row['route']=='/')
|
||||
parent=blueprints.new_block('layout')
|
||||
child=blueprints.new_block('image_text',{'title':'Nested draft stable'})
|
||||
parent['columns'][0]['blocks']=[child]
|
||||
uri=f'/api/sites/{sid}/pages/{eid}/studio-draft'
|
||||
payload={'blocks':[parent],'page_template':'home','layout_mode':'replace','expected_revision':0}
|
||||
put=client.put(uri,json=payload)
|
||||
assert put.status_code==200,put.text
|
||||
result=client.get(uri).json()
|
||||
assert result['blocks'][0]['columns'][0]['blocks'][0]['title']=='Nested draft stable'
|
||||
assert result['revision']==1
|
||||
assert client.put(uri,json=payload).status_code==409
|
||||
Reference in New Issue
Block a user