98 lines
4.5 KiB
Python
98 lines
4.5 KiB
Python
import json
|
|
import struct
|
|
import subprocess
|
|
import zipfile
|
|
|
|
import pytest
|
|
|
|
from test_est_native_export import ROOT, fixture
|
|
|
|
|
|
def inspect(path):
|
|
script = """const fs=require('fs'),m=require('./tools/est-test/inspect-accom.cjs');
|
|
try { process.stdout.write(JSON.stringify(m.inspectAccom(fs.readFileSync(process.argv[1])))); }
|
|
catch(e) { process.stdout.write(JSON.stringify({error:e.message})); }"""
|
|
return json.loads(subprocess.check_output(["node", "-e", script, str(path)], cwd=ROOT))
|
|
|
|
|
|
def test_accom_reads_synthetic_table_and_rejects_missing_or_bad_signature(tmp_path):
|
|
base = tmp_path / "base.estx"
|
|
fixture(base)
|
|
with zipfile.ZipFile(base) as archive:
|
|
data = bytearray(archive.read("EstMainDat.dat"))
|
|
# Fixture GU is a double field; rename it to the observed Accom quantity field.
|
|
offset = 512 + 768 * 4
|
|
data[offset + 2] = len("TotalGN")
|
|
data[offset + 3 : offset + 3 + len("TotalGN")] = b"TotalGN"
|
|
path = tmp_path / "accom.estx"
|
|
with zipfile.ZipFile(path, "w") as archive:
|
|
archive.writestr("AccomMainTable.Dat", data)
|
|
result = inspect(path)
|
|
assert result["rows"][0]["Code"] == "A"
|
|
assert result["rows"][0]["TotalGN"] == 100
|
|
assert "TotalGN" in result["fields"]
|
|
script = """const fs=require('fs'),{server}=require('./tools/est-test/server.cjs');
|
|
server.listen(0,'127.0.0.1',async()=>{try{
|
|
const r=await fetch(`http://127.0.0.1:${server.address().port}/api/inspect-accom`,
|
|
{method:'POST',body:fs.readFileSync(process.argv[1])});
|
|
const p=await r.json();process.stdout.write(JSON.stringify({status:r.status,rows:p.rows}));
|
|
}finally{server.close()}});"""
|
|
api = json.loads(subprocess.check_output(["node", "-e", script, str(path)], cwd=ROOT))
|
|
assert api["status"] == 200
|
|
assert api["rows"][0]["TotalGN"] == 100
|
|
assert "없습니다" in inspect(base)["error"]
|
|
data[24] ^= 1
|
|
with zipfile.ZipFile(path, "w") as archive:
|
|
archive.writestr("AccomMainTable.Dat", data)
|
|
assert "서명" in inspect(path)["error"]
|
|
|
|
|
|
def test_accom_view_reads_file_without_changing_project(tmp_path):
|
|
playwright = pytest.importorskip("playwright.sync_api")
|
|
base = tmp_path / "base.estx"
|
|
fixture(base)
|
|
with zipfile.ZipFile(base) as archive:
|
|
data = bytearray(archive.read("EstMainDat.dat"))
|
|
offset = 512 + 768 * 4
|
|
data[offset + 2] = len("TotalGN")
|
|
data[offset + 3 : offset + 3 + len("TotalGN")] = b"TotalGN"
|
|
stride = struct.unpack_from("<H", data, 45)[0]
|
|
data.extend(data[-stride:] * 200)
|
|
struct.pack_into("<I", data, 41, 201)
|
|
path = tmp_path / "accom.estx"
|
|
with zipfile.ZipFile(path, "w") as archive:
|
|
archive.writestr("AccomMainTable.Dat", data)
|
|
with playwright.sync_playwright() as p:
|
|
browser = p.chromium.launch(channel="msedge", headless=True)
|
|
page = browser.new_page()
|
|
try:
|
|
page.goto("http://100.65.141.15:5175", timeout=5000)
|
|
except Exception:
|
|
browser.close()
|
|
pytest.skip("EST test server unavailable")
|
|
page.wait_for_function("() => Boolean(EstApp.state.project)")
|
|
page.evaluate("EstApp.state.view='progress'; EstApp.render()")
|
|
before = page.evaluate("JSON.stringify(EstApp.state.project)")
|
|
page.locator("[data-accom-inspect]").set_input_files(str(path))
|
|
page.locator("#dialog-content").get_by_text("TotalGN").wait_for(timeout=5000)
|
|
assert page.locator("#dialog-content").get_by_text("100", exact=True).count() == 200
|
|
page.locator('[data-accom-page="1"]').click()
|
|
assert page.locator("#dialog-content").get_by_text("100", exact=True).count() == 1
|
|
assert page.evaluate("JSON.stringify(EstApp.state.project)") == before
|
|
page.evaluate("""() => {
|
|
document.getElementById('dialog').close();
|
|
const original=window.fetch;
|
|
window.fetch=(url,options)=>url==='/api/inspect-accom'
|
|
? new Promise(resolve=>window.releaseAccom=()=>resolve(original(url,options)))
|
|
: original(url,options);
|
|
}""")
|
|
page.locator("[data-accom-inspect]").set_input_files(str(path))
|
|
page.wait_for_function("() => typeof window.releaseAccom === 'function'")
|
|
page.evaluate("EstApp.showDialog('편집 중', '<input id=keep-value value=보존>')")
|
|
with page.expect_event("dialog") as dialog_event:
|
|
page.evaluate("window.releaseAccom()")
|
|
dialog_event.value.accept()
|
|
assert page.locator("#dialog-title").inner_text() == "편집 중"
|
|
assert page.locator("#keep-value").input_value() == "보존"
|
|
browser.close()
|