SFM/tests/unit/test_report.py
2026-07-30 12:37:18 +03:00

87 lines
2.7 KiB
Python

from __future__ import annotations
from pathlib import Path
from openpyxl import load_workbook
from app.pipeline.mapping import FIXED_REPORT_COLUMNS
from app.pipeline.report import TOP_GROUP_HEADERS, ReportRow, write_report
def test_write_report_streaming_preserves_header_and_formats(tmp_path: Path) -> None:
destination = tmp_path / "report.xlsx"
rows = [
ReportRow(
file_name="SKO115FZ_01_123456789_20260616_X00001.xml",
record_id="RID-1",
operation_index=1,
operation_fields={"СуммаОпер": "100.50", "ДатаОпер": "2026-06-16"},
participant_fields={},
)
]
write_report(rows, destination)
workbook = load_workbook(destination)
sheet = workbook["Отчет"]
headers = [cell.value for cell in sheet[2]]
assert headers == list(FIXED_REPORT_COLUMNS)
assert sheet.freeze_panes == "A3"
row_values = [
sheet.cell(row=3, column=index).value
for index in range(1, len(FIXED_REPORT_COLUMNS) + 1)
]
assert "SKO115FZ_01_123456789_20260616_X00001.xml" in row_values
date_col_idx = next(
(
index
for index, column in enumerate(FIXED_REPORT_COLUMNS, start=1)
if "Дата" in column
),
None,
)
if date_col_idx is not None:
assert sheet.cell(row=3, column=date_col_idx).number_format == "DD.MM.YYYY"
sum_col_idx = next(
(
index
for index, column in enumerate(FIXED_REPORT_COLUMNS, start=1)
if "Сумм" in column or "Сумма" in column
),
None,
)
if sum_col_idx is not None:
assert sheet.cell(row=3, column=sum_col_idx).number_format == "#,##0.00"
def test_write_report_contains_top_group_header_row(tmp_path: Path) -> None:
destination = tmp_path / "report.xlsx"
write_report([], destination)
workbook = load_workbook(destination)
sheet = workbook["Отчет"]
assert sheet.cell(row=1, column=1).value == "Служебные поля"
merged_ranges = {str(rng) for rng in sheet.merged_cells.ranges}
expected_ranges = set()
for header in TOP_GROUP_HEADERS:
if header.start_col > len(FIXED_REPORT_COLUMNS):
continue
end_col = min(header.end_col, len(FIXED_REPORT_COLUMNS))
if header.start_col == end_col:
continue
expected_ranges.add(
f"{_column_letter(header.start_col)}1:{_column_letter(end_col)}1"
)
assert merged_ranges == expected_ranges
def _column_letter(index: int) -> str:
value = index
result = ""
while value:
value, remainder = divmod(value - 1, 26)
result = chr(65 + remainder) + result
return result