"""Контракт третьей темы organic для зоотехника.""" from __future__ import annotations import unittest from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parent.parent ZOOTECH_PAGES = ( "static/recipes.html", "static/lab.html", "static/lab-profiles.html", "static/components.html", "static/consumption.html", "static/reports.html", "static/feed_dispensers.html", "static/login.html", "static/role_selection.html", ) SETTINGS_PAGES = ( "static/recipes.html", "static/components.html", "static/consumption.html", "static/reports.html", "static/feed_dispensers.html", ) class ZootechThemeTests(unittest.TestCase): def _read(self, rel: str) -> str: return (PROJECT_ROOT / rel).read_text(encoding="utf-8") def test_theme_js_supports_organic(self) -> None: js = self._read("static/js/wesp-theme.js") self.assertIn('"organic"', js) self.assertIn("initThemePicker", js) self.assertIn("wespThemePicker", js) def test_theme_boot_supports_organic(self) -> None: boot = self._read("static/js/wesp-theme-boot.js") self.assertIn('"organic"', boot) def test_organic_css_tokens(self) -> None: layout = self._read("static/css/wesp-zootech-layout.css") self.assertIn('html[data-theme="organic"]', layout) self.assertIn("#48816d", layout.lower()) self.assertIn("#f6f6f4", layout.lower()) def test_organic_theme_stylesheet_exists(self) -> None: organic = self._read("static/css/wesp-zootech-theme-organic.css") self.assertIn(".theme-picker", organic) self.assertIn('html[data-theme="organic"]', organic) def test_all_zootech_pages_include_organic_css(self) -> None: for page in ZOOTECH_PAGES: with self.subTest(page=page): html = self._read(page) self.assertIn("wesp-zootech-theme-organic.css", html) def test_settings_pages_use_theme_picker(self) -> None: for page in SETTINGS_PAGES: with self.subTest(page=page): html = self._read(page) self.assertIn('id="wespThemePicker"', html) self.assertIn('id="wespHighContrastToggle"', html) self.assertIn("settings-contrast-row", html) self.assertNotIn('id="darkThemeToggle"', html) def test_login_organic_tokens(self) -> None: css = self._read("static/css/zootechnician-login.css") self.assertIn('html[data-theme="organic"]', css) def test_organic_logo_and_icon_tinting(self) -> None: organic = self._read("static/css/wesp-zootech-theme-organic.css") layout = self._read("static/css/wesp-zootech-layout.css") self.assertIn("--organic-logo-filter", layout) self.assertIn(".logo--light-theme", organic) self.assertIn(".text-primary", organic) self.assertIn("--bs-primary", layout) def test_organic_dashboard_and_paste_buttons(self) -> None: organic = self._read("static/css/wesp-zootech-theme-organic.css") self.assertIn(".list-item-title", organic) self.assertIn("btn-outline-success", organic) self.assertIn("paste-recipe-btn", organic) def test_organic_css_loaded_last_in_recipes(self) -> None: html = self._read("static/recipes.html") head = html.split("", 1)[0] organic_pos = head.rfind("wesp-zootech-theme-organic.css") polish_pos = head.rfind("wesp-zootech-pages-polish") editor_pos = head.rfind("wesp-recipes-editor.css") self.assertGreater(organic_pos, 0) if polish_pos > 0: self.assertGreater(organic_pos, polish_pos) if editor_pos > 0: self.assertGreater(organic_pos, editor_pos) def test_theme_boot_injects_critical_css(self) -> None: boot = self._read("static/js/wesp-theme-boot.js") self.assertIn("wesp-theme-critical", boot) self.assertIn("ORGANIC_LOGO_FILTER", boot) self.assertIn('html[data-theme="organic"]', boot) def test_auth_settings_uses_theme_picker(self) -> None: js = self._read("static/js/pages/recipes-auth-settings.js") self.assertIn("initThemePicker", js) self.assertIn("initHighContrastToggle", js) def test_logo_loader_supports_organic_theme(self) -> None: loader = self._read("static/js/wesp-logo-loader.js") login = self._read("static/js/pages/login-page.js") self.assertIn("BRAND_ORGANIC", loader) self.assertIn("BRAND_ORGANIC_HC", loader) self.assertIn("prefers-contrast: more", loader) self.assertIn("resolveLoaderTheme", loader) self.assertIn("themeForLogoLoader", login) self.assertIn('theme: themeForLogoLoader()', login) self.assertNotIn("darkTheme: isDarkTheme()", login) def test_organic_prefers_contrast_tokens(self) -> None: layout = self._read("static/css/wesp-zootech-layout.css") organic = self._read("static/css/wesp-zootech-theme-organic.css") boot = self._read("static/js/wesp-theme-boot.js") theme_js = self._read("static/js/wesp-theme.js") self.assertIn("data-high-contrast", layout) self.assertIn("@media (prefers-contrast: more)", layout) self.assertIn("#2f6b57", layout.lower()) self.assertIn("data-high-contrast", organic) self.assertIn("highContrast", boot) self.assertIn("wespHighContrast", theme_js) self.assertIn("initHighContrastToggle", theme_js) def test_lab_heisenberg_background_visible(self) -> None: css = self._read("static/css/wesp-lab-sandbox.css") self.assertIn("lab-heisenberg-bg.jpg", css) self.assertIn("body.zootech-app-body.lab-sandbox-page", css) self.assertIn("background-color: transparent", css.split("body.zootech-app-body.lab-sandbox-page")[1][:120]) if __name__ == "__main__": unittest.main()