mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-09-29 08:46:45 +00:00
* Implemented optional link to override feature * Added translation strings (untranslated)
172 lines
6.4 KiB
Python
172 lines
6.4 KiB
Python
"""
|
|
Tests for the optional per-watch "Link to Open" (`link_to_open`).
|
|
|
|
A watch may point at something that is useless in a browser - an API endpoint or an RSS
|
|
feed - while the human-readable page lives somewhere else. `link_to_open` stores that page,
|
|
and every "go to the site" affordance (watch list, history/preview header, the
|
|
{{watch_open_url}} notification token) uses it in preference to the watched URL.
|
|
"""
|
|
|
|
import os
|
|
|
|
from flask import url_for
|
|
|
|
from .util import set_original_response, set_modified_response, wait_for_all_checks, \
|
|
wait_for_notification_endpoint_output
|
|
|
|
OPEN_URL = "https://example.com/the-real-human-page"
|
|
|
|
|
|
def _add_watch(client, test_url):
|
|
res = client.post(
|
|
url_for("ui.ui_views.form_quick_watch_add"),
|
|
data={"url": test_url, "tags": ''},
|
|
follow_redirects=True
|
|
)
|
|
assert b"Watch added" in res.data
|
|
wait_for_all_checks(client)
|
|
|
|
|
|
def _edit_watch(client, test_url, **extra):
|
|
data = {
|
|
"url": test_url,
|
|
"tags": "",
|
|
"headers": "",
|
|
"fetch_backend": "html_requests",
|
|
"time_between_check_use_default": "y",
|
|
}
|
|
data.update(extra)
|
|
return client.post(url_for("ui.ui_edit.edit_page", uuid="first"), data=data, follow_redirects=True)
|
|
|
|
|
|
def test_link_to_open_is_saved_and_used_in_the_watch_list(client, live_server, measure_memory_usage, datastore_path):
|
|
set_original_response(datastore_path=datastore_path)
|
|
test_url = url_for('test_endpoint', _external=True)
|
|
_add_watch(client, test_url)
|
|
|
|
# Without an override, the watch list links to the watched URL
|
|
res = client.get(url_for("watchlist.index"))
|
|
assert f'href="{test_url}"'.encode('utf-8') in res.data
|
|
assert OPEN_URL.encode('utf-8') not in res.data
|
|
|
|
res = _edit_watch(client, test_url, link_to_open=OPEN_URL)
|
|
assert b"Updated watch." in res.data
|
|
|
|
# It round-trips back into the edit form
|
|
res = client.get(url_for("ui.ui_edit.edit_page", uuid="first"))
|
|
assert OPEN_URL.encode('utf-8') in res.data
|
|
|
|
# ...and the watch list now points at it instead of the watched URL
|
|
res = client.get(url_for("watchlist.index"))
|
|
assert f'href="{OPEN_URL}"'.encode('utf-8') in res.data
|
|
assert f'href="{test_url}"'.encode('utf-8') not in res.data
|
|
|
|
|
|
def test_link_to_open_used_in_history_header(client, live_server, measure_memory_usage, datastore_path):
|
|
set_original_response(datastore_path=datastore_path)
|
|
test_url = url_for('test_endpoint', _external=True)
|
|
_add_watch(client, test_url)
|
|
|
|
set_modified_response(datastore_path=datastore_path)
|
|
client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
|
wait_for_all_checks(client)
|
|
|
|
assert b"Updated watch." in _edit_watch(client, test_url, link_to_open=OPEN_URL).data
|
|
|
|
uuid = next(iter(client.application.config.get('DATASTORE').data['watching'].keys()))
|
|
|
|
# Top-of-page link on the history/diff page
|
|
res = client.get(url_for("ui.ui_diff.diff_history_page", uuid=uuid))
|
|
assert f'class="current-diff-url" href="{OPEN_URL}"'.encode('utf-8') in res.data
|
|
|
|
# ...and on the preview page
|
|
res = client.get(url_for("ui.ui_preview.preview_page", uuid=uuid))
|
|
assert f'class="current-diff-url" href="{OPEN_URL}"'.encode('utf-8') in res.data
|
|
|
|
|
|
def test_invalid_link_to_open_is_rejected(client, live_server, measure_memory_usage, datastore_path):
|
|
set_original_response(datastore_path=datastore_path)
|
|
test_url = url_for('test_endpoint', _external=True)
|
|
_add_watch(client, test_url)
|
|
|
|
res = _edit_watch(client, test_url, link_to_open="javascript:alert(1)")
|
|
assert b"Updated watch." not in res.data
|
|
assert b"Watch protocol is not permitted or invalid URL format" in res.data
|
|
|
|
# Blank is fine - it means "use the watched URL"
|
|
res = _edit_watch(client, test_url, link_to_open="")
|
|
assert b"Updated watch." in res.data
|
|
watch = list(client.application.config.get('DATASTORE').data['watching'].values())[0]
|
|
assert watch.open_link == test_url
|
|
|
|
|
|
def test_watch_open_url_notification_token(client, live_server, measure_memory_usage, datastore_path):
|
|
set_original_response(datastore_path=datastore_path)
|
|
notification_file = os.path.join(datastore_path, "notification.txt")
|
|
if os.path.isfile(notification_file):
|
|
os.unlink(notification_file)
|
|
|
|
test_url = url_for('test_endpoint', _external=True)
|
|
_add_watch(client, test_url)
|
|
|
|
notification_url = url_for('test_notification_endpoint', _external=True).replace('http://', 'post://')
|
|
|
|
res = _edit_watch(
|
|
client,
|
|
test_url,
|
|
link_to_open=OPEN_URL,
|
|
notification_urls=notification_url,
|
|
notification_title="Test",
|
|
notification_body="watched={{watch_url}}\nopen={{watch_open_url}}",
|
|
notification_format="text",
|
|
)
|
|
assert b"Updated watch." in res.data
|
|
wait_for_all_checks(client)
|
|
|
|
set_modified_response(datastore_path=datastore_path)
|
|
client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
|
wait_for_all_checks(client)
|
|
assert wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
|
|
|
with open(notification_file, 'r') as f:
|
|
body = f.read()
|
|
|
|
assert f"watched={test_url}" in body
|
|
assert f"open={OPEN_URL}" in body
|
|
os.unlink(notification_file)
|
|
|
|
|
|
def test_watch_open_url_token_falls_back_to_watch_url(client, live_server, measure_memory_usage, datastore_path):
|
|
"""With no 'Link to Open' set, {{watch_open_url}} must still render the watched URL."""
|
|
set_original_response(datastore_path=datastore_path)
|
|
notification_file = os.path.join(datastore_path, "notification.txt")
|
|
if os.path.isfile(notification_file):
|
|
os.unlink(notification_file)
|
|
|
|
test_url = url_for('test_endpoint', _external=True)
|
|
_add_watch(client, test_url)
|
|
|
|
notification_url = url_for('test_notification_endpoint', _external=True).replace('http://', 'post://')
|
|
|
|
res = _edit_watch(
|
|
client,
|
|
test_url,
|
|
notification_urls=notification_url,
|
|
notification_title="Test",
|
|
notification_body="open={{watch_open_url}}",
|
|
notification_format="text",
|
|
)
|
|
assert b"Updated watch." in res.data
|
|
wait_for_all_checks(client)
|
|
|
|
set_modified_response(datastore_path=datastore_path)
|
|
client.post(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
|
wait_for_all_checks(client)
|
|
assert wait_for_notification_endpoint_output(datastore_path=datastore_path)
|
|
|
|
with open(notification_file, 'r') as f:
|
|
body = f.read()
|
|
|
|
assert f"open={test_url}" in body
|
|
os.unlink(notification_file)
|