mirror of
https://github.com/caronc/apprise.git
synced 2025-02-18 11:11:07 +01:00
more tests 70% coverage now!
This commit is contained in:
parent
5a7a8a624a
commit
f8c3d35f8c
@ -268,20 +268,11 @@ class NotifyBoxcar(NotifyBase):
|
|||||||
access = results['host']
|
access = results['host']
|
||||||
|
|
||||||
# Now fetch the remaining tokens
|
# Now fetch the remaining tokens
|
||||||
try:
|
secret = NotifyBase.split_path(results['fullpath'])[0]
|
||||||
secret = NotifyBase.split_path(results['fullpath'])[0]
|
|
||||||
|
|
||||||
except (AttributeError, IndexError):
|
# Our recipients
|
||||||
# Force a bad value that will get caught in parsing later
|
recipients = ','.join(
|
||||||
secret = None
|
NotifyBase.split_path(results['fullpath'])[1:])
|
||||||
|
|
||||||
try:
|
|
||||||
recipients = ','.join(
|
|
||||||
NotifyBase.split_path(results['fullpath'])[1:])
|
|
||||||
|
|
||||||
except (AttributeError, IndexError):
|
|
||||||
# Default to not having any recipients
|
|
||||||
recipients = None
|
|
||||||
|
|
||||||
if not (access and secret):
|
if not (access and secret):
|
||||||
# If we did not recive an access and/or secret code
|
# If we did not recive an access and/or secret code
|
||||||
|
@ -88,7 +88,7 @@ class NotifyFaast(NotifyBase):
|
|||||||
HTTP_ERROR_MAP[r.status_code],
|
HTTP_ERROR_MAP[r.status_code],
|
||||||
r.status_code))
|
r.status_code))
|
||||||
|
|
||||||
except IndexError:
|
except KeyError:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'Failed to send Faast notification '
|
'Failed to send Faast notification '
|
||||||
'(error=%s).' % (
|
'(error=%s).' % (
|
||||||
@ -96,10 +96,11 @@ class NotifyFaast(NotifyBase):
|
|||||||
|
|
||||||
# Return; we're done
|
# Return; we're done
|
||||||
return False
|
return False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.logger.info('Sent Faast notification.')
|
self.logger.info('Sent Faast notification.')
|
||||||
|
|
||||||
except requests.ConnectionError as e:
|
except requests.RequestException as e:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'A Connection error occured sending Faast notification.',
|
'A Connection error occured sending Faast notification.',
|
||||||
)
|
)
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from .gntp.notifier import GrowlNotifier
|
from .gntp import notifier
|
||||||
from .gntp.errors import NetworkError as GrowlNetworkError
|
from .gntp import errors
|
||||||
from .gntp.errors import AuthError as GrowlAuthenticationError
|
|
||||||
|
|
||||||
from ..NotifyBase import NotifyBase
|
from ..NotifyBase import NotifyBase
|
||||||
from ...common import NotifyImageSize
|
from ...common import NotifyImageSize
|
||||||
|
|
||||||
@ -31,7 +29,7 @@ GROWL_IMAGE_XY = NotifyImageSize.XY_72
|
|||||||
|
|
||||||
# Priorities
|
# Priorities
|
||||||
class GrowlPriority(object):
|
class GrowlPriority(object):
|
||||||
VERY_LOW = -2
|
LOW = -2
|
||||||
MODERATE = -1
|
MODERATE = -1
|
||||||
NORMAL = 0
|
NORMAL = 0
|
||||||
HIGH = 1
|
HIGH = 1
|
||||||
@ -39,7 +37,7 @@ class GrowlPriority(object):
|
|||||||
|
|
||||||
|
|
||||||
GROWL_PRIORITIES = (
|
GROWL_PRIORITIES = (
|
||||||
GrowlPriority.VERY_LOW,
|
GrowlPriority.LOW,
|
||||||
GrowlPriority.MODERATE,
|
GrowlPriority.MODERATE,
|
||||||
GrowlPriority.NORMAL,
|
GrowlPriority.NORMAL,
|
||||||
GrowlPriority.HIGH,
|
GrowlPriority.HIGH,
|
||||||
@ -61,7 +59,7 @@ class NotifyGrowl(NotifyBase):
|
|||||||
# Default Growl Port
|
# Default Growl Port
|
||||||
default_port = 23053
|
default_port = 23053
|
||||||
|
|
||||||
def __init__(self, priority=GrowlPriority.NORMAL, version=2, **kwargs):
|
def __init__(self, priority=None, version=2, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialize Growl Object
|
Initialize Growl Object
|
||||||
"""
|
"""
|
||||||
@ -69,9 +67,6 @@ class NotifyGrowl(NotifyBase):
|
|||||||
title_maxlen=250, body_maxlen=32768,
|
title_maxlen=250, body_maxlen=32768,
|
||||||
image_size=GROWL_IMAGE_XY, **kwargs)
|
image_size=GROWL_IMAGE_XY, **kwargs)
|
||||||
|
|
||||||
# A Global flag that tracks registration
|
|
||||||
self.is_registered = False
|
|
||||||
|
|
||||||
if not self.port:
|
if not self.port:
|
||||||
self.port = self.default_port
|
self.port = self.default_port
|
||||||
|
|
||||||
@ -100,27 +95,37 @@ class NotifyGrowl(NotifyBase):
|
|||||||
payload['password'] = self.password
|
payload['password'] = self.password
|
||||||
|
|
||||||
self.logger.debug('Growl Registration Payload: %s' % str(payload))
|
self.logger.debug('Growl Registration Payload: %s' % str(payload))
|
||||||
self.growl = GrowlNotifier(**payload)
|
self.growl = notifier.GrowlNotifier(**payload)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.growl.register()
|
self.growl.register()
|
||||||
# Toggle our flag
|
|
||||||
self.is_registered = True
|
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
'Growl server registration completed successfully.'
|
'Growl server registration completed successfully.'
|
||||||
)
|
)
|
||||||
|
|
||||||
except GrowlNetworkError:
|
except errors.NetworkError:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'A network error occured sending Growl '
|
'A network error occured sending Growl '
|
||||||
'notification to %s.' % self.host)
|
'notification to %s.' % self.host)
|
||||||
return
|
raise TypeError(
|
||||||
|
'A network error occured sending Growl '
|
||||||
|
'notification to %s.' % self.host)
|
||||||
|
|
||||||
except GrowlAuthenticationError:
|
except errors.AuthError:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'An authentication error occured sending Growl '
|
'An authentication error occured sending Growl '
|
||||||
'notification to %s.' % self.host)
|
'notification to %s.' % self.host)
|
||||||
return
|
raise TypeError(
|
||||||
|
'An authentication error occured sending Growl '
|
||||||
|
'notification to %s.' % self.host)
|
||||||
|
|
||||||
|
except errors.UnsupportedError:
|
||||||
|
self.logger.warning(
|
||||||
|
'An unsupported error occured sending Growl '
|
||||||
|
'notification to %s.' % self.host)
|
||||||
|
raise TypeError(
|
||||||
|
'An unsupported error occured sending Growl '
|
||||||
|
'notification to %s.' % self.host)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -129,10 +134,6 @@ class NotifyGrowl(NotifyBase):
|
|||||||
Perform Growl Notification
|
Perform Growl Notification
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self.is_registered:
|
|
||||||
# We can't do anything
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Limit results to just the first 2 line otherwise there is just to
|
# Limit results to just the first 2 line otherwise there is just to
|
||||||
# much content to display
|
# much content to display
|
||||||
body = re.split('[\r\n]+', body)
|
body = re.split('[\r\n]+', body)
|
||||||
@ -158,7 +159,9 @@ class NotifyGrowl(NotifyBase):
|
|||||||
}
|
}
|
||||||
self.logger.debug('Growl Payload: %s' % str(payload))
|
self.logger.debug('Growl Payload: %s' % str(payload))
|
||||||
|
|
||||||
# Update icon of payload to be raw data
|
# Update icon of payload to be raw data; this is intentionally done
|
||||||
|
# here after we spit the debug message above (so we don't try to
|
||||||
|
# print the binary contents of an image
|
||||||
payload['icon'] = icon
|
payload['icon'] = icon
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -174,7 +177,7 @@ class NotifyGrowl(NotifyBase):
|
|||||||
'Growl notification sent successfully.'
|
'Growl notification sent successfully.'
|
||||||
)
|
)
|
||||||
|
|
||||||
except GrowlNetworkError as e:
|
except errors.BaseError as e:
|
||||||
# Since Growl servers listen for UDP broadcasts, it's possible
|
# Since Growl servers listen for UDP broadcasts, it's possible
|
||||||
# that you will never get to this part of the code since there is
|
# that you will never get to this part of the code since there is
|
||||||
# no acknowledgement as to whether it accepted what was sent to it
|
# no acknowledgement as to whether it accepted what was sent to it
|
||||||
@ -221,13 +224,35 @@ class NotifyGrowl(NotifyBase):
|
|||||||
)
|
)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if 'priority' in results['qsd'] and len(results['qsd']['priority']):
|
||||||
|
_map = {
|
||||||
|
'l': GrowlPriority.LOW,
|
||||||
|
'-2': GrowlPriority.LOW,
|
||||||
|
'm': GrowlPriority.MODERATE,
|
||||||
|
'-1': GrowlPriority.MODERATE,
|
||||||
|
'n': GrowlPriority.NORMAL,
|
||||||
|
'0': GrowlPriority.NORMAL,
|
||||||
|
'h': GrowlPriority.HIGH,
|
||||||
|
'1': GrowlPriority.HIGH,
|
||||||
|
'e': GrowlPriority.EMERGENCY,
|
||||||
|
'2': GrowlPriority.EMERGENCY,
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
results['priority'] = \
|
||||||
|
_map[results['qsd']['priority'][0].lower()]
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
# No priority was set
|
||||||
|
pass
|
||||||
|
|
||||||
# Because of the URL formatting, the password is actually where the
|
# Because of the URL formatting, the password is actually where the
|
||||||
# username field is. For this reason, we just preform this small hack
|
# username field is. For this reason, we just preform this small hack
|
||||||
# to make it (the URL) conform correctly. The following strips out the
|
# to make it (the URL) conform correctly. The following strips out the
|
||||||
# existing password entry (if exists) so that it can be swapped with
|
# existing password entry (if exists) so that it can be swapped with
|
||||||
# the new one we specify.
|
# the new one we specify.
|
||||||
results['user'] = None
|
if results.get('password', None) is None:
|
||||||
results['password'] = results.get('user', None)
|
results['password'] = results.get('user', None)
|
||||||
|
|
||||||
if version:
|
if version:
|
||||||
results['version'] = version
|
results['version'] = version
|
||||||
|
|
||||||
|
@ -92,9 +92,9 @@ class NotifyJoin(NotifyBase):
|
|||||||
self.apikey = apikey.strip()
|
self.apikey = apikey.strip()
|
||||||
|
|
||||||
if compat_is_basestring(devices):
|
if compat_is_basestring(devices):
|
||||||
self.devices = filter(bool, DEVICE_LIST_DELIM.split(
|
self.devices = [x for x in filter(bool, DEVICE_LIST_DELIM.split(
|
||||||
devices,
|
devices,
|
||||||
))
|
))]
|
||||||
|
|
||||||
elif isinstance(devices, (set, tuple, list)):
|
elif isinstance(devices, (set, tuple, list)):
|
||||||
self.devices = devices
|
self.devices = devices
|
||||||
@ -103,19 +103,24 @@ class NotifyJoin(NotifyBase):
|
|||||||
self.devices = list()
|
self.devices = list()
|
||||||
|
|
||||||
if len(self.devices) == 0:
|
if len(self.devices) == 0:
|
||||||
self.logger.warning('No device(s) were specified.')
|
# Default to everyone
|
||||||
raise TypeError('No device(s) were specified.')
|
self.devices.append('group.all')
|
||||||
|
|
||||||
def notify(self, title, body, notify_type, **kwargs):
|
def notify(self, title, body, notify_type, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform Join Notification
|
Perform Join Notification
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Limit results to just the first 2 line otherwise
|
try:
|
||||||
# there is just to much content to display
|
# Limit results to just the first 2 line otherwise
|
||||||
body = re.split('[\r\n]+', body)
|
# there is just to much content to display
|
||||||
body[0] = body[0].strip('#').strip()
|
body = re.split('[\r\n]+', body)
|
||||||
body = '\r\n'.join(body[0:2])
|
body[0] = body[0].strip('#').strip()
|
||||||
|
body = '\r\n'.join(body[0:2])
|
||||||
|
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
# body was None or not of a type string
|
||||||
|
body = ''
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': self.app_id,
|
'User-Agent': self.app_id,
|
||||||
@ -123,7 +128,7 @@ class NotifyJoin(NotifyBase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# error tracking (used for function return)
|
# error tracking (used for function return)
|
||||||
has_error = False
|
return_status = True
|
||||||
|
|
||||||
# Create a copy of the devices list
|
# Create a copy of the devices list
|
||||||
devices = list(self.devices)
|
devices = list(self.devices)
|
||||||
@ -135,7 +140,7 @@ class NotifyJoin(NotifyBase):
|
|||||||
|
|
||||||
elif not IS_DEVICE_RE.match(device):
|
elif not IS_DEVICE_RE.match(device):
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
"The specified device '%s' is invalid; skipping." % (
|
"The specified device/group '%s' is invalid; skipping." % (
|
||||||
device,
|
device,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -180,7 +185,7 @@ class NotifyJoin(NotifyBase):
|
|||||||
JOIN_HTTP_ERROR_MAP[r.status_code],
|
JOIN_HTTP_ERROR_MAP[r.status_code],
|
||||||
r.status_code))
|
r.status_code))
|
||||||
|
|
||||||
except IndexError:
|
except KeyError:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'Failed to send Join:%s '
|
'Failed to send Join:%s '
|
||||||
'notification (error=%s).' % (
|
'notification (error=%s).' % (
|
||||||
@ -189,22 +194,21 @@ class NotifyJoin(NotifyBase):
|
|||||||
|
|
||||||
# self.logger.debug('Response Details: %s' % r.raw.read())
|
# self.logger.debug('Response Details: %s' % r.raw.read())
|
||||||
|
|
||||||
# Return; we're done
|
return_status = False
|
||||||
has_error = True
|
|
||||||
|
|
||||||
except requests.ConnectionError as e:
|
except requests.RequestException as e:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'A Connection error occured sending Join:%s '
|
'A Connection error occured sending Join:%s '
|
||||||
'notification.' % device
|
'notification.' % device
|
||||||
)
|
)
|
||||||
self.logger.debug('Socket Exception: %s' % str(e))
|
self.logger.debug('Socket Exception: %s' % str(e))
|
||||||
has_error = True
|
return_status = False
|
||||||
|
|
||||||
if len(devices):
|
if len(devices):
|
||||||
# Prevent thrashing requests
|
# Prevent thrashing requests
|
||||||
self.throttle()
|
self.throttle()
|
||||||
|
|
||||||
return has_error
|
return return_status
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_url(url):
|
def parse_url(url):
|
||||||
@ -220,14 +224,8 @@ class NotifyJoin(NotifyBase):
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
# Apply our settings now
|
# Apply our settings now
|
||||||
try:
|
devices = ' '.join(
|
||||||
devices = ' '.join(
|
filter(bool, NotifyBase.split_path(results['fullpath'])))
|
||||||
filter(bool, NotifyBase.split_path(results['fullpath'])))
|
|
||||||
|
|
||||||
except (AttributeError, IndexError):
|
|
||||||
# Force some bad values that will get caught
|
|
||||||
# in parsing later
|
|
||||||
devices = None
|
|
||||||
|
|
||||||
results['apikey'] = results['host']
|
results['apikey'] = results['host']
|
||||||
results['devices'] = devices
|
results['devices'] = devices
|
||||||
|
@ -176,13 +176,7 @@ class NotifyMatterMost(NotifyBase):
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
# Apply our settings now
|
# Apply our settings now
|
||||||
try:
|
authtoken = NotifyBase.split_path(results['fullpath'])[0]
|
||||||
authtoken = NotifyBase.split_path(results['fullpath'])[0]
|
|
||||||
|
|
||||||
except (AttributeError, IndexError):
|
|
||||||
# Force some bad values that will get caught
|
|
||||||
# in parsing later
|
|
||||||
authtoken = None
|
|
||||||
|
|
||||||
channel = None
|
channel = None
|
||||||
if 'channel' in results['qsd'] and len(results['qsd']['channel']):
|
if 'channel' in results['qsd'] and len(results['qsd']['channel']):
|
||||||
|
@ -37,7 +37,7 @@ VALIDATE_APIKEY = re.compile(r'[A-Za-z0-9]{48}')
|
|||||||
|
|
||||||
# Priorities
|
# Priorities
|
||||||
class NotifyMyAndroidPriority(object):
|
class NotifyMyAndroidPriority(object):
|
||||||
VERY_LOW = -2
|
LOW = -2
|
||||||
MODERATE = -1
|
MODERATE = -1
|
||||||
NORMAL = 0
|
NORMAL = 0
|
||||||
HIGH = 1
|
HIGH = 1
|
||||||
@ -45,7 +45,7 @@ class NotifyMyAndroidPriority(object):
|
|||||||
|
|
||||||
|
|
||||||
NMA_PRIORITIES = (
|
NMA_PRIORITIES = (
|
||||||
NotifyMyAndroidPriority.VERY_LOW,
|
NotifyMyAndroidPriority.LOW,
|
||||||
NotifyMyAndroidPriority.MODERATE,
|
NotifyMyAndroidPriority.MODERATE,
|
||||||
NotifyMyAndroidPriority.NORMAL,
|
NotifyMyAndroidPriority.NORMAL,
|
||||||
NotifyMyAndroidPriority.HIGH,
|
NotifyMyAndroidPriority.HIGH,
|
||||||
@ -64,8 +64,7 @@ class NotifyMyAndroid(NotifyBase):
|
|||||||
# Notify My Android uses the http protocol with JSON requests
|
# Notify My Android uses the http protocol with JSON requests
|
||||||
notify_url = 'https://www.notifymyandroid.com/publicapi/notify'
|
notify_url = 'https://www.notifymyandroid.com/publicapi/notify'
|
||||||
|
|
||||||
def __init__(self, apikey, priority=NotifyMyAndroidPriority.NORMAL,
|
def __init__(self, apikey, priority=None, devapikey=None, **kwargs):
|
||||||
devapikey=None, **kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize Notify My Android Object
|
Initialize Notify My Android Object
|
||||||
"""
|
"""
|
||||||
@ -143,7 +142,7 @@ class NotifyMyAndroid(NotifyBase):
|
|||||||
NMA_HTTP_ERROR_MAP[r.status_code],
|
NMA_HTTP_ERROR_MAP[r.status_code],
|
||||||
r.status_code))
|
r.status_code))
|
||||||
|
|
||||||
except IndexError:
|
except KeyError:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'Failed to send NMA notification (error=%s).' % (
|
'Failed to send NMA notification (error=%s).' % (
|
||||||
r.status_code))
|
r.status_code))
|
||||||
@ -152,10 +151,10 @@ class NotifyMyAndroid(NotifyBase):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.logger.debug('NMA Server Response: %s.' % r.text)
|
self.logger.debug('NMA Server Response: %s.' % r.raw.read())
|
||||||
self.logger.info('Sent NMA notification.')
|
self.logger.info('Sent NMA notification.')
|
||||||
|
|
||||||
except requests.ConnectionError as e:
|
except requests.RequestException as e:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'A Connection error occured sending NMA notification.'
|
'A Connection error occured sending NMA notification.'
|
||||||
)
|
)
|
||||||
@ -192,6 +191,32 @@ class NotifyMyAndroid(NotifyBase):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if 'priority' in results['qsd'] and len(results['qsd']['priority']):
|
||||||
|
_map = {
|
||||||
|
'l': NotifyMyAndroidPriority.LOW,
|
||||||
|
'-2': NotifyMyAndroidPriority.LOW,
|
||||||
|
'm': NotifyMyAndroidPriority.MODERATE,
|
||||||
|
'-1': NotifyMyAndroidPriority.MODERATE,
|
||||||
|
'n': NotifyMyAndroidPriority.NORMAL,
|
||||||
|
'0': NotifyMyAndroidPriority.NORMAL,
|
||||||
|
'h': NotifyMyAndroidPriority.HIGH,
|
||||||
|
'1': NotifyMyAndroidPriority.HIGH,
|
||||||
|
'e': NotifyMyAndroidPriority.EMERGENCY,
|
||||||
|
'2': NotifyMyAndroidPriority.EMERGENCY,
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
results['priority'] = \
|
||||||
|
_map[results['qsd']['priority'][0].lower()]
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
# No priority was set
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Now fetch devapi if specified
|
||||||
|
devapi = NotifyBase.split_path(results['fullpath'])[0]
|
||||||
|
if devapi:
|
||||||
|
results['devapikey'] = devapi
|
||||||
|
|
||||||
results['apikey'] = results['host']
|
results['apikey'] = results['host']
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
@ -23,7 +23,8 @@ from . import NotifyEmail as NotifyEmailBase
|
|||||||
from .NotifyBoxcar import NotifyBoxcar
|
from .NotifyBoxcar import NotifyBoxcar
|
||||||
from .NotifyEmail import NotifyEmail
|
from .NotifyEmail import NotifyEmail
|
||||||
from .NotifyFaast import NotifyFaast
|
from .NotifyFaast import NotifyFaast
|
||||||
from .NotifyGrowl import NotifyGrowl
|
from .NotifyGrowl.NotifyGrowl import NotifyGrowl
|
||||||
|
from .NotifyGrowl import gntp
|
||||||
from .NotifyJSON import NotifyJSON
|
from .NotifyJSON import NotifyJSON
|
||||||
from .NotifyMyAndroid import NotifyMyAndroid
|
from .NotifyMyAndroid import NotifyMyAndroid
|
||||||
from .NotifyProwl import NotifyProwl
|
from .NotifyProwl import NotifyProwl
|
||||||
@ -32,14 +33,14 @@ from .NotifyPushBullet import NotifyPushBullet
|
|||||||
from .NotifyPushover import NotifyPushover
|
from .NotifyPushover import NotifyPushover
|
||||||
from .NotifyRocketChat import NotifyRocketChat
|
from .NotifyRocketChat import NotifyRocketChat
|
||||||
from .NotifyToasty import NotifyToasty
|
from .NotifyToasty import NotifyToasty
|
||||||
from .NotifyTwitter import NotifyTwitter
|
from .NotifyTwitter.NotifyTwitter import NotifyTwitter
|
||||||
from .NotifyXBMC import NotifyXBMC
|
from .NotifyXBMC import NotifyXBMC
|
||||||
from .NotifyXML import NotifyXML
|
from .NotifyXML import NotifyXML
|
||||||
from .NotifySlack import NotifySlack
|
from .NotifySlack import NotifySlack
|
||||||
from .NotifyJoin import NotifyJoin
|
from .NotifyJoin import NotifyJoin
|
||||||
from .NotifyTelegram import NotifyTelegram
|
from .NotifyTelegram import NotifyTelegram
|
||||||
from .NotifyMatterMost import NotifyMatterMost
|
from .NotifyMatterMost import NotifyMatterMost
|
||||||
from .NotifyPushjet import NotifyPushjet
|
from .NotifyPushjet.NotifyPushjet import NotifyPushjet
|
||||||
|
|
||||||
from ..common import NotifyImageSize
|
from ..common import NotifyImageSize
|
||||||
from ..common import NOTIFY_IMAGE_SIZES
|
from ..common import NOTIFY_IMAGE_SIZES
|
||||||
@ -59,4 +60,7 @@ __all__ = [
|
|||||||
|
|
||||||
# NotifyEmail Base References (used for Testing)
|
# NotifyEmail Base References (used for Testing)
|
||||||
'NotifyEmailBase',
|
'NotifyEmailBase',
|
||||||
|
|
||||||
|
# gntp (used for Testing)
|
||||||
|
'gntp',
|
||||||
]
|
]
|
||||||
|
@ -24,7 +24,7 @@ import mock
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
VALID_URLS = (
|
TEST_URLS = (
|
||||||
##################################
|
##################################
|
||||||
# NotifyEmail
|
# NotifyEmail
|
||||||
##################################
|
##################################
|
||||||
@ -138,7 +138,7 @@ def test_email_plugin(mock_smtp):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# iterate over our dictionary and test it out
|
# iterate over our dictionary and test it out
|
||||||
for (url, meta) in VALID_URLS:
|
for (url, meta) in TEST_URLS:
|
||||||
|
|
||||||
# Our expected instance
|
# Our expected instance
|
||||||
instance = meta.get('instance', None)
|
instance = meta.get('instance', None)
|
||||||
@ -152,11 +152,6 @@ def test_email_plugin(mock_smtp):
|
|||||||
# Our expected Query response (True, False, or exception type)
|
# Our expected Query response (True, False, or exception type)
|
||||||
response = meta.get('response', True)
|
response = meta.get('response', True)
|
||||||
|
|
||||||
# Allow us to force the server response code to be something other then
|
|
||||||
# the defaults
|
|
||||||
smtplib_response_code = meta.get(
|
|
||||||
'smtplib_response_code', 200 if response else 404)
|
|
||||||
|
|
||||||
test_smtplib_exceptions = meta.get(
|
test_smtplib_exceptions = meta.get(
|
||||||
'test_smtplib_exceptions', False)
|
'test_smtplib_exceptions', False)
|
||||||
|
|
||||||
@ -168,16 +163,7 @@ def test_email_plugin(mock_smtp):
|
|||||||
# Create a mock SMTP Object
|
# Create a mock SMTP Object
|
||||||
mock_smtp.return_value = mock_socket
|
mock_smtp.return_value = mock_socket
|
||||||
|
|
||||||
if test_smtplib_exceptions is False:
|
if test_smtplib_exceptions:
|
||||||
pass
|
|
||||||
# Handle our default response
|
|
||||||
mock_socket.sendmail.return_value = smtplib_response_code
|
|
||||||
# mock_post.return_value.status_code = smtplib_response_code
|
|
||||||
# mock_get.return_value.status_code = smtplib_response_code
|
|
||||||
# mock_post.side_effect = None
|
|
||||||
# mock_get.side_effect = None
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Handle exception testing; first we turn the boolean flag ito
|
# Handle exception testing; first we turn the boolean flag ito
|
||||||
# a list of exceptions
|
# a list of exceptions
|
||||||
test_smtplib_exceptions = (
|
test_smtplib_exceptions = (
|
||||||
|
265
test/test_growl_plugin.py
Normal file
265
test/test_growl_plugin.py
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# NotifyGrowl - Unit Tests
|
||||||
|
#
|
||||||
|
# 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 mock
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
TEST_URLS = (
|
||||||
|
##################################
|
||||||
|
# NotifyGrowl
|
||||||
|
##################################
|
||||||
|
('growl://', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
('growl://:@/', {
|
||||||
|
'instance': None
|
||||||
|
}),
|
||||||
|
|
||||||
|
('growl://pass@growl.server', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://ignored:pass@growl.server', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://growl.server', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
}),
|
||||||
|
('growl://growl.server?version=1', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
# Force a failure
|
||||||
|
('growl://growl.server?version=1', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
'growl_response': None,
|
||||||
|
}),
|
||||||
|
('growl://growl.server?version=2', {
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://growl.server?version=2', {
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
'growl_response': None,
|
||||||
|
}),
|
||||||
|
|
||||||
|
# Priorities
|
||||||
|
('growl://pass@growl.server?priority=low', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://pass@growl.server?priority=moderate', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://pass@growl.server?priority=normal', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://pass@growl.server?priority=high', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://pass@growl.server?priority=emergency', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
|
||||||
|
# Invalid Priorities
|
||||||
|
('growl://pass@growl.server?priority=invalid', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://pass@growl.server?priority=', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
|
||||||
|
# invalid version
|
||||||
|
('growl://growl.server?version=', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://growl.server?version=crap', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
|
||||||
|
# Ports
|
||||||
|
('growl://growl.changeport:2000', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://growl.garbageport:garbage', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
('growl://growl.colon:', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
}),
|
||||||
|
# Exceptions
|
||||||
|
('growl://growl.exceptions01', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
|
# is set and tests that we gracfully handle them
|
||||||
|
'test_growl_notify_exceptions': True,
|
||||||
|
}),
|
||||||
|
('growl://growl.exceptions02', {
|
||||||
|
'instance': plugins.NotifyGrowl,
|
||||||
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
|
# is set and tests that we gracfully handle them
|
||||||
|
'test_growl_register_exceptions': True,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('apprise.plugins.gntp.notifier.GrowlNotifier')
|
||||||
|
def test_growl_plugin(mock_gntp):
|
||||||
|
"""
|
||||||
|
API: NotifyGrowl Plugin()
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# iterate over our dictionary and test it out
|
||||||
|
for (url, meta) in TEST_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
|
||||||
|
growl_response = meta.get(
|
||||||
|
'growl_response', True if response else False)
|
||||||
|
|
||||||
|
test_growl_notify_exceptions = meta.get(
|
||||||
|
'test_growl_notify_exceptions', False)
|
||||||
|
|
||||||
|
test_growl_register_exceptions = meta.get(
|
||||||
|
'test_growl_register_exceptions', False)
|
||||||
|
|
||||||
|
mock_notifier = mock.Mock()
|
||||||
|
mock_gntp.return_value = mock_notifier
|
||||||
|
|
||||||
|
test_growl_exceptions = (
|
||||||
|
plugins.gntp.errors.NetworkError(
|
||||||
|
0, 'gntp.ParseError() not handled'),
|
||||||
|
plugins.gntp.errors.AuthError(
|
||||||
|
0, 'gntp.AuthError() not handled'),
|
||||||
|
plugins.gntp.errors.UnsupportedError(
|
||||||
|
'gntp.UnsupportedError() not handled'),
|
||||||
|
)
|
||||||
|
|
||||||
|
if test_growl_notify_exceptions is True:
|
||||||
|
# Store oure exceptions
|
||||||
|
test_growl_notify_exceptions = test_growl_exceptions
|
||||||
|
|
||||||
|
elif test_growl_register_exceptions is True:
|
||||||
|
# Store oure exceptions
|
||||||
|
test_growl_register_exceptions = test_growl_exceptions
|
||||||
|
|
||||||
|
for exception in test_growl_register_exceptions:
|
||||||
|
mock_notifier.register.side_effect = exception
|
||||||
|
try:
|
||||||
|
obj = Apprise.instantiate(url, suppress_exceptions=False)
|
||||||
|
|
||||||
|
except TypeError:
|
||||||
|
# This is the response we expect
|
||||||
|
assert True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# We can't handle this exception type
|
||||||
|
print('%s / %s' % (url, str(e)))
|
||||||
|
assert False
|
||||||
|
|
||||||
|
# We're done this part of the test
|
||||||
|
continue
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Store our response
|
||||||
|
mock_notifier.notify.return_value = growl_response
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj = Apprise.instantiate(url, suppress_exceptions=False)
|
||||||
|
|
||||||
|
assert(exception is None)
|
||||||
|
|
||||||
|
if obj is None:
|
||||||
|
# We're done
|
||||||
|
continue
|
||||||
|
|
||||||
|
if instance is None:
|
||||||
|
# Expected None but didn't get it
|
||||||
|
print('%s instantiated %s' % (url, str(obj)))
|
||||||
|
assert(False)
|
||||||
|
|
||||||
|
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_growl_notify_exceptions is False:
|
||||||
|
# check that we're as expected
|
||||||
|
assert obj.notify(
|
||||||
|
title='test', body='body',
|
||||||
|
notify_type=NotifyType.INFO) == response
|
||||||
|
|
||||||
|
else:
|
||||||
|
for exception in test_growl_notify_exceptions:
|
||||||
|
mock_notifier.notify.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
|
||||||
|
print('%s / %s' % (url, str(e)))
|
||||||
|
assert False
|
||||||
|
|
||||||
|
except AssertionError:
|
||||||
|
# Don't mess with these entries
|
||||||
|
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
|
||||||
|
print('%s AssertionError' % url)
|
||||||
|
raise
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Handle our exception
|
||||||
|
print('%s / %s' % (url, str(e)))
|
||||||
|
assert(exception is not None)
|
||||||
|
assert(isinstance(e, exception))
|
@ -111,6 +111,12 @@ def test_notify_base():
|
|||||||
# Test is_hostname
|
# Test is_hostname
|
||||||
assert NotifyBase.is_hostname('example.com') is True
|
assert NotifyBase.is_hostname('example.com') is True
|
||||||
|
|
||||||
|
# Test quote
|
||||||
|
assert NotifyBase.unquote('%20') == ' '
|
||||||
|
assert NotifyBase.quote(' ') == '%20'
|
||||||
|
assert NotifyBase.unquote(None) == ''
|
||||||
|
assert NotifyBase.quote(None) == ''
|
||||||
|
|
||||||
|
|
||||||
def test_notify_base_urls():
|
def test_notify_base_urls():
|
||||||
"""
|
"""
|
||||||
|
@ -87,6 +87,103 @@ TEST_URLS = (
|
|||||||
'test_requests_exceptions': True,
|
'test_requests_exceptions': True,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
##################################
|
||||||
|
# NotifyFaast
|
||||||
|
##################################
|
||||||
|
('faast://', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
# Auth Token specified
|
||||||
|
('faast://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyFaast,
|
||||||
|
}),
|
||||||
|
('faast://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyFaast,
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
}),
|
||||||
|
('faast://:@/', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
('faast://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyFaast,
|
||||||
|
# force a failure
|
||||||
|
'response': False,
|
||||||
|
'requests_response_code': requests.codes.internal_server_error,
|
||||||
|
}),
|
||||||
|
('faast://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyFaast,
|
||||||
|
# throw a bizzare code forcing us to fail to look it up
|
||||||
|
'response': False,
|
||||||
|
'requests_response_code': 999,
|
||||||
|
}),
|
||||||
|
('faast://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyFaast,
|
||||||
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
|
# is set and tests that we gracfully handle them
|
||||||
|
'test_requests_exceptions': True,
|
||||||
|
}),
|
||||||
|
|
||||||
|
##################################
|
||||||
|
# NotifyJoin
|
||||||
|
##################################
|
||||||
|
('join://', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
# APIkey; no device
|
||||||
|
('join://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
}),
|
||||||
|
# Invalid APIKey
|
||||||
|
('join://%s' % ('a' * 24), {
|
||||||
|
'instance': None,
|
||||||
|
# Missing a channel
|
||||||
|
'exception': TypeError,
|
||||||
|
}),
|
||||||
|
# APIKey + device
|
||||||
|
('join://%s/%s' % ('a' * 32, 'd' * 32), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
}),
|
||||||
|
# APIKey + 2 devices
|
||||||
|
('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'e' * 32), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
}),
|
||||||
|
# APIKey + 1 device and 1 group
|
||||||
|
('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'group.chrome'), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
}),
|
||||||
|
# APIKey + bad device
|
||||||
|
('join://%s/%s' % ('a' * 32, 'd' * 10), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
}),
|
||||||
|
# APIKey + bad url
|
||||||
|
('join://:@/', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
('join://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
# force a failure
|
||||||
|
'response': False,
|
||||||
|
'requests_response_code': requests.codes.internal_server_error,
|
||||||
|
}),
|
||||||
|
('join://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
# throw a bizzare code forcing us to fail to look it up
|
||||||
|
'response': False,
|
||||||
|
'requests_response_code': 999,
|
||||||
|
}),
|
||||||
|
# apikey = a
|
||||||
|
('join://%s' % ('a' * 32), {
|
||||||
|
'instance': plugins.NotifyJoin,
|
||||||
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
|
# is set and tests that we gracfully handle them
|
||||||
|
'test_requests_exceptions': True,
|
||||||
|
}),
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
# NotifyJSON
|
# NotifyJSON
|
||||||
##################################
|
##################################
|
||||||
@ -271,6 +368,56 @@ TEST_URLS = (
|
|||||||
'test_requests_exceptions': True,
|
'test_requests_exceptions': True,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
##################################
|
||||||
|
# NotifyMyAndroid
|
||||||
|
##################################
|
||||||
|
('nma://', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
# APIkey; no device
|
||||||
|
('nma://%s' % ('a' * 48), {
|
||||||
|
'instance': plugins.NotifyMyAndroid,
|
||||||
|
}),
|
||||||
|
# Invalid APIKey
|
||||||
|
('nma://%s' % ('a' * 24), {
|
||||||
|
'instance': None,
|
||||||
|
# Missing a channel
|
||||||
|
'exception': TypeError,
|
||||||
|
}),
|
||||||
|
# APIKey
|
||||||
|
('nma://%s' % ('a' * 48), {
|
||||||
|
'instance': plugins.NotifyMyAndroid,
|
||||||
|
# don't include an image by default
|
||||||
|
'include_image': False,
|
||||||
|
}),
|
||||||
|
# APIKey + with image
|
||||||
|
('nma://%s' % ('a' * 48), {
|
||||||
|
'instance': plugins.NotifyMyAndroid,
|
||||||
|
}),
|
||||||
|
# bad url
|
||||||
|
('nma://:@/', {
|
||||||
|
'instance': None,
|
||||||
|
}),
|
||||||
|
('nma://%s' % ('a' * 48), {
|
||||||
|
'instance': plugins.NotifyMyAndroid,
|
||||||
|
# force a failure
|
||||||
|
'response': False,
|
||||||
|
'requests_response_code': requests.codes.internal_server_error,
|
||||||
|
}),
|
||||||
|
('nma://%s' % ('a' * 48), {
|
||||||
|
'instance': plugins.NotifyMyAndroid,
|
||||||
|
# throw a bizzare code forcing us to fail to look it up
|
||||||
|
'response': False,
|
||||||
|
'requests_response_code': 999,
|
||||||
|
}),
|
||||||
|
# apikey = a
|
||||||
|
('nma://%s' % ('a' * 48), {
|
||||||
|
'instance': plugins.NotifyMyAndroid,
|
||||||
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
|
# is set and tests that we gracfully handle them
|
||||||
|
'test_requests_exceptions': True,
|
||||||
|
}),
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
# NotifySlack
|
# NotifySlack
|
||||||
##################################
|
##################################
|
||||||
@ -498,8 +645,14 @@ def test_rest_plugins(mock_post, mock_get):
|
|||||||
test_requests_exceptions = meta.get(
|
test_requests_exceptions = meta.get(
|
||||||
'test_requests_exceptions', False)
|
'test_requests_exceptions', False)
|
||||||
|
|
||||||
mock_get.return_value = requests.Request()
|
# A request
|
||||||
mock_post.return_value = requests.Request()
|
robj = mock.Mock()
|
||||||
|
setattr(robj, 'raw', mock.Mock())
|
||||||
|
# Allow raw.read() calls
|
||||||
|
robj.raw.read.return_value = ''
|
||||||
|
mock_get.return_value = robj
|
||||||
|
mock_post.return_value = robj
|
||||||
|
|
||||||
if test_requests_exceptions is False:
|
if test_requests_exceptions is False:
|
||||||
# Handle our default response
|
# Handle our default response
|
||||||
mock_post.return_value.status_code = requests_response_code
|
mock_post.return_value.status_code = requests_response_code
|
||||||
@ -527,10 +680,13 @@ def test_rest_plugins(mock_post, mock_get):
|
|||||||
obj = Apprise.instantiate(
|
obj = Apprise.instantiate(
|
||||||
url, asset=asset, suppress_exceptions=False)
|
url, asset=asset, suppress_exceptions=False)
|
||||||
|
|
||||||
assert(exception is None)
|
# Make sure we weren't expecting an exception and just didn't get
|
||||||
|
# one.
|
||||||
|
assert exception is None
|
||||||
|
|
||||||
if obj is None:
|
if obj is None:
|
||||||
# We're done
|
# We're done (assuming this is what we were expecting)
|
||||||
|
assert instance is None
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if instance is None:
|
if instance is None:
|
||||||
@ -646,11 +802,44 @@ def test_notify_boxcar_plugin(mock_post, mock_get):
|
|||||||
mock_post.return_value = requests.Request()
|
mock_post.return_value = requests.Request()
|
||||||
mock_post.return_value.status_code = requests.codes.created
|
mock_post.return_value.status_code = requests.codes.created
|
||||||
mock_get.return_value.status_code = requests.codes.created
|
mock_get.return_value.status_code = requests.codes.created
|
||||||
|
|
||||||
# Test notifications without a body or a title
|
# Test notifications without a body or a title
|
||||||
p = plugins.NotifyBoxcar(access=access, secret=secret, recipients=None)
|
p = plugins.NotifyBoxcar(access=access, secret=secret, recipients=None)
|
||||||
p.notify(body=None, title=None, notify_type=NotifyType.INFO) is True
|
p.notify(body=None, title=None, notify_type=NotifyType.INFO) is True
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('requests.get')
|
||||||
|
@mock.patch('requests.post')
|
||||||
|
def test_notify_join_plugin(mock_post, mock_get):
|
||||||
|
"""
|
||||||
|
API: NotifyJoin() Extra Checks
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Generate some generic message types
|
||||||
|
device = 'A' * 32
|
||||||
|
group = 'group.chrome'
|
||||||
|
apikey = 'a' * 32
|
||||||
|
|
||||||
|
# Initializes the plugin with devices set to a string
|
||||||
|
plugins.NotifyJoin(apikey=apikey, devices=group)
|
||||||
|
|
||||||
|
# Initializes the plugin with devices set to None
|
||||||
|
plugins.NotifyJoin(apikey=apikey, devices=None)
|
||||||
|
|
||||||
|
# Initializes the plugin with devices set to a set
|
||||||
|
p = plugins.NotifyJoin(apikey=apikey, devices=[group, device])
|
||||||
|
|
||||||
|
# Prepare our mock responses
|
||||||
|
mock_get.return_value = requests.Request()
|
||||||
|
mock_post.return_value = requests.Request()
|
||||||
|
mock_post.return_value.status_code = requests.codes.created
|
||||||
|
mock_get.return_value.status_code = requests.codes.created
|
||||||
|
|
||||||
|
# Test notifications without a body or a title; nothing to send
|
||||||
|
# so we return False
|
||||||
|
p.notify(body=None, title=None, notify_type=NotifyType.INFO) is False
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.get')
|
@mock.patch('requests.get')
|
||||||
@mock.patch('requests.post')
|
@mock.patch('requests.post')
|
||||||
def test_notify_slack_plugin(mock_post, mock_get):
|
def test_notify_slack_plugin(mock_post, mock_get):
|
||||||
|
Loading…
Reference in New Issue
Block a user