54 lines
4.1 KiB
Python
54 lines
4.1 KiB
Python
import importlib.util
|
||
import io
|
||
import unittest
|
||
import zipfile
|
||
from pathlib import Path
|
||
from xml.sax.saxutils import escape
|
||
|
||
spec = importlib.util.spec_from_file_location("template_audit", Path(__file__).with_name("client-import-template-inspect.py"))
|
||
audit = importlib.util.module_from_spec(spec)
|
||
spec.loader.exec_module(audit)
|
||
|
||
|
||
def fixture(options=("测试仓|WH-A", "测试仓|WH-B"), rows="A3:A52", target="option_0", hidden=True):
|
||
ns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||
rel = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||
body = io.BytesIO()
|
||
with zipfile.ZipFile(body, "w") as z:
|
||
z.writestr("[Content_Types].xml", '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/></Types>')
|
||
z.writestr("_rels/.rels", f'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="{rel}/officeDocument" Target="xl/workbook.xml"/></Relationships>')
|
||
z.writestr("xl/workbook.xml", f'<workbook xmlns="{ns}" xmlns:r="{rel}"><sheets><sheet name="订单导入" sheetId="1" r:id="rId1"/><sheet name="选项数据" sheetId="2" state="{"hidden" if hidden else "visible"}" r:id="rId2"/><sheet name="填写说明" sheetId="3" r:id="rId3"/></sheets><definedNames><definedName name="option_0">选项数据!$A$1:$A${len(options)}</definedName></definedNames></workbook>')
|
||
z.writestr("xl/_rels/workbook.xml.rels", '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' + ''.join(f'<Relationship Id="rId{i}" Type="{rel}/worksheet" Target="worksheets/sheet{i}.xml"/>' for i in (1, 2, 3)) + '</Relationships>')
|
||
z.writestr("xl/worksheets/sheet1.xml", f'<worksheet xmlns="{ns}"><sheetData><row r="2"><c r="A2" t="inlineStr"><is><t>国内收货仓 *</t></is></c></row></sheetData><dataValidations count="1"><dataValidation type="list" showErrorMessage="1" sqref="{rows}"><formula1>{target}</formula1></dataValidation></dataValidations></worksheet>')
|
||
data = ''.join(f'<row r="{i}"><c r="A{i}" t="inlineStr"><is><t>{escape(value)}</t></is></c></row>' for i, value in enumerate(options, 1))
|
||
z.writestr("xl/worksheets/sheet2.xml", f'<worksheet xmlns="{ns}"><sheetData>{data}</sheetData></worksheet>')
|
||
z.writestr("xl/worksheets/sheet3.xml", f'<worksheet xmlns="{ns}"><sheetData/></worksheet>')
|
||
return body.getvalue()
|
||
|
||
|
||
class TemplateAuditTest(unittest.TestCase):
|
||
def test_reads_actual_xlsx_names_validation_and_all_options(self):
|
||
result = audit.inspect_template(fixture(), {"国内收货仓": ["测试仓|WH-A", "测试仓|WH-B"]})
|
||
self.assertTrue(result["passed"])
|
||
self.assertEqual(result["checks"]["国内收货仓"]["actualCount"], 2)
|
||
|
||
def test_missing_extra_and_duplicate_options_are_reported_without_values(self):
|
||
result = audit.inspect_template(fixture(), {"国内收货仓": ["测试仓|WH-A", "其他仓|WH-C"]})
|
||
self.assertFalse(result["passed"])
|
||
self.assertEqual(result["checks"]["国内收货仓"]["missingCount"], 1)
|
||
self.assertEqual(result["checks"]["国内收货仓"]["extraCount"], 1)
|
||
self.assertNotIn("WH-A", str(result))
|
||
self.assertFalse(audit.compare_options(["A", "A"], ["A"])["passed"])
|
||
|
||
def test_refuses_short_ranges_unresolved_names_and_exposed_options(self):
|
||
for options in ({"rows": "A3:A51"}, {"target": "missing"}, {"hidden": False}):
|
||
with self.assertRaises(AssertionError):
|
||
audit.inspect_template(fixture(**options), {"国内收货仓": ["测试仓|WH-A", "测试仓|WH-B"]})
|
||
|
||
def test_duplicate_business_labels_remain_distinct_choices(self):
|
||
self.assertEqual(audit.labels(["A", "A", "A"], lambda x: x), ["A", "A(同名选项 2)", "A(同名选项 3)"])
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|