Files

89 lines
3.3 KiB
Python

import io
import json
import subprocess
import zipfile
from pathlib import Path
import xml.etree.ElementTree as ET
from test_est_rea_parity import run
ROOT = Path(__file__).resolve().parents[2]
def export_workbook(project):
result = subprocess.run(
[
"node",
"-e",
"const fs=require('fs');process.stdout.write(require('./tools/est-test/exchange.cjs').workbook(JSON.parse(fs.readFileSync(0,'utf8'))))",
],
input=json.dumps(project, ensure_ascii=False).encode("utf-8"),
capture_output=True,
cwd=ROOT,
check=True,
)
return result.stdout
def test_excel_is_valid_office_zip_with_numeric_text_types_and_no_executable_formulas():
data = export_workbook(
{
"name": "한글 공사",
"tables": {
"EstMainDat": [
{
"PkID": 1,
"Code": "001",
"Name": '=HYPERLINK("bad")',
"GN": 1.23456789,
"TC": 99,
"NewItem": False,
"Editor": {"binary": "AAAA"},
}
],
"CadMainDat": [{"Code": "excluded"}],
},
}
)
with zipfile.ZipFile(io.BytesIO(data)) as archive:
assert archive.testzip() is None
workbook = archive.read("xl/workbook.xml").decode("utf-8")
assert "EstMainDat" in workbook and "CadMainDat" not in workbook
root = ET.fromstring(archive.read("xl/worksheets/sheet2.xml"))
ns = {"s": "http://schemas.openxmlformats.org/spreadsheetml/2006/main"}
rows = root.findall(".//s:row", ns)
assert "Editor" not in ET.tostring(rows[0], encoding="unicode")
assert rows[1].find("s:c[@r='B2']", ns).get("t") == "inlineStr"
assert rows[1].find("s:c[@r='D2']/s:v", ns).text == "1.23456789"
assert root.findall(".//s:f", ns) == []
assert "=HYPERLINK" in ET.tostring(root, encoding="unicode")
def test_print_settings_validation_blocks_css_injection_and_bad_pagination():
result = run(
"math",
"""(()=>{
return [{paper:'A4;display:none'}, {rowsPerPage:0}, {rowsPerPage:1.5}, {font:100}, {margin:-1}, {orientation:'portrait',paper:'A4',rowsPerPage:20,font:9}].map(s=>{
const p=EstNative.empty();p.printSettings=s;
try{EstModel.validate(p);return true}catch{return false}
});
})()""",
)
assert result == [False, False, False, False, False, True]
def test_excel_price_edits_refresh_linked_values_and_keep_binary_fields():
result = run(
"math",
"""(()=>{
const p=EstNative.empty();p.tables.StuffcDat=[{PkID:1,Code:'M',Name:'material',InputTC:100,ValueIndex:4,Editor:{binary:'AAAA'}}];
p.tables.EstMainDat=[{Code:'M',LinkIndex:5,GN:2},{LinkIndex:54}];
const q=EstNative.calculate(p),updated=EstExchange.apply(q,{StuffcDat:[{PkID:1,Code:'M',Name:'material',TC:150,InputTC:100,ValueIndex:4}]});
let rejected=false;try{EstExchange.apply(q,{StuffcDat:[{PkID:1,Code:'',TC:150}]})}catch{rejected=true}
return {next:EstNative.calculate(updated),rejected};
})()""",
)
assert result["rejected"]
assert result["next"]["tables"]["EstMainDat"][-1]["TC"] == 300
assert result["next"]["tables"]["StuffcDat"][0]["Editor"]["binary"] == "AAAA"