"""V8.26 global chrome review, version snapshots, and safe restoration.""" import copy import json from tests.test_factory import client, create from app import db, site_design_v87 def config(marker='Global HESU Header'): data=copy.deepcopy(site_design_v87.DEFAULTS) data['header'].update({'announcement': marker, 'show_announcement': True}) data['footer']['title']='HESU Footer' data['nav']=[{'title':'Products','route':'/products/','children':[ {'title':'Vehicles','route':'/vehicles/','children':[]}]}] return data def test_human_review_and_reviewed_publication_are_build_isolated(client): site=create(client);url=f'/api/sites/{site}/site-design' old=db.one('SELECT settings_json FROM sites WHERE id=?',(site,))['settings_json'] assert client.put(url,json={'config':config(), 'expected_revision':0}).status_code==200 proof=client.get(url+'/review');assert proof.status_code==200,proof.text body=proof.json() assert {'header','nav','footer'}.issubset(set(body['changed_sections'])) assert body['published_site_unchanged'] is True assert body['change_count']>=3 assert db.one('SELECT settings_json FROM sites WHERE id=?',(site,))['settings_json']==old wrong=client.post(url+'/publish-reviewed',json={'expected_revision':1,'plan_token':'1'*64}) assert wrong.status_code==409 good=client.post(url+'/publish-reviewed',json={'expected_revision':1,'plan_token':body['plan_token']}) assert good.status_code==200,good.text assert 'Global HESU Header' in db.one('SELECT settings_json FROM sites WHERE id=?',(site,))['settings_json'] assert client.get(url+'/review').status_code==409 def test_old_review_token_invalid_after_draft_edit(client): site=create(client);url=f'/api/sites/{site}/site-design' assert client.put(url,json={'config':config('First'), 'expected_revision':0}).status_code==200 stale=client.get(url+'/review').json() assert client.put(url,json={'config':config('Second'), 'expected_revision':1}).status_code==200 assert client.post(url+'/publish-reviewed',json={ 'expected_revision':2,'plan_token':stale['plan_token']}).status_code==409 fresh=client.get(url+'/review').json() assert fresh['plan_token']!=stale['plan_token'] assert client.post(url+'/publish-reviewed',json={ 'expected_revision':2,'plan_token':fresh['plan_token']}).status_code==200 def test_restore_history_as_new_draft_does_not_mutate_live(client): site=create(client);url=f'/api/sites/{site}/site-design' assert client.put(url,json={'config':config('Release A'),'expected_revision':0}).status_code==200 reviewed=client.get(url+'/review').json() pub=client.post(url+'/publish-reviewed',json={'expected_revision':1,'plan_token':reviewed['plan_token']}).json() pid=pub['publication_id'] old_live=db.one('SELECT settings_json FROM sites WHERE id=?',(site,))['settings_json'] history=client.get(url+f'/publications/{pid}');assert history.status_code==200 assert history.json()['after']['header']['announcement']=='Release A' assert any(x['field']=='header.announcement' for x in history.json()['changes']) live_hash=client.get(url+'/live-hash').json()['live_hash'] recovered=client.post(url+f'/publications/{pid}/restore',json={ 'snapshot':'before','expected_revision':0,'expected_live_hash':live_hash}) assert recovered.status_code==200,recovered.text assert recovered.json()['published_unchanged'] assert client.get(url).json()['revision']==1 assert db.one('SELECT settings_json FROM sites WHERE id=?',(site,))['settings_json']==old_live assert client.post(url+f'/publications/{pid}/restore',json={ 'snapshot':'before','expected_revision':0,'expected_live_hash':live_hash}).status_code==409 def test_restore_rejects_stale_live_site_and_foreign_history(client): a=create(client);b=create(client) ua=f'/api/sites/{a}/site-design';ub=f'/api/sites/{b}/site-design' assert client.put(ua,json={'config':config(), 'expected_revision':0}).status_code==200 preview=client.get(ua+'/review').json() pid=client.post(ua+'/publish-reviewed',json={ 'expected_revision':1,'plan_token':preview['plan_token']}).json()['publication_id'] old_hash=client.get(ua+'/live-hash').json()['live_hash'] assert client.get(ub+f'/publications/{pid}').status_code==404 assert client.post(ub+f'/publications/{pid}/restore',json={ 'snapshot':'after','expected_revision':0,'expected_live_hash':old_hash}).status_code==404 current=db.one('SELECT settings_json FROM sites WHERE id=?',(a,)) changed=json.loads(current['settings_json']);changed['external_setting']='changed' db.execute('UPDATE sites SET settings_json=? WHERE id=?',(json.dumps(changed),a)) assert client.post(ua+f'/publications/{pid}/restore',json={ 'snapshot':'after','expected_revision':0,'expected_live_hash':old_hash}).status_code==409 assert client.post(ua+f'/publications/{pid}/restore',json={ 'snapshot':'bad','expected_revision':0,'expected_live_hash':'a'*64}).status_code==400 def test_nav_editor_is_visual_and_review_ui_is_wired(client): sid=create(client) entry=next(x for x in client.get(f'/api/sites/{sid}/entries').json() if x['route']=='/') page=client.get(f'/editor/{sid}/{entry["id"]}').text assert 'siteNavRows' in page and '+ 添加一级菜单' in page assert 'siteDesignReviewModal' in page and 'siteDesignHistoryModal' in page code=client.get('/ui/editor.js').text assert 'drawSiteNav()' in code and 'publish-reviewed' in code assert 'showSiteDesignHistory' in code def test_invalid_navigation_remains_rejected(client): sid=create(client);url=f'/api/sites/{sid}/site-design' bad=config();bad['nav'][0]['children'][0]['route']='javascript:alert(1)' assert client.put(url,json={'config':bad,'expected_revision':0}).status_code==400 assert client.get(url).json()['revision']==0