from email_campaigns.emails.canonicalize import ( canonicalize, canonicalize_css, canonicalize_html, ) class TestCanonicalizeHtml: def test_attribute_order_does_not_matter(self) -> None: a = '
' b = '
' assert canonicalize_html(a) == canonicalize_html(b) def test_real_world_stripo_attribute_reorder(self) -> None: stored = ( "" '' '' "" ) fresh = ( "" '' '' "" ) assert canonicalize_html(stored) == canonicalize_html(fresh) def test_real_content_change_is_detected(self) -> None: a = "

Insert elements with custom code

" b = "

Updated copy

" assert canonicalize_html(a) != canonicalize_html(b) def test_class_token_order_does_not_matter(self) -> None: a = '
' b = '
' assert canonicalize_html(a) == canonicalize_html(b) def test_inline_style_declaration_order_does_not_matter(self) -> None: a = '
' b = '
' assert canonicalize_html(a) == canonicalize_html(b) def test_style_tag_whitespace_does_not_matter(self) -> None: a = "" b = "" assert canonicalize_html(a) == canonicalize_html(b) def test_whitespace_between_tags_does_not_matter(self) -> None: stored = ( "
\n " '' ) fresh = ( "
" '' ) assert canonicalize_html(stored) == canonicalize_html(fresh) def test_whitespace_around_text_does_not_matter(self) -> None: a = "

\n -privacyFooterBlock-\n

" b = "

-privacyFooterBlock-

" assert canonicalize_html(a) == canonicalize_html(b) def test_whitespace_after_comment_does_not_matter(self) -> None: a = "\n
" b = "
" assert canonicalize_html(a) == canonicalize_html(b) def test_whitespace_inside_text_is_preserved(self) -> None: a = "

a b

" b = "

ab

" assert canonicalize_html(a) != canonicalize_html(b) def test_empty_input_returns_empty(self) -> None: assert canonicalize_html("") == "" assert canonicalize_html(" \n") == "" class TestCanonicalizeCss: def test_comments_are_stripped(self) -> None: a = "/* leading */ a { color: red; } /* trailing */" b = "a { color: red; }" assert canonicalize_css(a) == canonicalize_css(b) def test_whitespace_collapsed(self) -> None: a = "a {\n color: red;\n margin: 0;\n}" b = "a { color: red; margin: 0; }" assert canonicalize_css(a) == canonicalize_css(b) def test_rule_order_is_preserved(self) -> None: a = "a { color: red; } a { color: blue; }" b = "a { color: blue; } a { color: red; }" assert canonicalize_css(a) != canonicalize_css(b) def test_real_content_change_is_detected(self) -> None: a = ".es-button { background: #2d4a9a; }" b = ".es-button { background: #ff0000; }" assert canonicalize_css(a) != canonicalize_css(b) class TestCanonicalize: def test_returns_html_and_css_pair(self) -> None: html, css = canonicalize("

x

", "p{color:red}") assert "

x

" in html assert css == "p{color:red}" def test_none_inputs_yield_empty_strings(self) -> None: assert canonicalize(None, None) == ("", "")