""" Module 11 — HTML Improvements tests. All tests are deterministic: no API calls, no disk access. html_improvements.generate() is a pure function tested with controlled AnalysisResult fixtures. """ from __future__ import annotations from backend.models.analysis import AnalysisResult from backend.models.issue import Category, Issue, Severity from backend.services import html_improvements # ── helpers ─────────────────────────────────────────────────────────────────── def _result(issues: list[Issue]) -> AnalysisResult: return AnalysisResult(overall_score=70.0, category_scores=[], issues=issues) def _issue(rule_id: str, cat: Category = Category.ACCESSIBILITY) -> Issue: return Issue( rule_id=rule_id, category=cat, severity=Severity.HIGH, confidence=0.9, message="test", recommendation="fix it", evidence="none", estimated_time="5 minutes", estimated_gain=2.0, ) def _clean() -> AnalysisResult: return _result([]) # ── always-present elements ─────────────────────────────────────────────────── class TestAlwaysPresent: def test_output_is_string(self): assert isinstance(html_improvements.generate(_clean()), str) def test_doctype_always_included(self): assert "" in html_improvements.generate(_clean()) def test_lang_attribute_always_included(self): assert 'lang="en"' in html_improvements.generate(_clean()) def test_viewport_meta_always_included(self): assert 'name="viewport"' in html_improvements.generate(_clean()) def test_charset_meta_always_included(self): assert 'charset="UTF-8"' in html_improvements.generate(_clean()) def test_landmark_roles_always_included(self): out = html_improvements.generate(_clean()) assert 'role="banner"' in out assert 'role="contentinfo"' in out def test_main_id_always_included(self): assert 'id="main-content"' in html_improvements.generate(_clean()) def test_score_appears_in_header(self): assert "70.0/100" in html_improvements.generate(_clean()) # ── skip link ───────────────────────────────────────────────────────────────── class TestSkipLink: def test_skip_link_present_when_a11y_issue_exists(self): result = _result([_issue("F1_missing_label")]) assert "skip-link" in html_improvements.generate(result) def test_skip_link_present_when_focus_issue(self): result = _result([_issue("B3_focus_style")]) assert "skip-link" in html_improvements.generate(result) def test_skip_link_present_when_touch_target_issue(self): result = _result([_issue("B4_touch_target")]) assert "skip-link" in html_improvements.generate(result) # ── form patterns ───────────────────────────────────────────────────────────── class TestFormPatterns: def test_label_pattern_when_f1_fires(self): result = _result([_issue("F1_missing_label")]) out = html_improvements.generate(result) assert '