Initial commit
This commit is contained in:
197
tests/test_reporters.py
Normal file
197
tests/test_reporters.py
Normal file
@@ -0,0 +1,197 @@
|
||||
from pathlib import Path
|
||||
|
||||
from applepy.findings import Finding, Severity
|
||||
from applepy.reporters.markdown import write_markdown_report
|
||||
from applepy.reporters.xlsx import (
|
||||
_evidence_chunks_for_excel,
|
||||
_xlsx_cell_text,
|
||||
write_xlsx_report,
|
||||
)
|
||||
|
||||
|
||||
def test_markdown_and_xlsx(tmp_path: Path) -> None:
|
||||
f = Finding(
|
||||
id="t-1",
|
||||
title="Test finding",
|
||||
category="Test",
|
||||
severity=Severity.INFORMATIONAL,
|
||||
description="Desc",
|
||||
evidence="Ev",
|
||||
worksheet="Test checks",
|
||||
mitre_techniques=("T1082",),
|
||||
)
|
||||
cis = Finding(
|
||||
id="cis-099",
|
||||
title="CIS tab sample",
|
||||
category="Compliance",
|
||||
severity=Severity.INFORMATIONAL,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="CIS",
|
||||
)
|
||||
md = tmp_path / "r.md"
|
||||
xl = tmp_path / "f.xlsx"
|
||||
write_markdown_report(md, [f, cis], ["warn1"])
|
||||
write_xlsx_report(xl, [f, cis])
|
||||
md_text = md.read_text(encoding="utf-8")
|
||||
assert md_text.startswith("# ApplePY")
|
||||
assert "## Contents" in md_text
|
||||
assert "[Executive summary](#executive-summary)" in md_text
|
||||
assert "overarching themes" in md_text.lower()
|
||||
assert "## Other findings" in md_text or "## Core platform and controls" in md_text
|
||||
assert "Detail category:" in md_text
|
||||
assert "Granular categories covered here:" in md_text
|
||||
assert "#### Evidence" in md_text
|
||||
assert "```" in md_text
|
||||
assert "CIS macOS worksheet index" in md_text
|
||||
assert "cis-099" in md_text
|
||||
assert xl.is_file() and xl.stat().st_size > 200
|
||||
from openpyxl import load_workbook
|
||||
|
||||
wb = load_workbook(xl)
|
||||
assert wb.sheetnames[0] == "Summary"
|
||||
assert wb.sheetnames[1] == "Findings list"
|
||||
assert "CIS" in wb.sheetnames
|
||||
assert wb["CIS"]["A2"].value == "cis-099"
|
||||
fl = wb["Findings list"]
|
||||
assert fl["A1"].value == "ID"
|
||||
assert fl["E1"].value == "Detail worksheet"
|
||||
assert fl.max_row == 1
|
||||
# Summary sheet must contain the worksheet index section
|
||||
summary_ws = wb["Summary"]
|
||||
col_a_vals = [summary_ws.cell(row=r, column=1).value for r in range(1, summary_ws.max_row + 1)]
|
||||
assert "Findings list (non-informational)" in col_a_vals
|
||||
assert "CIS" in col_a_vals
|
||||
|
||||
|
||||
def test_xlsx_cell_text_strips_control_chars() -> None:
|
||||
raw = "a\x00b\x08c"
|
||||
assert _xlsx_cell_text(raw) == "a b c"
|
||||
|
||||
|
||||
def test_evidence_chunks_split_for_excel_limit() -> None:
|
||||
long_ev = "X" * 40000
|
||||
chunks = _evidence_chunks_for_excel(long_ev)
|
||||
assert len(chunks) >= 2
|
||||
assert all(len(c) <= 32767 for c in chunks)
|
||||
assert "".join(chunks) == _xlsx_cell_text(long_ev)
|
||||
|
||||
|
||||
def test_xlsx_sorts_by_severity_descending(tmp_path: Path) -> None:
|
||||
from openpyxl import load_workbook
|
||||
|
||||
lo = Finding(
|
||||
id="a-low",
|
||||
title="Later",
|
||||
category="Test",
|
||||
severity=Severity.INFORMATIONAL,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="Zebra",
|
||||
)
|
||||
hi = Finding(
|
||||
id="z-high",
|
||||
title="First",
|
||||
category="Test",
|
||||
severity=Severity.HIGH,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="Zebra",
|
||||
)
|
||||
xl = tmp_path / "sort.xlsx"
|
||||
write_xlsx_report(xl, [lo, hi])
|
||||
wb = load_workbook(xl)
|
||||
assert wb.sheetnames[:2] == ["Summary", "Findings list"]
|
||||
fl = wb["Findings list"]
|
||||
assert fl.max_row == 2
|
||||
assert fl["A2"].value == "z-high"
|
||||
assert fl["C2"].value == "high"
|
||||
ws = wb["Zebra"]
|
||||
assert ws["A2"].value == "z-high"
|
||||
assert ws["A3"].value == "a-low"
|
||||
|
||||
|
||||
def test_xlsx_findings_list_includes_non_informational_only(tmp_path: Path) -> None:
|
||||
from openpyxl import load_workbook
|
||||
|
||||
info = Finding(
|
||||
id="i-1",
|
||||
title="Noise",
|
||||
category="Test",
|
||||
severity=Severity.INFORMATIONAL,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="Alpha",
|
||||
)
|
||||
med = Finding(
|
||||
id="m-1",
|
||||
title="Material",
|
||||
category="Test",
|
||||
severity=Severity.MEDIUM,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="Alpha",
|
||||
)
|
||||
xl = tmp_path / "fl.xlsx"
|
||||
write_xlsx_report(xl, [info, med])
|
||||
wb = load_workbook(xl)
|
||||
fl = wb["Findings list"]
|
||||
assert fl.max_row == 2
|
||||
assert fl["A2"].value == "m-1"
|
||||
assert fl["E2"].value == "Alpha"
|
||||
|
||||
|
||||
def test_xlsx_severity_row_has_distinct_fill(tmp_path: Path) -> None:
|
||||
from openpyxl import load_workbook
|
||||
|
||||
high_f = Finding(
|
||||
id="h-sev",
|
||||
title="High item",
|
||||
category="Test",
|
||||
severity=Severity.HIGH,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="Alpha",
|
||||
)
|
||||
low_f = Finding(
|
||||
id="l-sev",
|
||||
title="Low item",
|
||||
category="Test",
|
||||
severity=Severity.LOW,
|
||||
description="d",
|
||||
evidence="e",
|
||||
worksheet="Alpha",
|
||||
)
|
||||
xl = tmp_path / "sevfill.xlsx"
|
||||
write_xlsx_report(xl, [high_f, low_f])
|
||||
wb = load_workbook(xl)
|
||||
ws = wb["Alpha"]
|
||||
hi_fill = ws["A2"].fill
|
||||
lo_fill = ws["A3"].fill
|
||||
assert hi_fill.fill_type == "solid"
|
||||
assert lo_fill.fill_type == "solid"
|
||||
assert hi_fill.start_color.rgb != lo_fill.start_color.rgb
|
||||
fl = wb["Findings list"]
|
||||
assert fl["A2"].fill.start_color.rgb == hi_fill.start_color.rgb
|
||||
|
||||
|
||||
def test_xlsx_long_evidence_writes_continuation_rows(tmp_path: Path) -> None:
|
||||
from openpyxl import load_workbook
|
||||
|
||||
long_ev = "Y" * 35000
|
||||
f = Finding(
|
||||
id="long-1",
|
||||
title="Long evidence",
|
||||
category="Test",
|
||||
severity=Severity.INFORMATIONAL,
|
||||
description="d",
|
||||
evidence=long_ev,
|
||||
worksheet="Evidence sheet",
|
||||
)
|
||||
xl = tmp_path / "big.xlsx"
|
||||
write_xlsx_report(xl, [f])
|
||||
wb = load_workbook(xl)
|
||||
assert wb.sheetnames[1] == "Findings list"
|
||||
assert wb["Findings list"].max_row == 1
|
||||
ws = wb["Evidence sheet"]
|
||||
assert ws.max_row >= 3
|
||||
Reference in New Issue
Block a user