Files
wyndham-ARR/tests/test_company_reports_acceptance.py
2026-07-29 16:38:05 +08:00

141 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import os
import shutil
import tempfile
import unittest
from pathlib import Path
from company_reports.contracts import COMPANY_NAMES, REPORT_HEADERS, WarningCode
from company_reports.core import build_all_company_reports
from company_reports.publishing import ArtifactToolBuilder
from tests.company_reports_acceptance_fixture import (
AS_OF_DATE,
REPORT_MONTH,
REPORT_YEAR,
acceptance_snapshot,
)
PROJECT_ROOT = Path(__file__).resolve().parents[1]
BUILDER_SCRIPT = PROJECT_ROOT / "company_reports" / "xlsx" / "build_workbook.mjs"
ARTIFACT_PACKAGE = (
PROJECT_ROOT
/ "company_reports"
/ "xlsx"
/ "node_modules"
/ "@oai"
/ "artifact-tool"
)
def acceptance_reports():
return build_all_company_reports(
REPORT_YEAR,
REPORT_MONTH,
AS_OF_DATE,
acceptance_snapshot(),
)
def artifact_tool_available() -> bool:
configured = os.environ.get("COMPANY_REPORT_ARTIFACT_TOOL_MODULE", "").strip()
return ARTIFACT_PACKAGE.exists() or bool(configured and Path(configured).is_file())
def node_binary() -> str:
configured = os.environ.get("COMPANY_REPORT_NODE_BINARY", "").strip()
return configured or shutil.which("node") or ""
class CompanyReportAcceptanceCoreTests(unittest.TestCase):
def test_all_five_companies_have_contract_complete_month_end_reports(self):
reports = acceptance_reports()
self.assertEqual(tuple(report.company for report in reports), COMPANY_NAMES)
self.assertTrue(all(report.valid for report in reports))
self.assertTrue(all(len(report.periods) == 3 for report in reports))
self.assertTrue(all(all(period.active for period in report.periods) for report in reports))
self.assertTrue(
all(report.to_workbook_payload()["headers"] == list(REPORT_HEADERS) for report in reports)
)
self.assertEqual(
{report.company: [len(period.rows) for period in report.periods] for report in reports},
{
"LianTai": [1, 0, 0],
"QBD": [1, 1, 0],
"DY-AI-Easy-KB": [0, 1, 0],
"FengRun": [0, 0, 1],
"HanaTour": [0, 0, 1],
},
)
self.assertEqual(
{report.filename for report in reports},
{f"{company}-July-2026.xlsx" for company in COMPANY_NAMES},
)
def test_acceptance_rows_exercise_aggregation_duplicate_and_review_rules(self):
reports = {report.company: report for report in acceptance_reports()}
lian_tai = reports["LianTai"].periods[0].rows[0]
self.assertEqual(
lian_tai.booking_room,
"【SYN-SUP-TWN-BF】2【SYN-SUP-TRP-BF】1",
)
self.assertEqual(
lian_tai.total_booking_price,
"【SYN-RM2】900×2 + 【SYN-RM3】3,400×1 = 5,200",
)
qbd_report = reports["QBD"]
qbd_rows = [row for period in qbd_report.periods for row in period.rows]
self.assertEqual(len(qbd_rows), 2)
self.assertTrue(all(row.duplicate_group for row in qbd_rows))
self.assertTrue(qbd_rows[0].multi_price_review)
self.assertFalse(qbd_rows[1].multi_price_review)
self.assertEqual(
qbd_rows[0].total_booking_price,
"【SYN-RM2】900×1 + 【SYN-RM2】1,800×1 = 2,700",
)
self.assertEqual(
[warning.code for warning in qbd_report.warnings],
[WarningCode.MULTI_PRICE_REVIEW],
)
dy_row = reports["DY-AI-Easy-KB"].periods[1].rows[0]
self.assertEqual(dy_row.res_comment, "SYN-DY-0720")
self.assertEqual(dy_row.departure.day, 20)
@unittest.skipUnless(artifact_tool_available(), "artifact-tool dependency is not installed")
class CompanyReportAcceptanceWorkbookTests(unittest.TestCase):
def test_real_builder_exports_reopens_and_renders_all_five_workbooks(self):
node = node_binary()
if not node:
self.skipTest("Node.js is unavailable")
builder = ArtifactToolBuilder(
BUILDER_SCRIPT,
node_binary=node,
timeout_seconds=180,
)
with tempfile.TemporaryDirectory(prefix="company-report-acceptance-") as temp_dir:
root = Path(temp_dir)
for report in acceptance_reports():
with self.subTest(company=report.company):
built = builder.build(report, root / report.company)
self.assertTrue(built.path.is_file())
self.assertEqual(built.path.name, report.filename)
self.assertEqual(built.summary["formula_count"], 0)
self.assertEqual(built.summary["preview_count"], 3)
self.assertEqual(
built.summary["row_counts"],
[len(period.rows) for period in report.periods],
)
self.assertEqual(
len(list((root / report.company / "previews").glob("sheet-*.png"))),
3,
)
if __name__ == "__main__":
unittest.main()