apprise/test/test_rest_plugins.py

266 lines
8.7 KiB
Python
Raw Normal View History

2017-12-04 02:48:23 +00:00
# -*- coding: utf-8 -*-
#
2017-12-06 05:35:03 +00:00
# REST Based Plugins - Unit Tests
2017-12-04 02:48:23 +00:00
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
#
# This file is part of apprise.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
from apprise import plugins
from apprise import NotifyType
from apprise import Apprise
import requests
import mock
VALID_URLS = (
##################################
# NotifyJSON
##################################
('json://', {
'instance': None,
}),
2017-12-04 03:28:46 +00:00
('jsons://', {
'instance': None,
}),
2017-12-04 02:48:23 +00:00
('json://localhost', {
'instance': plugins.NotifyJSON,
}),
('json://user:pass@localhost', {
'instance': plugins.NotifyJSON,
}),
('json://localhost:8080', {
'instance': plugins.NotifyJSON,
}),
('json://user:pass@localhost:8080', {
'instance': plugins.NotifyJSON,
}),
('jsons://localhost', {
'instance': plugins.NotifyJSON,
}),
('jsons://user:pass@localhost', {
'instance': plugins.NotifyJSON,
}),
('jsons://localhost:8080/path/', {
'instance': plugins.NotifyJSON,
}),
('jsons://user:pass@localhost:8080', {
'instance': plugins.NotifyJSON,
}),
2017-12-06 05:35:03 +00:00
('json://:@/', {
'instance': None,
}),
2017-12-04 02:48:23 +00:00
('json://user:pass@localhost:8081', {
'instance': plugins.NotifyJSON,
# force a failure
'response': False,
'requests_response_code': 500,
}),
('json://user:pass@localhost:8082', {
'instance': plugins.NotifyJSON,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('json://user:pass@localhost:8083', {
'instance': plugins.NotifyJSON,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
2017-12-04 03:28:46 +00:00
}),
##################################
# NotifyMatterMost
##################################
('mmost://', {
'instance': None,
}),
('mmosts://', {
'instance': None,
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
}),
('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?channel=test', {
'instance': plugins.NotifyMatterMost,
}),
('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
}),
('mmost://localhost:0/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
}),
('mmost://localhost:invalid-port/3ccdd113474722377935511fc85d3dd4', {
'instance': None,
}),
('mmosts://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
}),
('mmosts://localhost', {
'instance': plugins.NotifyMatterMost,
# Thrown because there was no webhook id specified
'exception': TypeError,
}),
('mmost://localhost/bad-web-hook', {
'instance': plugins.NotifyMatterMost,
# Thrown because the webhook is not in a valid format
'exception': TypeError,
}),
2017-12-06 05:35:03 +00:00
('mmost://:@/', {
'instance': None,
}),
2017-12-04 03:28:46 +00:00
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
# force a failure
'response': False,
'requests_response_code': 500,
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMatterMost,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
2017-12-04 02:48:23 +00:00
)
@mock.patch('requests.get')
@mock.patch('requests.post')
2017-12-06 05:35:03 +00:00
def test_rest_plugins(mock_post, mock_get):
2017-12-04 02:48:23 +00:00
"""
2017-12-06 05:35:03 +00:00
API: REST Based Plugins()
2017-12-04 02:48:23 +00:00
"""
# iterate over our dictionary and test it out
for (url, meta) in VALID_URLS:
# Our expected instance
instance = meta.get('instance', None)
# Our expected exception
exception = meta.get('exception', None)
# Our expected server objects
self = meta.get('self', None)
# Our expected Query response (True, False, or exception type)
response = meta.get('response', True)
# Allow us to force the server response code to be something other then
# the defaults
requests_response_code = meta.get(
'requests_response_code', 200 if response else 404)
test_requests_exceptions = meta.get(
'test_requests_exceptions', False)
mock_get.return_value = requests.Request()
mock_post.return_value = requests.Request()
if test_requests_exceptions is False:
# Handle our default response
mock_post.return_value.status_code = requests_response_code
mock_get.return_value.status_code = requests_response_code
mock_post.side_effect = None
mock_get.side_effect = None
else:
# Handle exception testing; first we turn the boolean flag ito
# a list of exceptions
test_requests_exceptions = (
requests.ConnectionError(
0, 'requests.ConnectionError() not handled'),
requests.RequestException(
0, 'requests.RequestException() not handled'),
requests.HTTPError(
0, 'requests.HTTPError() not handled'),
requests.ReadTimeout(
0, 'requests.ReadTimeout() not handled'),
requests.TooManyRedirects(
0, 'requests.TooManyRedirects() not handled'),
)
try:
obj = Apprise.instantiate(url, suppress_exceptions=False)
assert(exception is None)
if obj is None:
# We're done
continue
2017-12-06 05:35:03 +00:00
if instance is None:
# Expected None but didn't get it
print('%s instantiated %s' % (url, str(obj)))
assert(False)
2017-12-04 02:48:23 +00:00
assert(isinstance(obj, instance))
if self:
# Iterate over our expected entries inside of our object
for key, val in self.items():
# Test that our object has the desired key
assert(hasattr(key, obj))
assert(getattr(key, obj) == val)
try:
if test_requests_exceptions is False:
2017-12-06 05:35:03 +00:00
# check that we're as expected
2017-12-04 02:48:23 +00:00
assert obj.notify(
title='test', body='body',
notify_type=NotifyType.INFO) == response
else:
for exception in test_requests_exceptions:
mock_post.side_effect = exception
mock_get.side_effect = exception
try:
assert obj.notify(
title='test', body='body',
notify_type=NotifyType.INFO) is False
except AssertionError:
# Don't mess with these entries
raise
except Exception as e:
# We can't handle this exception type
2017-12-06 05:35:03 +00:00
print('%s / %s' % (url, str(e)))
2017-12-04 02:48:23 +00:00
assert False
except AssertionError:
# Don't mess with these entries
2017-12-06 05:35:03 +00:00
print('%s AssertionError' % url)
2017-12-04 02:48:23 +00:00
raise
except Exception as e:
# Check that we were expecting this exception to happen
assert isinstance(e, response)
except AssertionError:
# Don't mess with these entries
2017-12-06 05:35:03 +00:00
print('%s / %s' % (url, str(e)))
2017-12-04 02:48:23 +00:00
raise
except Exception as e:
# Handle our exception
2017-12-06 05:35:03 +00:00
print('%s / %s' % (url, str(e)))
2017-12-04 02:48:23 +00:00
assert(exception is not None)
assert(isinstance(e, exception))