"""Tests for HTML detection and stripping in document upload.""" from html_utils import looks_like_html as _looks_like_html, strip_html as _strip_html class TestLooksLikeHtml: def test_html_document(self): assert _looks_like_html("

Text

") def test_html_div(self): assert _looks_like_html('
§ 312
') def test_html_with_doctype(self): assert _looks_like_html("") def test_plain_text(self): assert not _looks_like_html("§ 312 Anwendungsbereich\n\n(1) Die Vorschriften...") def test_legal_text_with_angle_brackets(self): # Legal text might use < or > but not as HTML tags assert not _looks_like_html("Wert < 100 EUR und > 50 EUR ist zulaessig.") def test_markdown(self): assert not _looks_like_html("# § 312 Anwendungsbereich\n\n(1) Die Vorschriften...") class TestStripHtml: def test_basic_div_tags(self): html = "
§ 312 Anwendungsbereich
" result = _strip_html(html) assert result.startswith("§ 312 Anwendungsbereich") def test_paragraph_tags_become_newlines(self): html = "

Absatz 1

Absatz 2

" result = _strip_html(html) assert "Absatz 1" in result assert "Absatz 2" in result # Paragraphs should be on separate lines lines = [ln.strip() for ln in result.split("\n") if ln.strip()] assert len(lines) >= 2 def test_preserves_section_headers(self): """§ signs must be at line starts after stripping.""" html = '
§ 312 Anwendungsbereich
' result = _strip_html(html) # § should be at the start of a line for line in result.split("\n"): if "§ 312" in line: assert line.strip().startswith("§ 312") break else: raise AssertionError("§ 312 not found in stripped text") def test_decodes_html_entities(self): html = "Gelöscht und geändert und § 312" result = _strip_html(html) assert "Gelöscht" in result assert "geändert" in result assert "§ 312" in result def test_decodes_named_entities(self): html = "§ 312 & § 313" result = _strip_html(html) assert "§ 312" in result assert "§ 313" in result def test_removes_script_style(self): html = '

§ 1 Text

' result = _strip_html(html) assert "color" not in result assert "alert" not in result assert "§ 1 Text" in result def test_br_becomes_newline(self): html = "Zeile 1
Zeile 2
Zeile 3" result = _strip_html(html) assert "Zeile 1" in result assert "Zeile 2" in result def test_no_excessive_whitespace(self): html = "
Text
" result = _strip_html(html) assert "\n\n\n" not in result def test_gesetze_im_internet_format(self): """Realistic HTML from gesetze-im-internet.de.""" html = """
§ 312k Kündigung von Verbraucherverträgen im elektronischen Geschäftsverkehr
(1) Wird Verbrauchern über eine Webseite ermöglicht, einen Vertrag im elektronischen Geschäftsverkehr zu schließen, der auf die Begründung eines Dauerschuldverhältnisses gerichtet ist, das einen Unternehmer zu einer entgeltlichen Leistung verpflichtet, so treffen den Unternehmer die Pflichten nach dieser Vorschrift.
(2) Der Unternehmer hat sicherzustellen, dass der Verbraucher auf der Webseite eine Erklärung zur ordentlichen oder außerordentlichen Kündigung abgeben kann.
""" result = _strip_html(html) # § 312k should be at start of a line found_312k = False for line in result.split("\n"): stripped = line.strip() if stripped.startswith("§ 312k"): found_312k = True break assert found_312k, f"§ 312k not at line start. Text:\n{result[:500]}" # Content should be present without tags assert "Dauerschuldverhältnisses" in result assert "
" not in result assert "class=" not in result def test_plain_text_passthrough(self): """Non-HTML text should pass through unchanged.""" text = "§ 312 Anwendungsbereich\n\n(1) Die Vorschriften..." result = _strip_html(text) assert "§ 312 Anwendungsbereich" in result assert "(1) Die Vorschriften" in result