72 lines
3.5 KiB
Python
72 lines
3.5 KiB
Python
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from viano_bug_analysis.package import PackageReader
|
|
|
|
spec=importlib.util.spec_from_file_location('case_review',Path(__file__).parents[1]/'scripts'/'render_case_review.py')
|
|
review=importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(review)
|
|
|
|
|
|
def test_local_review_escapes_untrusted_text_and_preserves_all_files(make_package,manifest,tmp_path):
|
|
manifest['artifacts']['case']='case/case.json'
|
|
data={'bug':{'reports':[{'title':'<script>alert(1)</script>',
|
|
'summary':'Tester observation, not a diagnosis.'}]}}
|
|
package=make_package(document=manifest,entries={'case/case.json':json.dumps(data),
|
|
'unknown/preserve.txt':'untouched'})
|
|
original=package.read_bytes()
|
|
output=review.create(package,tmp_path/'view')
|
|
html=output.read_text(encoding='utf8')
|
|
assert '<script>alert(1)</script>' not in html
|
|
assert '<script>alert(1)</script>' in html
|
|
assert 'Tester observation, not a diagnosis.' in html
|
|
assert 'noch nicht vor' in html # Do not imply completion.
|
|
assert package.read_bytes()==original
|
|
with PackageReader(package) as reader:
|
|
for name in reader.files:assert (output.parent/name).read_bytes()==reader.read_bytes(name)
|
|
with pytest.raises(ValueError,match='never overwritten'):
|
|
review.create(package,output.parent)
|
|
|
|
|
|
def test_counterevidence_links_and_code_are_readable_without_executing_markup():
|
|
b={'findings':[{'id':'B0001','direction':'against','text':'Hook exists.',
|
|
'scope':'Pinned source only.','evidence_refs':['E000001']}]}
|
|
html=review.findings(b)
|
|
assert 'Dagegen' in html and 'href="#E000001"' in html
|
|
content={'scope':'source','coverage':'selected_lines','items':[
|
|
{'query':{'kind':'source.read'},'result':{'items':[{'line':5,'text':'<img src=x onerror=alert(1)>'}]}}]}
|
|
rendered=review.evidence_body(content)
|
|
assert '<img' in rendered and '<img' not in rendered
|
|
assert '5 <img' in rendered
|
|
|
|
|
|
def test_empty_query_is_explicitly_scoped_not_general_absence():
|
|
html=review.evidence_body({'scope':'entry 5','coverage':'complete_filtered_rows',
|
|
'items':[{'query':{'entry':5},'result':{'items':[]}}]})
|
|
assert 'entry 5' in html and 'Keine Treffer für diese Abfrage.' in html
|
|
|
|
|
|
def test_reserved_filename_never_overwrites_package_payload(make_package,tmp_path):
|
|
p=make_package(entries={'LESEANSICHT.html':'original'})
|
|
dest=tmp_path/'review'
|
|
with pytest.raises(ValueError,match='reserved'):
|
|
review.create(p,dest)
|
|
assert not dest.exists()
|
|
|
|
|
|
def test_completed_package_displays_coding_and_human_handoffs(make_package,manifest,tmp_path):
|
|
manifest['artifacts'].update(change_request='handoffs/coding.json',human_dev_request='handoffs/human.md')
|
|
p=make_package(document=manifest,entries={
|
|
'handoffs/coding.json':json.dumps({'assignment':'assigned','request':{
|
|
'required_change':'SQL template with placeholders','placeholders':[{'token':'{{POSITION_X}}'}]}}),
|
|
'handoffs/human.md':'# Human\n\nResearch or define suitable coordinates.\n<script>bad()</script>'})
|
|
output=review.create(p,tmp_path/'view')
|
|
html=output.read_text(encoding='utf8')
|
|
assert 'href="#handoffs"' in html
|
|
assert 'SQL template with placeholders' in html and '{{POSITION_X}}' in html
|
|
assert 'Research or define suitable coordinates.' in html
|
|
assert '<script>bad()' not in html and '<script>' in html
|