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

76 lines
2.4 KiB
Python

from __future__ import annotations
import json
import unittest
from decimal import Decimal
from channel_analytics.contracts import (
AggregatedRoomFact,
AnalyticsError,
build_dashboard,
)
class ChannelAnalyticsContractsTests(unittest.TestCase):
def test_dashboard_keeps_manifest_order_empty_channels_and_frozen_totals(self):
payload = build_dashboard(
"2026-07",
"2026-07-28T15:54:00+08:00",
"2026-07-26",
"a" * 64,
("B", "A", "EMPTY"),
(
AggregatedRoomFact("A", "RM2", 2, Decimal("100"), 6, 1),
AggregatedRoomFact("B", "RM3", 3, Decimal("90"), 4, 2),
AggregatedRoomFact("B", "RM2", 1, Decimal("50"), 2, 1),
),
)
self.assertEqual(payload["version"], "1.2")
self.assertEqual(
[channel["worksheet"] for channel in payload["channels"]],
["B", "A", "EMPTY"],
)
self.assertEqual(payload["overall"]["totals"], {
"rooms_sold": 6,
"total_price": 240,
"room_nights": 12,
"reservation_rows": 4,
"room_type_count": 2,
"channel_count": 3,
})
self.assertEqual(payload["channels"][0]["totals"]["total_price"], 140)
self.assertEqual(payload["channels"][2]["room_types"], [])
self.assertEqual(
[room["room_type"] for room in payload["channels"][0]["room_types"]],
["RM3", "RM2"],
)
def test_dashboard_rejects_channels_outside_manifest_and_private_rows_are_absent(self):
with self.assertRaises(AnalyticsError):
build_dashboard(
"2026-07",
"2026-07-28T15:54:00+08:00",
"2026-07-26",
"a" * 64,
("A",),
(AggregatedRoomFact("B", "RM2", 1, Decimal("10"), 1, 1),),
)
serialized = json.dumps(
build_dashboard(
"2026-07",
"2026-07-28T15:54:00+08:00",
"2026-07-26",
"a" * 64,
("A",),
(AggregatedRoomFact("A", "RM2", 1, Decimal("10"), 1, 1),),
),
ensure_ascii=False,
).lower()
for forbidden in ("full_name", "confirmation_no", "disp_room_no", "res_comment"):
self.assertNotIn(forbidden, serialized)
if __name__ == "__main__":
unittest.main()