diff --git a/static/js/emailLibrary/signatureFold.js b/static/js/emailLibrary/signatureFold.js index 4cd932b..375cbc0 100644 --- a/static/js/emailLibrary/signatureFold.js +++ b/static/js/emailLibrary/signatureFold.js @@ -298,7 +298,7 @@ export function _foldSignature(html, hintSig) { m = html.match(/]*id=["'](?:Signature|signature|divRplyFwdMsg)["'][\s\S]*$/i); if (m) return wrap(html.slice(0, html.length - m[0].length), '', m[0]); - m = html.match(/(
|\n)\s*--\s*(
|\n)([\s\S]*)$/i); + m = html.match(/(|\n)\s*--\s*(|\n)([\s\S]*)$/i); if (m) { const idx = html.lastIndexOf(m[0]); return wrap(html.slice(0, idx), m[1], m[3]); diff --git a/tests/test_signature_fold_self_closing_br_js.py b/tests/test_signature_fold_self_closing_br_js.py new file mode 100644 index 0000000..3d37b5b --- /dev/null +++ b/tests/test_signature_fold_self_closing_br_js.py @@ -0,0 +1,52 @@ +"""Pin the RFC-3676 "-- " signature delimiter fold for self-closing breaks. + +_foldSignature folded the standard "-- " sig delimiter only when the +surrounding line breaks were the literal `
`; the regex missed `
` +and `
` (what Apple Mail and many clients emit), even though the very +next matcher in the same function already uses ``. So a plain-text +signature delimiter with self-closing breaks was never folded. +""" +import json +import shutil +import subprocess +from pathlib import Path + +import pytest + +_REPO = Path(__file__).resolve().parent.parent +_MOD = _REPO / "static" / "js" / "emailLibrary" / "signatureFold.js" +_HAS_NODE = shutil.which("node") is not None + + +def _folds(html): + js = f""" + globalThis.document = {{ createElement: () => {{ let t=''; return {{ set textContent(v){{t=String(v);}}, get innerHTML(){{return t;}} }}; }} }}; + const mod = await import('{_MOD.as_posix()}'); + const html = {json.dumps(html)}; + const out = mod._foldSignature(html, null); + console.log(JSON.stringify(out.includes('email-sig-fold'))); + """ + proc = subprocess.run(["node", "--input-type=module"], input=js, + capture_output=True, text=True, cwd=str(_REPO), timeout=30) + assert proc.returncode == 0, proc.stderr + return json.loads(proc.stdout.strip()) + + +_SIG = "X" * 250 # long enough to be a "bloated" foldable signature + + +@pytest.mark.skipif(not _HAS_NODE, reason="node binary not on PATH") +def test_self_closing_br_delimiter_folds(): + assert _folds(f"Hello, please review.
--
John Smith
Acme
{_SIG}") is True + assert _folds(f"Hi.
--
Jane Doe
{_SIG}") is True + + +@pytest.mark.skipif(not _HAS_NODE, reason="node binary not on PATH") +def test_classic_br_delimiter_still_folds(): + assert _folds(f"Hello.
--
John Smith
{_SIG}") is True + + +@pytest.mark.skipif(not _HAS_NODE, reason="node binary not on PATH") +def test_short_signature_is_not_folded(): + # not bloated -> wrap() returns the html unchanged (no fold) + assert _folds("Hello.
--
JS") is False