from __future__ import annotations import unittest from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] STATIC_ROOT = PROJECT_ROOT / "arr_web" / "static" class ChannelBiVisualStaticContractTests(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.desktop = (STATIC_ROOT / "index.html").read_text(encoding="utf-8") cls.mobile = (STATIC_ROOT / "h5.html").read_text(encoding="utf-8") cls.desktop_script = (STATIC_ROOT / "app.js").read_text(encoding="utf-8") cls.mobile_script = (STATIC_ROOT / "h5.js").read_text(encoding="utf-8") cls.i18n = (STATIC_ROOT / "i18n.js").read_text(encoding="utf-8") cls.desktop_styles = (STATIC_ROOT / "styles.css").read_text(encoding="utf-8") cls.mobile_styles = (STATIC_ROOT / "h5.css").read_text(encoding="utf-8") def test_bi_removes_old_labels_and_places_data_range_under_sales_title(self) -> None: for content in (self.desktop, self.mobile): self.assertNotIn("CHANNEL PERFORMANCE", content) self.assertNotIn("数据库月报快照", content) self.assertNotIn("TOTAL PRICE", content) self.assertNotIn("CHANNEL PERFORMANCE", self.i18n) self.assertNotIn("数据库月报快照", self.i18n) self.assertNotIn("TOTAL PRICE", self.i18n) self.assertNotIn('"bi.updated"', self.i18n) self.assertNotIn("bi-subtitle", self.desktop) self.assertNotIn("h5-updated", self.mobile) self.assertIn('

数据范围:—

', self.desktop) self.assertIn('

数据范围:—

', self.mobile) self.assertIn('"bi.data_range"', self.i18n) def test_bi_surface_keeps_only_a_compact_month_control(self) -> None: desktop_start = self.desktop.index('id="panel-bi"') desktop_end = self.desktop.index('id="panel-usage"', desktop_start) desktop_bi = self.desktop[desktop_start:desktop_end] mobile_start = self.mobile.index('
') mobile_end = self.mobile.index('
渠道BI", desktop_bi) self.assertNotIn("

渠道BI

", mobile_bi) self.assertIn('class="section-heading bi-heading"', desktop_bi) self.assertIn('class="hero bi-hero"', mobile_bi) self.assertIn(".bi-heading .month-picker", self.desktop_styles) self.assertIn(".bi-heading .month-picker select", self.desktop_styles) self.assertIn("min-height: 26px", self.desktop_styles) self.assertIn(".bi-hero select", self.mobile_styles) self.assertIn("#panel-bi { margin-top: -20px; }", self.desktop_styles) self.assertIn("#panel-bi { margin-top: -10px; }", self.desktop_styles) self.assertNotIn("数据库已连接", self.desktop) self.assertNotIn("数据库已连接", self.mobile) self.assertNotIn("数据库已连接", self.desktop_script) self.assertNotIn("数据库已连接", self.mobile_script) self.assertNotIn("数据库已连接", self.i18n) def test_header_utilities_are_low_emphasis_links(self) -> None: self.assertIn(' None: for script, element_id in ( (self.desktop_script, "bi-data-range"), (self.mobile_script, "h5-data-range"), ): self.assertIn("min_arrival_date", script) self.assertIn("max_arrival_date", script) self.assertIn(element_id, script) self.assertIn("bi.data_range", script) self.assertIn(".chart-data-range", self.desktop_styles) self.assertIn(".card-title .data-range", self.mobile_styles) def test_bi_uses_five_second_updated_at_refresh_without_reloading_every_poll(self) -> None: self.assertIn("const BI_POLL_INTERVAL = 5000", self.desktop_script) self.assertIn("const BI_POLL_INTERVAL = 5000", self.mobile_script) self.assertIn('api("/api/months")', self.desktop_script) self.assertIn('api("/api/public/h5/months")', self.mobile_script) self.assertIn("metadata.updated_at !== current.updated_at", self.desktop_script) self.assertIn("metadata.updated_at !== lastData.updated_at", self.mobile_script) self.assertIn("loadAnalytics(false, Boolean(current))", self.desktop_script) self.assertIn("load(false, Boolean(lastData))", self.mobile_script) self.assertIn("function checkBiFreshness", self.desktop_script) self.assertIn("function checkBiFreshness", self.mobile_script) self.assertIn("clearBiPoll()", self.desktop_script) self.assertIn("clearBiPoll()", self.mobile_script) self.assertIn("document.hidden", self.desktop_script) self.assertIn("document.hidden", self.mobile_script) if __name__ == "__main__": unittest.main(verbosity=2)