More test coverage

This commit is contained in:
Chris Caron 2024-01-14 12:59:32 -05:00
parent 426c1080bd
commit 5dba9b415f
5 changed files with 97 additions and 18 deletions

View File

@ -172,6 +172,12 @@ curl -X POST \
-F attachment=https://i.redd.it/my2t4d2fx0u31.jpg \
http://localhost:8000/notify
# To send more then one URL, the following would work:
curl -X POST \
-F 'urls=mailto://user:pass@gmail.com' \
-F attachment=https://i.redd.it/my2t4d2fx0u31.jpg \
-F attachment=https://raw.githubusercontent.com/caronc/apprise/master/apprise/assets/themes/default/apprise-logo.png \
http://localhost:8000/notify
```
### Persistent Storage Solution

View File

@ -245,7 +245,7 @@ class AttachmentTests(SimpleTestCase):
'filename': 'a' * 1000,
}
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# filename invalid
attachment_payload = {
@ -253,35 +253,35 @@ class AttachmentTests(SimpleTestCase):
'filename': 1,
}
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
attachment_payload = {
'base64': base64.b64encode(b'data to be encoded').decode('utf-8'),
'filename': None,
}
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
attachment_payload = {
'base64': base64.b64encode(b'data to be encoded').decode('utf-8'),
'filename': object(),
}
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# List Entry with bad data
attachment_payload = [
None,
]
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# We expect at least a 'base64' or something in our dict
attachment_payload = [
{},
]
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# We can't parse entries that are not base64 but specified as
# though they are
@ -289,7 +289,7 @@ class AttachmentTests(SimpleTestCase):
'base64': 'not-base-64',
}
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# Support string; these become web requests
attachment_payload = \
@ -316,7 +316,7 @@ class AttachmentTests(SimpleTestCase):
with patch('builtins.open', m):
with self.assertRaises(ValueError):
attachment_payload = b"some data to work with."
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# Test a case where our attachment exceeds the maximum size we allow
# for
@ -324,7 +324,7 @@ class AttachmentTests(SimpleTestCase):
attachment_payload = \
b"some content more then 1 byte in length to pass along."
with self.assertRaises(ValueError):
result = parse_attachments(attachment_payload, {})
parse_attachments(attachment_payload, {})
# Support byte data
attachment_payload = b"some content to pass along as an attachment."
@ -341,6 +341,16 @@ class AttachmentTests(SimpleTestCase):
assert isinstance(result, list)
assert len(result) == 2
attachment_payload = [{
# Request several images
'url': "https://localhost/myotherfile.png",
}, {
'url': "https://localhost/myfile.png"
}]
result = parse_attachments(attachment_payload, {})
assert isinstance(result, list)
assert len(result) == 2
# Test pure binary payload (raw)
attachment_payload = [
b"some content to pass along as an attachment.",
@ -349,3 +359,28 @@ class AttachmentTests(SimpleTestCase):
result = parse_attachments(attachment_payload, {})
assert isinstance(result, list)
assert len(result) == 2
def test_direct_attachment_parsing_nw(self):
"""
Test the parsing of file attachments with network availability
We test web requests that do not work or in accessible to access
this part of the test cases
"""
attachment_payload = [
# While we have a network in place, we're intentionally requesting
# URLs that do not exist (hopefully they don't anyway) as we want
# this test to fail.
"https://localhost/garbage/abcd1.png",
"https://localhost/garbage/abcd2.png",
]
with self.assertRaises(ValueError):
parse_attachments(attachment_payload, {})
# Support url encoding
attachment_payload = [{
'url': "https://localhost/garbage/abcd1.png",
}, {
'url': "https://localhost/garbage/abcd2.png",
}]
with self.assertRaises(ValueError):
parse_attachments(attachment_payload, {})

View File

@ -828,6 +828,25 @@ class NotifyTests(SimpleTestCase):
assert response.status_code == 424
assert mock_notify.call_count == 2
# One more test but we test our URL fetching
mock_notify.side_effect = True
# Reset our mock object
mock_notify.reset_mock()
# Preare our form data
form_data = {
'body': 'test notifiction',
'attachment': 'https://localhost/invalid/path/to/image.png',
}
# Send our notification
response = self.client.post(
'/notify/{}'.format(key), form_data)
# We fail because we couldn't retrieve our attachment
assert response.status_code == 400
assert mock_notify.call_count == 0
@mock.patch('apprise.Apprise.notify')
def test_notify_by_loaded_urls_with_json(self, mock_notify):
"""

View File

@ -231,6 +231,25 @@ class StatelessNotifyTests(SimpleTestCase):
assert response.status_code == 424
assert mock_notify.call_count == 2
# Reset our mock object
mock_notify.reset_mock()
# Preare our form data
form_data = {
'body': 'test notifiction',
'urls': ', '.join([
'mailto://user:pass@hotmail.com',
'mailto://user:pass@gmail.com',
]),
'attachment': 'https://localhost/invalid/path/to/image.png',
}
# Send our notification
response = self.client.post('/notify', form_data)
# We fail because we couldn't retrieve our attachment
assert response.status_code == 400
assert mock_notify.call_count == 0
@override_settings(APPRISE_RECURSION_MAX=1)
@mock.patch('apprise.Apprise.notify')
def test_stateless_notify_recursion(self, mock_notify):

View File

@ -612,7 +612,7 @@ class NotifyView(View):
attach = None
if not content.get('attachment') and 'attachment' in request.POST:
# Acquire attachments to work with them
content['attachment'] = request.POST['attachment']
content['attachment'] = request.POST.getlist('attachment')
if 'attachment' in content or request.FILES:
try:
@ -1017,7 +1017,7 @@ class StatelessNotifyView(View):
except (AttributeError, ValueError):
# could not parse JSON response...
logger.warning(
'SNOTIFY - %s - Invalid JSON Payload provided',
'NOTIFY - %s - Invalid JSON Payload provided',
request.META['REMOTE_ADDR'])
return HttpResponse(
@ -1027,7 +1027,7 @@ class StatelessNotifyView(View):
if not content:
# We could not handle the Content-Type
logger.warning(
'SNOTIFY - %s - Invalid FORM Payload provided',
'NOTIFY - %s - Invalid FORM Payload provided',
request.META['REMOTE_ADDR'])
return HttpResponse(
@ -1045,7 +1045,7 @@ class StatelessNotifyView(View):
not in apprise.NOTIFY_TYPES:
logger.warning(
'SNOTIFY - %s - Payload lacks minimum requirements',
'NOTIFY - %s - Payload lacks minimum requirements',
request.META['REMOTE_ADDR'])
return HttpResponse(
@ -1056,7 +1056,7 @@ class StatelessNotifyView(View):
body_format = content.get('format', apprise.NotifyFormat.TEXT)
if body_format and body_format not in apprise.NOTIFY_FORMATS:
logger.warning(
'SNOTIFY - %s - Format parameter contains an unsupported '
'NOTIFY - %s - Format parameter contains an unsupported '
'value (%s)', request.META['REMOTE_ADDR'], str(body_format))
return HttpResponse(
_('An invalid body input format was specified.'),
@ -1083,7 +1083,7 @@ class StatelessNotifyView(View):
if recursion > settings.APPRISE_RECURSION_MAX:
logger.warning(
'SNOTIFY - %s - Recursion limit reached (%d > %d)',
'NOTIFY - %s - Recursion limit reached (%d > %d)',
request.META['REMOTE_ADDR'], recursion,
settings.APPRISE_RECURSION_MAX)
return HttpResponse(
@ -1095,7 +1095,7 @@ class StatelessNotifyView(View):
except (TypeError, ValueError):
logger.warning(
'SNOTIFY - %s - Invalid recursion value (%s) provided',
'NOTIFY - %s - Invalid recursion value (%s) provided',
request.META['REMOTE_ADDR'], str(recursion))
return HttpResponse(
_('An invalid recursion value was specified.'),
@ -1129,7 +1129,7 @@ class StatelessNotifyView(View):
attach = None
if not content.get('attachment') and 'attachment' in request.POST:
# Acquire attachments to work with them
content['attachment'] = request.POST['attachment']
content['attachment'] = request.POST.getlist('attachment')
if 'attachment' in content or request.FILES:
try:
@ -1210,7 +1210,7 @@ class StatelessNotifyView(View):
status=ResponseCode.failed_dependency)
logger.info(
'SNOTIFY - %s - Delivered Stateless Notification(s)',
'NOTIFY - %s - Delivered Stateless Notification(s)',
request.META['REMOTE_ADDR'])
# Return our retrieved content