From 6922b160ee93cb2d60e2ea4d7a669bbc273d7890 Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Tue, 5 May 2026 18:09:04 +0200 Subject: [PATCH] Improving test coverage --- changedetectionio/tests/test_notification.py | 31 ++++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/changedetectionio/tests/test_notification.py b/changedetectionio/tests/test_notification.py index 20dc92a8..bcdacd57 100644 --- a/changedetectionio/tests/test_notification.py +++ b/changedetectionio/tests/test_notification.py @@ -636,11 +636,11 @@ def test_html_color_notifications(client, live_server, measure_memory_usage, dat _test_color_notifications(client, '{{diff_full}}',datastore_path=datastore_path) -def test_plaintext_watch_custom_html_in_notification_body_not_escaped(client, live_server, measure_memory_usage, datastore_path): +def _test_custom_html_in_notification_body_not_escaped(client, datastore_path, content_type=None): """ - #4121 - When the watched URL returns text/plain content-type and the notification body - contains custom HTML (e.g. ), that HTML must NOT be HTML-escaped - in the output. Only the diff content (from the text/plain page) should be escaped. + #4121 - Custom HTML in the notification body (e.g. ) must NOT be + HTML-escaped regardless of the watched page's content-type. Only raw diff content from + text/plain pages needs escaping (to prevent raw '<' chars breaking HTML email rendering). """ set_original_response(datastore_path=datastore_path) @@ -649,15 +649,14 @@ def test_plaintext_watch_custom_html_in_notification_body_not_escaped(client, li test_notification_url = url_for('test_notification_endpoint', _external=True).replace('http://', 'post://') - # Watch a URL that returns text/plain content-type - test_url = url_for('test_endpoint', content_type="text/plain", _external=True) + kwargs = {'content_type': content_type} if content_type else {} + test_url = url_for('test_endpoint', _external=True, **kwargs) res = client.post( url_for("settings.settings_page"), data={ "application-fetch_backend": "html_requests", "application-minutes_between_check": 180, - # Custom HTML in notification body — these tags must NOT be escaped in the output "application-notification_body": 'Watch Link had changes\n\n{{diff}}', "application-notification_format": "htmlcolor", "application-notification_urls": test_notification_url, @@ -686,12 +685,18 @@ def test_plaintext_watch_custom_html_in_notification_body_not_escaped(client, li with open(os.path.join(datastore_path, "notification.txt"), 'r') as f: x = f.read() - # The custom from the notification template must NOT be HTML-escaped - assert '<a href=' not in x, "Custom HTML tag in notification body was incorrectly HTML-escaped" - assert ' tags from htmlcolor format not found in notification" + assert '<a href=' not in x, f"Custom HTML tag was incorrectly escaped (content_type={content_type})" + assert ' tags not found (content_type={content_type})" client.get(url_for("ui.form_delete", uuid="all"), follow_redirects=True) + +def test_plaintext_watch_custom_html_in_notification_body_not_escaped(client, live_server, measure_memory_usage, datastore_path): + # text/plain: diff content may contain raw '<' chars — those must be escaped, but NOT the user's template HTML + _test_custom_html_in_notification_body_not_escaped(client, datastore_path, content_type="text/plain") + # text/html: HTML processor strips tags before diffing, no escaping needed, user's template HTML must be preserved + _test_custom_html_in_notification_body_not_escaped(client, datastore_path, content_type="text/html") + # no MIME type (None): same as HTML case, user's template HTML must be preserved + _test_custom_html_in_notification_body_not_escaped(client, datastore_path, content_type=None) +