mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-13 19:45:56 +00:00
Introduce an AJAX button for sending test notifications instead of the checkbox (#519)
This commit is contained in:
@@ -400,6 +400,37 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
# AJAX endpoint for sending a test
|
||||||
|
@app.route("/notification/send-test", methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def ajax_callback_send_notification_test():
|
||||||
|
|
||||||
|
import apprise
|
||||||
|
apobj = apprise.Apprise()
|
||||||
|
|
||||||
|
# validate URLS
|
||||||
|
if not len(request.form['notification_urls'].strip()):
|
||||||
|
return make_response({'error': 'No Notification URLs set'}, 400)
|
||||||
|
|
||||||
|
for server_url in request.form['notification_urls'].splitlines():
|
||||||
|
if not apobj.add(server_url):
|
||||||
|
message = '{} is not a valid AppRise URL.'.format(server_url)
|
||||||
|
return make_response({'error': message}, 400)
|
||||||
|
|
||||||
|
try:
|
||||||
|
n_object = {'watch_url': request.form['window_url'],
|
||||||
|
'notification_urls': request.form['notification_urls'].splitlines(),
|
||||||
|
'notification_title': request.form['notification_title'].strip(),
|
||||||
|
'notification_body': request.form['notification_body'].strip(),
|
||||||
|
'notification_format': request.form['notification_format'].strip()
|
||||||
|
}
|
||||||
|
notification_q.put(n_object)
|
||||||
|
except Exception as e:
|
||||||
|
return make_response({'error': str(e)}, 400)
|
||||||
|
|
||||||
|
return 'OK'
|
||||||
|
|
||||||
@app.route("/scrub", methods=['GET', 'POST'])
|
@app.route("/scrub", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def scrub_page():
|
def scrub_page():
|
||||||
@@ -561,20 +592,6 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
# Queue the watch for immediate recheck
|
# Queue the watch for immediate recheck
|
||||||
update_q.put(uuid)
|
update_q.put(uuid)
|
||||||
|
|
||||||
if form.trigger_check.data:
|
|
||||||
if len(form.notification_urls.data):
|
|
||||||
n_object = {'watch_url': form.url.data.strip(),
|
|
||||||
'notification_urls': form.notification_urls.data,
|
|
||||||
'notification_title': form.notification_title.data,
|
|
||||||
'notification_body': form.notification_body.data,
|
|
||||||
'notification_format': form.notification_format.data,
|
|
||||||
'uuid': uuid
|
|
||||||
}
|
|
||||||
notification_q.put(n_object)
|
|
||||||
flash('Test notification queued.')
|
|
||||||
else:
|
|
||||||
flash('No notification URLs set, cannot send test.', 'error')
|
|
||||||
|
|
||||||
# Diff page [edit] link should go back to diff page
|
# Diff page [edit] link should go back to diff page
|
||||||
if request.args.get("next") and request.args.get("next") == 'diff' and not form.save_and_preview_button.data:
|
if request.args.get("next") and request.args.get("next") == 'diff' and not form.save_and_preview_button.data:
|
||||||
return redirect(url_for('diff_history_page', uuid=uuid))
|
return redirect(url_for('diff_history_page', uuid=uuid))
|
||||||
@@ -650,19 +667,6 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
datastore.data['settings']['application']['ignore_whitespace'] = form.ignore_whitespace.data
|
datastore.data['settings']['application']['ignore_whitespace'] = form.ignore_whitespace.data
|
||||||
datastore.data['settings']['application']['real_browser_save_screenshot'] = form.real_browser_save_screenshot.data
|
datastore.data['settings']['application']['real_browser_save_screenshot'] = form.real_browser_save_screenshot.data
|
||||||
|
|
||||||
if form.trigger_check.data:
|
|
||||||
if len(form.notification_urls.data):
|
|
||||||
n_object = {'watch_url': "Test from changedetection.io!",
|
|
||||||
'notification_urls': form.notification_urls.data,
|
|
||||||
'notification_title': form.notification_title.data,
|
|
||||||
'notification_body': form.notification_body.data,
|
|
||||||
'notification_format': form.notification_format.data,
|
|
||||||
}
|
|
||||||
notification_q.put(n_object)
|
|
||||||
flash('Test notification queued.')
|
|
||||||
else:
|
|
||||||
flash('No notification URLs set, cannot send test.', 'error')
|
|
||||||
|
|
||||||
if not os.getenv("SALTED_PASS", False) and form.password.encrypted_password:
|
if not os.getenv("SALTED_PASS", False) and form.password.encrypted_password:
|
||||||
datastore.data['settings']['application']['password'] = form.password.encrypted_password
|
datastore.data['settings']['application']['password'] = form.password.encrypted_password
|
||||||
flash("Password protection enabled.", 'notice')
|
flash("Password protection enabled.", 'notice')
|
||||||
@@ -1027,10 +1031,14 @@ def changedetection_app(config=None, datastore_o=None):
|
|||||||
flash("Error")
|
flash("Error")
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/delete", methods=['GET'])
|
@app.route("/api/delete", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def api_delete():
|
def api_delete():
|
||||||
uuid = request.args.get('uuid')
|
uuid = request.args.get('uuid')
|
||||||
|
# More for testing, possible to return the first/only
|
||||||
|
if uuid == 'first':
|
||||||
|
uuid = list(datastore.data['watching'].keys()).pop()
|
||||||
datastore.delete(uuid)
|
datastore.delete(uuid)
|
||||||
flash('Deleted.')
|
flash('Deleted.')
|
||||||
|
|
||||||
|
|||||||
@@ -306,7 +306,6 @@ class commonSettingsForm(Form):
|
|||||||
notification_title = StringField('Notification Title', default=default_notification_title, validators=[validators.Optional(), ValidateTokensList()])
|
notification_title = StringField('Notification Title', default=default_notification_title, validators=[validators.Optional(), ValidateTokensList()])
|
||||||
notification_body = TextAreaField('Notification Body', default=default_notification_body, validators=[validators.Optional(), ValidateTokensList()])
|
notification_body = TextAreaField('Notification Body', default=default_notification_body, validators=[validators.Optional(), ValidateTokensList()])
|
||||||
notification_format = SelectField('Notification Format', choices=valid_notification_formats.keys(), default=default_notification_format)
|
notification_format = SelectField('Notification Format', choices=valid_notification_formats.keys(), default=default_notification_format)
|
||||||
trigger_check = BooleanField('Send test notification on save')
|
|
||||||
fetch_backend = RadioField(u'Fetch Method', choices=content_fetcher.available_fetchers(), validators=[ValidateContentFetcherIsReady()])
|
fetch_backend = RadioField(u'Fetch Method', choices=content_fetcher.available_fetchers(), validators=[ValidateContentFetcherIsReady()])
|
||||||
extract_title_as_title = BooleanField('Extract <title> from document and use as watch title', default=False)
|
extract_title_as_title = BooleanField('Extract <title> from document and use as watch title', default=False)
|
||||||
|
|
||||||
|
|||||||
42
changedetectionio/static/js/notifications.js
Normal file
42
changedetectionio/static/js/notifications.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
$('#send-test-notification').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// this can be global
|
||||||
|
var csrftoken = $('input[name=csrf_token]').val();
|
||||||
|
$.ajaxSetup({
|
||||||
|
beforeSend: function(xhr, settings) {
|
||||||
|
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
|
||||||
|
xhr.setRequestHeader("X-CSRFToken", csrftoken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
data = {
|
||||||
|
window_url : window.location.href,
|
||||||
|
notification_urls : $('#notification_urls').val(),
|
||||||
|
notification_title : $('#notification_title').val(),
|
||||||
|
notification_body : $('#notification_body').val(),
|
||||||
|
notification_format : $('#notification_format').val(),
|
||||||
|
}
|
||||||
|
for (key in data) {
|
||||||
|
if (!data[key].length) {
|
||||||
|
alert(key+" is empty, cannot send test.")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: notification_base_url,
|
||||||
|
data : data
|
||||||
|
}).done(function(data){
|
||||||
|
console.log(data);
|
||||||
|
alert('Sent');
|
||||||
|
}).fail(function(data){
|
||||||
|
console.log(data);
|
||||||
|
alert('Error: '+data.responseJSON.error);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
<li>Go here for <a href="{{url_for('notification_logs')}}">Notification debug logs</a></li>
|
<li>Go here for <a href="{{url_for('notification_logs')}}">Notification debug logs</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<br/>
|
||||||
|
<a id="send-test-notification" class="pure-button button-secondary button-xsmall" style="font-size: 70%">Send test notification</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="notification-customisation">
|
<div id="notification-customisation">
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
@@ -93,7 +95,4 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-control-group">
|
|
||||||
{{ render_field(form.trigger_check) }}
|
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
background-image: url({{url_for('static_content', group='images', filename='gradient-border.png')}});
|
background-image: url({{url_for('static_content', group='images', filename='gradient-border.png')}});
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='jquery-3.6.0.min.js')}}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
{% from '_helpers.jinja' import render_button %}
|
{% from '_helpers.jinja' import render_button %}
|
||||||
{% from '_common_fields.jinja' import render_common_settings_form %}
|
{% from '_common_fields.jinja' import render_common_settings_form %}
|
||||||
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
|
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
|
||||||
|
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='notifications.js')}}" defer></script>
|
||||||
|
<script>
|
||||||
|
var notification_base_url="{{url_for('ajax_callback_send_notification_test')}}";
|
||||||
|
</script>
|
||||||
|
|
||||||
<div class="edit-form monospaced-textarea">
|
<div class="edit-form monospaced-textarea">
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='settings.js')}}" defer></script>
|
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='settings.js')}}" defer></script>
|
||||||
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
|
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='tabs.js')}}" defer></script>
|
||||||
|
<script type="text/javascript" src="{{url_for('static_content', group='js', filename='notifications.js')}}" defer></script>
|
||||||
|
<script>
|
||||||
|
var notification_base_url="{{url_for('ajax_callback_send_notification_test')}}";
|
||||||
|
</script>
|
||||||
<div class="edit-form">
|
<div class="edit-form">
|
||||||
<div class="tabs collapsable">
|
<div class="tabs collapsable">
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -2,15 +2,17 @@ import os
|
|||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from . util import set_original_response, set_modified_response, live_server_setup
|
from . util import set_original_response, set_modified_response, set_more_modified_response, live_server_setup
|
||||||
import logging
|
import logging
|
||||||
from changedetectionio.notification import default_notification_body, default_notification_title
|
from changedetectionio.notification import default_notification_body, default_notification_title
|
||||||
|
|
||||||
|
def test_setup(live_server):
|
||||||
|
live_server_setup(live_server)
|
||||||
|
|
||||||
# Hard to just add more live server URLs when one test is already running (I think)
|
# Hard to just add more live server URLs when one test is already running (I think)
|
||||||
# So we add our test here (was in a different file)
|
# So we add our test here (was in a different file)
|
||||||
def test_check_notification(client, live_server):
|
def test_check_notification(client, live_server):
|
||||||
|
|
||||||
live_server_setup(live_server)
|
|
||||||
set_original_response()
|
set_original_response()
|
||||||
|
|
||||||
# Give the endpoint time to spin up
|
# Give the endpoint time to spin up
|
||||||
@@ -49,84 +51,76 @@ def test_check_notification(client, live_server):
|
|||||||
notification_url = url.replace('http', 'json')
|
notification_url = url.replace('http', 'json')
|
||||||
|
|
||||||
print (">>>> Notification URL: "+notification_url)
|
print (">>>> Notification URL: "+notification_url)
|
||||||
|
|
||||||
|
notification_form_data = {"notification_urls": notification_url,
|
||||||
|
"notification_title": "New ChangeDetection.io Notification - {watch_url}",
|
||||||
|
"notification_body": "BASE URL: {base_url}\n"
|
||||||
|
"Watch URL: {watch_url}\n"
|
||||||
|
"Watch UUID: {watch_uuid}\n"
|
||||||
|
"Watch title: {watch_title}\n"
|
||||||
|
"Watch tag: {watch_tag}\n"
|
||||||
|
"Preview: {preview_url}\n"
|
||||||
|
"Diff URL: {diff_url}\n"
|
||||||
|
"Snapshot: {current_snapshot}\n"
|
||||||
|
"Diff: {diff}\n"
|
||||||
|
"Diff Full: {diff_full}\n"
|
||||||
|
":-)",
|
||||||
|
"notification_format": "Text"}
|
||||||
|
|
||||||
|
notification_form_data.update({
|
||||||
|
"url": test_url,
|
||||||
|
"tag": "my tag",
|
||||||
|
"title": "my title",
|
||||||
|
"headers": "",
|
||||||
|
"fetch_backend": "html_requests"})
|
||||||
|
|
||||||
res = client.post(
|
res = client.post(
|
||||||
url_for("edit_page", uuid="first"),
|
url_for("edit_page", uuid="first"),
|
||||||
data={"notification_urls": notification_url,
|
data=notification_form_data,
|
||||||
"notification_title": "New ChangeDetection.io Notification - {watch_url}",
|
|
||||||
"notification_body": "BASE URL: {base_url}\n"
|
|
||||||
"Watch URL: {watch_url}\n"
|
|
||||||
"Watch UUID: {watch_uuid}\n"
|
|
||||||
"Watch title: {watch_title}\n"
|
|
||||||
"Watch tag: {watch_tag}\n"
|
|
||||||
"Preview: {preview_url}\n"
|
|
||||||
"Diff URL: {diff_url}\n"
|
|
||||||
"Snapshot: {current_snapshot}\n"
|
|
||||||
"Diff: {diff}\n"
|
|
||||||
"Diff Full: {diff_full}\n"
|
|
||||||
":-)",
|
|
||||||
"notification_format": "Text",
|
|
||||||
"url": test_url,
|
|
||||||
"tag": "my tag",
|
|
||||||
"title": "my title",
|
|
||||||
"headers": "",
|
|
||||||
"fetch_backend": "html_requests",
|
|
||||||
"trigger_check": "y"},
|
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
assert b"Updated watch." in res.data
|
assert b"Updated watch." in res.data
|
||||||
assert b"Test notification queued" in res.data
|
|
||||||
|
|
||||||
# Hit the edit page, be sure that we saved it
|
# Hit the edit page, be sure that we saved it
|
||||||
|
# Re #242 - wasnt saving?
|
||||||
res = client.get(
|
res = client.get(
|
||||||
url_for("edit_page", uuid="first"))
|
url_for("edit_page", uuid="first"))
|
||||||
assert bytes(notification_url.encode('utf-8')) in res.data
|
assert bytes(notification_url.encode('utf-8')) in res.data
|
||||||
|
|
||||||
# Re #242 - wasnt saving?
|
|
||||||
assert bytes("New ChangeDetection.io Notification".encode('utf-8')) in res.data
|
assert bytes("New ChangeDetection.io Notification".encode('utf-8')) in res.data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Because we hit 'send test notification on save'
|
## Now recheck, and it should have sent the notification
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
set_modified_response()
|
||||||
|
|
||||||
notification_submission = None
|
notification_submission = None
|
||||||
|
|
||||||
|
# Trigger a check
|
||||||
|
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
||||||
|
time.sleep(3)
|
||||||
# Verify what was sent as a notification, this file should exist
|
# Verify what was sent as a notification, this file should exist
|
||||||
with open("test-datastore/notification.txt", "r") as f:
|
with open("test-datastore/notification.txt", "r") as f:
|
||||||
notification_submission = f.read()
|
notification_submission = f.read()
|
||||||
# Did we see the URL that had a change, in the notification?
|
|
||||||
|
|
||||||
assert test_url in notification_submission
|
|
||||||
|
|
||||||
os.unlink("test-datastore/notification.txt")
|
os.unlink("test-datastore/notification.txt")
|
||||||
|
|
||||||
set_modified_response()
|
# Did we see the URL that had a change, in the notification?
|
||||||
|
|
||||||
# Trigger a check
|
|
||||||
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
|
||||||
|
|
||||||
# Give the thread time to pick it up
|
|
||||||
time.sleep(3)
|
|
||||||
|
|
||||||
# Did the front end see it?
|
|
||||||
res = client.get(
|
|
||||||
url_for("index"))
|
|
||||||
|
|
||||||
assert bytes("just now".encode('utf-8')) in res.data
|
|
||||||
|
|
||||||
notification_submission=None
|
|
||||||
# Verify what was sent as a notification
|
|
||||||
with open("test-datastore/notification.txt", "r") as f:
|
|
||||||
notification_submission = f.read()
|
|
||||||
# Did we see the URL that had a change, in the notification?
|
|
||||||
|
|
||||||
assert test_url in notification_submission
|
|
||||||
|
|
||||||
# Diff was correctly executed
|
# Diff was correctly executed
|
||||||
|
assert test_url in notification_submission
|
||||||
|
assert ':-)' in notification_submission
|
||||||
assert "Diff Full: Some initial text" in notification_submission
|
assert "Diff Full: Some initial text" in notification_submission
|
||||||
assert "Diff: (changed) Which is across multiple lines" in notification_submission
|
assert "Diff: (changed) Which is across multiple lines" in notification_submission
|
||||||
assert "(into ) which has this one new line" in notification_submission
|
assert "(into ) which has this one new line" in notification_submission
|
||||||
|
# Re #342 - check for accidental python byte encoding of non-utf8/string
|
||||||
|
assert "b'" not in notification_submission
|
||||||
|
assert re.search('Watch UUID: [0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}', notification_submission, re.IGNORECASE)
|
||||||
|
assert "Watch title: my title" in notification_submission
|
||||||
|
assert "Watch tag: my tag" in notification_submission
|
||||||
|
assert "diff/" in notification_submission
|
||||||
|
assert "preview/" in notification_submission
|
||||||
|
assert ":-)" in notification_submission
|
||||||
|
assert "New ChangeDetection.io Notification - {}".format(test_url) in notification_submission
|
||||||
|
|
||||||
if env_base_url:
|
if env_base_url:
|
||||||
# Re #65 - did we see our BASE_URl ?
|
# Re #65 - did we see our BASE_URl ?
|
||||||
@@ -135,50 +129,17 @@ def test_check_notification(client, live_server):
|
|||||||
else:
|
else:
|
||||||
logging.debug(">>> Skipping BASE_URL check")
|
logging.debug(">>> Skipping BASE_URL check")
|
||||||
|
|
||||||
## Now configure something clever, we go into custom config (non-default) mode, this is returned by the endpoint
|
|
||||||
with open("test-datastore/endpoint-content.txt", "w") as f:
|
|
||||||
f.write(";jasdhflkjadshf kjhsdfkjl ahslkjf haslkjd hfaklsj hf\njl;asdhfkasj stuff we will detect\n")
|
|
||||||
|
|
||||||
res = client.post(
|
|
||||||
url_for("settings_page"),
|
|
||||||
data={"notification_title": "New ChangeDetection.io Notification - {watch_url}",
|
|
||||||
"notification_urls": "json://foobar.com", #Re #143 should not see that it sent without [test checkbox]
|
|
||||||
"minutes_between_check": 180,
|
|
||||||
"fetch_backend": "html_requests",
|
|
||||||
},
|
|
||||||
follow_redirects=True
|
|
||||||
)
|
|
||||||
assert b"Settings updated." in res.data
|
|
||||||
# Re #143 - should not see this if we didnt hit the test box
|
|
||||||
assert b"Test notification queued" not in res.data
|
|
||||||
|
|
||||||
# Trigger a check
|
# This should insert the {current_snapshot}
|
||||||
|
set_more_modified_response()
|
||||||
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
||||||
|
|
||||||
# Give the thread time to pick it up
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
# Verify what was sent as a notification, this file should exist
|
||||||
# Did the front end see it?
|
|
||||||
res = client.get(
|
|
||||||
url_for("index"))
|
|
||||||
|
|
||||||
assert bytes("just now".encode('utf-8')) in res.data
|
|
||||||
|
|
||||||
with open("test-datastore/notification.txt", "r") as f:
|
with open("test-datastore/notification.txt", "r") as f:
|
||||||
notification_submission = f.read()
|
notification_submission = f.read()
|
||||||
print ("Notification submission was:", notification_submission)
|
assert "Ohh yeah awesome" in notification_submission
|
||||||
# Re #342 - check for accidental python byte encoding of non-utf8/string
|
|
||||||
assert "b'" not in notification_submission
|
|
||||||
|
|
||||||
assert re.search('Watch UUID: [0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}', notification_submission, re.IGNORECASE)
|
|
||||||
assert "Watch title: my title" in notification_submission
|
|
||||||
assert "Watch tag: my tag" in notification_submission
|
|
||||||
assert "diff/" in notification_submission
|
|
||||||
assert "preview/" in notification_submission
|
|
||||||
assert ":-)" in notification_submission
|
|
||||||
assert "New ChangeDetection.io Notification - {}".format(test_url) in notification_submission
|
|
||||||
# This should insert the {current_snapshot}
|
|
||||||
assert "stuff we will detect" in notification_submission
|
|
||||||
|
|
||||||
# Prove that "content constantly being marked as Changed with no Updating causes notification" is not a thing
|
# Prove that "content constantly being marked as Changed with no Updating causes notification" is not a thing
|
||||||
# https://github.com/dgtlmoon/changedetection.io/discussions/192
|
# https://github.com/dgtlmoon/changedetection.io/discussions/192
|
||||||
@@ -186,33 +147,39 @@ def test_check_notification(client, live_server):
|
|||||||
|
|
||||||
# Trigger a check
|
# Trigger a check
|
||||||
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
||||||
time.sleep(3)
|
time.sleep(1)
|
||||||
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
||||||
time.sleep(3)
|
time.sleep(1)
|
||||||
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
client.get(url_for("api_watch_checknow"), follow_redirects=True)
|
||||||
time.sleep(3)
|
time.sleep(1)
|
||||||
assert os.path.exists("test-datastore/notification.txt") == False
|
assert os.path.exists("test-datastore/notification.txt") == False
|
||||||
|
|
||||||
|
# cleanup for the next
|
||||||
# Now adding a wrong token should give us an error
|
client.get(
|
||||||
res = client.post(
|
url_for("api_delete", uuid="first"),
|
||||||
url_for("settings_page"),
|
|
||||||
data={"notification_title": "New ChangeDetection.io Notification - {watch_url}",
|
|
||||||
"notification_body": "Rubbish: {rubbish}\n",
|
|
||||||
"notification_format": "Text",
|
|
||||||
"notification_urls": "json://foobar.com",
|
|
||||||
"minutes_between_check": 180,
|
|
||||||
"fetch_backend": "html_requests"
|
|
||||||
},
|
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
|
|
||||||
assert bytes("is not a valid token".encode('utf-8')) in res.data
|
|
||||||
|
def test_notification_validation(client, live_server):
|
||||||
|
#live_server_setup(live_server)
|
||||||
|
time.sleep(3)
|
||||||
|
# re #242 - when you edited an existing new entry, it would not correctly show the notification settings
|
||||||
|
# Add our URL to the import page
|
||||||
|
test_url = url_for('test_endpoint', _external=True)
|
||||||
|
res = client.post(
|
||||||
|
url_for("api_watch_add"),
|
||||||
|
data={"url": test_url, "tag": 'nice one'},
|
||||||
|
follow_redirects=True
|
||||||
|
)
|
||||||
|
with open("xxx.bin", "wb") as f:
|
||||||
|
f.write(res.data)
|
||||||
|
assert b"Watch added" in res.data
|
||||||
|
|
||||||
# Re #360 some validation
|
# Re #360 some validation
|
||||||
res = client.post(
|
res = client.post(
|
||||||
url_for("edit_page", uuid="first"),
|
url_for("edit_page", uuid="first"),
|
||||||
data={"notification_urls": notification_url,
|
data={"notification_urls": 'json://localhost/foobar',
|
||||||
"notification_title": "",
|
"notification_title": "",
|
||||||
"notification_body": "",
|
"notification_body": "",
|
||||||
"notification_format": "Text",
|
"notification_format": "Text",
|
||||||
@@ -220,8 +187,28 @@ def test_check_notification(client, live_server):
|
|||||||
"tag": "my tag",
|
"tag": "my tag",
|
||||||
"title": "my title",
|
"title": "my title",
|
||||||
"headers": "",
|
"headers": "",
|
||||||
"fetch_backend": "html_requests",
|
"fetch_backend": "html_requests"},
|
||||||
"trigger_check": "y"},
|
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
assert b"Notification Body and Title is required when a Notification URL is used" in res.data
|
assert b"Notification Body and Title is required when a Notification URL is used" in res.data
|
||||||
|
|
||||||
|
# Now adding a wrong token should give us an error
|
||||||
|
res = client.post(
|
||||||
|
url_for("settings_page"),
|
||||||
|
data={"notification_title": "New ChangeDetection.io Notification - {watch_url}",
|
||||||
|
"notification_body": "Rubbish: {rubbish}\n",
|
||||||
|
"notification_format": "Text",
|
||||||
|
"notification_urls": "json://localhost/foobar",
|
||||||
|
"time_between_check": {'seconds': 180},
|
||||||
|
"fetch_backend": "html_requests"
|
||||||
|
},
|
||||||
|
follow_redirects=True
|
||||||
|
)
|
||||||
|
|
||||||
|
assert bytes("is not a valid token".encode('utf-8')) in res.data
|
||||||
|
|
||||||
|
# cleanup for the next
|
||||||
|
client.get(
|
||||||
|
url_for("api_delete", uuid="first"),
|
||||||
|
follow_redirects=True
|
||||||
|
)
|
||||||
|
|||||||
@@ -35,6 +35,24 @@ def set_modified_response():
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def set_more_modified_response():
|
||||||
|
test_return_data = """<html>
|
||||||
|
<head><title>modified head title</title></head>
|
||||||
|
<body>
|
||||||
|
Some initial text</br>
|
||||||
|
<p>which has this one new line</p>
|
||||||
|
</br>
|
||||||
|
So let's see what happens. </br>
|
||||||
|
Ohh yeah awesome<br/>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open("test-datastore/endpoint-content.txt", "w") as f:
|
||||||
|
f.write(test_return_data)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def live_server_setup(live_server):
|
def live_server_setup(live_server):
|
||||||
|
|
||||||
@@ -82,7 +100,7 @@ def live_server_setup(live_server):
|
|||||||
if data != None:
|
if data != None:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
print("\n>> Test notification endpoint was hit.\n")
|
print("\n>> Test notification endpoint was hit.\n", data)
|
||||||
return "Text was set"
|
return "Text was set"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user