Resolve ambiguity with apprise.plugins module namespace

While the namespace is physically made of modules, it has been amended
to be the namespace home for the corresponding notifier classes as well.

This turned out to confuse both humans and machines on various ends.

While it has apparently worked for a while, it croaks on Python 3.11
now, and is not considered to have been a good idea in general.
This commit is contained in:
Andreas Motl 2022-10-09 11:28:18 +02:00
parent c797d1e2eb
commit c9f0751b61
88 changed files with 1721 additions and 1688 deletions

View File

@ -115,9 +115,6 @@ def __load_matrix(path=abspath(dirname(__file__)), name='apprise.plugins'):
# Add our module name to our __all__
__all__.append(plugin_name)
# Load our module into memory so it's accessible to all
globals()[plugin_name] = plugin
fn = getattr(plugin, 'schemas', None)
schemas = set([]) if not callable(fn) else fn(plugin)
@ -147,8 +144,6 @@ def __reset_matrix():
# Iterate over our module map so we can clear out our __all__ and globals
for plugin_name in common.NOTIFY_MODULE_MAP.keys():
# Clear out globals
del globals()[plugin_name]
# Remove element from plugins
__all__.remove(plugin_name)

View File

@ -23,9 +23,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from .rest import AppriseURLTester
from .module import module_reload
from .module import reload_plugin
__all__ = [
'AppriseURLTester',
'module_reload',
'reload_plugin',
]

View File

@ -23,16 +23,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import re
import os
import sys
from importlib import reload
def module_reload(filename):
def reload_plugin(name):
"""
Reload builtin plugin module, e.g. `NotifyGnome`.
set filename to plugin to be reloaded (for example NotifyGnome.py)
The following libraries need to be reloaded to prevent
@ -44,12 +42,12 @@ def module_reload(filename):
"""
module_name = 'apprise.plugins.{}'.format(
re.match(r'^(.+)(\.py)?$', os.path.basename(filename), re.I).group(1))
module_name = f"apprise.plugins.{name}"
reload(sys.modules['apprise.common'])
reload(sys.modules['apprise.attachment'])
reload(sys.modules['apprise.config'])
if module_name in sys.modules:
reload(sys.modules[module_name])
reload(sys.modules['apprise.plugins'])
reload(sys.modules['apprise.Apprise'])

View File

@ -32,7 +32,7 @@ from random import choice
from string import ascii_uppercase as str_alpha
from string import digits as str_num
from apprise import plugins
from apprise import NotifyBase
from apprise import NotifyType
from apprise import Apprise
from apprise import AppriseAsset
@ -116,7 +116,7 @@ class AppriseURLTester:
Run a specific test
"""
# Disable Throttling to speed testing
plugins.NotifyBase.request_rate_per_sec = 0
NotifyBase.request_rate_per_sec = 0
# Our expected instance
instance = meta.get('instance', None)
@ -229,7 +229,7 @@ class AppriseURLTester:
url, type(instance), str(obj)))
assert False
if isinstance(obj, plugins.NotifyBase):
if isinstance(obj, NotifyBase):
# Ensure we are not performing any type of thorttling
obj.request_rate_per_sec = 0
@ -264,7 +264,7 @@ class AppriseURLTester:
# Our object should be the same instance as what we had
# originally expected above.
if not isinstance(obj_cmp, plugins.NotifyBase):
if not isinstance(obj_cmp, NotifyBase):
# Assert messages are hard to trace back with the
# way these tests work. Just printing before
# throwing our assertion failure makes things

View File

@ -27,11 +27,13 @@ import pytest
from apprise.AppriseAsset import AppriseAsset
from apprise.config.ConfigBase import ConfigBase
from apprise import ConfigFormat
from apprise import plugins
import yaml
# Disable logging for a cleaner testing output
import logging
from apprise.plugins.NotifyEmail import NotifyEmail
logging.disable(logging.CRITICAL)
@ -949,8 +951,8 @@ def test_yaml_vs_text_tagging():
# Now we compare our results and verify they are the same
assert len(yaml_result) == len(text_result)
assert isinstance(yaml_result[0], plugins.NotifyEmail)
assert isinstance(text_result[0], plugins.NotifyEmail)
assert isinstance(yaml_result[0], NotifyEmail)
assert isinstance(text_result[0], NotifyEmail)
assert 'mytag' in text_result[0]
assert 'mytag' in yaml_result[0]

View File

@ -22,8 +22,8 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise.plugins.NotifyAppriseAPI import NotifyAppriseAPI
from helpers import AppriseURLTester
from apprise import plugins
import requests
# Disable logging for a cleaner testing output
@ -54,101 +54,101 @@ apprise_url_tests = (
}),
# A valid URL with Token
('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprise://localhost/a...a/',
}),
# A valid URL with Token (using port)
('apprise://localhost:8080/%s' % ('b' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprise://localhost:8080/b...b/',
}),
# A secure (https://) reference
('apprises://localhost/%s' % ('c' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://localhost/c...c/',
}),
# Native URL suport (https)
('https://example.com/path/notify/%s' % ('d' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://example.com/path/d...d/',
}),
# Native URL suport (http)
('http://example.com/notify/%s' % ('d' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprise://example.com/d...d/',
}),
# support to= keyword
('apprises://localhost/?to=%s' % ('e' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
'privacy_url': 'apprises://localhost/e...e/',
}),
# support token= keyword (even when passed with to=, token over-rides)
('apprise://localhost/?token=%s&to=%s' % ('f' * 32, 'abcd'), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://localhost/f...f/',
}),
# Test tags
('apprise://localhost/?token=%s&tags=admin,team' % ('abcd'), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://localhost/a...d/',
}),
# Test Format string
('apprise://user@localhost/mytoken0/?format=markdown', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://user@localhost/m...0/',
}),
('apprise://user@localhost/mytoken1/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://user@localhost/m...1/',
}),
('apprise://localhost:8080/mytoken/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
}),
('apprise://user:pass@localhost:8080/mytoken2/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://user:****@localhost:8080/m...2/',
}),
('apprises://localhost/mytoken/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
}),
('apprises://user:pass@localhost/mytoken3/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://user:****@localhost/m...3/',
}),
('apprises://localhost:8080/mytoken4/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://localhost:8080/m...4/',
}),
('apprises://user:password@localhost:8080/mytoken5/', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://user:****@localhost:8080/m...5/',
}),
('apprises://localhost:8080/path?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
}),
('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI,
'instance': NotifyAppriseAPI,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyBark import NotifyBark
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,7 +41,7 @@ apprise_url_tests = (
}),
('bark://localhost', {
# No Device Key specified
'instance': plugins.NotifyBark,
'instance': NotifyBark,
# Expected notify() response False (because we won't be able
# to actually notify anything if no device_key was specified
'notify_response': False,
@ -49,79 +49,79 @@ apprise_url_tests = (
}),
('bark://192.168.0.6:8081/device_key', {
# Everything is okay
'instance': plugins.NotifyBark,
'instance': NotifyBark,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'bark://192.168.0.6:8081/',
}),
('bark://user@192.168.0.6:8081/device_key', {
# Everything is okay (test with user)
'instance': plugins.NotifyBark,
'instance': NotifyBark,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'bark://user@192.168.0.6:8081/',
}),
('bark://192.168.0.6:8081/device_key/?sound=invalid', {
# bad sound, but we go ahead anyway
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?sound=alarm', {
# alarm.caf sound loaded
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?sound=NOiR.cAf', {
# noir.caf sound loaded
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?badge=100', {
# set badge
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('barks://192.168.0.6:8081/device_key/?badge=invalid', {
# set invalid badge
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('barks://192.168.0.6:8081/device_key/?badge=-12', {
# set invalid badge
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?category=apprise', {
# set category
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?image=no', {
# do not display image
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?group=apprise', {
# set group
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?level=invalid', {
# bad level, but we go ahead anyway
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/?to=device_key', {
# test use of to= argument
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?click=http://localhost', {
# Our click link
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://192.168.0.6:8081/device_key/?level=active', {
# active level
'instance': plugins.NotifyBark,
'instance': NotifyBark,
}),
('bark://user:pass@192.168.0.5:8086/device_key/device_key2/', {
# Everything is okay
'instance': plugins.NotifyBark,
'instance': NotifyBark,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'bark://user:****@192.168.0.5:8086/',
}),
('barks://192.168.0.7/device_key/', {
'instance': plugins.NotifyBark,
'instance': NotifyBark,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -130,7 +130,7 @@ apprise_url_tests = (
'privacy_url': 'barks://192.168.0.7/device_key',
}),
('bark://192.168.0.7/device_key', {
'instance': plugins.NotifyBark,
'instance': NotifyBark,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -25,8 +25,8 @@
import pytest
from unittest import mock
from apprise.plugins.NotifyBoxcar import NotifyBoxcar
from helpers import AppriseURLTester
from apprise import plugins
from apprise import NotifyType
import requests
@ -58,48 +58,48 @@ apprise_url_tests = (
}),
# Provide both an access and a secret
('boxcar://%s/%s' % ('a' * 64, 'b' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
'requests_response_code': requests.codes.created,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'boxcar://a...a/****/',
}),
# Test without image set
('boxcar://%s/%s?image=True' % ('a' * 64, 'b' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
'requests_response_code': requests.codes.created,
# don't include an image in Asset by default
'include_image': False,
}),
('boxcar://%s/%s?image=False' % ('a' * 64, 'b' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
'requests_response_code': requests.codes.created,
}),
# our access, secret and device are all 64 characters
# which is what we're doing here
('boxcar://%s/%s/@tag1/tag2///%s/?to=tag3' % (
'a' * 64, 'b' * 64, 'd' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
'requests_response_code': requests.codes.created,
}),
# An invalid tag
('boxcar://%s/%s/@%s' % ('a' * 64, 'b' * 64, 't' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
'requests_response_code': requests.codes.created,
}),
('boxcar://%s/%s/' % ('a' * 64, 'b' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('boxcar://%s/%s/' % ('a' * 64, 'b' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('boxcar://%s/%s/' % ('a' * 64, 'b' * 64), {
'instance': plugins.NotifyBoxcar,
'instance': NotifyBoxcar,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -133,19 +133,19 @@ def test_plugin_boxcar_edge_cases(mock_post, mock_get, no_throttling):
secret = '_' * 64
# Initializes the plugin with recipients set to None
plugins.NotifyBoxcar(access=access, secret=secret, targets=None)
NotifyBoxcar(access=access, secret=secret, targets=None)
# Initializes the plugin with a valid access, but invalid access key
with pytest.raises(TypeError):
plugins.NotifyBoxcar(access=None, secret=secret, targets=None)
NotifyBoxcar(access=None, secret=secret, targets=None)
# Initializes the plugin with a valid access, but invalid secret
with pytest.raises(TypeError):
plugins.NotifyBoxcar(access=access, secret=None, targets=None)
NotifyBoxcar(access=access, secret=None, targets=None)
# Initializes the plugin with recipients list
# the below also tests our the variation of recipient types
plugins.NotifyBoxcar(
NotifyBoxcar(
access=access, secret=secret, targets=[device, tag])
mock_get.return_value = requests.Request()
@ -154,14 +154,14 @@ def test_plugin_boxcar_edge_cases(mock_post, mock_get, no_throttling):
mock_get.return_value.status_code = requests.codes.created
# Test notifications without a body or a title
p = plugins.NotifyBoxcar(access=access, secret=secret, targets=None)
p = NotifyBoxcar(access=access, secret=secret, targets=None)
assert p.notify(body=None, title=None, notify_type=NotifyType.INFO) is True
# Test comma, separate values
device = 'a' * 64
p = plugins.NotifyBoxcar(
p = NotifyBoxcar(
access=access, secret=secret,
targets=','.join([device, device, device]))
assert len(p.device_tokens) == 3

View File

@ -27,7 +27,7 @@ from unittest import mock
import requests
from json import loads
from apprise import Apprise
from apprise import plugins
from apprise.plugins.NotifyBulkSMS import NotifyBulkSMS
from helpers import AppriseURLTester
from apprise import NotifyType
@ -39,53 +39,53 @@ logging.disable(logging.CRITICAL)
apprise_url_tests = (
('bulksms://', {
# Instantiated but no auth, so no otification can happen
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# Expected notify() response because we have no one to notify
'notify_response': False,
}),
('bulksms://:@/', {
# invalid auth
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# Expected notify() response because we have no one to notify
'notify_response': False,
}),
('bulksms://{}@12345678'.format('a' * 10), {
# Just user provided (no password)
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# Expected notify() response because we have no one to notify
'notify_response': False,
}),
('bulksms://{}:{}@{}'.format('a' * 10, 'b' * 10, '3' * 5), {
# invalid nubmer provided
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# Expected notify() response because we have no one to notify
'notify_response': False,
}),
('bulksms://{}:{}@123/{}/abcd/'.format(
'a' * 5, 'b' * 10, '3' * 11), {
# included group and phone, short number (123) dropped
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
'privacy_url': 'bulksms://a...a:****@+33333333333/@abcd'
}),
('bulksms://{}:{}@{}?batch=y&unicode=n'.format(
'b' * 5, 'c' * 10, '4' * 11), {
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'bulksms://b...b:****@+4444444444',
}),
('bulksms://{}:{}@123456/{}'.format('a' * 10, 'b' * 10, '4' * 11), {
# using short-code (6 characters)
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
}),
('bulksms://{}:{}@{}'.format('a' * 10, 'b' * 10, '5' * 11), {
# using phone no with no target - we text ourselves in
# this case
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
}),
# Test route group
('bulksms://{}:{}@admin?route=premium'.format('a' * 10, 'b' * 10), {
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
}),
('bulksms://{}:{}@admin?route=invalid'.format('a' * 10, 'b' * 10), {
# invalid route
@ -94,7 +94,7 @@ apprise_url_tests = (
('bulksms://_?user={}&password={}&from={}'.format(
'a' * 10, 'b' * 10, '5' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
}),
('bulksms://_?user={}&password={}&from={}'.format(
'a' * 10, 'b' * 10, '5' * 3), {
@ -104,16 +104,16 @@ apprise_url_tests = (
('bulksms://_?user={}&password={}&from={}&to={}'.format(
'a' * 10, 'b' * 10, '5' * 11, '7' * 13), {
# use to=
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
}),
('bulksms://{}:{}@{}'.format('a' * 10, 'b' * 10, 'a' * 3), {
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('bulksms://{}:{}@{}'.format('a' * 10, 'b' * 10, '6' * 11), {
'instance': plugins.NotifyBulkSMS,
'instance': NotifyBulkSMS,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyClickSend import NotifyClickSend
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,31 +41,31 @@ apprise_url_tests = (
}),
('clicksend://user:pass@{}/{}/{}'.format('1' * 9, '2' * 15, 'a' * 13), {
# invalid target numbers; we'll fail to notify anyone
'instance': plugins.NotifyClickSend,
'instance': NotifyClickSend,
'notify_response': False,
}),
('clicksend://user:pass@{}?batch=yes'.format('3' * 14), {
# valid number
'instance': plugins.NotifyClickSend,
'instance': NotifyClickSend,
}),
('clicksend://user:pass@{}?batch=yes&to={}'.format('3' * 14, '6' * 14), {
# valid number but using the to= variable
'instance': plugins.NotifyClickSend,
'instance': NotifyClickSend,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'clicksend://user:****',
}),
('clicksend://user:pass@{}?batch=no'.format('3' * 14), {
# valid number - no batch
'instance': plugins.NotifyClickSend,
'instance': NotifyClickSend,
}),
('clicksend://user:pass@{}'.format('3' * 14), {
'instance': plugins.NotifyClickSend,
'instance': NotifyClickSend,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('clicksend://user:pass@{}'.format('3' * 14), {
'instance': plugins.NotifyClickSend,
'instance': NotifyClickSend,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -26,7 +26,8 @@ import os
from unittest import mock
import requests
from apprise import plugins
from apprise.plugins.NotifyForm import NotifyForm
from helpers import AppriseURLTester
from apprise import Apprise
from apprise import NotifyType
@ -51,89 +52,89 @@ apprise_url_tests = (
'instance': None,
}),
('form://localhost', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user@localhost?method=invalid', {
'instance': TypeError,
}),
('form://user:pass@localhost', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'form://user:****@localhost',
}),
('form://user@localhost', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
# Test method variations
('form://user@localhost?method=put', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user@localhost?method=get', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user@localhost?method=post', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user@localhost?method=head', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user@localhost?method=delete', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
# Custom payload options
('form://localhost:8080?:key=value&:key2=value2', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
# Continue testing other cases
('form://localhost:8080', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user:pass@localhost:8080', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('forms://localhost', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('forms://user:pass@localhost', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('forms://localhost:8080/path/', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'forms://localhost:8080/path/',
}),
('forms://user:password@localhost:8080', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'forms://user:****@localhost:8080',
}),
# Test our GET params
('form://localhost:8080/path?-ParamA=Value', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
# Test our Headers
('form://localhost:8080/path?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
}),
('form://user:pass@localhost:8081', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('form://user:pass@localhost:8082', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('form://user:pass@localhost:8083', {
'instance': plugins.NotifyForm,
'instance': NotifyForm,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -167,7 +168,7 @@ def test_plugin_custom_form_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'form://user@localhost.localdomain/?method=post')
assert isinstance(obj, plugins.NotifyForm)
assert isinstance(obj, NotifyForm)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -238,7 +239,7 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
mock_post.return_value = response
mock_get.return_value = response
results = plugins.NotifyForm.parse_url(
results = NotifyForm.parse_url(
'form://localhost:8080/command?:abcd=test&method=POST')
assert isinstance(results, dict)
@ -254,8 +255,8 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
assert isinstance(results['qsd:'], dict) is True
assert results['qsd:']['abcd'] == 'test'
instance = plugins.NotifyForm(**results)
assert isinstance(instance, plugins.NotifyForm)
instance = NotifyForm(**results)
assert isinstance(instance, NotifyForm)
response = instance.send(title='title', body='body')
assert response is True
@ -275,7 +276,7 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
'form://localhost:8080/command?')
# Generate a new URL based on our last and verify key values are the same
new_results = plugins.NotifyForm.parse_url(instance.url(safe=False))
new_results = NotifyForm.parse_url(instance.url(safe=False))
for k in ('user', 'password', 'port', 'host', 'fullpath', 'path', 'query',
'schema', 'url', 'payload', 'method'):
assert new_results[k] == results[k]
@ -284,7 +285,7 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
mock_post.reset_mock()
mock_get.reset_mock()
results = plugins.NotifyForm.parse_url(
results = NotifyForm.parse_url(
'form://localhost:8080/command?:message=test&method=POST')
assert isinstance(results, dict)
@ -300,8 +301,8 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
assert isinstance(results['qsd:'], dict) is True
assert results['qsd:']['message'] == 'test'
instance = plugins.NotifyForm(**results)
assert isinstance(instance, plugins.NotifyForm)
instance = NotifyForm(**results)
assert isinstance(instance, NotifyForm)
response = instance.send(title='title', body='body')
assert response is True
@ -320,7 +321,7 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
'form://localhost:8080/command?')
# Generate a new URL based on our last and verify key values are the same
new_results = plugins.NotifyForm.parse_url(instance.url(safe=False))
new_results = NotifyForm.parse_url(instance.url(safe=False))
for k in ('user', 'password', 'port', 'host', 'fullpath', 'path', 'query',
'schema', 'url', 'payload', 'method'):
assert new_results[k] == results[k]
@ -329,7 +330,7 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
mock_post.reset_mock()
mock_get.reset_mock()
results = plugins.NotifyForm.parse_url(
results = NotifyForm.parse_url(
'form://localhost:8080/command?:message=test&method=GET')
assert isinstance(results, dict)
@ -345,8 +346,8 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
assert isinstance(results['qsd:'], dict) is True
assert results['qsd:']['message'] == 'test'
instance = plugins.NotifyForm(**results)
assert isinstance(instance, plugins.NotifyForm)
instance = NotifyForm(**results)
assert isinstance(instance, NotifyForm)
response = instance.send(title='title', body='body')
assert response is True
@ -366,7 +367,7 @@ def test_plugin_custom_form_edge_cases(mock_get, mock_post, no_throttling):
'form://localhost:8080/command?')
# Generate a new URL based on our last and verify key values are the same
new_results = plugins.NotifyForm.parse_url(instance.url(safe=False))
new_results = NotifyForm.parse_url(instance.url(safe=False))
for k in ('user', 'password', 'port', 'host', 'fullpath', 'path', 'query',
'schema', 'url', 'payload', 'method'):
assert new_results[k] == results[k]

View File

@ -28,10 +28,11 @@ import json
from unittest import mock
import requests
from apprise import plugins
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import NotifyType
from apprise.plugins.NotifyJSON import NotifyJSON
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,84 +54,84 @@ apprise_url_tests = (
'instance': None,
}),
('json://localhost', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user@localhost?method=invalid', {
'instance': TypeError,
}),
('json://user:pass@localhost', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'json://user:****@localhost',
}),
('json://user@localhost', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
# Test method variations
('json://user@localhost?method=put', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user@localhost?method=get', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user@localhost?method=post', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user@localhost?method=head', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user@localhost?method=delete', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
# Continue testing other cases
('json://localhost:8080', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user:pass@localhost:8080', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('jsons://localhost', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('jsons://user:pass@localhost', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('jsons://localhost:8080/path/', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'jsons://localhost:8080/path/',
}),
# Test our GET params
('json://localhost:8080/path?-ParamA=Value', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('jsons://user:password@localhost:8080', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'jsons://user:****@localhost:8080',
}),
# Test our Headers
('json://localhost:8080/path?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
}),
('json://user:pass@localhost:8081', {
'instance': plugins.NotifyJSON,
'instance': NotifyJSON,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('json://user:pass@localhost:8082', {
'instance': plugins.NotifyJSON,
'instance': 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,
'instance': 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,
@ -164,7 +165,7 @@ def test_plugin_custom_json_edge_cases(mock_get, mock_post, no_throttling):
mock_post.return_value = response
mock_get.return_value = response
results = plugins.NotifyJSON.parse_url(
results = NotifyJSON.parse_url(
'json://localhost:8080/command?:message=test&method=GET')
assert isinstance(results, dict)
@ -180,8 +181,8 @@ def test_plugin_custom_json_edge_cases(mock_get, mock_post, no_throttling):
assert isinstance(results['qsd:'], dict) is True
assert results['qsd:']['message'] == 'test'
instance = plugins.NotifyJSON(**results)
assert isinstance(instance, plugins.NotifyJSON)
instance = NotifyJSON(**results)
assert isinstance(instance, NotifyJSON)
response = instance.send(title='title', body='body')
assert response is True
@ -201,20 +202,18 @@ def test_plugin_custom_json_edge_cases(mock_get, mock_post, no_throttling):
'json://localhost:8080/command?')
# Generate a new URL based on our last and verify key values are the same
new_results = plugins.NotifyJSON.parse_url(instance.url(safe=False))
new_results = NotifyJSON.parse_url(instance.url(safe=False))
for k in ('user', 'password', 'port', 'host', 'fullpath', 'path', 'query',
'schema', 'url', 'method'):
assert new_results[k] == results[k]
@mock.patch('requests.post')
def test_notify_json_plugin_attachments(mock_post):
def test_notify_json_plugin_attachments(mock_post, no_throttling):
"""
NotifyJSON() Attachments
"""
# Disable Throttling to speed testing
plugins.NotifyBase.request_rate_per_sec = 0
okay_response = requests.Request()
okay_response.status_code = requests.codes.ok
@ -224,7 +223,7 @@ def test_notify_json_plugin_attachments(mock_post):
mock_post.return_value = okay_response
obj = Apprise.instantiate('json://localhost.localdomain/')
assert isinstance(obj, plugins.NotifyJSON)
assert isinstance(obj, NotifyJSON)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -265,7 +264,7 @@ def test_notify_json_plugin_attachments(mock_post):
# test the handling of our batch modes
obj = Apprise.instantiate('json://no-reply@example.com/')
assert isinstance(obj, plugins.NotifyJSON)
assert isinstance(obj, NotifyJSON)
# Now send an attachment normally without issues
mock_post.reset_mock()

View File

@ -27,10 +27,10 @@ import re
from unittest import mock
import requests
from apprise import plugins
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import NotifyType
from apprise.plugins.NotifyXML import NotifyXML
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,16 +53,16 @@ apprise_url_tests = (
'instance': None,
}),
('xml://localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user@localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user@localhost?method=invalid', {
'instance': TypeError,
}),
('xml://user:pass@localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'xml://user:****@localhost',
@ -70,83 +70,83 @@ apprise_url_tests = (
# Test method variations
('xml://user@localhost?method=put', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user@localhost?method=get', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user@localhost?method=post', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user@localhost?method=head', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user@localhost?method=delete', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
# Continue testing other cases
('xml://localhost:8080', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user:pass@localhost:8080', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xmls://localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xmls://user:pass@localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
# Continue testing other cases
('xml://localhost:8080', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user:pass@localhost:8080', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xmls://user:pass@localhost', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'xmls://user:****@localhost',
}),
('xml://user@localhost:8080/path/', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
'privacy_url': 'xml://user@localhost:8080/path',
}),
('xmls://localhost:8080/path/', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'xmls://localhost:8080/path/',
}),
('xmls://user:pass@localhost:8080', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
# Test our GET params
('xml://localhost:8080/path?-ParamA=Value', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
# Test our Headers
('xml://localhost:8080/path?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
}),
('xml://user:pass@localhost:8081', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('xml://user:pass@localhost:8082', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('xml://user:pass@localhost:8083', {
'instance': plugins.NotifyXML,
'instance': NotifyXML,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -179,7 +179,7 @@ def test_notify_xml_plugin_attachments(mock_post, no_throttling):
mock_post.return_value = okay_response
obj = Apprise.instantiate('xml://localhost.localdomain/')
assert isinstance(obj, plugins.NotifyXML)
assert isinstance(obj, NotifyXML)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -213,7 +213,7 @@ def test_notify_xml_plugin_attachments(mock_post, no_throttling):
# test the handling of our batch modes
obj = Apprise.instantiate('xml://no-reply@example.com/')
assert isinstance(obj, plugins.NotifyXML)
assert isinstance(obj, NotifyXML)
# Now send an attachment normally without issues
mock_post.reset_mock()
@ -239,7 +239,7 @@ def test_plugin_custom_xml_edge_cases(mock_get, mock_post, no_throttling):
mock_post.return_value = response
mock_get.return_value = response
results = plugins.NotifyXML.parse_url(
results = NotifyXML.parse_url(
'xml://localhost:8080/command?:Message=test&method=GET'
'&:Key=value&:,=invalid')
@ -258,8 +258,8 @@ def test_plugin_custom_xml_edge_cases(mock_get, mock_post, no_throttling):
assert results['qsd:']['Key'] == 'value'
assert results['qsd:'][','] == 'invalid'
instance = plugins.NotifyXML(**results)
assert isinstance(instance, plugins.NotifyXML)
instance = NotifyXML(**results)
assert isinstance(instance, NotifyXML)
response = instance.send(title='title', body='body')
assert response is True
@ -272,7 +272,7 @@ def test_plugin_custom_xml_edge_cases(mock_get, mock_post, no_throttling):
'xml://localhost:8080/command?')
# Generate a new URL based on our last and verify key values are the same
new_results = plugins.NotifyXML.parse_url(instance.url(safe=False))
new_results = NotifyXML.parse_url(instance.url(safe=False))
for k in ('user', 'password', 'port', 'host', 'fullpath', 'path', 'query',
'schema', 'url', 'method'):
assert new_results[k] == results[k]

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyD7Networks import NotifyD7Networks
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,20 +41,20 @@ apprise_url_tests = (
}),
('d7sms://user:pass@{}/{}/{}'.format('1' * 9, '2' * 15, 'a' * 13), {
# No valid targets to notify
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
}),
('d7sms://user:pass@{}?batch=yes'.format('3' * 14), {
# valid number
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'd7sms://user:****@',
}),
('d7sms://user:pass@{}?batch=yes'.format('7' * 14), {
# valid number
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
# Test what happens if a batch send fails to return a messageCount
'requests_response_text': {
'data': {
@ -66,40 +66,40 @@ apprise_url_tests = (
}),
('d7sms://user:pass@{}?batch=yes&to={}'.format('3' * 14, '6' * 14), {
# valid number
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}?batch=yes&from=apprise'.format('3' * 14), {
# valid number, utilizing the optional from= variable
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}?batch=yes&source=apprise'.format('3' * 14), {
# valid number, utilizing the optional source= variable (same as from)
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}?priority=invalid'.format('3' * 14), {
# valid number; invalid priority
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}?priority=3'.format('3' * 14), {
# valid number; adjusted priority
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}?priority=high'.format('3' * 14), {
# valid number; adjusted priority (string supported)
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}?batch=no'.format('3' * 14), {
# valid number - no batch
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
}),
('d7sms://user:pass@{}'.format('3' * 14), {
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('d7sms://user:pass@{}'.format('3' * 14), {
'instance': plugins.NotifyD7Networks,
'instance': NotifyD7Networks,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -28,8 +28,7 @@ import requests
from unittest import mock
import apprise
from apprise.plugins.NotifyDapnet import DapnetPriority
from apprise import plugins
from apprise.plugins.NotifyDapnet import DapnetPriority, NotifyDapnet
from helpers import AppriseURLTester
logging.disable(logging.CRITICAL)
@ -54,18 +53,18 @@ apprise_url_tests = (
}),
('dapnet://user:pass@{}'.format('DF1ABC'), {
# valid call sign
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}/{}'.format('DF1ABC', 'DF1DEF'), {
# valid call signs
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@DF1ABC-1/DF1ABC/DF1ABC-15', {
# valid call signs; but a few are duplicates;
# at the end there will only be 1 entry
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
# Our expected url(privacy=True) startswith() response:
# Note that only 1 entry is saved (as other 2 are duplicates)
@ -73,50 +72,50 @@ apprise_url_tests = (
}),
('dapnet://user:pass@?to={},{}'.format('DF1ABC', 'DF1DEF'), {
# support the to= argument
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}?priority=normal'.format('DF1ABC'), {
# valid call sign with priority
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}?priority=em&batch=false'.format(
'/'.join(['DF1ABC', '0A1DEF'])), {
# valid call sign with priority (emergency) + no batch
# transmissions
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}?priority=invalid'.format('DF1ABC'), {
# invalid priority
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}?txgroups=dl-all,all'.format('DF1ABC'), {
# valid call sign with two transmitter groups
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}?txgroups=invalid'.format('DF1ABC'), {
# valid call sign with invalid transmitter group
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'requests_response_code': requests.codes.created,
}),
('dapnet://user:pass@{}/{}'.format('abcdefghi', 'a'), {
# invalid call signs
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
'notify_response': False,
}),
# Edge cases
('dapnet://user:pass@{}'.format('DF1ABC'), {
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('dapnet://user:pass@{}'.format('DF1ABC'), {
'instance': plugins.NotifyDapnet,
'instance': NotifyDapnet,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -163,7 +162,7 @@ def test_plugin_dapnet_config_files(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifyDapnet.request_rate_per_sec = 0
NotifyDapnet.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyDingTalk import NotifyDingTalk
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,27 +41,27 @@ apprise_url_tests = (
}),
('dingtalk://12345678', {
# access token
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'dingtalk://1...8',
}),
('dingtalk://{}/{}'.format('a' * 8, '1' * 14), {
# access token + phone number
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
}),
('dingtalk://{}/{}/invalid'.format('a' * 8, '1' * 3), {
# access token + 2 invalid phone numbers
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
}),
('dingtalk://{}/?to={}'.format('a' * 8, '1' * 14), {
# access token + phone number using 'to'
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
}),
# Test secret via user@
('dingtalk://secret@{}/?to={}'.format('a' * 8, '1' * 14), {
# access token + phone number using 'to'
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'dingtalk://****@a...a',
}),
@ -69,7 +69,7 @@ apprise_url_tests = (
('dingtalk://?token={}&to={}&secret={}'.format(
'b' * 8, '1' * 14, 'a' * 15), {
# access token + phone number using 'to'
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
'privacy_url': 'dingtalk://****@b...b',
}),
# Invalid secret
@ -78,16 +78,16 @@ apprise_url_tests = (
}),
('dingtalk://{}?format=markdown'.format('a' * 8), {
# access token
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
}),
('dingtalk://{}'.format('a' * 8), {
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('dingtalk://{}'.format('a' * 8), {
'instance': plugins.NotifyDingTalk,
'instance': NotifyDingTalk,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -28,10 +28,11 @@ from unittest import mock
import pytest
import requests
from apprise.plugins.NotifyDiscord import NotifyDiscord
from helpers import AppriseURLTester
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import plugins
from apprise import NotifyType
from apprise import NotifyFormat
@ -57,99 +58,99 @@ apprise_url_tests = (
}),
# Provide both an webhook id and a webhook token
('discord://%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# Provide a temporary username
('discord://l2g@%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# test image= field
('discord://%s/%s?format=markdown&footer=Yes&image=Yes' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
# don't include an image by default
'include_image': False,
}),
('discord://%s/%s?format=markdown&footer=Yes&image=No&fields=no' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('discord://%s/%s?format=markdown&footer=Yes&image=Yes' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('https://discord.com/api/webhooks/{}/{}'.format(
'0' * 10, 'B' * 40), {
# Native URL Support, support the provided discord URL from their
# webpage.
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('https://discordapp.com/api/webhooks/{}/{}'.format(
'0' * 10, 'B' * 40), {
# Legacy Native URL Support, support the older URL (to be
# decomissioned on Nov 7th 2020)
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('https://discordapp.com/api/webhooks/{}/{}?footer=yes'.format(
'0' * 10, 'B' * 40), {
# Native URL Support with arguments
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('discord://%s/%s?format=markdown&avatar=No&footer=No' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# different format support
('discord://%s/%s?format=markdown' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# Thread ID
('discord://%s/%s?format=markdown&thread=abc123' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('discord://%s/%s?format=text' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# Test with avatar URL
('discord://%s/%s?avatar_url=http://localhost/test.jpg' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# Test without image set
('discord://%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
'requests_response_code': requests.codes.no_content,
# don't include an image by default
'include_image': False,
}),
('discord://%s/%s/' % ('a' * 24, 'b' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('discord://%s/%s/' % ('a' * 24, 'b' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('discord://%s/%s/' % ('a' * 24, 'b' * 64), {
'instance': plugins.NotifyDiscord,
'instance': NotifyDiscord,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -184,19 +185,19 @@ def test_plugin_discord_general(mock_post, no_throttling):
# Invalid webhook id
with pytest.raises(TypeError):
plugins.NotifyDiscord(webhook_id=None, webhook_token=webhook_token)
NotifyDiscord(webhook_id=None, webhook_token=webhook_token)
# Invalid webhook id (whitespace)
with pytest.raises(TypeError):
plugins.NotifyDiscord(webhook_id=" ", webhook_token=webhook_token)
NotifyDiscord(webhook_id=" ", webhook_token=webhook_token)
# Invalid webhook token
with pytest.raises(TypeError):
plugins.NotifyDiscord(webhook_id=webhook_id, webhook_token=None)
NotifyDiscord(webhook_id=webhook_id, webhook_token=None)
# Invalid webhook token (whitespace)
with pytest.raises(TypeError):
plugins.NotifyDiscord(webhook_id=webhook_id, webhook_token=" ")
NotifyDiscord(webhook_id=webhook_id, webhook_token=" ")
obj = plugins.NotifyDiscord(
obj = NotifyDiscord(
webhook_id=webhook_id,
webhook_token=webhook_token,
footer=True, thumbnail=False)
@ -286,7 +287,7 @@ def test_plugin_discord_general(mock_post, no_throttling):
webhook_token=webhook_token)) is True
# This call includes an image with it's payload:
plugins.NotifyDiscord.discord_max_fields = 1
NotifyDiscord.discord_max_fields = 1
assert a.notify(body=test_markdown, title='title',
notify_type=NotifyType.INFO,
@ -304,7 +305,7 @@ def test_plugin_discord_general(mock_post, no_throttling):
# Test our markdown
obj = Apprise.instantiate(
'discord://{}/{}/?format=markdown'.format(webhook_id, webhook_token))
assert isinstance(obj, plugins.NotifyDiscord)
assert isinstance(obj, NotifyDiscord)
assert obj.notify(
body=test_markdown, title='title',
notify_type=NotifyType.INFO) is False

View File

@ -30,8 +30,7 @@ from unittest import mock
import smtplib
from email.header import decode_header
from apprise import plugins
from apprise import NotifyType
from apprise import NotifyType, NotifyBase
from apprise import Apprise
from apprise import AttachBase
from apprise import AppriseAttachment
@ -39,6 +38,9 @@ from apprise.plugins import NotifyEmailBase
# Disable logging for a cleaner testing output
import logging
from apprise.plugins.NotifyEmail import NotifyEmail
logging.disable(logging.CRITICAL)
# Attachment Directory
@ -65,116 +67,116 @@ TEST_URLS = (
# Pre-Configured Email Services
('mailto://user:pass@gmail.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@hotmail.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@live.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@prontomail.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@yahoo.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@yahoo.ca', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@fastmail.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@sendgrid.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
# Yandex
('mailto://user:pass@yandex.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@yandex.ru', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@yandex.fr', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
# Custom Emails
('mailtos://user:pass@nuxref.com:567', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@nuxref.com:567?format=html', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailtos://user:pass@nuxref.com:567?to=l2g@nuxref.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailtos://user:pass@nuxref.com:567/l2g@nuxref.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
(
'mailto://user:pass@example.com:2525?user=l2g@example.com'
'&pass=l2g@apprise!is!Awesome', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
'mailto://user:pass@example.com:2525?user=l2g@example.com'
'&pass=l2g@apprise!is!Awesome&format=text', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
# Test Carbon Copy
'mailtos://user:pass@example.com?smtp=smtp.example.com'
'&name=l2g&cc=noreply@example.com,test@example.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
# Test Blind Carbon Copy
'mailtos://user:pass@example.com?smtp=smtp.example.com'
'&name=l2g&bcc=noreply@example.com,test@example.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
# Test Carbon Copy with bad email
'mailtos://user:pass@example.com?smtp=smtp.example.com'
'&name=l2g&cc=noreply@example.com,@', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
# Test Blind Carbon Copy with bad email
'mailtos://user:pass@example.com?smtp=smtp.example.com'
'&name=l2g&bcc=noreply@example.com,@', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
# Test Reply To
'mailtos://user:pass@example.com?smtp=smtp.example.com'
'&name=l2g&reply=test@example.com,test2@example.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
(
# Test Reply To with bad email
'mailtos://user:pass@example.com?smtp=smtp.example.com'
'&name=l2g&reply=test@example.com,@', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
},
),
# headers
('mailto://user:pass@localhost.localdomain'
'?+X-Customer-Campaign-ID=Apprise', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
# No Password
('mailtos://user:@nuxref.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
# Invalid From Address
('mailtos://user:pass@nuxref.com?from=@', {
@ -187,7 +189,7 @@ TEST_URLS = (
# Invalid To Address is accepted, but we won't be able to properly email
# using the notify() call
('mailtos://user:pass@nuxref.com?to=@', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
'response': False,
}),
# Valid URL, but can't structure a proper email
@ -204,44 +206,44 @@ TEST_URLS = (
}),
# STARTTLS flag checking
('mailtos://user:pass@gmail.com?mode=starttls', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'mailtos://user:****@gmail.com',
}),
# SSL flag checking
('mailtos://user:pass@gmail.com?mode=ssl', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
# Can make a To address using what we have (l2g@nuxref.com)
('mailtos://nuxref.com?user=l2g&pass=.', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'mailtos://l2g:****@nuxref.com',
}),
('mailto://user:pass@localhost:2525', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_smtplib_exceptions': True,
}),
# Test no auth at all
('mailto://localhost?from=test@example.com&to=test@example.com', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
'privacy_url': 'mailto://localhost',
}),
# Test multi-emails where some are bad
('mailto://user:pass@localhost/test@example.com/test2@/$@!/', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
'privacy_url': 'mailto://user:****@localhost/'
}),
('mailto://user:pass@localhost/?bcc=test2@,$@!/', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@localhost/?cc=test2@,$@!/', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
('mailto://user:pass@localhost/?reply=test2@,$@!/', {
'instance': plugins.NotifyEmail,
'instance': NotifyEmail,
}),
)
@ -319,7 +321,7 @@ def test_plugin_email(mock_smtp, mock_smtpssl, no_throttling):
assert isinstance(obj, instance)
if isinstance(obj, plugins.NotifyBase):
if isinstance(obj, NotifyBase):
# We loaded okay; now lets make sure we can reverse this url
assert isinstance(obj.url(), str) is True
@ -342,7 +344,7 @@ def test_plugin_email(mock_smtp, mock_smtpssl, no_throttling):
# Our object should be the same instance as what we had
# originally expected above.
if not isinstance(obj_cmp, plugins.NotifyBase):
if not isinstance(obj_cmp, NotifyBase):
# Assert messages are hard to trace back with the way
# these tests work. Just printing before throwing our
# assertion failure makes things easier to debug later on
@ -430,7 +432,7 @@ def test_plugin_email_webbase_lookup(mock_smtp, mock_smtpssl):
obj = Apprise.instantiate(
'mailto://user:pass@l2g.com', suppress_exceptions=True)
assert isinstance(obj, plugins.NotifyEmail)
assert isinstance(obj, NotifyEmail)
assert len(obj.targets) == 1
assert (False, 'user@l2g.com') in obj.targets
assert obj.from_addr == 'user@l2g.com'
@ -456,7 +458,7 @@ def test_plugin_email_smtplib_init_fail(mock_smtplib, no_throttling):
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com', suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail)
assert isinstance(obj, NotifyEmail)
# Support Exception handling of smtplib.SMTP
mock_smtplib.side_effect = RuntimeError('Test')
@ -480,7 +482,7 @@ def test_plugin_email_smtplib_send_okay(mock_smtplib, no_throttling):
# Defaults to HTML
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com', suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail)
assert isinstance(obj, NotifyEmail)
# Support an email simulation where we can correctly quit
mock_smtplib.starttls.return_value = True
@ -494,7 +496,7 @@ def test_plugin_email_smtplib_send_okay(mock_smtplib, no_throttling):
# Set Text
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com?format=text', suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail)
assert isinstance(obj, NotifyEmail)
assert obj.notify(
body='body', title='test', notify_type=NotifyType.INFO) is True
@ -547,7 +549,7 @@ def test_plugin_email_smtplib_internationalization(mock_smtp, no_throttling):
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com?name=Например%20так',
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail)
assert isinstance(obj, NotifyEmail)
class SMTPMock:
def sendmail(self, *args, **kwargs):
@ -611,7 +613,7 @@ def test_plugin_email_url_escaping():
# So the above translates to ' %20' (a space in front of %20). We want
# to verify the handling of the password escaping and when it happens.
# a very bad response would be ' ' (double space)
obj = plugins.NotifyEmail.parse_url(
obj = NotifyEmail.parse_url(
'mailto://user:{}@gmail.com?format=text'.format(passwd))
assert isinstance(obj, dict) is True
@ -624,7 +626,7 @@ def test_plugin_email_url_escaping():
obj = Apprise.instantiate(
'mailto://user:{}@gmail.com?format=text'.format(passwd),
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
# The password is escaped only 'once'
assert obj.password == ' %20'
@ -642,7 +644,7 @@ def test_plugin_email_url_variations():
user='apprise%40example21.ca',
passwd='abcd123'),
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.password == 'abcd123'
assert obj.user == 'apprise@example21.ca'
@ -654,7 +656,7 @@ def test_plugin_email_url_variations():
user='apprise%40example21.ca',
passwd='abcd123'),
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.password == 'abcd123'
assert obj.user == 'apprise@example21.ca'
@ -666,7 +668,7 @@ def test_plugin_email_url_variations():
user='apprise%40example21.ca',
passwd='abcd123'),
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.password == 'abcd123'
assert obj.user == 'apprise@example21.ca'
@ -683,7 +685,7 @@ def test_plugin_email_url_variations():
user='apprise%40example21.ca',
passwd='abcd123'),
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.password == 'abcd123'
assert obj.user == 'apprise@example21.ca'
@ -704,7 +706,7 @@ def test_plugin_email_url_variations():
that='to@example.jp',
smtp_host='smtp.example.edu'),
suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.password == 'abcd123'
assert obj.user == 'apprise@example21.ca'
@ -728,7 +730,7 @@ def test_plugin_email_dict_variations():
'user': 'apprise@example.com',
'password': 'abd123',
'host': 'example.com'}, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
@mock.patch('smtplib.SMTP_SSL')
@ -746,7 +748,7 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
# Test variations of username required to be an email address
# user@example.com; we also test an over-ride port on a template driven
# mailto:// entry
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
'mailtos://user:pass123@hotmail.com:444'
'?to=user2@yahoo.com&name=test%20name')
assert isinstance(results, dict)
@ -758,7 +760,7 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
assert 'user2@yahoo.com' in results['targets']
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert mock_smtp.call_count == 0
assert mock_smtp_ssl.call_count == 0
@ -794,7 +796,7 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
# The below switches the `name` with the `to` to verify the results
# are the same; it also verfies that the mode gets changed to SSL
# instead of STARTTLS
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
'mailtos://user:pass123@hotmail.com?smtp=override.com'
'&name=test%20name&to=user2@yahoo.com&mode=ssl')
assert isinstance(results, dict)
@ -805,7 +807,7 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
assert 'user2@yahoo.com' in results['targets']
assert 'ssl' == results['secure_mode']
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert mock_smtp.call_count == 0
assert mock_smtp_ssl.call_count == 0
@ -842,44 +844,44 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
#
# Test outlook/hotmail lookups
#
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
'mailtos://user:pass123@outlook.com')
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.smtp_host == 'smtp-mail.outlook.com'
# No entries in the reply_to
assert not obj.reply_to
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
'mailtos://user:pass123@outlook.com.au')
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
assert obj.smtp_host == 'smtp-mail.outlook.com'
# No entries in the reply_to
assert not obj.reply_to
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
'mailtos://user:pass123@live.com')
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
# No entries in the reply_to
assert not obj.reply_to
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
'mailtos://user:pass123@hotmail.com')
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
# No entries in the reply_to
assert not obj.reply_to
#
# Test Port Over-Riding
#
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
"mailtos://abc:password@xyz.cn:465?"
"smtp=smtp.exmail.qq.com&mode=ssl")
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
# Verify our over-rides are in place
assert obj.smtp_host == 'smtp.exmail.qq.com'
@ -889,11 +891,11 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
# No entries in the reply_to
assert not obj.reply_to
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
"mailtos://abc:password@xyz.cn?"
"smtp=smtp.exmail.qq.com&mode=ssl&port=465")
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
# Verify our over-rides are in place
assert obj.smtp_host == 'smtp.exmail.qq.com'
@ -906,10 +908,10 @@ def test_plugin_email_url_parsing(mock_smtp, mock_smtp_ssl, no_throttling):
#
# Test Reply-To Email
#
results = plugins.NotifyEmail.parse_url(
results = NotifyEmail.parse_url(
"mailtos://user:pass@example.com?reply=noreply@example.com")
obj = Apprise.instantiate(results, suppress_exceptions=False)
assert isinstance(obj, plugins.NotifyEmail) is True
assert isinstance(obj, NotifyEmail) is True
# Verify our over-rides are in place
assert obj.smtp_host == 'example.com'
assert obj.from_addr == 'user@example.com'

View File

@ -27,6 +27,8 @@ from unittest import mock
from json import dumps
from apprise import Apprise
import requests
from apprise.plugins.NotifyEmby import NotifyEmby
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,13 +55,13 @@ apprise_url_tests = (
}),
# Valid Authentication
('emby://l2g@localhost', {
'instance': plugins.NotifyEmby,
'instance': NotifyEmby,
# our response will be False because our authentication can't be
# tested very well using this matrix.
'response': False,
}),
('embys://l2g:password@localhost', {
'instance': plugins.NotifyEmby,
'instance': NotifyEmby,
# our response will be False because our authentication can't be
# tested very well using this matrix.
'response': False,
@ -80,9 +82,9 @@ def test_plugin_template_urls():
AppriseURLTester(tests=apprise_url_tests).run_all()
@mock.patch('apprise.plugins.NotifyEmby.sessions')
@mock.patch('apprise.plugins.NotifyEmby.login')
@mock.patch('apprise.plugins.NotifyEmby.logout')
@mock.patch('apprise.plugins.NotifyEmby.NotifyEmby.sessions')
@mock.patch('apprise.plugins.NotifyEmby.NotifyEmby.login')
@mock.patch('apprise.plugins.NotifyEmby.NotifyEmby.logout')
@mock.patch('requests.get')
@mock.patch('requests.post')
def test_plugin_emby_general(mock_post, mock_get, mock_logout,
@ -104,14 +106,14 @@ def test_plugin_emby_general(mock_post, mock_get, mock_logout,
mock_sessions.return_value = {'abcd': {}}
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost?modal=False')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
assert obj.notify('title', 'body', 'info') is True
obj.access_token = 'abc'
obj.user_id = '123'
# Test Modal support
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost?modal=True')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
assert obj.notify('title', 'body', 'info') is True
obj.access_token = 'abc'
obj.user_id = '123'
@ -171,7 +173,7 @@ def test_plugin_emby_login(mock_post, mock_get, no_throttling):
mock_post.return_value = requests.Request()
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
# Test our exception handling
for _exception in AppriseURLTester.req_exceptions:
@ -203,7 +205,7 @@ def test_plugin_emby_login(mock_post, mock_get, no_throttling):
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost:1234')
# Set a different port (outside of default)
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
assert obj.port == 1234
# The login will fail because '' is not a parseable JSON response
@ -215,7 +217,7 @@ def test_plugin_emby_login(mock_post, mock_get, no_throttling):
# Default port assignments
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
assert obj.port == 8096
# The login will (still) fail because '' is not a parseable JSON response
@ -228,7 +230,7 @@ def test_plugin_emby_login(mock_post, mock_get, no_throttling):
mock_get.return_value.content = mock_post.return_value.content
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
# The login will fail because the 'User' or 'Id' field wasn't parsed
assert obj.login() is False
@ -246,7 +248,7 @@ def test_plugin_emby_login(mock_post, mock_get, no_throttling):
mock_get.return_value.content = mock_post.return_value.content
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
# Login
assert obj.login() is True
@ -270,8 +272,8 @@ def test_plugin_emby_login(mock_post, mock_get, no_throttling):
assert obj.access_token == '0000-0000-0000-0000'
@mock.patch('apprise.plugins.NotifyEmby.login')
@mock.patch('apprise.plugins.NotifyEmby.logout')
@mock.patch('apprise.plugins.NotifyEmby.NotifyEmby.login')
@mock.patch('apprise.plugins.NotifyEmby.NotifyEmby.logout')
@mock.patch('requests.get')
@mock.patch('requests.post')
def test_plugin_emby_sessions(mock_post, mock_get, mock_logout, mock_login,
@ -290,7 +292,7 @@ def test_plugin_emby_sessions(mock_post, mock_get, mock_logout, mock_login,
mock_logout.return_value = True
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
obj.access_token = 'abc'
obj.user_id = '123'
@ -367,7 +369,7 @@ def test_plugin_emby_sessions(mock_post, mock_get, mock_logout, mock_login,
assert len(sessions) == 0
@mock.patch('apprise.plugins.NotifyEmby.login')
@mock.patch('apprise.plugins.NotifyEmby.NotifyEmby.login')
@mock.patch('requests.get')
@mock.patch('requests.post')
def test_plugin_emby_logout(mock_post, mock_get, mock_login, no_throttling):
@ -384,7 +386,7 @@ def test_plugin_emby_logout(mock_post, mock_get, mock_login, no_throttling):
mock_login.return_value = True
obj = Apprise.instantiate('emby://l2g:l2gpass@localhost')
assert isinstance(obj, plugins.NotifyEmby)
assert isinstance(obj, NotifyEmby)
obj.access_token = 'abc'
obj.user_id = '123'

View File

@ -22,8 +22,9 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
import requests
from apprise.plugins.NotifyEnigma2 import NotifyEnigma2
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -42,18 +43,18 @@ apprise_url_tests = (
'instance': None,
}),
('enigma2://localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
# This will fail because we're also expecting a server acknowledgement
'notify_response': False,
}),
('enigma2://localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
# invalid JSON response
'requests_response_text': '{',
'notify_response': False,
}),
('enigma2://localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
# False is returned
'requests_response_text': {
'result': False
@ -61,41 +62,41 @@ apprise_url_tests = (
'notify_response': False,
}),
('enigma2://localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
# With the right content, this will succeed
'requests_response_text': {
'result': True
}
}),
('enigma2://user@localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
}
}),
# Set timeout
('enigma2://user@localhost?timeout=-1', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
}
}),
# Set timeout
('enigma2://user@localhost?timeout=-1000', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
}
}),
# Set invalid timeout (defaults to a set value)
('enigma2://user@localhost?timeout=invalid', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
}
}),
('enigma2://user:pass@localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
@ -104,25 +105,25 @@ apprise_url_tests = (
'privacy_url': 'enigma2://user:****@localhost',
}),
('enigma2://localhost:8080', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
}),
('enigma2://user:pass@localhost:8080', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
}),
('enigma2s://localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
}),
('enigma2s://user:pass@localhost', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
@ -131,7 +132,7 @@ apprise_url_tests = (
'privacy_url': 'enigma2s://user:****@localhost',
}),
('enigma2s://localhost:8080/path/', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
@ -139,19 +140,19 @@ apprise_url_tests = (
'privacy_url': 'enigma2s://localhost:8080/path/',
}),
('enigma2s://user:pass@localhost:8080', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
}),
('enigma2://localhost:8080/path?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
}),
('enigma2://user:pass@localhost:8081', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
@ -160,7 +161,7 @@ apprise_url_tests = (
'requests_response_code': requests.codes.internal_server_error,
}),
('enigma2://user:pass@localhost:8082', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},
@ -169,7 +170,7 @@ apprise_url_tests = (
'requests_response_code': 999,
}),
('enigma2://user:pass@localhost:8083', {
'instance': plugins.NotifyEnigma2,
'instance': NotifyEnigma2,
'requests_response_text': {
'result': True
},

View File

@ -22,8 +22,9 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
import requests
from apprise.plugins.NotifyFaast import NotifyFaast
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -40,30 +41,30 @@ apprise_url_tests = (
}),
# Auth Token specified
('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast,
'instance': NotifyFaast,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'faast://a...a',
}),
('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast,
'instance': NotifyFaast,
# don't include an image by default
'include_image': False,
}),
('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast,
'instance': NotifyFaast,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast,
'instance': 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,
'instance': 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,

View File

@ -37,7 +37,7 @@ import pytest
import requests
import json
from apprise import Apprise
from apprise import plugins
from apprise.plugins.NotifyFCM import NotifyFCM
from helpers import AppriseURLTester
try:
@ -76,18 +76,18 @@ apprise_url_tests = (
}),
('fcm://apikey/', {
# no project id specified so we operate in legacy mode
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# but there are no targets specified so we return False
'notify_response': False,
}),
('fcm://apikey/device', {
# Valid device
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
'privacy_url': 'fcm://a...y/device',
}),
('fcm://apikey/#topic', {
# Valid topic
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
'privacy_url': 'fcm://a...y/%23topic',
}),
('fcm://apikey/device?mode=invalid', {
@ -96,39 +96,39 @@ apprise_url_tests = (
}),
('fcm://apikey/#topic1/device/%20/', {
# Valid topic, valid device, and invalid entry
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://apikey?to=#topic1,device', {
# Test to=
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://?apikey=abc123&to=device', {
# Test apikey= to=
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://?apikey=abc123&to=device&image=yes', {
# Test image boolean
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://?apikey=abc123&to=device&color=no', {
# Disable colors
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://?apikey=abc123&to=device&color=aabbcc', {
# custom colors
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://?apikey=abc123&to=device'
'&image_url=http://example.com/interesting.jpg', {
# Test image_url
'instance': plugins.NotifyFCM}),
'instance': NotifyFCM}),
('fcm://?apikey=abc123&to=device'
'&image_url=http://example.com/interesting.jpg&image=no', {
# Test image_url but set to no
'instance': plugins.NotifyFCM}),
'instance': NotifyFCM}),
('fcm://?apikey=abc123&to=device&+key=value&+key2=value2', {
# Test apikey= to= and data arguments
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
}),
('fcm://%20?to=device&keyfile=/invalid/path', {
# invalid Project ID
@ -136,13 +136,13 @@ apprise_url_tests = (
}),
('fcm://project_id?to=device&keyfile=/invalid/path', {
# Test to= and auto detection of oauth mode
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# we'll fail to send our notification as a result
'response': False,
}),
('fcm://?to=device&project=project_id&keyfile=/invalid/path', {
# Test project= & to= and auto detection of oauth mode
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# we'll fail to send our notification as a result
'response': False,
}),
@ -153,18 +153,18 @@ apprise_url_tests = (
('fcm://project_id?to=device&mode=oauth2&keyfile=/invalid/path', {
# Same test as above except we explicitly set our oauth2 mode
# Test to= and auto detection of oauth mode
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# we'll fail to send our notification as a result
'response': False,
}),
('fcm://apikey/#topic1/device/?mode=legacy', {
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('fcm://apikey/#topic1/device/?mode=legacy', {
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -173,7 +173,7 @@ apprise_url_tests = (
os.path.join(
os.path.dirname(__file__), 'var', 'fcm',
'service_account.json')), {
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -182,7 +182,7 @@ apprise_url_tests = (
os.path.join(
os.path.dirname(__file__), 'var', 'fcm',
'service_account.json')), {
'instance': plugins.NotifyFCM,
'instance': NotifyFCM,
# Throws a series of connection and transfer exceptions when
# this flag is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -862,5 +862,5 @@ def test_plugin_fcm_edge_cases(mock_post, no_throttling):
# this tests an edge case where verify if the data_kwargs is a dictionary
# or not. Below, we don't even define it, so it will be None (causing
# the check to go). We'll still correctly instantiate a plugin:
obj = plugins.NotifyFCM("project", "api:123", targets='device')
obj = NotifyFCM("project", "api:123", targets='device')
assert obj is not None

View File

@ -26,7 +26,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyFlock import NotifyFlock
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -44,74 +45,74 @@ apprise_url_tests = (
}),
# Provide a token
('flock://%s' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Image handling
('flock://%s?image=True' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'flock://t...t',
}),
('flock://%s?image=False' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
('flock://%s?image=True' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
# Run test when image is set to True, but one couldn't actually be
# loaded from the Asset Object.
'include_image': False,
}),
# Test to=
('flock://%s?to=u:%s&format=markdown' % ('i' * 24, 'u' * 12), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Provide markdown format
('flock://%s?format=markdown' % ('i' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Provide text format
('flock://%s?format=text' % ('i' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Native URL Support, take the slack URL and still build from it
('https://api.flock.com/hooks/sendMessage/{}/'.format('i' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Native URL Support with arguments
('https://api.flock.com/hooks/sendMessage/{}/?format=markdown'.format(
'i' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Bot API presumed if one or more targets are specified
# Provide markdown format
('flock://%s/u:%s?format=markdown' % ('i' * 24, 'u' * 12), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Bot API presumed if one or more targets are specified
# Provide text format
('flock://%s/u:%s?format=html' % ('i' * 24, 'u' * 12), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Bot API presumed if one or more targets are specified
# u: is optional
('flock://%s/%s?format=text' % ('i' * 24, 'u' * 12), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Bot API presumed if one or more targets are specified
# Multi-entries
('flock://%s/g:%s/u:%s?format=text' % ('i' * 24, 'g' * 12, 'u' * 12), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Bot API presumed if one or more targets are specified
# Multi-entries using @ for user and # for channel
('flock://%s/#%s/@%s?format=text' % ('i' * 24, 'g' * 12, 'u' * 12), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Bot API presumed if one or more targets are specified
# has bad entry
('flock://%s/g:%s/u:%s?format=text' % ('i' * 24, 'g' * 12, 'u' * 10), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Invalid user/group defined
('flock://%s/g:/u:?format=text' % ('i' * 24), {
@ -121,29 +122,29 @@ apprise_url_tests = (
# As a result, the following will load and pass the data upstream
('flock://%s/g:%s/u:%s?format=text' % ('i' * 24, 'g' * 14, 'u' * 10), {
# We will still instantiate the object
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
}),
# Error Testing
('flock://%s/g:%s/u:%s?format=text' % ('i' * 24, 'g' * 12, 'u' * 10), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('flock://%s/' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('flock://%s/' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('flock://%s/' % ('t' * 24), {
'instance': plugins.NotifyFlock,
'instance': NotifyFlock,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -171,7 +172,7 @@ def test_plugin_flock_edge_cases(mock_post, mock_get, no_throttling):
# Initializes the plugin with an invalid token
with pytest.raises(TypeError):
plugins.NotifyFlock(token=None)
NotifyFlock(token=None)
# Whitespace also acts as an invalid token value
with pytest.raises(TypeError):
plugins.NotifyFlock(token=" ")
NotifyFlock(token=" ")

View File

@ -27,8 +27,9 @@ import pytest
from unittest import mock
import requests
from apprise.plugins.NotifyGitter import NotifyGitter
from helpers import AppriseURLTester
from apprise import plugins
from json import dumps
from datetime import datetime
@ -58,12 +59,12 @@ apprise_url_tests = (
}),
# Token + channel
('gitter://%s/apprise' % ('b' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
'response': False,
}),
# include image in post
('gitter://%s/apprise?image=Yes' % ('c' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
'response': False,
# Our expected url(privacy=True) startswith() response:
@ -71,30 +72,30 @@ apprise_url_tests = (
}),
# Don't include image in post (this is the default anyway)
('gitter://%s/apprise?image=Yes' % ('d' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
'response': False,
# don't include an image by default
'include_image': False,
}),
# Don't include image in post (this is the default anyway)
('gitter://%s/apprise?image=No' % ('e' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
'response': False,
}),
('gitter://%s/apprise' % ('f' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('gitter://%s/apprise' % ('g' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('gitter://%s/apprise' % ('h' * 40), {
'instance': plugins.NotifyGitter,
'instance': NotifyGitter,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -163,8 +164,8 @@ def test_plugin_gitter_general(mock_post, mock_get, no_throttling):
mock_post.return_value = request
# Variation Initializations
obj = plugins.NotifyGitter(token=token, targets='apprise')
assert isinstance(obj, plugins.NotifyGitter) is True
obj = NotifyGitter(token=token, targets='apprise')
assert isinstance(obj, NotifyGitter) is True
assert isinstance(obj.url(), str) is True
# apprise room was found
@ -233,7 +234,7 @@ def test_plugin_gitter_general(mock_post, mock_get, no_throttling):
request.content = '{}'
# Support the 'to' as a target
results = plugins.NotifyGitter.parse_url(
results = NotifyGitter.parse_url(
'gitter://{}?to={}'.format(token, 'apprise'))
assert isinstance(results, dict) is True
assert 'apprise' in results['targets']
@ -246,8 +247,8 @@ def test_plugin_gitter_general(mock_post, mock_get, no_throttling):
assert obj.send(body="test") is True
# Variation Initializations
obj = plugins.NotifyGitter(token=token, targets='apprise')
assert isinstance(obj, plugins.NotifyGitter) is True
obj = NotifyGitter(token=token, targets='apprise')
assert isinstance(obj, NotifyGitter) is True
assert isinstance(obj.url(), str) is True
# apprise room was not found
assert obj.send(body="test") is False
@ -277,7 +278,7 @@ def test_plugin_gitter_edge_cases():
# Initializes the plugin with an invalid token
with pytest.raises(TypeError):
plugins.NotifyGitter(token=None, targets=targets)
NotifyGitter(token=None, targets=targets)
# Whitespace also acts as an invalid token value
with pytest.raises(TypeError):
plugins.NotifyGitter(token=" ", targets=targets)
NotifyGitter(token=" ", targets=targets)

View File

@ -30,7 +30,7 @@ from unittest import mock
import sys
import types
import apprise
from helpers import module_reload
from helpers import reload_plugin
from importlib import reload
@ -113,33 +113,34 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
mock_mainloop.glib.DBusGMainLoop.side_effect = None
mock_mainloop.glib.NativeMainLoop.side_effect = None
module_reload('NotifyDBus')
reload_plugin('NotifyDBus')
from apprise.plugins.NotifyDBus import NotifyDBus
# Create our instance (identify all supported types)
obj = apprise.Apprise.instantiate('dbus://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.url().startswith('dbus://_/')
obj = apprise.Apprise.instantiate('kde://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.url().startswith('kde://_/')
obj = apprise.Apprise.instantiate('qt://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.url().startswith('qt://_/')
obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.url().startswith('glib://_/')
obj.duration = 0
# Test our class loading using a series of arguments
with pytest.raises(TypeError):
apprise.plugins.NotifyDBus(**{'schema': 'invalid'})
NotifyDBus(**{'schema': 'invalid'})
# Set our X and Y coordinate and try the notification
assert apprise.plugins.NotifyDBus(
assert NotifyDBus(
x_axis=0, y_axis=0, **{'schema': 'dbus'})\
.notify(title='', body='body',
notify_type=apprise.NotifyType.INFO) is True
@ -157,7 +158,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Test our arguments through the instantiate call
obj = apprise.Apprise.instantiate(
'dbus://_/?image=True', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.url().startswith('dbus://_/')
assert re.search('image=yes', obj.url())
@ -168,7 +169,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate(
'dbus://_/?image=False', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.url().startswith('dbus://_/')
assert re.search('image=no', obj.url())
@ -180,7 +181,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Test priority (alias to urgency) handling
obj = apprise.Apprise.instantiate(
'dbus://_/?priority=invalid', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -188,7 +189,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate(
'dbus://_/?priority=high', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -196,7 +197,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate(
'dbus://_/?priority=2', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -205,7 +206,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Test urgency handling
obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=invalid', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -213,7 +214,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=high', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -221,7 +222,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=2', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -229,7 +230,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -238,7 +239,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Test x/y
obj = apprise.Apprise.instantiate(
'dbus://_/?x=5&y=5', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(
title='title', body='body',
@ -345,7 +346,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
notify_type=apprise.NotifyType.INFO) is False
# Test the setting of a the urgency
apprise.plugins.NotifyDBus(urgency=0)
NotifyDBus(urgency=0)
#
# We can still notify if the gi library is the only inaccessible
@ -354,11 +355,12 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Emulate require_version function:
gi.require_version.side_effect = ImportError()
module_reload('NotifyDBus')
reload_plugin('NotifyDBus')
from apprise.plugins.NotifyDBus import NotifyDBus
# Create our instance
obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
obj.duration = 0
# Test url() call
@ -383,11 +385,12 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Emulate require_version function:
gi.require_version.side_effect = ValueError()
module_reload('NotifyDBus')
reload_plugin('NotifyDBus')
from apprise.plugins.NotifyDBus import NotifyDBus
# Create our instance
obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyDBus) is True
assert isinstance(obj, NotifyDBus) is True
obj.duration = 0
# Test url() call
@ -403,7 +406,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
sys.modules['dbus'] = compile('raise ImportError()', 'dbus', 'exec')
# Reload our modules
module_reload('NotifyDBus')
reload_plugin('NotifyDBus')
# We can no longer instantiate an instance because dbus has been
# officialy marked unavailable and thus the module is marked
@ -415,4 +418,4 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# let's just put our old configuration back:
sys.modules['dbus'] = _session_bus
# Reload our modules
module_reload('NotifyDBus')
reload_plugin('NotifyDBus')

View File

@ -28,8 +28,8 @@ import types
from unittest import mock
import apprise
from helpers import module_reload
from apprise.plugins.NotifyGnome import GnomeUrgency
from helpers import reload_plugin
# Disable logging for a cleaner testing output
import logging
@ -53,7 +53,7 @@ def test_plugin_gnome_general():
# for the purpose of testing and capture the handling of the
# library when it is missing
del sys.modules[gi_name]
module_reload('NotifyGnome')
reload_plugin('NotifyGnome')
# We need to fake our gnome environment for testing purposes since
# the gi library isn't available in Travis CI
@ -88,7 +88,9 @@ def test_plugin_gnome_general():
notify_obj.show.return_value = True
mock_notify.new.return_value = notify_obj
mock_pixbuf.new_from_file.return_value = True
module_reload('NotifyGnome')
reload_plugin('NotifyGnome')
from apprise.plugins.NotifyGnome import NotifyGnome
# Create our instance
obj = apprise.Apprise.instantiate('gnome://', suppress_exceptions=False)
@ -113,34 +115,35 @@ def test_plugin_gnome_general():
obj = apprise.Apprise.instantiate(
'gnome://_/?image=True', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
print("obj:", obj, type(obj))
assert isinstance(obj, NotifyGnome) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate(
'gnome://_/?image=False', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
# Test Priority (alias of urgency)
obj = apprise.Apprise.instantiate(
'gnome://_/?priority=invalid', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.urgency == 1
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate(
'gnome://_/?priority=high', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.urgency == 2
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate(
'gnome://_/?priority=2', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.urgency == 2
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
@ -149,20 +152,20 @@ def test_plugin_gnome_general():
obj = apprise.Apprise.instantiate(
'gnome://_/?urgency=invalid', suppress_exceptions=False)
assert obj.urgency == 1
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate(
'gnome://_/?urgency=high', suppress_exceptions=False)
assert obj.urgency == 2
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate(
'gnome://_/?urgency=2', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyGnome) is True
assert isinstance(obj, NotifyGnome) is True
assert obj.urgency == 2
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
@ -263,14 +266,14 @@ def test_plugin_gnome_general():
notify_type=apprise.NotifyType.INFO) is False
# Test the setting of a the urgency (through priority keyword)
apprise.plugins.NotifyGnome(priority=0)
NotifyGnome(priority=0)
# Verify this all works in the event a ValueError is also thronw
# out of the call to gi.require_version()
# Emulate require_version function:
gi.require_version.side_effect = ValueError()
module_reload('NotifyGnome')
reload_plugin('NotifyGnome')
# We can now no longer load our instance
# The object internally is marked disabled

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyGoogleChat import NotifyGoogleChat
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -48,34 +49,34 @@ apprise_url_tests = (
}),
# Credentials are good
('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat,
'instance': NotifyGoogleChat,
'privacy_url': 'gchat://w...e/k...y/t...n',
}),
# Test arguments
('gchat://?workspace=ws&key=mykey&token=mytoken', {
'instance': plugins.NotifyGoogleChat,
'instance': NotifyGoogleChat,
'privacy_url': 'gchat://w...s/m...y/m...n',
}),
# Google Native Webhohok URL
('https://chat.googleapis.com/v1/spaces/myworkspace/messages'
'?key=mykey&token=mytoken', {
'instance': plugins.NotifyGoogleChat,
'instance': NotifyGoogleChat,
'privacy_url': 'gchat://m...e/m...y/m...n'}),
('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat,
'instance': NotifyGoogleChat,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat,
'instance': NotifyGoogleChat,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat,
'instance': NotifyGoogleChat,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -27,8 +27,7 @@ from unittest import mock
import pytest
import requests
import apprise
from apprise import plugins
from apprise.plugins.NotifyGotify import GotifyPriority
from apprise.plugins.NotifyGotify import GotifyPriority, NotifyGotify
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -46,55 +45,55 @@ apprise_url_tests = (
}),
# Provide a hostname and token
('gotify://hostname/%s' % ('t' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'gotify://hostname/t...t',
}),
# Provide a hostname, path, and token
('gotify://hostname/a/path/ending/in/a/slash/%s' % ('u' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'gotify://hostname/a/path/ending/in/a/slash/u...u/',
}),
# Markdown test
('gotify://hostname/%s?format=markdown' % ('t' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
}),
# Provide a hostname, path, and token
('gotify://hostname/a/path/not/ending/in/a/slash/%s' % ('v' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'gotify://hostname/a/path/not/ending/in/a/slash/v...v/',
}),
# Provide a priority
('gotify://hostname/%s?priority=high' % ('i' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
}),
# Provide an invalid priority
('gotify://hostname:8008/%s?priority=invalid' % ('i' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
}),
# An invalid url
('gotify://:@/', {
'instance': None,
}),
('gotify://hostname/%s/' % ('t' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('gotifys://localhost/%s/' % ('t' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('gotify://localhost/%s/' % ('t' * 16), {
'instance': plugins.NotifyGotify,
'instance': NotifyGotify,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -119,10 +118,10 @@ def test_plugin_gotify_edge_cases():
"""
# Initializes the plugin with an invalid token
with pytest.raises(TypeError):
plugins.NotifyGotify(token=None)
NotifyGotify(token=None)
# Whitespace also acts as an invalid token value
with pytest.raises(TypeError):
plugins.NotifyGotify(token=" ")
NotifyGotify(token=" ")
@mock.patch('requests.post')
@ -157,7 +156,7 @@ def test_plugin_gotify_config_files(mock_post):
""" % ('a' * 16, 'b' * 16)
# Disable Throttling to speed testing
plugins.NotifyGotify.request_rate_per_sec = 0
NotifyGotify.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()

View File

@ -28,7 +28,8 @@ from unittest import mock
import pytest
import apprise
from apprise.plugins.NotifyGrowl import GrowlPriority
from apprise import NotifyBase
from apprise.plugins.NotifyGrowl import GrowlPriority, NotifyGrowl
try:
from gntp import errors
@ -145,85 +146,85 @@ def test_plugin_growl_general(mock_gntp):
}),
('growl://pass@growl.server', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://ignored:pass@growl.server', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://growl.server', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
# don't include an image by default
'include_image': False,
}),
('growl://growl.server?version=1', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
# Test sticky flag
('growl://growl.server?sticky=yes', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://growl.server?sticky=no', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
# Force a failure
('growl://growl.server?version=1', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
'growl_response': None,
}),
('growl://growl.server?version=2', {
# don't include an image by default
'include_image': False,
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://growl.server?version=2', {
# don't include an image by default
'include_image': False,
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
'growl_response': None,
}),
# Priorities
('growl://pass@growl.server?priority=low', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://pass@growl.server?priority=moderate', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://pass@growl.server?priority=normal', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://pass@growl.server?priority=high', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://pass@growl.server?priority=emergency', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
# Invalid Priorities
('growl://pass@growl.server?priority=invalid', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://pass@growl.server?priority=', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
# invalid version
('growl://growl.server?version=', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://growl.server?version=crap', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
# Ports
('growl://growl.changeport:2000', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://growl.garbageport:garbage', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
('growl://growl.colon:', {
'instance': apprise.plugins.NotifyGrowl,
'instance': NotifyGrowl,
}),
)
@ -269,7 +270,7 @@ def test_plugin_growl_general(mock_gntp):
assert isinstance(obj, instance) is True
if isinstance(obj, apprise.plugins.NotifyBase):
if isinstance(obj, NotifyBase):
# We loaded okay; now lets make sure we can reverse this url
assert isinstance(obj.url(), str) is True
@ -283,7 +284,7 @@ def test_plugin_growl_general(mock_gntp):
# Our object should be the same instance as what we had
# originally expected above.
if not isinstance(obj_cmp, apprise.plugins.NotifyBase):
if not isinstance(obj_cmp, NotifyBase):
# Assert messages are hard to trace back with the way
# these tests work. Just printing before throwing our
# assertion failure makes things easier to debug later on

View File

@ -28,8 +28,9 @@ from unittest import mock
import pytest
import requests
from apprise.plugins.NotifyGuilded import NotifyGuilded
from helpers import AppriseURLTester
from apprise import plugins
# Disable logging for a cleaner testing output
import logging
@ -53,80 +54,80 @@ apprise_url_tests = (
}),
# Provide both an webhook id and a webhook token
('guilded://%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
# Provide a temporary username
('guilded://l2g@%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
# test image= field
('guilded://%s/%s?format=markdown&footer=Yes&image=Yes' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
# don't include an image by default
'include_image': False,
}),
('guilded://%s/%s?format=markdown&footer=Yes&image=No&fields=no' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
('guilded://%s/%s?format=markdown&footer=Yes&image=Yes' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
('https://media.guilded.gg/webhooks/{}/{}'.format(
'0' * 10, 'B' * 40), {
# Native URL Support, support the provided guilded URL from their
# webpage.
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
('guilded://%s/%s?format=markdown&avatar=No&footer=No' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
# different format support
('guilded://%s/%s?format=markdown' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
('guilded://%s/%s?format=text' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
# Test with avatar URL
('guilded://%s/%s?avatar_url=http://localhost/test.jpg' % (
'i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
}),
# Test without image set
('guilded://%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
'requests_response_code': requests.codes.no_content,
# don't include an image by default
'include_image': False,
}),
('guilded://%s/%s/' % ('a' * 24, 'b' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('guilded://%s/%s/' % ('a' * 24, 'b' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('guilded://%s/%s/' % ('a' * 24, 'b' * 64), {
'instance': plugins.NotifyGuilded,
'instance': NotifyGuilded,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -161,19 +162,19 @@ def test_plugin_guilded_general(mock_post, no_throttling):
# Invalid webhook id
with pytest.raises(TypeError):
plugins.NotifyGuilded(webhook_id=None, webhook_token=webhook_token)
NotifyGuilded(webhook_id=None, webhook_token=webhook_token)
# Invalid webhook id (whitespace)
with pytest.raises(TypeError):
plugins.NotifyGuilded(webhook_id=" ", webhook_token=webhook_token)
NotifyGuilded(webhook_id=" ", webhook_token=webhook_token)
# Invalid webhook token
with pytest.raises(TypeError):
plugins.NotifyGuilded(webhook_id=webhook_id, webhook_token=None)
NotifyGuilded(webhook_id=webhook_id, webhook_token=None)
# Invalid webhook token (whitespace)
with pytest.raises(TypeError):
plugins.NotifyGuilded(webhook_id=webhook_id, webhook_token=" ")
NotifyGuilded(webhook_id=webhook_id, webhook_token=" ")
obj = plugins.NotifyGuilded(
obj = NotifyGuilded(
webhook_id=webhook_id,
webhook_token=webhook_token,
footer=True, thumbnail=False)

View File

@ -26,8 +26,8 @@
from unittest import mock
import requests
from apprise import plugins
from apprise import Apprise
from apprise.plugins.NotifyHomeAssistant import NotifyHomeAssistant
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -50,19 +50,19 @@ apprise_url_tests = (
'instance': TypeError,
}),
('hassio://localhost/long-lived-access-token', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
}),
('hassio://user:pass@localhost/long-lived-access-token/', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'hassio://user:****@localhost/l...n',
}),
('hassio://localhost:80/long-lived-access-token', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
}),
('hassio://user@localhost:8123/llat', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
'privacy_url': 'hassio://user@localhost/l...t',
}),
('hassios://localhost/llat?nid=!%', {
@ -71,41 +71,41 @@ apprise_url_tests = (
}),
('hassios://localhost/llat?nid=abcd', {
# Valid notification_id
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
}),
('hassios://user:pass@localhost/llat', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
'privacy_url': 'hassios://user:****@localhost/l...t',
}),
('hassios://localhost:8443/path/llat/', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
'privacy_url': 'hassios://localhost:8443/path/l...t',
}),
('hassio://localhost:8123/a/path?accesstoken=llat', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
# Default port; so it's stripped off
# accesstoken was specified as kwarg
'privacy_url': 'hassio://localhost/a/path/l...t',
}),
('hassios://user:password@localhost:80/llat/', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
'privacy_url': 'hassios://user:****@localhost:80',
}),
('hassio://user:pass@localhost:8123/llat', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('hassio://user:pass@localhost/llat', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('hassio://user:pass@localhost/llat', {
'instance': plugins.NotifyHomeAssistant,
'instance': NotifyHomeAssistant,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -139,7 +139,7 @@ def test_plugin_homeassistant_general(mock_post, no_throttling):
# Variation Initializations
obj = Apprise.instantiate('hassio://localhost/accesstoken')
assert isinstance(obj, plugins.NotifyHomeAssistant) is True
assert isinstance(obj, NotifyHomeAssistant) is True
assert isinstance(obj.url(), str) is True
# Send Notification

View File

@ -26,8 +26,8 @@ import pytest
from unittest import mock
import requests
from apprise import plugins
from apprise import NotifyType
from apprise.plugins.NotifyIFTTT import NotifyIFTTT
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -48,22 +48,22 @@ apprise_url_tests = (
}),
# A nicely formed ifttt url with 1 event and a new key/value store
('ifttt://WebHookID@EventID/?+TemplateKey=TemplateVal', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'ifttt://W...D',
}),
# Test to= in which case we set the host to the webhook id
('ifttt://WebHookID?to=EventID,EventID2', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
}),
# Removing certain keys:
('ifttt://WebHookID@EventID/?-Value1=&-Value2', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
}),
# A nicely formed ifttt url with 2 events defined:
('ifttt://WebHookID@EventID/EventID2/', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
}),
# Support Native URL references
('https://maker.ifttt.com/use/WebHookID/', {
@ -71,27 +71,27 @@ apprise_url_tests = (
'instance': TypeError,
}),
('https://maker.ifttt.com/use/WebHookID/EventID/', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
}),
# Native URL with arguments
('https://maker.ifttt.com/use/WebHookID/EventID/?-Value1=', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
}),
# Test website connection failures
('ifttt://WebHookID@EventID', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('ifttt://WebHookID@EventID', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('ifttt://WebHookID@EventID', {
'instance': plugins.NotifyIFTTT,
'instance': NotifyIFTTT,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -131,72 +131,72 @@ def test_plugin_ifttt_edge_cases(mock_post, mock_get, no_throttling):
# No webhook_id specified
with pytest.raises(TypeError):
plugins.NotifyIFTTT(webhook_id=None, events=None)
NotifyIFTTT(webhook_id=None, events=None)
# Initializes the plugin with an invalid webhook id
with pytest.raises(TypeError):
plugins.NotifyIFTTT(webhook_id=None, events=events)
NotifyIFTTT(webhook_id=None, events=events)
# Whitespace also acts as an invalid webhook id
with pytest.raises(TypeError):
plugins.NotifyIFTTT(webhook_id=" ", events=events)
NotifyIFTTT(webhook_id=" ", events=events)
# No events specified
with pytest.raises(TypeError):
plugins.NotifyIFTTT(webhook_id=webhook_id, events=None)
NotifyIFTTT(webhook_id=webhook_id, events=None)
obj = plugins.NotifyIFTTT(webhook_id=webhook_id, events=events)
assert isinstance(obj, plugins.NotifyIFTTT) is True
obj = NotifyIFTTT(webhook_id=webhook_id, events=events)
assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True
# Test the addition of tokens
obj = plugins.NotifyIFTTT(
obj = NotifyIFTTT(
webhook_id=webhook_id, events=events,
add_tokens={'Test': 'ValueA', 'Test2': 'ValueB'})
assert isinstance(obj, plugins.NotifyIFTTT) is True
assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True
# Invalid del_tokens entry
with pytest.raises(TypeError):
plugins.NotifyIFTTT(
NotifyIFTTT(
webhook_id=webhook_id, events=events,
del_tokens=plugins.NotifyIFTTT.ifttt_default_title_key)
del_tokens=NotifyIFTTT.ifttt_default_title_key)
assert isinstance(obj, plugins.NotifyIFTTT) is True
assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True
# Test removal of tokens by a list
obj = plugins.NotifyIFTTT(
obj = NotifyIFTTT(
webhook_id=webhook_id, events=events,
add_tokens={
'MyKey': 'MyValue'
},
del_tokens=(
plugins.NotifyIFTTT.ifttt_default_title_key,
plugins.NotifyIFTTT.ifttt_default_body_key,
plugins.NotifyIFTTT.ifttt_default_type_key))
NotifyIFTTT.ifttt_default_title_key,
NotifyIFTTT.ifttt_default_body_key,
NotifyIFTTT.ifttt_default_type_key))
assert isinstance(obj, plugins.NotifyIFTTT) is True
assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True
# Test removal of tokens as dict
obj = plugins.NotifyIFTTT(
obj = NotifyIFTTT(
webhook_id=webhook_id, events=events,
add_tokens={
'MyKey': 'MyValue'
},
del_tokens={
plugins.NotifyIFTTT.ifttt_default_title_key: None,
plugins.NotifyIFTTT.ifttt_default_body_key: None,
plugins.NotifyIFTTT.ifttt_default_type_key: None})
NotifyIFTTT.ifttt_default_title_key: None,
NotifyIFTTT.ifttt_default_body_key: None,
NotifyIFTTT.ifttt_default_type_key: None})
assert isinstance(obj, plugins.NotifyIFTTT) is True
assert isinstance(obj, NotifyIFTTT) is True

View File

@ -27,10 +27,9 @@ from unittest import mock
import pytest
import requests
import apprise
from apprise import plugins
from apprise import NotifyType
from helpers import AppriseURLTester
from apprise.plugins.NotifyJoin import JoinPriority
from apprise.plugins.NotifyJoin import JoinPriority, NotifyJoin
# Disable logging for a cleaner testing output
import logging
@ -47,69 +46,69 @@ apprise_url_tests = (
}),
# APIkey; no device
('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# API Key + device (using to=)
('join://%s?to=%s' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'join://a...a/',
}),
# API Key + priority setting
('join://%s?priority=high' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# API Key + invalid priority setting
('join://%s?priority=invalid' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# API Key + priority setting (empty)
('join://%s?priority=' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# API Key + device
('join://%s@%s?image=True' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# No image
('join://%s@%s?image=False' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# API Key + Device Name
('join://%s/%s' % ('a' * 32, 'My Device'), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
# API Key + device
('join://%s/%s' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
# don't include an image by default
'include_image': False,
}),
# API Key + 2 devices
('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'e' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
# don't include an image by default
'include_image': False,
}),
# API Key + 1 device and 1 group
('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'group.chrome'), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
}),
('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': NotifyJoin,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin,
'instance': 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,
@ -141,21 +140,21 @@ def test_plugin_join_edge_cases(mock_post, mock_get, no_throttling):
apikey = 'a' * 32
# Initializes the plugin with devices set to a string
plugins.NotifyJoin(apikey=apikey, targets=group)
NotifyJoin(apikey=apikey, targets=group)
# Initializes the plugin with devices set to None
plugins.NotifyJoin(apikey=apikey, targets=None)
NotifyJoin(apikey=apikey, targets=None)
# Initializes the plugin with an invalid apikey
with pytest.raises(TypeError):
plugins.NotifyJoin(apikey=None)
NotifyJoin(apikey=None)
# Whitespace also acts as an invalid apikey
with pytest.raises(TypeError):
plugins.NotifyJoin(apikey=" ")
NotifyJoin(apikey=" ")
# Initializes the plugin with devices set to a set
p = plugins.NotifyJoin(apikey=apikey, targets=[group, device])
p = NotifyJoin(apikey=apikey, targets=[group, device])
# Prepare our mock responses
req = requests.Request()

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyKavenegar import NotifyKavenegar
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,26 +41,26 @@ apprise_url_tests = (
}),
('kavenegar://{}/{}/{}'.format('1' * 10, '2' * 15, 'a' * 13), {
# valid api key and valid authentication
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
}),
('kavenegar://{}/{}'.format('a' * 24, '3' * 14), {
# valid api key and valid number
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kavenegar://a...a/',
}),
('kavenegar://{}?to={}'.format('a' * 24, '3' * 14), {
# valid api key and valid number
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kavenegar://a...a/',
}),
('kavenegar://{}@{}/{}'.format('1' * 14, 'b' * 24, '3' * 14), {
# valid api key and valid number
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kavenegar://{}@b...b/'.format('1' * 14),
}),
@ -74,18 +74,18 @@ apprise_url_tests = (
}),
('kavenegar://{}/{}?from={}'.format('b' * 24, '3' * 14, '1' * 14), {
# valid api key and valid number
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kavenegar://{}@b...b/'.format('1' * 14),
}),
('kavenegar://{}/{}'.format('b' * 24, '4' * 14), {
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('kavenegar://{}/{}'.format('c' * 24, '5' * 14), {
'instance': plugins.NotifyKavenegar,
'instance': NotifyKavenegar,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -24,7 +24,8 @@
# THE SOFTWARE.
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyKumulos import NotifyKumulos
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,13 +54,13 @@ apprise_url_tests = (
}),
('kumulos://{}/{}/'.format(UUID4, 'w' * 36), {
# Everything is okay
'instance': plugins.NotifyKumulos,
'instance': NotifyKumulos,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kumulos://8...2/w...w/',
}),
('kumulos://{}/{}/'.format(UUID4, 'x' * 36), {
'instance': plugins.NotifyKumulos,
'instance': NotifyKumulos,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
@ -68,7 +69,7 @@ apprise_url_tests = (
'privacy_url': 'kumulos://8...2/x...x/',
}),
('kumulos://{}/{}/'.format(UUID4, 'y' * 36), {
'instance': plugins.NotifyKumulos,
'instance': NotifyKumulos,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -77,7 +78,7 @@ apprise_url_tests = (
'privacy_url': 'kumulos://8...2/y...y/',
}),
('kumulos://{}/{}/'.format(UUID4, 'z' * 36), {
'instance': plugins.NotifyKumulos,
'instance': NotifyKumulos,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -103,12 +104,12 @@ def test_plugin_kumulos_edge_cases(no_throttling):
# Invalid API Key
with pytest.raises(TypeError):
plugins.NotifyKumulos(None, None)
NotifyKumulos(None, None)
with pytest.raises(TypeError):
plugins.NotifyKumulos(" ", None)
NotifyKumulos(" ", None)
# Invalid Server Key
with pytest.raises(TypeError):
plugins.NotifyKumulos("abcd", None)
NotifyKumulos("abcd", None)
with pytest.raises(TypeError):
plugins.NotifyKumulos("abcd", " ")
NotifyKumulos("abcd", " ")

View File

@ -24,7 +24,7 @@
# THE SOFTWARE.
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyLametric import NotifyLametric
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -52,7 +52,7 @@ apprise_url_tests = (
('lametric://root:{}@192.168.0.5:8080/'.format(UUID4), {
# Everything is okay; this would be picked up in Device Mode
# We're using a default port and enforcing a special user
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://root:8...2@192.168.0.5/',
@ -60,21 +60,21 @@ apprise_url_tests = (
('lametric://{}@192.168.0.4:8000/'.format(UUID4), {
# Everything is okay; this would be picked up in Device Mode
# Port is enforced
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://8...2@192.168.0.4:8000/',
}),
('lametric://{}@192.168.0.5/'.format(UUID4), {
# Everything is okay; this would be picked up in Device Mode
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://8...2@192.168.0.5/',
}),
('lametrics://{}@192.168.0.6/?mode=device'.format(UUID4), {
# Everything is okay; Device mode forced
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametrics://8...2@192.168.0.6/',
@ -83,7 +83,7 @@ apprise_url_tests = (
('https://developer.lametric.com/api/v1/dev/widget/update/'
'com.lametric.ABCD123/1?token={}=='.format('D' * 88), {
# Everything is okay; Device mode forced
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://D...=@A...3/1/',
@ -91,7 +91,7 @@ apprise_url_tests = (
('lametric://192.168.2.8/?mode=device&apikey=abc123', {
# Everything is okay; Device mode forced
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://a...3@192.168.2.8/',
@ -101,7 +101,7 @@ apprise_url_tests = (
# Everything is okay; Cloud mode forced
# We gracefully strip off the com.lametric. part as well
# We also set an application version of 2
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://A...=@9...0/',
@ -115,7 +115,7 @@ apprise_url_tests = (
('lametric://?app=com.lametric.941c51dff3135bd87aa72db9d855dd50&token={}=='
'&mode=cloud'.format('B' * 88), {
# Everything is okay; Cloud mode forced
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://B...=@9...0/',
@ -124,7 +124,7 @@ apprise_url_tests = (
'&priority=critical&cycles=10'.format('C' * 88), {
# Cloud mode forced, sound, icon_type, and priority not supported
# with cloud mode so warnings are created
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'lametric://C...=@a...d/',
@ -135,70 +135,70 @@ apprise_url_tests = (
}),
('lametrics://{}@192.168.0.6/?sound=alarm1'.format(UUID4), {
# Device mode with sound set to alarm1
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametrics://{}@192.168.0.7/?sound=bike'.format(UUID4), {
# Device mode with sound set to bicycle using alias
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Bike is an alias,
'url_matches': r'sound=bicycle',
}),
('lametrics://{}@192.168.0.8/?sound=invalid!'.format(UUID4), {
# Invalid sounds just produce warnings... object still loads
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametrics://{}@192.168.0.9/?icon_type=alert'.format(UUID4), {
# Icon Type Changed
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# icon=alert exists somewhere on our generated URL
'url_matches': r'icon_type=alert',
}),
('lametrics://{}@192.168.0.10/?icon_type=invalid'.format(UUID4), {
# Invalid icon types just produce warnings... object still loads
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.1/?priority=warning'.format(UUID4), {
# Priority changed
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametrics://{}@192.168.1.2/?priority=invalid'.format(UUID4), {
# Invalid priority just produce warnings... object still loads
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.2/?icon=230'.format(UUID4), {
# Our custom icon by it's ID
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametrics://{}@192.168.1.2/?icon=#230'.format(UUID4), {
# Our custom icon by it's ID; the hashtag at the front is ignored
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.2/?icon=Heart'.format(UUID4), {
# Our custom icon; the hashtag at the front is ignored
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.2/?icon=#'.format(UUID4), {
# a hashtag and nothing else
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.2/?icon=#%20%20%20'.format(UUID4), {
# a hashtag and some spaces
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.3/?cycles=2'.format(UUID4), {
# Cycles changed
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@192.168.1.4/?cycles=-1'.format(UUID4), {
# Cycles changed (out of range)
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametrics://{}@192.168.1.5/?cycles=invalid'.format(UUID4), {
# Invalid priority just produce warnings... object still loads
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
}),
('lametric://{}@example.com/'.format(UUID4), {
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
@ -207,7 +207,7 @@ apprise_url_tests = (
'privacy_url': 'lametric://8...2@example.com/',
}),
('lametrics://{}@example.ca/'.format(UUID4), {
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -216,7 +216,7 @@ apprise_url_tests = (
'privacy_url': 'lametrics://8...2@example.ca/',
}),
('lametrics://{}@example.net/'.format(UUID4), {
'instance': plugins.NotifyLametric,
'instance': NotifyLametric,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -241,8 +241,8 @@ def test_plugin_lametric_edge_cases():
"""
# Initializes the plugin with an invalid API Key
with pytest.raises(TypeError):
plugins.NotifyLametric(apikey=None, mode="device")
NotifyLametric(apikey=None, mode="device")
# Initializes the plugin with an invalid Client Secret
with pytest.raises(TypeError):
plugins.NotifyLametric(client_id='valid', secret=None, mode="cloud")
NotifyLametric(client_id='valid', secret=None, mode="cloud")

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyLine import NotifyLine
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,41 +41,41 @@ apprise_url_tests = (
}),
('line://token', {
# no target specified
'instance': plugins.NotifyLine,
'instance': NotifyLine,
# Expected notify() response
'notify_response': False,
}),
('line://token=/target', {
# minimum requirements met
'instance': plugins.NotifyLine,
'instance': NotifyLine,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'line://****/t...t?',
}),
('line://token/target?image=no', {
# minimum requirements met; no icon display
'instance': plugins.NotifyLine,
'instance': NotifyLine,
}),
('line://a/very/long/token=/target?image=no', {
# minimum requirements met; no icon display
'instance': plugins.NotifyLine,
'instance': NotifyLine,
}),
('line://?token=token&to=target1', {
# minimum requirements met
'instance': plugins.NotifyLine,
'instance': NotifyLine,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'line://****/t...1?',
}),
('line://token/target', {
'instance': plugins.NotifyLine,
'instance': NotifyLine,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('line://token/target', {
'instance': plugins.NotifyLine,
'instance': NotifyLine,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -26,7 +26,7 @@
import os
from unittest import mock
from helpers import module_reload
from helpers import reload_plugin
import apprise
@ -59,15 +59,16 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
mock_macver.return_value = ('10.8', ('', '', ''), '')
mock_popen.return_value = mock_cmd_response
# Ensure our enviroment is loaded with this configuration
module_reload('NotifyMacOSX')
# Ensure our environment is loaded with this configuration
reload_plugin('NotifyMacOSX')
from apprise.plugins.NotifyMacOSX import NotifyMacOSX
# Point our object to our new temporary existing file
apprise.plugins.NotifyMacOSX.notify_paths = (str(script), )
NotifyMacOSX.notify_paths = (str(script), )
obj = apprise.Apprise.instantiate(
'macosx://_/?image=True', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMacOSX) is True
assert isinstance(obj, NotifyMacOSX) is True
# Test url() call
assert isinstance(obj.url(), str) is True
@ -82,13 +83,13 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
obj = apprise.Apprise.instantiate(
'macosx://_/?image=True', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMacOSX) is True
assert isinstance(obj, NotifyMacOSX) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate(
'macosx://_/?image=False', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMacOSX) is True
assert isinstance(obj, NotifyMacOSX) is True
assert isinstance(obj.url(), str) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True
@ -96,7 +97,7 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
# Test Sound
obj = apprise.Apprise.instantiate(
'macosx://_/?sound=default', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMacOSX) is True
assert isinstance(obj, NotifyMacOSX) is True
assert obj.sound == 'default'
assert isinstance(obj.url(), str) is True
assert obj.notify(title='title', body='body',
@ -121,7 +122,7 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
mock_cmd_response.returncode = 1
obj = apprise.Apprise.instantiate(
'macosx://', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMacOSX) is True
assert isinstance(obj, NotifyMacOSX) is True
assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is False
@ -130,10 +131,10 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
# Test case where we simply aren't on a mac
mock_system.return_value = 'Linux'
module_reload('NotifyMacOSX')
reload_plugin('NotifyMacOSX')
# Point our object to our new temporary existing file
apprise.plugins.NotifyMacOSX.notify_paths = (str(script), )
NotifyMacOSX.notify_paths = (str(script), )
# Our object is disabled
obj = apprise.Apprise.instantiate(
@ -145,10 +146,10 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
# Now we must be Mac OS v10.8 or higher...
mock_macver.return_value = ('10.7', ('', '', ''), '')
module_reload('NotifyMacOSX')
reload_plugin('NotifyMacOSX')
# Point our object to our new temporary existing file
apprise.plugins.NotifyMacOSX.notify_paths = (str(script), )
NotifyMacOSX.notify_paths = (str(script), )
obj = apprise.Apprise.instantiate(
'macosx://_/?sound=default', suppress_exceptions=False)
@ -156,10 +157,10 @@ def test_plugin_macosx_general(mock_macver, mock_system, mock_popen, tmpdir):
# A newer environment to test edge case where this is tested
mock_macver.return_value = ('9.12', ('', '', ''), '')
module_reload('NotifyMacOSX')
reload_plugin('NotifyMacOSX')
# Point our object to our new temporary existing file
apprise.plugins.NotifyMacOSX.notify_paths = (str(script), )
NotifyMacOSX.notify_paths = (str(script), )
# This is just to test that the the minor (in this case .12)
# is only weighed with respect to the major number as wel

View File

@ -27,8 +27,9 @@ import os
from unittest import mock
import requests
from apprise.plugins.NotifyMailgun import NotifyMailgun
from helpers import AppriseURLTester
from apprise import plugins
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import NotifyType
@ -65,29 +66,29 @@ apprise_url_tests = (
# No To email address, but everything else is valid
('mailgun://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
('mailgun://user@localhost.localdomain/{}-{}-{}?format=markdown'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
('mailgun://user@localhost.localdomain/{}-{}-{}?format=html'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
('mailgun://user@localhost.localdomain/{}-{}-{}?format=text'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
# valid url with region specified (case insensitve)
('mailgun://user@localhost.localdomain/{}-{}-{}?region=uS'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
# valid url with region specified (case insensitve)
('mailgun://user@localhost.localdomain/{}-{}-{}?region=EU'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
# invalid url with region specified (case insensitve)
('mailgun://user@localhost.localdomain/{}-{}-{}?region=invalid'.format(
@ -98,38 +99,38 @@ apprise_url_tests = (
('mailgun://user@localhost.localdomain/{}-{}-{}'
'?+X-Customer-Campaign-ID=Apprise'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
# template tokens
('mailgun://user@localhost.localdomain/{}-{}-{}'
'?:name=Chris&:status=admin'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
# bcc and cc
('mailgun://user@localhost.localdomain/{}-{}-{}'
'?bcc=user@example.com&cc=user2@example.com'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
# One To Email address
('mailgun://user@localhost.localdomain/{}-{}-{}/test@example.com'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
('mailgun://user@localhost.localdomain/'
'{}-{}-{}?to=test@example.com'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun}),
'instance': NotifyMailgun}),
# One To Email address, a from name specified too
('mailgun://user@localhost.localdomain/{}-{}-{}/'
'test@example.com?name="Frodo"'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun}),
'instance': NotifyMailgun}),
# Invalid 'To' Email address
('mailgun://user@localhost.localdomain/{}-{}-{}/invalid'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
# Expected notify() response
'notify_response': False,
}),
@ -139,25 +140,25 @@ apprise_url_tests = (
'/'.join(('user1@example.com', 'invalid', 'User2:user2@example.com')),
','.join(('user3@example.com', 'i@v', 'User1:user1@example.com')),
','.join(('user4@example.com', 'g@r@b', 'Da:user5@example.com'))), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
}),
('mailgun://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('mailgun://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('mailgun://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifyMailgun,
'instance': NotifyMailgun,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -194,7 +195,7 @@ def test_plugin_mailgun_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'mailgun://user@localhost.localdomain/{}'.format(apikey))
assert isinstance(obj, plugins.NotifyMailgun)
assert isinstance(obj, NotifyMailgun)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -266,7 +267,7 @@ def test_plugin_mailgun_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'mailgun://no-reply@example.com/{}/'
'user1@example.com/user2@example.com?batch=yes'.format(apikey))
assert isinstance(obj, plugins.NotifyMailgun)
assert isinstance(obj, NotifyMailgun)
# Force our batch to break into separate messages
obj.default_batch_size = 1

View File

@ -27,9 +27,10 @@ from unittest import mock
import requests
import pytest
from apprise import plugins
from apprise import AppriseAsset
from json import dumps
from apprise.plugins.NotifyMatrix import NotifyMatrix
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -49,7 +50,7 @@ apprise_url_tests = (
}),
('matrix://localhost?mode=off', {
# treats it as a anonymous user to register
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# response is false because we have nothing to notify
'response': False,
}),
@ -59,18 +60,18 @@ apprise_url_tests = (
'instance': TypeError
}),
('matrix://user:pass@localhost/#room1/#room2/#room3', {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('matrix://user:pass@localhost/#room1/#room2/!room1', {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('matrix://user:pass@localhost:1234/#room', {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -82,42 +83,42 @@ apprise_url_tests = (
# Matrix supports webhooks too; the following tests this now:
('matrix://user:token@localhost?mode=matrix&format=text', {
# user and token correctly specified with webhook
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
'response': False,
}),
('matrix://user:token@localhost?mode=matrix&format=html', {
# user and token correctly specified with webhook
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
('matrix://user:token@localhost?mode=slack&format=text', {
# user and token correctly specified with webhook
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
('matrixs://user:token@localhost?mode=SLACK&format=markdown', {
# user and token specified; slack webhook still detected
# despite uppercase characters
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
('matrix://user@localhost?mode=SLACK&format=markdown&token=mytoken', {
# user and token specified; slack webhook still detected
# despite uppercase characters; token also set on URL as arg
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
('matrix://_?mode=t2bot&token={}'.format('b' * 64), {
# Testing t2bot initialization and setting the password using the
# token directive
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'matrix://b...b/',
}),
# Image Reference
('matrixs://user:token@localhost?mode=slack&format=markdown&image=True', {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
('matrixs://user:token@localhost?mode=slack&format=markdown&image=False', {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
# A Bunch of bad ports
('matrixs://user:pass@hostname:port/#room_alias', {
@ -136,15 +137,15 @@ apprise_url_tests = (
('matrixs://user@{}?mode=t2bot&format=markdown&image=True'
.format('a' * 64), {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix}),
'instance': NotifyMatrix}),
('matrix://user@{}?mode=t2bot&format=html&image=False'
.format('z' * 64), {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix}),
'instance': NotifyMatrix}),
# This will default to t2bot because no targets were specified and no
# password
('matrixs://{}'.format('c' * 64), {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -152,31 +153,31 @@ apprise_url_tests = (
# Test Native URL
('https://webhooks.t2bot.io/api/v1/matrix/hook/{}/'.format('d' * 64), {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
}),
('matrix://user:token@localhost?mode=On', {
# invalid webhook specified (unexpected boolean)
'instance': TypeError,
}),
('matrix://token@localhost/?mode=Matrix', {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('matrix://user:token@localhost/mode=matrix', {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('matrix://token@localhost:8080/?mode=slack', {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
('matrix://{}/?mode=t2bot'.format('b' * 64), {
'instance': plugins.NotifyMatrix,
'instance': NotifyMatrix,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -218,70 +219,70 @@ def test_plugin_matrix_general(mock_post, mock_get, no_throttling):
mock_post.return_value = request
# Variation Initializations
obj = plugins.NotifyMatrix(host='host', targets='#abcd')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', targets='#abcd')
assert isinstance(obj, NotifyMatrix) is True
assert isinstance(obj.url(), str) is True
# Registration successful
assert obj.send(body="test") is True
obj = plugins.NotifyMatrix(host='host', user='user', targets='#abcd')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', user='user', targets='#abcd')
assert isinstance(obj, NotifyMatrix) is True
assert isinstance(obj.url(), str) is True
# Registration successful
assert obj.send(body="test") is True
obj = plugins.NotifyMatrix(host='host', password='passwd', targets='#abcd')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', password='passwd', targets='#abcd')
assert isinstance(obj, NotifyMatrix) is True
assert isinstance(obj.url(), str) is True
# A username gets automatically generated in these cases
assert obj.send(body="test") is True
obj = plugins.NotifyMatrix(
obj = NotifyMatrix(
host='host', user='user', password='passwd', targets='#abcd')
assert isinstance(obj.url(), str) is True
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
# Registration Successful
assert obj.send(body="test") is True
# Test sending other format types
kwargs = plugins.NotifyMatrix.parse_url(
kwargs = NotifyMatrix.parse_url(
'matrix://user:passwd@hostname/#abcd?format=html')
obj = plugins.NotifyMatrix(**kwargs)
obj = NotifyMatrix(**kwargs)
assert isinstance(obj.url(), str) is True
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
obj.send(body="test") is True
obj.send(title="title", body="test") is True
kwargs = plugins.NotifyMatrix.parse_url(
kwargs = NotifyMatrix.parse_url(
'matrix://user:passwd@hostname/#abcd/#abcd:localhost?format=markdown')
obj = plugins.NotifyMatrix(**kwargs)
obj = NotifyMatrix(**kwargs)
assert isinstance(obj.url(), str) is True
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
obj.send(body="test") is True
obj.send(title="title", body="test") is True
kwargs = plugins.NotifyMatrix.parse_url(
kwargs = NotifyMatrix.parse_url(
'matrix://user:passwd@hostname/#abcd/!abcd:localhost?format=text')
obj = plugins.NotifyMatrix(**kwargs)
obj = NotifyMatrix(**kwargs)
assert isinstance(obj.url(), str) is True
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
obj.send(body="test") is True
obj.send(title="title", body="test") is True
# Test notice type notifications
kwargs = plugins.NotifyMatrix.parse_url(
kwargs = NotifyMatrix.parse_url(
'matrix://user:passwd@hostname/#abcd?msgtype=notice')
obj = plugins.NotifyMatrix(**kwargs)
obj = NotifyMatrix(**kwargs)
assert isinstance(obj.url(), str) is True
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
obj.send(body="test") is True
obj.send(title="title", body="test") is True
with pytest.raises(TypeError):
# invalid message type specified
kwargs = plugins.NotifyMatrix.parse_url(
kwargs = NotifyMatrix.parse_url(
'matrix://user:passwd@hostname/#abcd?msgtype=invalid')
obj = plugins.NotifyMatrix(**kwargs)
obj = NotifyMatrix(**kwargs)
# Force a failed login
ro = response_obj.copy()
@ -292,20 +293,20 @@ def test_plugin_matrix_general(mock_post, mock_get, no_throttling):
# Fails because we couldn't register because of 404 errors
assert obj.send(body="test") is False
obj = plugins.NotifyMatrix(host='host', user='test', targets='#abcd')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', user='test', targets='#abcd')
assert isinstance(obj, NotifyMatrix) is True
# Fails because we still couldn't register
assert obj.send(user='test', password='passwd', body="test") is False
obj = plugins.NotifyMatrix(
obj = NotifyMatrix(
host='host', user='test', password='passwd', targets='#abcd')
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
# Fails because we still couldn't register
assert obj.send(body="test") is False
obj = plugins.NotifyMatrix(host='host', password='passwd', targets='#abcd')
obj = NotifyMatrix(host='host', password='passwd', targets='#abcd')
# Fails because we still couldn't register
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
assert obj.send(body="test") is False
# Force a empty joined list response
@ -331,8 +332,8 @@ def test_plugin_matrix_general(mock_post, mock_get, no_throttling):
request.content = dumps(response_obj)
request.status_code = requests.codes.ok
obj = plugins.NotifyMatrix(host='host', targets=None)
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', targets=None)
assert isinstance(obj, NotifyMatrix) is True
# Force a empty joined list response
ro = response_obj.copy()
@ -388,17 +389,17 @@ def test_plugin_matrix_fetch(mock_post, mock_get, no_throttling):
mock_get.side_effect = fetch_failed
mock_post.side_effect = fetch_failed
obj = plugins.NotifyMatrix(
obj = NotifyMatrix(
host='host', user='user', password='passwd', include_image=True)
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
# We would hve failed to send our image notification
assert obj.send(user='test', password='passwd', body="test") is False
# Do the same query with no images to fetch
asset = AppriseAsset(image_path_mask=False, image_url_mask=False)
obj = plugins.NotifyMatrix(
obj = NotifyMatrix(
host='host', user='user', password='passwd', asset=asset)
assert isinstance(obj, plugins.NotifyMatrix) is True
assert isinstance(obj, NotifyMatrix) is True
# We would hve failed to send our notification
assert obj.send(user='test', password='passwd', body="test") is False
@ -422,8 +423,8 @@ def test_plugin_matrix_fetch(mock_post, mock_get, no_throttling):
mock_post.return_value = request
mock_get.return_value = request
obj = plugins.NotifyMatrix(host='host', include_image=True)
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', include_image=True)
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
assert obj._register() is True
assert obj.access_token is not None
@ -473,8 +474,8 @@ def test_plugin_matrix_auth(mock_post, mock_get, no_throttling):
mock_post.return_value = request
mock_get.return_value = request
obj = plugins.NotifyMatrix(host='localhost')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='localhost')
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# logging out without an access_token is silently a success
assert obj._logout() is True
@ -510,8 +511,8 @@ def test_plugin_matrix_auth(mock_post, mock_get, no_throttling):
assert obj.access_token is None
# So will login
obj = plugins.NotifyMatrix(host='host', user='user', password='password')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', user='user', password='password')
assert isinstance(obj, NotifyMatrix) is True
assert obj._login() is False
assert obj.access_token is None
@ -573,8 +574,8 @@ def test_plugin_matrix_rooms(mock_post, mock_get, no_throttling):
mock_post.return_value = request
mock_get.return_value = request
obj = plugins.NotifyMatrix(host='host')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host')
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# Can't get room listing if we're not connnected
@ -632,8 +633,8 @@ def test_plugin_matrix_rooms(mock_post, mock_get, no_throttling):
# Room creation
request.status_code = requests.codes.ok
obj = plugins.NotifyMatrix(host='host')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host')
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# Can't get room listing if we're not connnected
@ -677,8 +678,8 @@ def test_plugin_matrix_rooms(mock_post, mock_get, no_throttling):
# Room detection
request.status_code = requests.codes.ok
request.content = dumps(response_obj)
obj = plugins.NotifyMatrix(host='localhost')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='localhost')
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# No rooms if we're not connected
@ -703,8 +704,8 @@ def test_plugin_matrix_rooms(mock_post, mock_get, no_throttling):
# Room id lookup
request.status_code = requests.codes.ok
obj = plugins.NotifyMatrix(host='localhost')
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='localhost')
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# Can't get room listing if we're not connnected
@ -737,13 +738,13 @@ def test_plugin_matrix_url_parsing():
NotifyMatrix() URL Testing
"""
result = plugins.NotifyMatrix.parse_url(
result = NotifyMatrix.parse_url(
'matrix://user:token@localhost?to=#room')
assert isinstance(result, dict) is True
assert len(result['targets']) == 1
assert '#room' in result['targets']
result = plugins.NotifyMatrix.parse_url(
result = NotifyMatrix.parse_url(
'matrix://user:token@localhost?to=#room1,#room2,#room3')
assert isinstance(result, dict) is True
assert len(result['targets']) == 3
@ -786,16 +787,16 @@ def test_plugin_matrix_image_errors(mock_post, mock_get):
mock_get.side_effect = mock_function_handing
mock_post.side_effect = mock_function_handing
obj = plugins.NotifyMatrix(host='host', include_image=True)
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', include_image=True)
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# Notification was successful, however we could not post image and since
# we had post errors (of any kind) we still report a failure.
assert obj.notify('test', 'test') is False
obj = plugins.NotifyMatrix(host='host', include_image=False)
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', include_image=False)
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
# We didn't post an image (which was set to fail) and therefore our
@ -823,14 +824,14 @@ def test_plugin_matrix_image_errors(mock_post, mock_get):
# Prepare Mock
mock_get.side_effect = mock_function_handing
mock_post.side_effect = mock_function_handing
obj = plugins.NotifyMatrix(host='host', include_image=True)
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', include_image=True)
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
assert obj.notify('test', 'test') is True
obj = plugins.NotifyMatrix(host='host', include_image=False)
assert isinstance(obj, plugins.NotifyMatrix) is True
obj = NotifyMatrix(host='host', include_image=False)
assert isinstance(obj, NotifyMatrix) is True
assert obj.access_token is None
assert obj.notify('test', 'test') is True

View File

@ -24,7 +24,8 @@
# THE SOFTWARE.
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyMattermost import NotifyMattermost
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -47,64 +48,64 @@ apprise_url_tests = (
'instance': TypeError,
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
}),
('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?channel=test', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
}),
('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?to=test', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'mmost://user@localhost/3...4/',
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4'
'?to=test&image=True', {
'instance': plugins.NotifyMattermost}),
'instance': NotifyMattermost}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4' \
'?to=test&image=False', {
'instance': plugins.NotifyMattermost}),
'instance': NotifyMattermost}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4' \
'?to=test&image=True', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
# don't include an image by default
'include_image': False}),
('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'mmost://localhost:8080/3...4/',
}),
('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
}),
('mmost://localhost:invalid-port/3ccdd113474722377935511fc85d3dd4', {
'instance': None,
}),
('mmosts://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
}),
# Test our paths
('mmosts://localhost/a/path/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
}),
('mmosts://localhost/////3ccdd113474722377935511fc85d3dd4///', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': NotifyMattermost,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost,
'instance': 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,
'instance': 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,
@ -130,6 +131,6 @@ def test_plugin_mattermost_edge_cases(no_throttling):
# Invalid Authorization Token
with pytest.raises(TypeError):
plugins.NotifyMattermost(None)
NotifyMattermost(None)
with pytest.raises(TypeError):
plugins.NotifyMattermost(" ")
NotifyMattermost(" ")

View File

@ -26,7 +26,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyMessageBird import NotifyMessageBird
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -49,42 +50,42 @@ apprise_url_tests = (
}),
('msgbird://{}/15551232000'.format('a' * 25), {
# target phone number becomes who we text too; all is good
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'msgbird://a...a/15551232000',
}),
('msgbird://{}/15551232000/abcd'.format('a' * 25), {
# valid credentials
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
}),
('msgbird://{}/15551232000/123'.format('a' * 25), {
# valid credentials
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
}),
('msgbird://{}/?from=15551233000&to=15551232000'.format('a' * 25), {
# reference to to= and from=
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
}),
('msgbird://{}/15551232000'.format('a' * 25), {
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('msgbird://{}/15551232000'.format('a' * 25), {
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('msgbird://{}/15551232000'.format('a' * 25), {
'instance': plugins.NotifyMessageBird,
'instance': NotifyMessageBird,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -122,6 +123,6 @@ def test_plugin_messagebird_edge_cases(mock_post, no_throttling):
# No apikey specified
with pytest.raises(TypeError):
plugins.NotifyMessageBird(apikey=None, source=source)
NotifyMessageBird(apikey=None, source=source)
with pytest.raises(TypeError):
plugins.NotifyMessageBird(apikey=" ", source=source)
NotifyMessageBird(apikey=" ", source=source)

View File

@ -33,6 +33,9 @@ import apprise
# Disable logging for a cleaner testing output
import logging
from apprise.plugins.NotifyMQTT import NotifyMQTT
logging.disable(logging.CRITICAL)
@ -76,7 +79,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# Instantiate our object
obj = apprise.Apprise.instantiate(
'mqtt://localhost:1234/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtt://localhost:1234/my/topic')
# Detect our defaults
assert re.search(r'qos=0', obj.url())
@ -87,7 +90,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# leverage the to= argument to identify our topic
obj = apprise.Apprise.instantiate(
'mqtt://localhost?to=my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtt://localhost/my/topic')
# Detect our defaults
assert re.search(r'qos=0', obj.url())
@ -123,7 +126,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# the URL
obj = apprise.Apprise.instantiate(
'mqtt://localhost?qos=1&version=v3.1', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtt://localhost')
assert re.search(r'qos=1', obj.url())
assert re.search(r'version=v3.1', obj.url())
@ -136,30 +139,30 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# A Secure URL
obj = apprise.Apprise.instantiate(
'mqtts://user:pass@localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtts://user:pass@localhost/my/topic')
assert obj.notify(body="test=test") is True
# Clear CA Certificates
ca_certs_backup = \
list(apprise.plugins.NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS)
apprise.plugins.NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS = []
list(NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS)
NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS = []
obj = apprise.Apprise.instantiate(
'mqtts://user:pass@localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtts://user:pass@localhost/my/topic')
# A notification is not possible now (without ca_certs)
assert obj.notify(body="test=test") is False
# Restore our certificates (for future tests)
apprise.plugins.NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS = ca_certs_backup
NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS = ca_certs_backup
# A single user (not password) + no verifying of host
obj = apprise.Apprise.instantiate(
'mqtts://user@localhost/my/topic,my/other/topic?verify=False',
suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtts://user@localhost')
assert re.search(r'my/other/topic', obj.url())
assert re.search(r'my/topic', obj.url())
@ -169,7 +172,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
obj = apprise.Apprise.instantiate(
'mqtts://user@localhost/my/topic?session=yes&client_id=apprise',
suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtts://user@localhost')
assert re.search(r'my/topic', obj.url())
assert re.search(r'client_id=apprise', obj.url())
@ -180,7 +183,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
_mock_client.connect.return_value = 2
obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.notify(body="test=test") is False
# Restore our values
_mock_client.connect.return_value = 0
@ -190,7 +193,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
_mock_client.is_connected.return_value = False
obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.notify(body="test=test") is False
# Restore our values
_mock_client.reconnect.return_value = 0
@ -200,7 +203,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
publish_result.rc = 2
obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
assert obj.notify(body="test=test") is False
# Restore our values
publish_result.rc = 0
@ -220,7 +223,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# Exception handling
obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT)
assert isinstance(obj, NotifyMQTT)
_mock_client.connect.return_value = None
for side_effect in (

View File

@ -26,7 +26,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyMSG91 import NotifyMSG91
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -45,21 +46,21 @@ apprise_url_tests = (
}),
('msg91://{}'.format('a' * 23), {
# valid AuthKey
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
}),
('msg91://{}/123'.format('a' * 23), {
# invalid phone number
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
}),
('msg91://{}/abcd'.format('a' * 23), {
# No number to notify
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
@ -82,32 +83,32 @@ apprise_url_tests = (
}),
('msg91://{}/15551232000'.format('a' * 23), {
# a valid message
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'msg91://a...a/15551232000',
}),
('msg91://{}/?to=15551232000'.format('a' * 23), {
# a valid message
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
}),
('msg91://{}/15551232000?country=91&route=1'.format('a' * 23), {
# using phone no with no target - we text ourselves in
# this case
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
}),
('msg91://{}/15551232000'.format('a' * 23), {
# use get args to acomplish the same thing
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
}),
('msg91://{}/15551232000'.format('a' * 23), {
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('msg91://{}/15551232000'.format('a' * 23), {
'instance': plugins.NotifyMSG91,
'instance': NotifyMSG91,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -145,6 +146,6 @@ def test_plugin_msg91_edge_cases(mock_post, no_throttling):
# No authkey specified
with pytest.raises(TypeError):
plugins.NotifyMSG91(authkey=None, targets=target)
NotifyMSG91(authkey=None, targets=target)
with pytest.raises(TypeError):
plugins.NotifyMSG91(authkey=" ", targets=target)
NotifyMSG91(authkey=" ", targets=target)

View File

@ -31,8 +31,8 @@ import requests
import pytest
from apprise import Apprise
from apprise import AppriseConfig
from apprise import plugins
from apprise import NotifyType
from apprise.plugins.NotifyMSTeams import NotifyMSTeams
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -71,13 +71,13 @@ apprise_url_tests = (
}),
('msteams://{}@{}/{}/{}?t1'.format(UUID4, UUID4, 'b' * 32, UUID4), {
# All tokens provided - we're good
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
}),
# Support native URLs
('https://outlook.office.com/webhook/{}@{}/IncomingWebhook/{}/{}'
.format(UUID4, UUID4, 'k' * 32, UUID4), {
# All tokens provided - we're good
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Our expected url(privacy=True) startswith() response (v1 format)
'privacy_url': 'msteams://8...2/k...k/8...2/'}),
@ -86,7 +86,7 @@ apprise_url_tests = (
('https://myteam.webhook.office.com/webhookb2/{}@{}/IncomingWebhook/{}/{}'
.format(UUID4, UUID4, 'm' * 32, UUID4), {
# All tokens provided - we're good
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Our expected url(privacy=True) startswith() response (v2 format):
'privacy_url': 'msteams://myteam/8...2/m...m/8...2/'}),
@ -94,14 +94,14 @@ apprise_url_tests = (
# Legacy URL Formatting
('msteams://{}@{}/{}/{}?t2'.format(UUID4, UUID4, 'c' * 32, UUID4), {
# All tokens provided - we're good
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# don't include an image by default
'include_image': False,
}),
# Legacy URL Formatting
('msteams://{}@{}/{}/{}?image=No'.format(UUID4, UUID4, 'd' * 32, UUID4), {
# All tokens provided - we're good no image
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'msteams://8...2/d...d/8...2/',
@ -110,7 +110,7 @@ apprise_url_tests = (
('msteams://apprise/{}@{}/{}/{}'.format(
UUID4, UUID4, 'e' * 32, UUID4), {
# All tokens provided - we're good no image
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'msteams://apprise/8...2/e...e/8...2/',
@ -119,7 +119,7 @@ apprise_url_tests = (
('msteams://{}@{}/{}/{}?team=teamname'.format(
UUID4, UUID4, 'f' * 32, UUID4), {
# All tokens provided - we're good no image
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'msteams://teamname/8...2/f...f/8...2/',
@ -128,7 +128,7 @@ apprise_url_tests = (
('msteams://apprise/{}@{}/{}/{}?version=1'.format(
UUID4, UUID4, 'e' * 32, UUID4), {
# All tokens provided - we're good
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'msteams://8...2/e...e/8...2/',
@ -145,19 +145,19 @@ apprise_url_tests = (
'instance': TypeError,
}),
('msteams://{}@{}/{}/{}?tx'.format(UUID4, UUID4, 'x' * 32, UUID4), {
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('msteams://{}@{}/{}/{}?ty'.format(UUID4, UUID4, 'y' * 32, UUID4), {
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('msteams://{}@{}/{}/{}?tz'.format(UUID4, UUID4, 'z' * 32, UUID4), {
'instance': plugins.NotifyMSTeams,
'instance': NotifyMSTeams,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -214,7 +214,7 @@ def test_plugin_msteams_templating(mock_post, tmpdir, no_throttling):
kwargs=':key1=token&:key2=token',
))
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -244,7 +244,7 @@ def test_plugin_msteams_templating(mock_post, tmpdir, no_throttling):
kwargs=':key1=token&:key2=token',
))
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
# We will fail to preform our notifcation because the JSON is bad
assert obj.notify(
body="body", title='title',
@ -274,7 +274,7 @@ def test_plugin_msteams_templating(mock_post, tmpdir, no_throttling):
kwargs=':key1=token&:key2=token',
))
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
# We can not load the file because we're missing the @type entry
assert obj.notify(
@ -305,7 +305,7 @@ def test_plugin_msteams_templating(mock_post, tmpdir, no_throttling):
kwargs=':key1=token&:key2=token',
))
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
# We can not load the file because we're missing the @context entry
assert obj.notify(
body="body", title='title',
@ -360,7 +360,7 @@ def test_plugin_msteams_templating(mock_post, tmpdir, no_throttling):
kwargs=':key1=token&:key2=token&:target=http://localhost',
))
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -434,7 +434,7 @@ def test_msteams_yaml_config(mock_post, tmpdir, no_throttling):
assert len(cfg[0]) == 1
obj = cfg[0][0]
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is False
@ -458,7 +458,7 @@ def test_msteams_yaml_config(mock_post, tmpdir, no_throttling):
assert len(cfg[0]) == 1
obj = cfg[0][0]
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -496,7 +496,7 @@ def test_msteams_yaml_config(mock_post, tmpdir, no_throttling):
assert len(cfg[0]) == 1
obj = cfg[0][0]
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -535,7 +535,7 @@ def test_msteams_yaml_config(mock_post, tmpdir, no_throttling):
assert len(cfg[0]) == 1
obj = cfg[0][0]
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -574,7 +574,7 @@ def test_msteams_yaml_config(mock_post, tmpdir, no_throttling):
assert len(cfg[0]) == 1
obj = cfg[0][0]
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -611,7 +611,7 @@ def test_msteams_yaml_config(mock_post, tmpdir, no_throttling):
assert len(cfg[0]) == 1
obj = cfg[0][0]
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)
assert obj.notify(
body="body", title='title',
notify_type=NotifyType.INFO) is True
@ -657,27 +657,27 @@ def test_plugin_msteams_edge_cases():
"""
# Initializes the plugin with an invalid token
with pytest.raises(TypeError):
plugins.NotifyMSTeams(token_a=None, token_b='abcd', token_c='abcd')
NotifyMSTeams(token_a=None, token_b='abcd', token_c='abcd')
# Whitespace also acts as an invalid token value
with pytest.raises(TypeError):
plugins.NotifyMSTeams(token_a=' ', token_b='abcd', token_c='abcd')
NotifyMSTeams(token_a=' ', token_b='abcd', token_c='abcd')
with pytest.raises(TypeError):
plugins.NotifyMSTeams(token_a='abcd', token_b=None, token_c='abcd')
NotifyMSTeams(token_a='abcd', token_b=None, token_c='abcd')
# Whitespace also acts as an invalid token value
with pytest.raises(TypeError):
plugins.NotifyMSTeams(token_a='abcd', token_b=' ', token_c='abcd')
NotifyMSTeams(token_a='abcd', token_b=' ', token_c='abcd')
with pytest.raises(TypeError):
plugins.NotifyMSTeams(token_a='abcd', token_b='abcd', token_c=None)
NotifyMSTeams(token_a='abcd', token_b='abcd', token_c=None)
# Whitespace also acts as an invalid token value
with pytest.raises(TypeError):
plugins.NotifyMSTeams(token_a='abcd', token_b='abcd', token_c=' ')
NotifyMSTeams(token_a='abcd', token_b='abcd', token_c=' ')
uuid4 = '8b799edf-6f98-4d3a-9be7-2862fb4e5752'
token_a = '{}@{}'.format(uuid4, uuid4)
token_b = 'A' * 32
# test case where no tokens are specified
obj = plugins.NotifyMSTeams(
obj = NotifyMSTeams(
token_a=token_a, token_b=token_b, token_c=uuid4)
assert isinstance(obj, plugins.NotifyMSTeams)
assert isinstance(obj, NotifyMSTeams)

View File

@ -26,7 +26,7 @@
from unittest import mock
import requests
from apprise import plugins
from apprise.plugins.NotifyNextcloud import NotifyNextcloud
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -64,55 +64,55 @@ apprise_url_tests = (
'instance': TypeError,
}),
('ncloud://localhost/admin', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://user@localhost/admin', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://user@localhost?to=user1,user2', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://user@localhost?to=user1,user2&version=20', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://user@localhost?to=user1,user2&version=21', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://user:pass@localhost/user1/user2', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'ncloud://user:****@localhost/user1/user2',
}),
('ncloud://user:pass@localhost:8080/admin', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('nclouds://user:pass@localhost/admin', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'nclouds://user:****@localhost/admin',
}),
('nclouds://user:pass@localhost:8080/admin/', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://localhost:8080/admin?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
}),
('ncloud://user:pass@localhost:8081/admin', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('ncloud://user:pass@localhost:8082/admin', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('ncloud://user:pass@localhost:8083/user1/user2/user3', {
'instance': plugins.NotifyNextcloud,
'instance': NotifyNextcloud,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -146,9 +146,9 @@ def test_plugin_nextcloud_edge_cases(mock_post, no_throttling):
mock_post.return_value = robj
# Variation Initializations
obj = plugins.NotifyNextcloud(
obj = NotifyNextcloud(
host="localhost", user="admin", password="pass", targets="user")
assert isinstance(obj, plugins.NotifyNextcloud) is True
assert isinstance(obj, NotifyNextcloud) is True
assert isinstance(obj.url(), str) is True
# An empty body

View File

@ -26,7 +26,7 @@
from unittest import mock
import requests
from apprise import plugins
from apprise.plugins.NotifyNextcloudTalk import NotifyNextcloudTalk
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -64,45 +64,45 @@ apprise_url_tests = (
'instance': TypeError,
}),
('nctalk://user:pass@localhost/roomid1/roomid2', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
'requests_response_code': requests.codes.created,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'nctalk://user:****@localhost/roomid1/roomid2',
}),
('nctalk://user:pass@localhost:8080/roomid', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
'requests_response_code': requests.codes.created,
}),
('nctalks://user:pass@localhost/roomid', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
'requests_response_code': requests.codes.created,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'nctalks://user:****@localhost/roomid',
}),
('nctalks://user:pass@localhost:8080/roomid/', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
'requests_response_code': requests.codes.created,
}),
('nctalk://user:pass@localhost:8080/roomid?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
'requests_response_code': requests.codes.created,
}),
('nctalk://user:pass@localhost:8081/roomid', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('nctalk://user:pass@localhost:8082/roomid', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('nctalk://user:pass@localhost:8083/roomid1/roomid2/roomid3', {
'instance': plugins.NotifyNextcloudTalk,
'instance': NotifyNextcloudTalk,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -136,9 +136,9 @@ def test_plugin_nextcloudtalk_edge_cases(mock_post, no_throttling):
mock_post.return_value = robj
# Variation Initializations
obj = plugins.NotifyNextcloudTalk(
obj = NotifyNextcloudTalk(
host="localhost", user="admin", password="pass", targets="roomid")
assert isinstance(obj, plugins.NotifyNextcloudTalk) is True
assert isinstance(obj, NotifyNextcloudTalk) is True
assert isinstance(obj.url(), str) is True
# An empty body

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyNotica import NotifyNotica
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -40,90 +41,90 @@ apprise_url_tests = (
}),
# Native URL
('https://notica.us/?%s' % ('z' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://z...z/',
}),
# Native URL with additional arguments
('https://notica.us/?%s&overflow=upstream' % ('z' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://z...z/',
}),
# Token specified
('notica://%s' % ('a' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://a...a/',
}),
# Self-Hosted configuration
('notica://localhost/%s' % ('b' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
}),
('notica://user@localhost/%s' % ('c' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
}),
('notica://user:pass@localhost/%s/' % ('d' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://user:****@localhost/d...d',
}),
('notica://user:pass@localhost/a/path/%s/' % ('r' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://user:****@localhost/a/path/r...r',
}),
('notica://localhost:8080/%s' % ('a' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
}),
('notica://user:pass@localhost:8080/%s' % ('b' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
}),
('noticas://localhost/%s' % ('j' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
'privacy_url': 'noticas://localhost/j...j',
}),
('noticas://user:pass@localhost/%s' % ('e' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'noticas://user:****@localhost/e...e',
}),
('noticas://localhost:8080/path/%s' % ('5' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
'privacy_url': 'noticas://localhost:8080/path/5...5',
}),
('noticas://user:pass@localhost:8080/%s' % ('6' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
}),
('notica://%s' % ('b' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# don't include an image by default
'include_image': False,
}),
# Test Header overrides
('notica://localhost:8080//%s/?+HeaderKey=HeaderValue' % ('7' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
}),
('notica://%s' % ('c' * 6), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('notica://%s' % ('d' * 7), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('notica://%s' % ('e' * 8), {
'instance': plugins.NotifyNotica,
'instance': NotifyNotica,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyNotifico import NotifyNotifico
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -48,62 +49,62 @@ apprise_url_tests = (
}),
('notifico://1234/ckhrjW8w672m6HG', {
# A project id and message hook provided
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
}),
('notifico://1234/ckhrjW8w672m6HG?prefix=no', {
# Disable our prefix
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
}),
('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
'notify_type': 'info',
}),
('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
'notify_type': 'success',
}),
('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
'notify_type': 'warning',
}),
('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
'notify_type': 'failure',
}),
('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
'notify_type': 'invalid',
}),
('notifico://1234/ckhrjW8w672m6HG?color=no', {
# Test our color flag by having it set to off
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notifico://1...4/c...G',
}),
# Support Native URLs
('https://n.tkte.ch/h/2144/uJmKaBW9WFk42miB146ci3Kj', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
}),
('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
# don't include an image by default
'include_image': False,
}),
('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico,
'instance': NotifyNotifico,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -27,11 +27,10 @@ import json
from unittest import mock
import requests
from apprise import plugins
import apprise
from helpers import AppriseURLTester
from apprise.plugins.NotifyNtfy import NtfyPriority
from apprise.plugins.NotifyNtfy import NtfyPriority, NotifyNtfy
# Disable logging for a cleaner testing output
import logging
@ -50,7 +49,7 @@ GOOD_RESPONSE_TEXT = {
apprise_url_tests = (
('ntfy://', {
# Initializes okay (as cloud mode) but has no topics to notify
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# invalid topics specified (nothing to notify)
# as a result the response type will be false
'requests_response_text': GOOD_RESPONSE_TEXT,
@ -58,7 +57,7 @@ apprise_url_tests = (
}),
('ntfys://', {
# Initializes okay (as cloud mode) but has no topics to notify
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# invalid topics specified (nothing to notify)
# as a result the response type will be false
'requests_response_text': GOOD_RESPONSE_TEXT,
@ -66,7 +65,7 @@ apprise_url_tests = (
}),
('ntfy://:@/', {
# Initializes okay (as cloud mode) but has no topics to notify
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# invalid topics specified (nothing to notify)
# as a result the response type will be false
'requests_response_text': GOOD_RESPONSE_TEXT,
@ -74,7 +73,7 @@ apprise_url_tests = (
}),
# No topics
('ntfy://user:pass@localhost?mode=private', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# invalid topics specified (nothing to notify)
# as a result the response type will be false
'requests_response_text': GOOD_RESPONSE_TEXT,
@ -82,7 +81,7 @@ apprise_url_tests = (
}),
# No valid topics
('ntfy://user:pass@localhost/#/!/@', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# invalid topics specified (nothing to notify)
# as a result the response type will be false
'requests_response_text': GOOD_RESPONSE_TEXT,
@ -90,83 +89,83 @@ apprise_url_tests = (
}),
# user/pass combos
('ntfy://user@localhost/topic/', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Ntfy cloud mode (enforced)
('ntfy://ntfy.sh/topic1/topic2/', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# No user/pass combo
('ntfy://localhost/topic1/topic2/', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# A Email Testing
('ntfy://localhost/topic1/?email=user@gmail.com', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Tags
('ntfy://localhost/topic1/?tags=tag1,tag2,tag3', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Delay
('ntfy://localhost/topic1/?delay=3600', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Title
('ntfy://localhost/topic1/?title=A%20Great%20Title', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Click
('ntfy://localhost/topic1/?click=yes', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Email
('ntfy://localhost/topic1/?email=user@example.com', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Attach
('ntfy://localhost/topic1/?attach=http://example.com/file.jpg', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Attach with filename over-ride
('ntfy://localhost/topic1/'
'?attach=http://example.com/file.jpg&filename=smoke.jpg', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT}),
# Attach with bad url
('ntfy://localhost/topic1/?attach=http://-%20', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Priority
('ntfy://localhost/topic1/?priority=default', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Priority higher
('ntfy://localhost/topic1/?priority=high', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# A topic and port identifier
('ntfy://user:pass@localhost:8080/topic/', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# The response text is expected to be the following on a success
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# A topic (using the to=)
('ntfys://user:pass@localhost?to=topic', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# The response text is expected to be the following on a success
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
@ -176,19 +175,19 @@ apprise_url_tests = (
}),
# reference the ntfy.sh url
('https://ntfy.sh?to=topic', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# The response text is expected to be the following on a success
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Several topics
('ntfy://user:pass@topic1/topic2/topic3/?mode=cloud', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# The response text is expected to be the following on a success
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
# Several topics (but do not add ntfy.sh)
('ntfy://user:pass@ntfy.sh/topic1/topic2/?mode=cloud', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# The response text is expected to be the following on a success
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
@ -201,20 +200,20 @@ apprise_url_tests = (
'instance': None,
}),
('ntfy://user:pass@localhost:8089/topic/topic2', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# force a failure using basic mode
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('ntfy://user:pass@localhost:8082/topic', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
'requests_response_text': GOOD_RESPONSE_TEXT,
}),
('ntfy://user:pass@localhost:8083/topic1/topic2/', {
'instance': plugins.NotifyNtfy,
'instance': NotifyNtfy,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -363,7 +362,7 @@ def test_plugin_custom_ntfy_edge_cases(mock_post, no_throttling):
# Prepare Mock
mock_post.return_value = response
results = plugins.NotifyNtfy.parse_url(
results = NotifyNtfy.parse_url(
'ntfys://abc---,topic2,~~,,?priority=max&tags=smile,de')
assert isinstance(results, dict)
@ -380,13 +379,13 @@ def test_plugin_custom_ntfy_edge_cases(mock_post, no_throttling):
assert results['qsd']['priority'] == 'max'
assert results['qsd']['tags'] == 'smile,de'
instance = plugins.NotifyNtfy(**results)
assert isinstance(instance, plugins.NotifyNtfy)
instance = NotifyNtfy(**results)
assert isinstance(instance, NotifyNtfy)
assert len(instance.topics) == 2
assert 'abc---' in instance.topics
assert 'topic2' in instance.topics
results = plugins.NotifyNtfy.parse_url(
results = NotifyNtfy.parse_url(
'ntfy://localhost/topic1/'
'?attach=http://example.com/file.jpg&filename=smoke.jpg')
@ -403,8 +402,8 @@ def test_plugin_custom_ntfy_edge_cases(mock_post, no_throttling):
assert results['attach'] == 'http://example.com/file.jpg'
assert results['filename'] == 'smoke.jpg'
instance = plugins.NotifyNtfy(**results)
assert isinstance(instance, plugins.NotifyNtfy)
instance = NotifyNtfy(**results)
assert isinstance(instance, NotifyNtfy)
assert len(instance.topics) == 1
assert 'topic1' in instance.topics

View File

@ -31,7 +31,7 @@ import requests
from datetime import datetime
from json import dumps
from apprise import Apprise
from apprise import plugins
from apprise.plugins.NotifyOffice365 import NotifyOffice365
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -84,7 +84,7 @@ apprise_url_tests = (
targets='/'.join(['email1@test.ca'])), {
# We're valid and good to go
'instance': plugins.NotifyOffice365,
'instance': NotifyOffice365,
# Test what happens if a batch send fails to return a messageCount
'requests_response_text': {
@ -105,7 +105,7 @@ apprise_url_tests = (
targets='email1@test.ca'),
{
# We're valid and good to go
'instance': plugins.NotifyOffice365,
'instance': NotifyOffice365,
# Test what happens if a batch send fails to return a messageCount
'requests_response_text': {
@ -125,7 +125,7 @@ apprise_url_tests = (
targets='/'.join(['email1@test.ca'])), {
# We're valid and good to go
'instance': plugins.NotifyOffice365,
'instance': NotifyOffice365,
# invalid JSON response
'requests_response_text': '{',
@ -139,7 +139,7 @@ apprise_url_tests = (
secret='abcd/123/3343/@jack/test'), {
# We're valid and good to go
'instance': plugins.NotifyOffice365,
'instance': NotifyOffice365,
# There were no targets to notify; so we use our own email
'requests_response_text': {
@ -153,7 +153,7 @@ apprise_url_tests = (
aid='user@example.com',
secret='abcd/abc/dcba/@john/test',
targets='/'.join(['email1@test.ca'])), {
'instance': plugins.NotifyOffice365,
'instance': NotifyOffice365,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -164,7 +164,7 @@ apprise_url_tests = (
aid='user@example.com',
secret='abcd/321/4321/@test/test',
targets='/'.join(['email1@test.ca'])), {
'instance': plugins.NotifyOffice365,
'instance': NotifyOffice365,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -215,7 +215,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
secret=secret,
targets=targets))
assert isinstance(obj, plugins.NotifyOffice365)
assert isinstance(obj, NotifyOffice365)
# Test our URL generation
assert isinstance(obj.url(), str)
@ -236,7 +236,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
bcc='Bruce Willis bwillis@hotmail.com, Frodo@lotr.me invalid@!',
))
assert isinstance(obj, plugins.NotifyOffice365)
assert isinstance(obj, NotifyOffice365)
# Test our URL generation
assert isinstance(obj.url(), str)
@ -246,7 +246,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
with pytest.raises(TypeError):
# No secret
plugins.NotifyOffice365(
NotifyOffice365(
email=email,
client_id=client_id,
tenant=tenant,
@ -256,7 +256,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
with pytest.raises(TypeError):
# Invalid email
plugins.NotifyOffice365(
NotifyOffice365(
email=None,
client_id=client_id,
tenant=tenant,
@ -266,7 +266,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
with pytest.raises(TypeError):
# Invalid email
plugins.NotifyOffice365(
NotifyOffice365(
email='garbage',
client_id=client_id,
tenant=tenant,
@ -275,7 +275,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
)
# One of the targets are invalid
obj = plugins.NotifyOffice365(
obj = NotifyOffice365(
email=email,
client_id=client_id,
tenant=tenant,
@ -286,7 +286,7 @@ def test_plugin_office365_general(mock_post, no_throttling):
assert obj.notify(title='title', body='test') is True
# all of the targets are invalid
obj = plugins.NotifyOffice365(
obj = NotifyOffice365(
email=email,
client_id=client_id,
tenant=tenant,
@ -340,7 +340,7 @@ def test_plugin_office365_authentication(mock_post, no_throttling):
secret=secret,
targets=targets))
assert isinstance(obj, plugins.NotifyOffice365)
assert isinstance(obj, NotifyOffice365)
# Authenticate
assert obj.authenticate() is True

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyOneSignal import NotifyOneSignal
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,61 +53,61 @@ apprise_url_tests = (
}),
('onesignal://appid@apikey/', {
# No targets specified; we will initialize but not notify anything
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
'notify_response': False,
}),
('onesignal://appid@apikey/playerid', {
# Valid playerid
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
'privacy_url': 'onesignal://a...d@a...y/playerid',
}),
('onesignal://appid@apikey/player', {
# Valid player id
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
# don't include an image by default
'include_image': False,
}),
('onesignal://appid@apikey/@user?image=no', {
# Valid userid, no image
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://appid@apikey/user@email.com/#seg/player/@user/%20/a', {
# Valid email, valid playerid, valid user, invalid entry (%20),
# and too short of an entry (a)
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://appid@apikey?to=#segment,playerid', {
# Test to=
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://appid@apikey/#segment/@user/?batch=yes', {
# Test batch=
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://appid@apikey/#segment/@user/?batch=no', {
# Test batch=
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://templateid:appid@apikey/playerid', {
# Test Template ID
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://appid@apikey/playerid/?lang=es&subtitle=Sub', {
# Test Language and Subtitle Over-ride
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://?apikey=abc&template=tp&app=123&to=playerid', {
# Test Kwargs
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
}),
('onesignal://appid@apikey/#segment/playerid/', {
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('onesignal://appid@apikey/#segment/playerid/', {
'instance': plugins.NotifyOneSignal,
'instance': NotifyOneSignal,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -25,8 +25,8 @@
from unittest import mock
import requests
from apprise.plugins.NotifyOpsgenie import OpsgeniePriority
import apprise
from apprise.plugins.NotifyOpsgenie import NotifyOpsgenie, OpsgeniePriority
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -56,72 +56,72 @@ apprise_url_tests = (
}),
('opsgenie://apikey/', {
# No targets specified; this is allowed
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/user', {
# Valid user
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
'privacy_url': 'opsgenie://a...y/%40user',
}),
('opsgenie://apikey/@user?region=eu', {
# European Region
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/@user?entity=A%20Entity', {
# Assign an entity
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/@user?alias=An%20Alias', {
# Assign an alias
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/@user?priority=p3', {
# Assign our priority
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/?tags=comma,separated', {
# Test our our 'tags' (tag is reserved in Apprise) but not 'tags'
# Also test the fact we do not need to define a target
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/@user?priority=invalid', {
# Invalid priority (loads using default)
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/user@email.com/#team/*sche/^esc/%20/a', {
# Valid user (email), valid schedule, Escalated ID,
# an invalid entry (%20), and too short of an entry (a)
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/{}/@{}/#{}/*{}/^{}/'.format(
UUID4, UUID4, UUID4, UUID4, UUID4), {
# similar to the above, except we use the UUID's
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey?to=#team,user&+key=value&+type=override', {
# Test to= and details (key/value pair) also override 'type'
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/#team/@user/?batch=yes', {
# Test batch=
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/#team/@user/?batch=no', {
# Test batch=
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://?apikey=abc&to=user', {
# Test Kwargs
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
}),
('opsgenie://apikey/#team/user/', {
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('opsgenie://apikey/#topic1/device/', {
'instance': apprise.plugins.NotifyOpsgenie,
'instance': NotifyOpsgenie,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -136,7 +136,7 @@ def test_plugin_opsgenie_urls():
"""
# Disable Throttling to speed testing
apprise.plugins.NotifyOpsgenie.request_rate_per_sec = 0
NotifyOpsgenie.request_rate_per_sec = 0
# Run our general tests
AppriseURLTester(tests=apprise_url_tests).run_all()
@ -175,7 +175,7 @@ def test_plugin_opsgenie_config_files(mock_post):
"""
# Disable Throttling to speed testing
apprise.plugins.NotifyOpsgenie.request_rate_per_sec = 0
NotifyOpsgenie.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyPagerDuty import NotifyPagerDuty
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -61,47 +61,47 @@ apprise_url_tests = (
}),
('pagerduty://myroutekey@myapikey', {
# minimum requirements met
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'pagerduty://****@****/A...e/N...n?',
}),
('pagerduty://myroutekey@myapikey?image=no', {
# minimum requirements met and disable images
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
}),
('pagerduty://myroutekey@myapikey?region=eu', {
# european region
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
}),
# Custom values
('pagerduty://myroutekey@myapikey?+key=value&+key2=value2', {
# minimum requirements and support custom key/value pairs
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
}),
('pagerduty://myroutekey@myapikey/mysource/mycomponent', {
# a valid url
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'pagerduty://****@****/m...e/m...t?',
}),
('pagerduty://routekey@apikey/ms/mc?group=mygroup&class=myclass', {
# class/group testing
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
}),
('pagerduty://?integrationkey=r&apikey=a&source=s&component=c'
'&group=g&class=c&image=no&click=http://localhost', {
# all parameters
'instance': plugins.NotifyPagerDuty}),
'instance': NotifyPagerDuty}),
('pagerduty://somerkey@someapikey/bizzare/code', {
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pagerduty://myroutekey@myapikey/mysource/mycomponent', {
'instance': plugins.NotifyPagerDuty,
'instance': NotifyPagerDuty,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyParsePlatform import NotifyParsePlatform
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,14 +54,14 @@ apprise_url_tests = (
}),
# app_id + master_key (using arguments=)
('parseps://localhost?app_id=%s&master_key=%s' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyParsePlatform,
'instance': NotifyParsePlatform,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'parseps://a...a:d...d@localhost',
}),
# Set a device id + custom port
('parsep://app_id:master_key@localhost:8080?device=ios', {
'instance': plugins.NotifyParsePlatform,
'instance': NotifyParsePlatform,
}),
# invalid device id
('parsep://app_id:master_key@localhost?device=invalid', {
@ -68,22 +69,22 @@ apprise_url_tests = (
}),
# Normal Query
('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform,
'instance': NotifyParsePlatform,
}),
('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform,
'instance': NotifyParsePlatform,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform,
'instance': NotifyParsePlatform,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform,
'instance': NotifyParsePlatform,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -23,7 +23,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyPopcornNotify import NotifyPopcornNotify
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -42,40 +42,40 @@ apprise_url_tests = (
}),
('popcorn://{}/1232348923489234923489234289-32423'.format('a' * 9), {
# invalid phone number
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
'notify_response': False,
}),
('popcorn://{}/abc'.format('b' * 9), {
# invalid email
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
'notify_response': False,
}),
('popcorn://{}/15551232000/user@example.com'.format('c' * 9), {
# value phone and email
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
}),
('popcorn://{}/15551232000/user@example.com?batch=yes'.format('w' * 9), {
# value phone and email with batch mode set
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
}),
('popcorn://{}/?to=15551232000'.format('w' * 9), {
# reference to to=
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
}),
('popcorn://{}/15551232000'.format('x' * 9), {
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('popcorn://{}/15551232000'.format('y' * 9), {
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('popcorn://{}/15551232000'.format('z' * 9), {
'instance': plugins.NotifyPopcornNotify,
'instance': NotifyPopcornNotify,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -26,9 +26,8 @@ from unittest import mock
import pytest
import requests
from apprise.plugins.NotifyProwl import ProwlPriority
from apprise import plugins
import apprise
from apprise.plugins.NotifyProwl import NotifyProwl, ProwlPriority
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -50,7 +49,7 @@ apprise_url_tests = (
}),
# Provider Key
('prowl://%s/%s' % ('a' * 40, 'b' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
}),
# Invalid Provider Key
('prowl://%s/%s' % ('a' * 40, 'b' * 20), {
@ -58,58 +57,58 @@ apprise_url_tests = (
}),
# APIkey; no device
('prowl://%s' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
}),
# API Key
('prowl://%s' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
# don't include an image by default
'include_image': False,
}),
# API Key + priority setting
('prowl://%s?priority=high' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
}),
# API Key + invalid priority setting
('prowl://%s?priority=invalid' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
}),
# API Key + priority setting (empty)
('prowl://%s?priority=' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
}),
# API Key + No Provider Key (empty)
('prowl://%s///' % ('w' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'prowl://w...w/',
}),
# API Key + Provider Key
('prowl://%s/%s' % ('a' * 40, 'b' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'prowl://a...a/b...b',
}),
# API Key + with image
('prowl://%s' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
}),
('prowl://%s' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('prowl://%s' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('prowl://%s' % ('a' * 40), {
'instance': plugins.NotifyProwl,
'instance': NotifyProwl,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -134,16 +133,16 @@ def test_plugin_prowl_edge_cases():
"""
# Initializes the plugin with an invalid apikey
with pytest.raises(TypeError):
plugins.NotifyProwl(apikey=None)
NotifyProwl(apikey=None)
# Whitespace also acts as an invalid apikey value
with pytest.raises(TypeError):
plugins.NotifyProwl(apikey=' ')
NotifyProwl(apikey=' ')
# Whitespace also acts as an invalid provider key
with pytest.raises(TypeError):
plugins.NotifyProwl(apikey='abcd', providerkey=object())
NotifyProwl(apikey='abcd', providerkey=object())
with pytest.raises(TypeError):
plugins.NotifyProwl(apikey='abcd', providerkey=' ')
NotifyProwl(apikey='abcd', providerkey=' ')
@mock.patch('requests.post')
@ -175,7 +174,7 @@ def test_plugin_prowl_config_files(mock_post):
""" % ('a' * 40, 'b' * 40)
# Disable Throttling to speed testing
plugins.NotifyProwl.request_rate_per_sec = 0
NotifyProwl.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()

View File

@ -31,7 +31,7 @@ import requests
from json import dumps
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import plugins
from apprise.plugins.NotifyPushBullet import NotifyPushBullet
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -51,12 +51,12 @@ apprise_url_tests = (
}),
# APIkey
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# APIkey; but support attachment response
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# Test what happens if a batch send fails to return a messageCount
'requests_response_text': {
@ -68,7 +68,7 @@ apprise_url_tests = (
}),
# APIkey; attachment testing that isn't an image type
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# Test what happens if a batch send fails to return a messageCount
'requests_response_text': {
@ -80,7 +80,7 @@ apprise_url_tests = (
}),
# APIkey; attachment testing were expected entry in payload is missing
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# Test what happens if a batch send fails to return a messageCount
'requests_response_text': {
@ -94,17 +94,17 @@ apprise_url_tests = (
}),
# API Key + channel
('pbul://%s/#channel/' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# API Key + channel (via to=
('pbul://%s/?to=#channel' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# API Key + 2 channels
('pbul://%s/#channel1/#channel2' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'pbul://a...a/',
@ -112,67 +112,67 @@ apprise_url_tests = (
}),
# API Key + device
('pbul://%s/device/' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# API Key + 2 devices
('pbul://%s/device1/device2/' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# API Key + email
('pbul://%s/user@example.com/' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# API Key + 2 emails
('pbul://%s/user@example.com/abc@def.com/' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# API Key + Combo
('pbul://%s/device/#channel/user@example.com/' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
'check_attachments': False,
}),
# ,
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
'check_attachments': False,
}),
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
'check_attachments': False,
}),
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
'check_attachments': False,
}),
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
'check_attachments': False,
}),
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
'check_attachments': False,
}),
('pbul://%s' % ('a' * 32), {
'instance': plugins.NotifyPushBullet,
'instance': NotifyPushBullet,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -353,23 +353,23 @@ def test_plugin_pushbullet_edge_cases(mock_post, mock_get, no_throttling):
# Invalid Access Token
with pytest.raises(TypeError):
plugins.NotifyPushBullet(accesstoken=None)
NotifyPushBullet(accesstoken=None)
with pytest.raises(TypeError):
plugins.NotifyPushBullet(accesstoken=" ")
NotifyPushBullet(accesstoken=" ")
obj = plugins.NotifyPushBullet(
obj = NotifyPushBullet(
accesstoken=accesstoken, targets=recipients)
assert isinstance(obj, plugins.NotifyPushBullet) is True
assert isinstance(obj, NotifyPushBullet) is True
assert len(obj.targets) == 4
obj = plugins.NotifyPushBullet(accesstoken=accesstoken)
assert isinstance(obj, plugins.NotifyPushBullet) is True
obj = NotifyPushBullet(accesstoken=accesstoken)
assert isinstance(obj, NotifyPushBullet) is True
# Default is to send to all devices, so there will be a
# recipient here
assert len(obj.targets) == 1
obj = plugins.NotifyPushBullet(accesstoken=accesstoken, targets=set())
assert isinstance(obj, plugins.NotifyPushBullet) is True
obj = NotifyPushBullet(accesstoken=accesstoken, targets=set())
assert isinstance(obj, NotifyPushBullet) is True
# Default is to send to all devices, so there will be a
# recipient here
assert len(obj.targets) == 1

View File

@ -26,7 +26,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyPushed import NotifyPushed
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -48,15 +49,15 @@ apprise_url_tests = (
}),
# Application Key+Secret
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
}),
# Application Key+Secret + channel
('pushed://%s/%s/#channel/' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
}),
# Application Key+Secret + channel (via to=)
('pushed://%s/%s?to=channel' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'pushed://a...a/****/',
}),
@ -67,65 +68,65 @@ apprise_url_tests = (
}),
# Application Key+Secret + 2 channels
('pushed://%s/%s/#channel1/#channel2' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
}),
# Application Key+Secret + User Pushed ID
('pushed://%s/%s/@ABCD/' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
}),
# Application Key+Secret + 2 devices
('pushed://%s/%s/@ABCD/@DEFG/' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
}),
# Application Key+Secret + Combo
('pushed://%s/%s/@ABCD/#channel' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
}),
# ,
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pushed://%s/%s/#channel' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pushed://%s/%s/@user' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pushed://%s/%s' % ('a' * 32, 'a' * 64), {
'instance': plugins.NotifyPushed,
'instance': NotifyPushed,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -166,49 +167,49 @@ def test_plugin_pushed_edge_cases(mock_post, mock_get, no_throttling):
# No application Key specified
with pytest.raises(TypeError):
plugins.NotifyPushed(
NotifyPushed(
app_key=None,
app_secret=app_secret,
recipients=None,
)
with pytest.raises(TypeError):
plugins.NotifyPushed(
NotifyPushed(
app_key=" ",
app_secret=app_secret,
recipients=None,
)
# No application Secret specified
with pytest.raises(TypeError):
plugins.NotifyPushed(
NotifyPushed(
app_key=app_key,
app_secret=None,
recipients=None,
)
with pytest.raises(TypeError):
plugins.NotifyPushed(
NotifyPushed(
app_key=app_key,
app_secret=" ",
)
# recipients list set to (None) is perfectly fine; in this case it will
# notify the App
obj = plugins.NotifyPushed(
obj = NotifyPushed(
app_key=app_key,
app_secret=app_secret,
recipients=None,
)
assert isinstance(obj, plugins.NotifyPushed) is True
assert isinstance(obj, NotifyPushed) is True
assert len(obj.channels) == 0
assert len(obj.users) == 0
obj = plugins.NotifyPushed(
obj = NotifyPushed(
app_key=app_key,
app_secret=app_secret,
targets=recipients,
)
assert isinstance(obj, plugins.NotifyPushed) is True
assert isinstance(obj, NotifyPushed) is True
assert len(obj.channels) == 2
assert len(obj.users) == 2

View File

@ -24,7 +24,8 @@
# THE SOFTWARE.
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyPushjet import NotifyPushjet
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -48,37 +49,37 @@ apprise_url_tests = (
}),
# The proper way to log in
('pjet://user:pass@localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
}),
# The proper way to log in
('pjets://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
}),
# Specify your own server with login (secret= MUST be provided)
('pjet://user:pass@localhost?secret=%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'pjet://user:****@localhost',
}),
# Specify your own server with port
('pjets://localhost:8080/%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
}),
('pjets://localhost:8080/%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('pjets://localhost:4343/%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pjet://localhost:8081/%s' % ('a' * 32), {
'instance': plugins.NotifyPushjet,
'instance': NotifyPushjet,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -104,7 +105,7 @@ def test_plugin_pushjet_edge_cases(no_throttling):
# No application Key specified
with pytest.raises(TypeError):
plugins.NotifyPushjet(secret_key=None)
NotifyPushjet(secret_key=None)
with pytest.raises(TypeError):
plugins.NotifyPushjet(secret_key=" ")
NotifyPushjet(secret_key=" ")

View File

@ -29,8 +29,7 @@ from unittest import mock
import requests
import pytest
from json import dumps
from apprise.plugins.NotifyPushover import PushoverPriority
from apprise import plugins
from apprise.plugins.NotifyPushover import PushoverPriority, NotifyPushover
import apprise
from helpers import AppriseURLTester
@ -60,89 +59,89 @@ apprise_url_tests = (
}),
# API Key + valid alternate sound picked
('pover://%s@%s?sound=spacealarm' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + valid url_title with url
('pover://%s@%s?url=my-url&url_title=title' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + Valid User
('pover://%s@%s' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# don't include an image by default
'include_image': False,
}),
# API Key + Valid User + 1 Device
('pover://%s@%s/DEVICE' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + Valid User + 1 Device (via to=)
('pover://%s@%s?to=DEVICE' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + Valid User + 2 Devices
('pover://%s@%s/DEVICE1/DEVICE2/' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'pover://u...u@a...a',
}),
# API Key + Valid User + invalid device
('pover://%s@%s/%s/' % ('u' * 30, 'a' * 30, 'd' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# Notify will return False since there is a bad device in our list
'response': False,
}),
# API Key + Valid User + device + invalid device
('pover://%s@%s/DEVICE1/%s/' % ('u' * 30, 'a' * 30, 'd' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# Notify will return False since there is a bad device in our list
'response': False,
}),
# API Key + priority setting
('pover://%s@%s?priority=high' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + priority setting + html mode
('pover://%s@%s?priority=high&format=html' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + priority setting + markdown mode
('pover://%s@%s?priority=high&format=markdown' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + invalid priority setting
('pover://%s@%s?priority=invalid' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + emergency(2) priority setting
('pover://%s@%s?priority=emergency' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + emergency(2) priority setting (via numeric value
('pover://%s@%s?priority=2' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + emergency priority setting with retry and expire
('pover://%s@%s?priority=emergency&%s&%s' % ('u' * 30,
'a' * 30,
'retry=30',
'expire=300'), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + emergency priority setting with text retry
('pover://%s@%s?priority=emergency&%s&%s' % ('u' * 30,
'a' * 30,
'retry=invalid',
'expire=300'), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + emergency priority setting with text expire
('pover://%s@%s?priority=emergency&%s&%s' % ('u' * 30,
'a' * 30,
'retry=30',
'expire=invalid'), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
# API Key + emergency priority setting with invalid expire
('pover://%s@%s?priority=emergency&%s' % ('u' * 30,
@ -158,22 +157,22 @@ apprise_url_tests = (
}),
# API Key + priority setting (empty)
('pover://%s@%s?priority=' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
}),
('pover://%s@%s' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('pover://%s@%s' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('pover://%s@%s' % ('u' * 30, 'a' * 30), {
'instance': plugins.NotifyPushover,
'instance': NotifyPushover,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -198,7 +197,7 @@ def test_plugin_pushover_attachments(mock_post, tmpdir):
"""
# Disable Throttling to speed testing
plugins.NotifyPushover.request_rate_per_sec = 0
NotifyPushover.request_rate_per_sec = 0
# Initialize some generic (but valid) tokens
user_key = 'u' * 30
@ -226,7 +225,7 @@ def test_plugin_pushover_attachments(mock_post, tmpdir):
# Instantiate our object
obj = apprise.Apprise.instantiate(
'pover://{}@{}/'.format(user_key, api_token))
assert isinstance(obj, plugins.NotifyPushover)
assert isinstance(obj, NotifyPushover)
# Test our attachment
assert obj.notify(body="test", attach=attach) is True
@ -254,7 +253,7 @@ def test_plugin_pushover_attachments(mock_post, tmpdir):
mock_post.reset_mock()
image = tmpdir.mkdir("pover_image").join("test.jpg")
image.write('a' * plugins.NotifyPushover.attach_max_size_bytes)
image.write('a' * NotifyPushover.attach_max_size_bytes)
attach = apprise.AppriseAttachment.instantiate(str(image))
assert obj.notify(body="test", attach=attach) is True
@ -269,7 +268,7 @@ def test_plugin_pushover_attachments(mock_post, tmpdir):
# Add 1 more byte to the file (putting it over the limit)
image.write(
'a' * (plugins.NotifyPushover.attach_max_size_bytes + 1))
'a' * (NotifyPushover.attach_max_size_bytes + 1))
attach = apprise.AppriseAttachment.instantiate(str(image))
assert obj.notify(body="test", attach=attach) is False
@ -317,11 +316,11 @@ def test_plugin_pushover_edge_cases(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifyPushover.request_rate_per_sec = 0
NotifyPushover.request_rate_per_sec = 0
# No token
with pytest.raises(TypeError):
plugins.NotifyPushover(token=None)
NotifyPushover(token=None)
# Initialize some generic (but valid) tokens
token = 'a' * 30
@ -338,11 +337,11 @@ def test_plugin_pushover_edge_cases(mock_post):
# No webhook id specified
with pytest.raises(TypeError):
plugins.NotifyPushover(user_key=user_key, webhook_id=None)
NotifyPushover(user_key=user_key, webhook_id=None)
obj = plugins.NotifyPushover(
obj = NotifyPushover(
user_key=user_key, token=token, targets=devices)
assert isinstance(obj, plugins.NotifyPushover) is True
assert isinstance(obj, NotifyPushover) is True
assert len(obj.targets) == 3
# This call fails because there is 1 invalid device
@ -350,8 +349,8 @@ def test_plugin_pushover_edge_cases(mock_post):
body='body', title='title',
notify_type=apprise.NotifyType.INFO) is False
obj = plugins.NotifyPushover(user_key=user_key, token=token)
assert isinstance(obj, plugins.NotifyPushover) is True
obj = NotifyPushover(user_key=user_key, token=token)
assert isinstance(obj, NotifyPushover) is True
# Default is to send to all devices, so there will be a
# device defined here
assert len(obj.targets) == 1
@ -361,23 +360,23 @@ def test_plugin_pushover_edge_cases(mock_post):
body='body', title='title',
notify_type=apprise.NotifyType.INFO) is True
obj = plugins.NotifyPushover(
obj = NotifyPushover(
user_key=user_key, token=token, targets=set())
assert isinstance(obj, plugins.NotifyPushover) is True
assert isinstance(obj, NotifyPushover) is True
# Default is to send to all devices, so there will be a
# device defined here
assert len(obj.targets) == 1
# No User Key specified
with pytest.raises(TypeError):
plugins.NotifyPushover(user_key=None, token="abcd")
NotifyPushover(user_key=None, token="abcd")
# No Access Token specified
with pytest.raises(TypeError):
plugins.NotifyPushover(user_key="abcd", token=None)
NotifyPushover(user_key="abcd", token=None)
with pytest.raises(TypeError):
plugins.NotifyPushover(user_key="abcd", token=" ")
NotifyPushover(user_key="abcd", token=" ")
@mock.patch('requests.post')
@ -409,7 +408,7 @@ def test_plugin_pushover_config_files(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifyPushover.request_rate_per_sec = 0
NotifyPushover.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()

View File

@ -31,7 +31,7 @@ import requests
from json import dumps
from apprise import AppriseAttachment
from apprise import NotifyType
from apprise import plugins
from apprise.plugins.NotifyPushSafer import NotifyPushSafer
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -53,18 +53,18 @@ apprise_url_tests = (
'instance': TypeError,
}),
('psafer://{}'.format('a' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# This will fail because we're also expecting a server acknowledgement
'notify_response': False,
}),
('psafer://{}'.format('b' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# invalid JSON response
'requests_response_text': '{',
'notify_response': False,
}),
('psafer://{}'.format('c' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A failure has status set to zero
# We also expect an 'error' flag to be set
'requests_response_text': {
@ -74,7 +74,7 @@ apprise_url_tests = (
'notify_response': False,
}),
('psafers://{}'.format('d' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A failure has status set to zero
# Test without an 'error' flag
'requests_response_text': {
@ -84,7 +84,7 @@ apprise_url_tests = (
}),
# This will notify all users ('a')
('psafer://{}'.format('e' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A status of 1 is a success
'requests_response_text': {
'status': 1,
@ -92,7 +92,7 @@ apprise_url_tests = (
}),
# This will notify a selected set of devices
('psafer://{}/12/24/53'.format('e' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A status of 1 is a success
'requests_response_text': {
'status': 1,
@ -100,7 +100,7 @@ apprise_url_tests = (
}),
# Same as above, but exercises the to= argument
('psafer://{}?to=12,24,53'.format('e' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A status of 1 is a success
'requests_response_text': {
'status': 1,
@ -108,14 +108,14 @@ apprise_url_tests = (
}),
# Set priority
('psafer://{}?priority=emergency'.format('f' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
'requests_response_text': {
'status': 1,
}
}),
# Support integer value too
('psafer://{}?priority=-1'.format('f' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
'requests_response_text': {
'status': 1,
}
@ -132,14 +132,14 @@ apprise_url_tests = (
}),
# Set sound
('psafer://{}?sound=ok'.format('g' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
'requests_response_text': {
'status': 1,
}
}),
# Support integer value too
('psafers://{}?sound=14'.format('g' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
'requests_response_text': {
'status': 1,
},
@ -156,7 +156,7 @@ apprise_url_tests = (
}),
# Set vibration (integer only)
('psafers://{}?vibration=1'.format('h' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
'requests_response_text': {
'status': 1,
},
@ -173,7 +173,7 @@ apprise_url_tests = (
'instance': TypeError,
}),
('psafers://{}'.format('d' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A failure has status set to zero
# Test without an 'error' flag
'requests_response_text': {
@ -185,7 +185,7 @@ apprise_url_tests = (
'requests_response_code': requests.codes.internal_server_error,
}),
('psafer://{}'.format('d' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A failure has status set to zero
# Test without an 'error' flag
'requests_response_text': {
@ -197,7 +197,7 @@ apprise_url_tests = (
'requests_response_code': 999,
}),
('psafers://{}'.format('d' * 20), {
'instance': plugins.NotifyPushSafer,
'instance': NotifyPushSafer,
# A failure has status set to zero
# Test without an 'error' flag
'requests_response_text': {
@ -227,7 +227,7 @@ def test_plugin_pushsafer_general(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifyPushSafer.request_rate_per_sec = 0
NotifyPushSafer.request_rate_per_sec = 0
# Private Key
privatekey = 'abc123'
@ -242,7 +242,7 @@ def test_plugin_pushsafer_general(mock_post):
# Exception should be thrown about the fact no private key was specified
with pytest.raises(TypeError):
plugins.NotifyPushSafer(privatekey=None)
NotifyPushSafer(privatekey=None)
# Multiple Attachment Support
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -250,7 +250,7 @@ def test_plugin_pushsafer_general(mock_post):
for _ in range(0, 4):
attach.add(path)
obj = plugins.NotifyPushSafer(privatekey=privatekey)
obj = NotifyPushSafer(privatekey=privatekey)
assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO,
attach=attach) is True

View File

@ -24,7 +24,8 @@
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyReddit import NotifyReddit
from helpers import AppriseURLTester
from unittest import mock
@ -67,14 +68,14 @@ apprise_url_tests = (
}),
('reddit://user:password@app-id/app-secret/apprise', {
# Login failed
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
# Expected notify() response is False because internally we would
# have failed to login
'notify_response': False,
}),
('reddit://user:password@app-id/app-secret', {
# Login successful, but there was no subreddit to notify
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -91,7 +92,7 @@ apprise_url_tests = (
'notify_response': False,
}),
('reddit://user:password@app-id/app-secret/apprise', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -110,7 +111,7 @@ apprise_url_tests = (
}),
('reddit://user:password@app-id/app-secret/apprise', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -128,7 +129,7 @@ apprise_url_tests = (
}),
('reddit://user:password@app-id/app-secret/apprise/subreddit2', {
# password:login acceptable
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -148,7 +149,7 @@ apprise_url_tests = (
# Pass in some arguments to over-ride defaults
('reddit://user:pass@id/secret/sub/'
'?ad=yes&nsfw=yes&replies=no&resubmit=yes&spoiler=yes&kind=self', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -166,7 +167,7 @@ apprise_url_tests = (
# Pass in more arguments
('reddit://'
'?user=l2g&pass=pass&app_secret=abc123&app_id=54321&to=sub1,sub2', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -184,7 +185,7 @@ apprise_url_tests = (
# More arguments ...
('reddit://user:pass@id/secret/sub7/sub6/sub5/'
'?flair_id=wonder&flair_text=not%20for%20you', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
'requests_response_text': {
"access_token": 'abc123',
"token_type": "bearer",
@ -200,13 +201,13 @@ apprise_url_tests = (
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'reddit://user:****@****/****/sub'}),
('reddit://user:password@app-id/app-secret/apprise', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('reddit://user:password@app-id/app-secret/apprise', {
'instance': plugins.NotifyReddit,
'instance': NotifyReddit,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -267,8 +268,8 @@ def test_plugin_reddit_general(mock_post, no_throttling):
mock_post.return_value = good_response
# Variation Initializations
obj = plugins.NotifyReddit(**kwargs)
assert isinstance(obj, plugins.NotifyReddit) is True
obj = NotifyReddit(**kwargs)
assert isinstance(obj, NotifyReddit) is True
assert isinstance(obj.url(), str) is True
# Dynamically pick up on a link
@ -346,12 +347,12 @@ def test_plugin_reddit_general(mock_post, no_throttling):
response.content = '{'
response.status_code = requests.codes.ok
mock_post.return_value = response
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is False
# Return it to a parseable string but missing the entries we expect
response.content = '{}'
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is False
# No access token provided
@ -362,12 +363,12 @@ def test_plugin_reddit_general(mock_post, no_throttling):
"errors": [],
},
})
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is False
# cause a json parsing issue now
response.content = None
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is False
# Reset to what we consider a good response
@ -395,7 +396,7 @@ def test_plugin_reddit_general(mock_post, no_throttling):
# Test sucessful re-authentication after failed post
mock_post.side_effect = [
good_response, bad_response, good_response, good_response]
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is True
assert mock_post.call_count == 4
assert mock_post.call_args_list[0][0][0] == \
@ -410,7 +411,7 @@ def test_plugin_reddit_general(mock_post, no_throttling):
# Test failed re-authentication
mock_post.side_effect = [
good_response, bad_response, bad_response]
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is False
# Test exception handing on re-auth attempt
@ -418,5 +419,5 @@ def test_plugin_reddit_general(mock_post, no_throttling):
response.status_code = requests.codes.ok
mock_post.side_effect = [
good_response, bad_response, good_response, response]
obj = plugins.NotifyReddit(**kwargs)
obj = NotifyReddit(**kwargs)
assert obj.send(body="test") is False

View File

@ -24,8 +24,8 @@
# THE SOFTWARE.
import pytest
import requests
from apprise import plugins
from apprise import NotifyType
from apprise.plugins.NotifyRocketChat import NotifyRocketChat
from helpers import AppriseURLTester
from unittest import mock
@ -66,7 +66,7 @@ apprise_url_tests = (
}),
# A room and port identifier
('rocket://user:pass@localhost:8080/room/', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -78,7 +78,7 @@ apprise_url_tests = (
}),
# A channel (using the to=)
('rockets://user:pass@localhost?to=#channel', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -90,7 +90,7 @@ apprise_url_tests = (
}),
# A channel
('rockets://user:pass@localhost/#channel', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -102,7 +102,7 @@ apprise_url_tests = (
}),
# Several channels
('rocket://user:pass@localhost/#channel1/#channel2/?avatar=Yes', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -114,7 +114,7 @@ apprise_url_tests = (
}),
# Several Rooms
('rocket://user:pass@localhost/room1/room2', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -126,7 +126,7 @@ apprise_url_tests = (
}),
# A room and channel
('rocket://user:pass@localhost/room/#channel?mode=basic&avatar=Yes', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -142,7 +142,7 @@ apprise_url_tests = (
# to ensure we get the right mode, we enforce basic mode
# so that web/token gets interpreted as a password
('rockets://user:pass%2Fwithslash@localhost/#channel/?mode=basic', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# The response text is expected to be the following on a success
'requests_response_text': {
'status': 'success',
@ -161,54 +161,54 @@ apprise_url_tests = (
'status': 'failure',
},
# Exception is thrown in this case
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# Notifications will fail in this event
'response': False,
}),
# A web token
('rockets://web/token@localhost/@user/#channel/roomid', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
}),
('rockets://user:web/token@localhost/@user/?mode=webhook', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
}),
('rockets://user:web/token@localhost?to=@user2,#channel2', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
}),
('rockets://web/token@localhost/?avatar=No', {
# a simple webhook token with default values
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'rockets://w...n@localhost',
}),
('rockets://localhost/@user/?mode=webhook&webhook=web/token', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
}),
('rockets://user:web/token@localhost/@user/?mode=invalid', {
# invalid mode
'instance': TypeError,
}),
('rocket://user:pass@localhost:8081/room1/room2', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# force a failure using basic mode
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('rockets://user:web/token@localhost?to=@user3,#channel3', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# force a failure using webhook mode
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('rocket://user:pass@localhost:8082/#channel', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('rocket://user:pass@localhost:8083/#chan1/#chan2/room', {
'instance': plugins.NotifyRocketChat,
'instance': NotifyRocketChat,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -249,16 +249,16 @@ def test_plugin_rocketchat_edge_cases(mock_post, mock_get, no_throttling):
mock_post.return_value.content = ''
mock_get.return_value.content = ''
obj = plugins.NotifyRocketChat(
obj = NotifyRocketChat(
user=user, password=password, targets=recipients)
assert isinstance(obj, plugins.NotifyRocketChat) is True
assert isinstance(obj, NotifyRocketChat) is True
assert len(obj.channels) == 2
assert len(obj.users) == 2
assert len(obj.rooms) == 1
# No Webhook specified
with pytest.raises(TypeError):
obj = plugins.NotifyRocketChat(webhook=None, mode='webhook')
obj = NotifyRocketChat(webhook=None, mode='webhook')
#
# Logout

View File

@ -24,7 +24,8 @@
# THE SOFTWARE.
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifyRyver import NotifyRyver
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -54,57 +55,57 @@ apprise_url_tests = (
('ryver://apprise/ckhrjW8w672m6HG?mode=slack', {
# No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our slack mode
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
}),
('ryver://apprise/ckhrjW8w672m6HG?mode=ryver', {
# No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our ryver mode
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
}),
# Legacy webhook mode setting:
# Legacy webhook mode setting:
('ryver://apprise/ckhrjW8w672m6HG?webhook=slack', {
# No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our slack mode
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
}),
('ryver://apprise/ckhrjW8w672m6HG?webhook=ryver', {
# No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our ryver mode
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'ryver://apprise/c...G',
}),
# Support Native URLs
('https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
}),
# Support Native URLs with arguments
('https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG'
'?webhook=ryver',
{
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
}),
('ryver://caronc@apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
# don't include an image by default
'include_image': False,
}),
('ryver://apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('ryver://apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('ryver://apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver,
'instance': NotifyRyver,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -130,14 +131,14 @@ def test_plugin_ryver_edge_cases(no_throttling):
# No token
with pytest.raises(TypeError):
plugins.NotifyRyver(organization="abc", token=None)
NotifyRyver(organization="abc", token=None)
with pytest.raises(TypeError):
plugins.NotifyRyver(organization="abc", token=" ")
NotifyRyver(organization="abc", token=" ")
# No organization
with pytest.raises(TypeError):
plugins.NotifyRyver(organization=None, token="abc")
NotifyRyver(organization=None, token="abc")
with pytest.raises(TypeError):
plugins.NotifyRyver(organization=" ", token="abc")
NotifyRyver(organization=" ", token="abc")

View File

@ -26,7 +26,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise.plugins.NotifySendGrid import NotifySendGrid
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -59,54 +60,54 @@ apprise_url_tests = (
('sendgrid://abcd:user@example.com', {
# No To/Target Address(es) specified; so we sub in the same From
# address
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
}),
('sendgrid://abcd:user@example.com/newuser@example.com', {
# A good email
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
}),
('sendgrid://abcd:user@example.com/newuser@example.com'
'?bcc=l2g@nuxref.com', {
# A good email with Blind Carbon Copy
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
}),
('sendgrid://abcd:user@example.com/newuser@example.com'
'?cc=l2g@nuxref.com', {
# A good email with Carbon Copy
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
}),
('sendgrid://abcd:user@example.com/newuser@example.com'
'?to=l2g@nuxref.com', {
# A good email with Carbon Copy
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
}),
('sendgrid://abcd:user@example.com/newuser@example.com'
'?template={}'.format(UUID4), {
# A good email with a template + no substitutions
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
}),
('sendgrid://abcd:user@example.com/newuser@example.com'
'?template={}&+sub=value&+sub2=value2'.format(UUID4), {
# A good email with a template + substitutions
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'sendgrid://a...d:user@example.com/',
}),
('sendgrid://abcd:user@example.ca/newuser@example.ca', {
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('sendgrid://abcd:user@example.uk/newuser@example.uk', {
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('sendgrid://abcd:user@example.au/newuser@example.au', {
'instance': plugins.NotifySendGrid,
'instance': NotifySendGrid,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -134,25 +135,25 @@ def test_plugin_sendgrid_edge_cases(mock_post, mock_get, no_throttling):
# no apikey
with pytest.raises(TypeError):
plugins.NotifySendGrid(
NotifySendGrid(
apikey=None, from_email='user@example.com')
# invalid from email
with pytest.raises(TypeError):
plugins.NotifySendGrid(
NotifySendGrid(
apikey='abcd', from_email='!invalid')
# no email
with pytest.raises(TypeError):
plugins.NotifySendGrid(apikey='abcd', from_email=None)
NotifySendGrid(apikey='abcd', from_email=None)
# Invalid To email address
plugins.NotifySendGrid(
NotifySendGrid(
apikey='abcd', from_email='user@example.com', targets="!invalid")
# Test invalid bcc/cc entries mixed with good ones
assert isinstance(plugins.NotifySendGrid(
assert isinstance(NotifySendGrid(
apikey='abcd',
from_email='l2g@example.com',
bcc=('abc@def.com', '!invalid'),
cc=('abc@test.org', '!invalid')), plugins.NotifySendGrid)
cc=('abc@test.org', '!invalid')), NotifySendGrid)

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyServerChan import NotifyServerChan
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,19 +41,19 @@ apprise_url_tests = (
}),
('schan://12345678', {
# access token
'instance': plugins.NotifyServerChan,
'instance': NotifyServerChan,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'schan://1...8',
}),
('schan://{}'.format('a' * 8), {
'instance': plugins.NotifyServerChan,
'instance': NotifyServerChan,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('schan://{}'.format('a' * 8), {
'instance': plugins.NotifyServerChan,
'instance': NotifyServerChan,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -31,7 +31,7 @@ import pytest
import requests
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import plugins
from apprise.plugins.NotifySES import NotifySES
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -100,7 +100,7 @@ apprise_url_tests = (
('ses://user@example.com/T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcevi7FQ/'
'us-west-2', {
# we have a valid URL and we'll use our own email as a target
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -108,7 +108,7 @@ apprise_url_tests = (
('ses://user@example.com/T1JJ3TD4JD/TIiajkdnlazk7FQ/us-west-2/'
'user2@example.ca/user3@example.eu', {
# Multi Email Suppport
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -119,7 +119,7 @@ apprise_url_tests = (
('ses://user@example.com/T1JJ3T3L2/A1BRTD4JD/TIiajkdnlaevi7FQ/us-east-1'
'?to=user2@example.ca', {
# leveraging to: keyword
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -132,7 +132,7 @@ apprise_url_tests = (
'&to=user2@example.ca', {
# leveraging a ton of our keywords
# We also test invlid emails specified on the bcc and cc list
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -140,7 +140,7 @@ apprise_url_tests = (
('ses://user@example.com/T1JJ3T3L2/A1BRTD4JD/TIiacevi7FQ/us-west-2/'
'?name=From%20Name&to=user2@example.ca,invalid-email', {
# leveraging a ton of our keywords
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -148,7 +148,7 @@ apprise_url_tests = (
('ses://user@example.com/T1JJ3T3L2/A1BRTD4JD/TIiacevi7FQ/us-west-2/'
'?format=text', {
# Send email as a text (instead of HTML)
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -157,7 +157,7 @@ apprise_url_tests = (
'?to=invalid-email', {
# An invalid email will get dropped during the initialization
# we'll have no targets to notify afterwards
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
@ -167,7 +167,7 @@ apprise_url_tests = (
}),
('ses://user@example.com/T1JJ3T3L2/A1BRTD4JD/TIiacevi7FQ/us-west-2/'
'user2@example.com', {
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
# throw a bizzare code forcing us to fail to look it up
@ -176,7 +176,7 @@ apprise_url_tests = (
}),
('ses://user@example.com/T1JJ3T3L2/A1BRTD4JD/TIiajkdnlavi7FQ/us-west-2/'
'user2@example.com', {
'instance': plugins.NotifySES,
'instance': NotifySES,
# Our response expected server response
'requests_response_text': AWS_SES_GOOD_RESPONSE,
# Throws a series of connection and transfer exceptions when this
@ -208,7 +208,7 @@ def test_plugin_ses_edge_cases(mock_post):
# Initializes the plugin with a valid access, but invalid access key
with pytest.raises(TypeError):
# No access_key_id specified
plugins.NotifySES(
NotifySES(
from_addr="user@example.eu",
access_key_id=None,
secret_access_key=TEST_ACCESS_KEY_SECRET,
@ -218,7 +218,7 @@ def test_plugin_ses_edge_cases(mock_post):
with pytest.raises(TypeError):
# No secret_access_key specified
plugins.NotifySES(
NotifySES(
from_addr="user@example.eu",
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=None,
@ -228,7 +228,7 @@ def test_plugin_ses_edge_cases(mock_post):
with pytest.raises(TypeError):
# No region_name specified
plugins.NotifySES(
NotifySES(
from_addr="user@example.eu",
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
@ -237,7 +237,7 @@ def test_plugin_ses_edge_cases(mock_post):
)
# No recipients
obj = plugins.NotifySES(
obj = NotifySES(
from_addr="user@example.eu",
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
@ -250,7 +250,7 @@ def test_plugin_ses_edge_cases(mock_post):
# The phone number is invalid, and without it, there is nothing
# to notify; we
obj = plugins.NotifySES(
obj = NotifySES(
from_addr="user@example.eu",
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
@ -269,7 +269,7 @@ def test_plugin_ses_url_parsing():
"""
# No recipients
results = plugins.NotifySES.parse_url('ses://%s/%s/%s/%s/' % (
results = NotifySES.parse_url('ses://%s/%s/%s/%s/' % (
'user@example.com',
TEST_ACCESS_KEY_ID,
TEST_ACCESS_KEY_SECRET,
@ -286,7 +286,7 @@ def test_plugin_ses_url_parsing():
assert TEST_ACCESS_KEY_SECRET == results['secret_access_key']
# Detect recipients
results = plugins.NotifySES.parse_url('ses://%s/%s/%s/%s/%s/%s/' % (
results = NotifySES.parse_url('ses://%s/%s/%s/%s/%s/%s/' % (
'user@example.com',
TEST_ACCESS_KEY_ID,
TEST_ACCESS_KEY_SECRET,
@ -314,28 +314,28 @@ def test_plugin_ses_aws_response_handling():
"""
# Not a string
response = plugins.NotifySES.aws_response_to_dict(None)
response = NotifySES.aws_response_to_dict(None)
assert response['type'] is None
assert response['request_id'] is None
# Invalid XML
response = plugins.NotifySES.aws_response_to_dict(
response = NotifySES.aws_response_to_dict(
'<Bad Response xmlns="http://ses.amazonaws.com/doc/2010-03-31/">')
assert response['type'] is None
assert response['request_id'] is None
# Single Element in XML
response = plugins.NotifySES.aws_response_to_dict(
response = NotifySES.aws_response_to_dict(
'<SingleElement></SingleElement>')
assert response['type'] == 'SingleElement'
assert response['request_id'] is None
# Empty String
response = plugins.NotifySES.aws_response_to_dict('')
response = NotifySES.aws_response_to_dict('')
assert response['type'] is None
assert response['request_id'] is None
response = plugins.NotifySES.aws_response_to_dict(
response = NotifySES.aws_response_to_dict(
"""
<SendRawEmailResponse
xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
@ -353,7 +353,7 @@ def test_plugin_ses_aws_response_handling():
assert response['message_id'] == \
'010f017d87656ee2-a2ea291f-79ea-44f3-9d25-00d041de307'
response = plugins.NotifySES.aws_response_to_dict(
response = NotifySES.aws_response_to_dict(
"""
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-03-31/">
<Error>
@ -378,7 +378,7 @@ def test_plugin_ses_attachments(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifySES.request_rate_per_sec = 0
NotifySES.request_rate_per_sec = 0
# Prepare Mock return object
response = mock.Mock()

View File

@ -29,8 +29,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise import Apprise
from apprise.plugins.NotifySignalAPI import NotifySignalAPI
from helpers import AppriseURLTester
from apprise import AppriseAttachment
from apprise import NotifyType
@ -67,7 +67,7 @@ apprise_url_tests = (
}),
('signal://localhost/{}/123/'.format('1' * 11), {
# invalid 'to' phone number
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
# Notify will fail because it couldn't send to anyone
'response': False,
# Our expected url(privacy=True) startswith() response:
@ -75,67 +75,67 @@ apprise_url_tests = (
}),
('signal://localhost:8080/{}/'.format('1' * 11), {
# one phone number will notify ourselves
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signal://localhost:8082/+{}/@group.abcd/'.format('2' * 11), {
# a valid group
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'signal://localhost:8082/+{}/@abcd'.format('2' * 11),
}),
('signal://localhost:8080/+{}/group.abcd/'.format('1' * 11), {
# another valid group (without @ symbol)
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'signal://localhost:8080/+{}/@abcd'.format('1' * 11),
}),
('signal://localhost:8080/?from={}&to={},{}'.format(
'1' * 11, '2' * 11, '3' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signal://localhost:8080/?from={}&to={},{},{}'.format(
'1' * 11, '2' * 11, '3' * 11, '5' * 3), {
# 2 good targets and one invalid one
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signal://localhost:8080/{}/{}/?from={}'.format(
'1' * 11, '2' * 11, '3' * 11), {
# If we have from= specified, then all elements take on the to= value
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signals://user@localhost/{}/{}'.format('1' * 11, '3' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signals://user:password@localhost/{}/{}'.format('1' * 11, '3' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signals://user:password@localhost/{}/{}'.format('1' * 11, '3' * 11), {
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
# Test that a 201 response code is still accepted
'requests_response_code': 201,
}),
('signals://localhost/{}/{}/{}?batch=True'.format(
'1' * 11, '3' * 11, '4' * 11), {
# test batch mode
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signals://localhost/{}/{}/{}?status=True'.format(
'1' * 11, '3' * 11, '4' * 11), {
# test status switch
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
}),
('signal://localhost/{}/{}'.format('1' * 11, '4' * 11), {
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('signal://localhost/{}/{}'.format('1' * 11, '4' * 11), {
'instance': plugins.NotifySignalAPI,
'instance': NotifySignalAPI,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -175,7 +175,7 @@ def test_plugin_signal_edge_cases(mock_post, no_throttling):
# No apikey specified
with pytest.raises(TypeError):
plugins.NotifySignalAPI(source=None)
NotifySignalAPI(source=None)
aobj = Apprise()
assert aobj.add("signals://localhost:231/{}/{}".format(source, target))
@ -321,7 +321,7 @@ def test_notify_signal_plugin_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'signal://10.0.0.112:8080/+12512222222/+12513333333/'
'12514444444?batch=no')
assert isinstance(obj, plugins.NotifySignalAPI)
assert isinstance(obj, NotifySignalAPI)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -364,7 +364,7 @@ def test_notify_signal_plugin_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'signal://10.0.0.112:8080/+12512222222/+12513333333/'
'12514444444?batch=yes')
assert isinstance(obj, plugins.NotifySignalAPI)
assert isinstance(obj, NotifySignalAPI)
# Now send an attachment normally without issues
mock_post.reset_mock()

View File

@ -29,7 +29,7 @@ import pytest
import requests
import json
from apprise import Apprise
from apprise import plugins
from apprise.plugins.NotifySimplePush import NotifySimplePush
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -45,13 +45,13 @@ apprise_url_tests = (
('spush://{}'.format('A' * 14), {
# API Key specified however expected server response
# didn't have 'OK' in JSON response
'instance': plugins.NotifySimplePush,
'instance': NotifySimplePush,
# Expected notify() response
'notify_response': False,
}),
('spush://{}'.format('Y' * 14), {
# API Key valid and expected response was valid
'instance': plugins.NotifySimplePush,
'instance': NotifySimplePush,
# Set our response to OK
'requests_response_text': {
'status': 'OK',
@ -62,7 +62,7 @@ apprise_url_tests = (
}),
('spush://{}?event=Not%20So%20Good'.format('X' * 14), {
# API Key valid and expected response was valid
'instance': plugins.NotifySimplePush,
'instance': NotifySimplePush,
# Set our response to something that is not okay
'requests_response_text': {
'status': 'NOT-OK',
@ -72,7 +72,7 @@ apprise_url_tests = (
}),
('spush://salt:pass@{}'.format('X' * 14), {
# Now we'll test encrypted messages with new salt
'instance': plugins.NotifySimplePush,
'instance': NotifySimplePush,
# Set our response to OK
'requests_response_text': {
'status': 'OK',
@ -82,7 +82,7 @@ apprise_url_tests = (
'privacy_url': 'spush://****:****@X...X/',
}),
('spush://{}'.format('Y' * 14), {
'instance': plugins.NotifySimplePush,
'instance': NotifySimplePush,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -93,7 +93,7 @@ apprise_url_tests = (
},
}),
('spush://{}'.format('Z' * 14), {
'instance': plugins.NotifySimplePush,
'instance': NotifySimplePush,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -138,17 +138,17 @@ def test_plugin_simplepush_edge_cases(no_throttling):
# No token
with pytest.raises(TypeError):
plugins.NotifySimplePush(apikey=None)
NotifySimplePush(apikey=None)
with pytest.raises(TypeError):
plugins.NotifySimplePush(apikey=" ")
NotifySimplePush(apikey=" ")
# Bad event
with pytest.raises(TypeError):
plugins.NotifySimplePush(apikey="abc", event=object)
NotifySimplePush(apikey="abc", event=object)
with pytest.raises(TypeError):
plugins.NotifySimplePush(apikey="abc", event=" ")
NotifySimplePush(apikey="abc", event=" ")
@pytest.mark.skipif(

View File

@ -27,7 +27,8 @@ from unittest import mock
import pytest
import requests
from json import dumps
from apprise import plugins
from apprise.plugins.NotifySinch import NotifySinch
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -55,7 +56,7 @@ apprise_url_tests = (
('sinch://{}:{}@{}'.format('a' * 32, 'b' * 32, '3' * 5), {
# using short-code (5 characters) without a target
# We can still instantiate ourselves with a valid short code
'instance': plugins.NotifySinch,
'instance': NotifySinch,
# Expected notify() response because we have no one to notify
'notify_response': False,
}),
@ -66,27 +67,27 @@ apprise_url_tests = (
('sinch://{}:{}@{}/123/{}/abcd/'.format(
'a' * 32, 'b' * 32, '3' * 11, '9' * 15), {
# valid everything but target numbers
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://{}:{}@12345/{}'.format('a' * 32, 'b' * 32, '4' * 11), {
# using short-code (5 characters)
'instance': plugins.NotifySinch,
'instance': NotifySinch,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'sinch://...aaaa:b...b@12345',
}),
('sinch://{}:{}@123456/{}'.format('a' * 32, 'b' * 32, '4' * 11), {
# using short-code (6 characters)
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://{}:{}@{}'.format('a' * 32, 'b' * 32, '5' * 11), {
# using phone no with no target - we text ourselves in
# this case
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://{}:{}@{}?region=eu'.format('a' * 32, 'b' * 32, '5' * 11), {
# Specify a region
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://{}:{}@{}?region=invalid'.format('a' * 32, 'b' * 32, '5' * 11), {
# Invalid region
@ -95,26 +96,26 @@ apprise_url_tests = (
('sinch://_?spi={}&token={}&from={}'.format(
'a' * 32, 'b' * 32, '5' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://_?spi={}&token={}&source={}'.format(
'a' * 32, 'b' * 32, '5' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://_?spi={}&token={}&from={}&to={}'.format(
'a' * 32, 'b' * 32, '5' * 11, '7' * 13), {
# use to=
'instance': plugins.NotifySinch,
'instance': NotifySinch,
}),
('sinch://{}:{}@{}'.format('a' * 32, 'b' * 32, '6' * 11), {
'instance': plugins.NotifySinch,
'instance': NotifySinch,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('sinch://{}:{}@{}'.format('a' * 32, 'b' * 32, '6' * 11), {
'instance': plugins.NotifySinch,
'instance': NotifySinch,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -153,12 +154,12 @@ def test_plugin_sinch_edge_cases(mock_post, no_throttling):
# No service_plan_id specified
with pytest.raises(TypeError):
plugins.NotifySinch(
NotifySinch(
service_plan_id=None, api_token=api_token, source=source)
# No api_token specified
with pytest.raises(TypeError):
plugins.NotifySinch(
NotifySinch(
service_plan_id=service_plan_id, api_token=None, source=source)
# a error response
@ -170,7 +171,7 @@ def test_plugin_sinch_edge_cases(mock_post, no_throttling):
mock_post.return_value = response
# Initialize our object
obj = plugins.NotifySinch(
obj = NotifySinch(
service_plan_id=service_plan_id, api_token=api_token, source=source)
# We will fail with the above error code

View File

@ -28,9 +28,9 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise import NotifyType
from apprise import AppriseAttachment
from apprise.plugins.NotifySlack import NotifySlack
from helpers import AppriseURLTester
from json import dumps
@ -61,7 +61,7 @@ apprise_url_tests = (
('slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#hmm/#-invalid-', {
# No username specified; this is still okay as we sub in
# default; The one invalid channel is skipped when sending a message
'instance': plugins.NotifySlack,
'instance': NotifySlack,
# There is an invalid channel that we will fail to deliver to
# as a result the response type will be false
'response': False,
@ -73,7 +73,7 @@ apprise_url_tests = (
('slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#channel', {
# No username specified; this is still okay as we sub in
# default; The one invalid channel is skipped when sending a message
'instance': plugins.NotifySlack,
'instance': NotifySlack,
# don't include an image by default
'include_image': False,
'requests_response_text': 'ok'
@ -81,48 +81,48 @@ apprise_url_tests = (
('slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/+id/@id/', {
# + encoded id,
# @ userid
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
('slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
'?to=#nuxref', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'slack://username@T...2/A...D/T...Q/',
'requests_response_text': 'ok',
}),
('slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#nuxref', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
# You can't send to email using webhook
('slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnl/user@gmail.com', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
# we'll have a notify response failure in this case
'notify_response': False,
}),
# Specify Token on argument string (with username)
('slack://bot@_/#nuxref?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnadfdajkjkfl/', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
# Specify Token and channels on argument string (no username)
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/&to=#chan', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
# Test webhook that doesn't have a proper response
('slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#nuxref', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'fail',
# we'll have a notify response failure in this case
'notify_response': False,
}),
# Test using a bot-token (also test footer set to no flag)
('slack://username@xoxb-1234-1234-abc124/#nuxref?footer=no', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': {
'ok': True,
'message': '',
@ -136,32 +136,32 @@ apprise_url_tests = (
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
'&to=#chan&blocks=yes&footer=yes',
{
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok'}),
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
'&to=#chan&blocks=yes&footer=no',
{
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok'}),
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
'&to=#chan&blocks=yes&footer=yes&image=no',
{
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok'}),
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
'&to=#chan&blocks=yes&format=text',
{
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok'}),
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
'&to=#chan&blocks=no&format=text',
{
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok'}),
# Test using a bot-token as argument
('slack://?token=xoxb-1234-1234-abc124&to=#nuxref&footer=no&user=test', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': {
'ok': True,
'message': '',
@ -175,7 +175,7 @@ apprise_url_tests = (
}),
# We contain 1 or more invalid channels, so we'll fail on our notify call
('slack://?token=xoxb-1234-1234-abc124&to=#nuxref,#$,#-&footer=no', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': {
'ok': True,
'message': '',
@ -188,7 +188,7 @@ apprise_url_tests = (
'notify_response': False,
}),
('slack://username@xoxb-1234-1234-abc124/#nuxref', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': {
'ok': True,
'message': '',
@ -200,19 +200,19 @@ apprise_url_tests = (
('slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ', {
# Missing a channel, falls back to webhook channel bindings
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
# Native URL Support, take the slack URL and still build from it
('https://hooks.slack.com/services/{}/{}/{}'.format(
'A' * 9, 'B' * 9, 'c' * 24), {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
# Native URL Support with arguments
('https://hooks.slack.com/services/{}/{}/{}?format=text'.format(
'A' * 9, 'B' * 9, 'c' * 24), {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
'requests_response_text': 'ok',
}),
('slack://username@-INVALID-/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#cool', {
@ -228,21 +228,21 @@ apprise_url_tests = (
'instance': TypeError,
}),
('slack://l2g@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#usenet', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
'requests_response_text': 'ok',
}),
('slack://respect@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#a', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
'requests_response_text': 'ok',
}),
('slack://notify@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#b', {
'instance': plugins.NotifySlack,
'instance': NotifySlack,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -268,7 +268,7 @@ def test_plugin_slack_oauth_access_token(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifySlack.request_rate_per_sec = 0
NotifySlack.request_rate_per_sec = 0
# Generate an invalid bot token
token = 'xo-invalid'
@ -287,7 +287,7 @@ def test_plugin_slack_oauth_access_token(mock_post):
# We'll fail to validate the access_token
with pytest.raises(TypeError):
plugins.NotifySlack(access_token=token)
NotifySlack(access_token=token)
# Generate a (valid) bot token
token = 'xoxb-1234-1234-abc124'
@ -296,8 +296,8 @@ def test_plugin_slack_oauth_access_token(mock_post):
mock_post.return_value = request
# Variation Initializations
obj = plugins.NotifySlack(access_token=token, targets='#apprise')
assert isinstance(obj, plugins.NotifySlack) is True
obj = NotifySlack(access_token=token, targets='#apprise')
assert isinstance(obj, NotifySlack) is True
assert isinstance(obj.url(), str) is True
# apprise room was found
@ -391,7 +391,7 @@ def test_plugin_slack_webhook_mode(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifySlack.request_rate_per_sec = 0
NotifySlack.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()
@ -407,7 +407,7 @@ def test_plugin_slack_webhook_mode(mock_post):
# Support strings
channels = 'chan1,#chan2,+BAK4K23G5,@user,,,'
obj = plugins.NotifySlack(
obj = NotifySlack(
token_a=token_a, token_b=token_b, token_c=token_c, targets=channels)
assert len(obj.channels) == 4
@ -417,12 +417,12 @@ def test_plugin_slack_webhook_mode(mock_post):
# Missing first Token
with pytest.raises(TypeError):
plugins.NotifySlack(
NotifySlack(
token_a=None, token_b=token_b, token_c=token_c,
targets=channels)
# Test include_image
obj = plugins.NotifySlack(
obj = NotifySlack(
token_a=token_a, token_b=token_b, token_c=token_c, targets=channels,
include_image=True)
@ -439,7 +439,7 @@ def test_plugin_slack_send_by_email(mock_get, mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifySlack.request_rate_per_sec = 0
NotifySlack.request_rate_per_sec = 0
# Generate a (valid) bot token
token = 'xoxb-1234-1234-abc124'
@ -459,8 +459,8 @@ def test_plugin_slack_send_by_email(mock_get, mock_post):
mock_get.return_value = request
# Variation Initializations
obj = plugins.NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, plugins.NotifySlack) is True
obj = NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, NotifySlack) is True
assert isinstance(obj.url(), str) is True
# No calls made yet
@ -515,8 +515,8 @@ def test_plugin_slack_send_by_email(mock_get, mock_post):
mock_get.return_value = request
# Variation Initializations
obj = plugins.NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, plugins.NotifySlack) is True
obj = NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, NotifySlack) is True
assert isinstance(obj.url(), str) is True
# No calls made yet
@ -549,8 +549,8 @@ def test_plugin_slack_send_by_email(mock_get, mock_post):
mock_get.return_value = request
# Variation Initializations
obj = plugins.NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, plugins.NotifySlack) is True
obj = NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, NotifySlack) is True
assert isinstance(obj.url(), str) is True
# No calls made yet
@ -583,8 +583,8 @@ def test_plugin_slack_send_by_email(mock_get, mock_post):
mock_get.return_value = request
# Variation Initializations
obj = plugins.NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, plugins.NotifySlack) is True
obj = NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, NotifySlack) is True
assert isinstance(obj.url(), str) is True
# No calls made yet
@ -627,8 +627,8 @@ def test_plugin_slack_send_by_email(mock_get, mock_post):
0, 'requests.ConnectionError() not handled')
# Variation Initializations
obj = plugins.NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, plugins.NotifySlack) is True
obj = NotifySlack(access_token=token, targets='user@gmail.com')
assert isinstance(obj, NotifySlack) is True
assert isinstance(obj.url(), str) is True
# No calls made yet

View File

@ -27,8 +27,8 @@ from json import loads, dumps
from unittest import mock
import requests
from apprise import plugins
from apprise import Apprise
from apprise.plugins.NotifySMSEagle import NotifySMSEagle
from helpers import AppriseURLTester
from apprise import AppriseAttachment
from apprise import NotifyType
@ -73,7 +73,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost/123/', {
# invalid 'to' phone number
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Notify will fail because it couldn't send to anyone
'response': False,
# Our expected url(privacy=True) startswith() response:
@ -83,7 +83,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost/%20/%20/', {
# invalid 'to' phone number
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Notify will fail because it couldn't send to anyone
'response': False,
# Our expected url(privacy=True) startswith() response:
@ -93,25 +93,25 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8080/{}/'.format('1' * 11), {
# one phone number will notify ourselves
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagle://localhost:8080/{}/?token=abc1234'.format('1' * 11), {
# pass our token in as an argument
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
# Set priority
('smseagle://token@localhost/@user/?priority=high', {
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
# Support integer value too
('smseagle://token@localhost/@user/?priority=1', {
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
# Invalid priority
@ -126,7 +126,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8082/#abcd/', {
# a valid group
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'smseagle://****@localhost:8082/#abcd',
# Our response expected server response
@ -134,7 +134,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8082/@abcd/', {
# a valid contact
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'smseagle://****@localhost:8082/@abcd',
# Our response expected server response
@ -142,7 +142,7 @@ apprise_url_tests = (
}),
('smseagles://token@localhost:8081/contact/', {
# another valid group (without @ symbol)
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'smseagles://****@localhost:8081/@contact',
# Our response expected server response
@ -150,7 +150,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8082/@/#/,/', {
# Test case where we provide bad data
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our failed response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
# as a result, we expect a failed notification
@ -158,7 +158,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8083/@user/', {
# Test case where we get a bad response
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'smseagle://****@localhost:8083/@user',
# Our failed response
@ -168,7 +168,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8084/@user/', {
# Test case where we get a bad response
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'smseagle://****@localhost:8084/@user',
# Our failed response
@ -178,7 +178,7 @@ apprise_url_tests = (
}),
('smseagle://token@localhost:8085/@user/', {
# Test case where we get a bad response
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'smseagle://****@localhost:8085/@user',
# Our failed response (bad json)
@ -189,60 +189,60 @@ apprise_url_tests = (
('smseagle://token@localhost:8086/?to={},{}'.format(
'2' * 11, '3' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagle://token@localhost:8087/?to={},{},{}'.format(
'2' * 11, '3' * 11, '5' * 3), {
# 2 good targets and one invalid one
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagle://token@localhost:8088/{}/{}/'.format(
'2' * 11, '3' * 11), {
# If we have from= specified, then all elements take on the to= value
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagles://token@localhost/{}'.format('3' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagles://token@localhost/{}/{}?batch=True'.format(
'3' * 11, '4' * 11), {
# test batch mode
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagles://token@localhost/{}/?flash=yes'.format(
'3' * 11), {
# test flash mode
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagles://token@localhost/{}/?test=yes'.format(
'3' * 11), {
# test mode
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagles://token@localhost/{}/{}?status=True'.format(
'3' * 11, '4' * 11), {
# test status switch
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Our response expected server response
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagle://token@localhost/{}'.format('4' * 11), {
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
@ -250,7 +250,7 @@ apprise_url_tests = (
'requests_response_text': SMSEAGLE_GOOD_RESPONSE,
}),
('smseagle://token@localhost/{}'.format('4' * 11), {
'instance': plugins.NotifySMSEagle,
'instance': NotifySMSEagle,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -554,7 +554,7 @@ def test_notify_smseagle_plugin_result_list(mock_post, no_throttling):
mock_post.return_value = okay_response
obj = Apprise.instantiate('smseagle://token@127.0.0.1/12222222/')
assert isinstance(obj, plugins.NotifySMSEagle)
assert isinstance(obj, NotifySMSEagle)
# We should successfully handle the list
assert obj.notify("test") is True
@ -593,7 +593,7 @@ def test_notify_smseagle_plugin_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'smseagle://token@10.0.0.112:8080/+12512222222/+12513333333/'
'12514444444?batch=no')
assert isinstance(obj, plugins.NotifySMSEagle)
assert isinstance(obj, NotifySMSEagle)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -628,7 +628,7 @@ def test_notify_smseagle_plugin_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'smseagle://token@10.0.0.112:8080/+12512222222/+12513333333/'
'12514444444?batch=yes')
assert isinstance(obj, plugins.NotifySMSEagle)
assert isinstance(obj, NotifySMSEagle)
# Now send an attachment normally without issues
mock_post.reset_mock()
@ -677,7 +677,7 @@ def test_notify_smseagle_plugin_attachments(mock_post, no_throttling):
# test the handling of our batch modes
obj = Apprise.instantiate(
'smseagle://token@10.0.0.112:8080/513333333/')
assert isinstance(obj, plugins.NotifySMSEagle)
assert isinstance(obj, NotifySMSEagle)
# Unsupported (non image types are not sent)
attach = os.path.join(TEST_VAR_DIR, 'apprise-test.mp4')

View File

@ -27,10 +27,10 @@ import os
from unittest import mock
import requests
from apprise import plugins
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import NotifyType
from apprise.plugins.NotifySMTP2Go import NotifySMTP2Go
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -65,50 +65,50 @@ apprise_url_tests = (
# No To email address, but everything else is valid
('smtp2go://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
('smtp2go://user@localhost.localdomain/{}-{}-{}?format=markdown'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
('smtp2go://user@localhost.localdomain/{}-{}-{}?format=html'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
('smtp2go://user@localhost.localdomain/{}-{}-{}?format=text'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
# headers
('smtp2go://user@localhost.localdomain/{}-{}-{}'
'?+X-Customer-Campaign-ID=Apprise'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
# bcc and cc
('smtp2go://user@localhost.localdomain/{}-{}-{}'
'?bcc=user@example.com&cc=user2@example.com'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
# One To Email address
('smtp2go://user@localhost.localdomain/{}-{}-{}/test@example.com'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
('smtp2go://user@localhost.localdomain/'
'{}-{}-{}?to=test@example.com'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go}),
'instance': NotifySMTP2Go}),
# One To Email address, a from name specified too
('smtp2go://user@localhost.localdomain/{}-{}-{}/'
'test@example.com?name="Frodo"'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go}),
'instance': NotifySMTP2Go}),
# Invalid 'To' Email address
('smtp2go://user@localhost.localdomain/{}-{}-{}/invalid'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
# Expected notify() response
'notify_response': False,
}),
@ -118,25 +118,25 @@ apprise_url_tests = (
'/'.join(('user1@example.com', 'invalid', 'User2:user2@example.com')),
','.join(('user3@example.com', 'i@v', 'User1:user1@example.com')),
','.join(('user4@example.com', 'g@r@b', 'Da:user5@example.com'))), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
}),
('smtp2go://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('smtp2go://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('smtp2go://user@localhost.localdomain/{}-{}-{}'.format(
'a' * 32, 'b' * 8, 'c' * 8), {
'instance': plugins.NotifySMTP2Go,
'instance': NotifySMTP2Go,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -173,7 +173,7 @@ def test_plugin_smtp2go_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'smtp2go://user@localhost.localdomain/{}'.format(apikey))
assert isinstance(obj, plugins.NotifySMTP2Go)
assert isinstance(obj, NotifySMTP2Go)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -216,7 +216,7 @@ def test_plugin_smtp2go_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'smtp2go://no-reply@example.com/{}/'
'user1@example.com/user2@example.com?batch=yes'.format(apikey))
assert isinstance(obj, plugins.NotifySMTP2Go)
assert isinstance(obj, NotifySMTP2Go)
# Force our batch to break into separate messages
obj.default_batch_size = 1

View File

@ -27,8 +27,8 @@ from unittest import mock
import pytest
import requests
from apprise import plugins
from apprise import Apprise
from apprise.plugins.NotifySNS import NotifySNS
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -58,16 +58,16 @@ apprise_url_tests = (
}),
('sns://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcevi7FQ/us-west-2/12223334444', {
# we have a valid URL and one number to text
'instance': plugins.NotifySNS,
'instance': NotifySNS,
}),
('sns://?access=T1JJ3T3L2&secret=A1BRTD4JD/TIiajkdnlazkcevi7FQ'
'&region=us-west-2&to=12223334444', {
# Initialize using get parameters instead
'instance': plugins.NotifySNS,
'instance': NotifySNS,
}),
('sns://T1JJ3TD4JD/TIiajkdnlazk7FQ/us-west-2/12223334444/12223334445', {
# Multi SNS Suppport
'instance': plugins.NotifySNS,
'instance': NotifySNS,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'sns://T...D/****/us-west-2',
@ -75,16 +75,16 @@ apprise_url_tests = (
('sns://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/us-east-1'
'?to=12223334444', {
# Missing a topic and/or phone No
'instance': plugins.NotifySNS,
'instance': NotifySNS,
}),
('sns://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcevi7FQ/us-west-2/12223334444', {
'instance': plugins.NotifySNS,
'instance': NotifySNS,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('sns://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcevi7FQ/us-west-2/15556667777', {
'instance': plugins.NotifySNS,
'instance': NotifySNS,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -114,7 +114,7 @@ def test_plugin_sns_edge_cases(mock_post):
# Initializes the plugin with a valid access, but invalid access key
with pytest.raises(TypeError):
# No access_key_id specified
plugins.NotifySNS(
NotifySNS(
access_key_id=None,
secret_access_key=TEST_ACCESS_KEY_SECRET,
region_name=TEST_REGION,
@ -123,7 +123,7 @@ def test_plugin_sns_edge_cases(mock_post):
with pytest.raises(TypeError):
# No secret_access_key specified
plugins.NotifySNS(
NotifySNS(
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=None,
region_name=TEST_REGION,
@ -132,7 +132,7 @@ def test_plugin_sns_edge_cases(mock_post):
with pytest.raises(TypeError):
# No region_name specified
plugins.NotifySNS(
NotifySNS(
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
region_name=None,
@ -140,7 +140,7 @@ def test_plugin_sns_edge_cases(mock_post):
)
# No recipients
obj = plugins.NotifySNS(
obj = NotifySNS(
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
region_name=TEST_REGION,
@ -152,7 +152,7 @@ def test_plugin_sns_edge_cases(mock_post):
# The phone number is invalid, and without it, there is nothing
# to notify
obj = plugins.NotifySNS(
obj = NotifySNS(
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
region_name=TEST_REGION,
@ -164,7 +164,7 @@ def test_plugin_sns_edge_cases(mock_post):
# The phone number is invalid, and without it, there is nothing
# to notify; we
obj = plugins.NotifySNS(
obj = NotifySNS(
access_key_id=TEST_ACCESS_KEY_ID,
secret_access_key=TEST_ACCESS_KEY_SECRET,
region_name=TEST_REGION,
@ -182,7 +182,7 @@ def test_plugin_sns_url_parsing():
"""
# No recipients
results = plugins.NotifySNS.parse_url('sns://%s/%s/%s/' % (
results = NotifySNS.parse_url('sns://%s/%s/%s/' % (
TEST_ACCESS_KEY_ID,
TEST_ACCESS_KEY_SECRET,
TEST_REGION)
@ -198,7 +198,7 @@ def test_plugin_sns_url_parsing():
assert TEST_ACCESS_KEY_SECRET == results['secret_access_key']
# Detect recipients
results = plugins.NotifySNS.parse_url('sns://%s/%s/%s/%s/%s/' % (
results = NotifySNS.parse_url('sns://%s/%s/%s/%s/%s/' % (
TEST_ACCESS_KEY_ID,
TEST_ACCESS_KEY_SECRET,
# Uppercase Region won't break anything
@ -252,28 +252,28 @@ def test_plugin_sns_aws_response_handling():
"""
# Not a string
response = plugins.NotifySNS.aws_response_to_dict(None)
response = NotifySNS.aws_response_to_dict(None)
assert response['type'] is None
assert response['request_id'] is None
# Invalid XML
response = plugins.NotifySNS.aws_response_to_dict(
response = NotifySNS.aws_response_to_dict(
'<Bad Response xmlns="http://sns.amazonaws.com/doc/2010-03-31/">')
assert response['type'] is None
assert response['request_id'] is None
# Single Element in XML
response = plugins.NotifySNS.aws_response_to_dict(
response = NotifySNS.aws_response_to_dict(
'<SingleElement></SingleElement>')
assert response['type'] == 'SingleElement'
assert response['request_id'] is None
# Empty String
response = plugins.NotifySNS.aws_response_to_dict('')
response = NotifySNS.aws_response_to_dict('')
assert response['type'] is None
assert response['request_id'] is None
response = plugins.NotifySNS.aws_response_to_dict(
response = NotifySNS.aws_response_to_dict(
"""
<PublishResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<PublishResult>
@ -288,7 +288,7 @@ def test_plugin_sns_aws_response_handling():
assert response['request_id'] == 'dc258024-d0e6-56bb-af1b-d4fe5f4181a4'
assert response['message_id'] == '5e16935a-d1fb-5a31-a716-c7805e5c1d2e'
response = plugins.NotifySNS.aws_response_to_dict(
response = NotifySNS.aws_response_to_dict(
"""
<CreateTopicResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<CreateTopicResult>
@ -303,7 +303,7 @@ def test_plugin_sns_aws_response_handling():
assert response['request_id'] == '604bef0f-369c-50c5-a7a4-bbd474c83d6a'
assert response['topic_arn'] == 'arn:aws:sns:us-east-1:000000000000:abcd'
response = plugins.NotifySNS.aws_response_to_dict(
response = NotifySNS.aws_response_to_dict(
"""
<ErrorResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<Error>
@ -330,7 +330,7 @@ def test_plugin_sns_aws_topic_handling(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifySNS.request_rate_per_sec = 0
NotifySNS.request_rate_per_sec = 0
arn_response = \
"""

View File

@ -29,10 +29,10 @@ from unittest import mock
import requests
from json import dumps
from apprise import plugins
from apprise import Apprise
from apprise import AppriseAttachment
from apprise import NotifyType
from apprise.plugins.NotifySparkPost import NotifySparkPost
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -64,7 +64,7 @@ apprise_url_tests = (
}),
# No To email address, but everything else is valid
('sparkpost://user@localhost.localdomain/{}'.format('c' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -75,7 +75,7 @@ apprise_url_tests = (
}),
('sparkpost://user@localhost.localdomain/{}?format=markdown'
.format('d' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -86,7 +86,7 @@ apprise_url_tests = (
}),
('sparkpost://user@localhost.localdomain/{}?format=html'
.format('d' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -97,7 +97,7 @@ apprise_url_tests = (
}),
('sparkpost://user@localhost.localdomain/{}?format=text'
.format('d' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -108,7 +108,7 @@ apprise_url_tests = (
}),
# valid url with region specified (case insensitve)
('sparkpost://user@localhost.localdomain/{}?region=uS'.format('d' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -119,7 +119,7 @@ apprise_url_tests = (
}),
# valid url with region specified (case insensitve)
('sparkpost://user@localhost.localdomain/{}?region=EU'.format('e' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -131,7 +131,7 @@ apprise_url_tests = (
# headers
('sparkpost://user@localhost.localdomain/{}'
'?+X-Customer-Campaign-ID=Apprise'.format('f' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -143,7 +143,7 @@ apprise_url_tests = (
# template tokens
('sparkpost://user@localhost.localdomain/{}'
'?:name=Chris&:status=admin'.format('g' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -155,7 +155,7 @@ apprise_url_tests = (
# bcc and cc
('sparkpost://user@localhost.localdomain/{}'
'?bcc=user@example.com&cc=user2@example.com'.format('h' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -172,7 +172,7 @@ apprise_url_tests = (
# One 'To' Email address
('sparkpost://user@localhost.localdomain/{}/test@example.com'.format(
'a' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -184,7 +184,7 @@ apprise_url_tests = (
# Invalid 'To' Email address
('sparkpost://user@localhost.localdomain/{}/invalid'.format(
'i' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
# Expected notify() response
'notify_response': False,
}),
@ -194,7 +194,7 @@ apprise_url_tests = (
'/'.join(('user1@example.com', 'invalid', 'User2:user2@example.com')),
','.join(('user3@example.com', 'i@v', 'User1:user1@example.com')),
','.join(('user4@example.com', 'g@r@b', 'Da:user5@example.com'))), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -205,7 +205,7 @@ apprise_url_tests = (
}),
('sparkpost://user@localhost.localdomain/'
'{}?to=test@example.com'.format('k' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -217,7 +217,7 @@ apprise_url_tests = (
# One To Email address, a from name specified too
('sparkpost://user@localhost.localdomain/{}/'
'test@example.com?name="Frodo"'.format('l' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': {
"results": {
"total_rejected_recipients": 0,
@ -228,23 +228,23 @@ apprise_url_tests = (
}),
# Test invalid JSON response
('sparkpost://user@localhost.localdomain/{}'.format('m' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
'requests_response_text': "{",
}),
('sparkpost://user@localhost.localdomain/{}'.format('n' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('sparkpost://user@localhost.localdomain/{}'.format('o' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('sparkpost://user@localhost.localdomain/{}'.format('p' * 32), {
'instance': plugins.NotifySparkPost,
'instance': NotifySparkPost,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -269,8 +269,8 @@ def test_plugin_sparkpost_throttling(mock_post, no_throttling):
"""
plugins.NotifySparkPost.sparkpost_retry_wait_sec = 0.1
plugins.NotifySparkPost.sparkpost_retry_attempts = 3
NotifySparkPost.sparkpost_retry_wait_sec = 0.1
NotifySparkPost.sparkpost_retry_attempts = 3
# API Key
apikey = 'abc123'
@ -280,12 +280,12 @@ def test_plugin_sparkpost_throttling(mock_post, no_throttling):
# Exception should be thrown about the fact no user was specified
with pytest.raises(TypeError):
plugins.NotifySparkPost(
NotifySparkPost(
apikey=apikey, targets=targets, host=host)
# Exception should be thrown about the fact no private key was specified
with pytest.raises(TypeError):
plugins.NotifySparkPost(
NotifySparkPost(
apikey=None, targets=targets, user=user, host=host)
okay_response = requests.Request()
@ -317,7 +317,7 @@ def test_plugin_sparkpost_throttling(mock_post, no_throttling):
obj = Apprise.instantiate(
'sparkpost://user@localhost.localdomain/{}'.format(apikey))
assert isinstance(obj, plugins.NotifySparkPost)
assert isinstance(obj, NotifySparkPost)
# We'll successfully perform the notification as we're within
# our retry limit
@ -337,8 +337,8 @@ def test_plugin_sparkpost_attachments(mock_post, no_throttling):
NotifySparkPost() Attachments
"""
plugins.NotifySparkPost.sparkpost_retry_wait_sec = 0.1
plugins.NotifySparkPost.sparkpost_retry_attempts = 3
NotifySparkPost.sparkpost_retry_wait_sec = 0.1
NotifySparkPost.sparkpost_retry_attempts = 3
okay_response = requests.Request()
okay_response.status_code = requests.codes.ok
@ -358,7 +358,7 @@ def test_plugin_sparkpost_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'sparkpost://user@localhost.localdomain/{}'.format(apikey))
assert isinstance(obj, plugins.NotifySparkPost)
assert isinstance(obj, NotifySparkPost)
# Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
@ -382,7 +382,7 @@ def test_plugin_sparkpost_attachments(mock_post, no_throttling):
obj = Apprise.instantiate(
'sparkpost://no-reply@example.com/{}/'
'user1@example.com/user2@example.com?batch=yes'.format(apikey))
assert isinstance(obj, plugins.NotifySparkPost)
assert isinstance(obj, NotifySparkPost)
# Force our batch to break into separate messages
obj.default_batch_size = 1

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifySpontit import NotifySpontit
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -50,26 +51,26 @@ apprise_url_tests = (
}),
# Provide a valid user and API Key
('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'spontit://{}@b...b/'.format('u' * 11),
}),
# Provide a valid user and API Key, but provide an invalid channel
('spontit://%s@%s/#!!' % ('u' * 11, 'b' * 100), {
# An instance is still created, but the channel won't be notified
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
# Provide a valid user, API Key and a valid channel
('spontit://%s@%s/#abcd' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
# Provide a valid user, API Key, and a subtitle
('spontit://%s@%s/?subtitle=Test' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
# Provide a valid user, API Key, and a lengthy subtitle
('spontit://%s@%s/?subtitle=%s' % ('u' * 11, 'b' * 100, 'c' * 300), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
# Provide a valid user and API Key, but provide a valid channel (that is
# not ours).
@ -77,30 +78,30 @@ apprise_url_tests = (
# specifying channel entries. For Apprise we need to encode this
# so we convert the slash (/) into %2F
('spontit://{}@{}/#1245%2Fabcd'.format('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
# Provide multipe channels
('spontit://{}@{}/#1245%2Fabcd/defg'.format('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
# Provide multipe channels through the use of the to= variable
('spontit://{}@{}/?to=#1245/abcd'.format('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
}),
('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit,
'instance': NotifySpontit,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from apprise import plugins
from apprise.plugins.NotifyStreamlabs import NotifyStreamlabs
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -41,7 +41,7 @@ apprise_url_tests = (
}),
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso', {
# access token
'instance': plugins.NotifyStreamlabs,
'instance': NotifyStreamlabs,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'strmlabs://I...o',
@ -53,17 +53,17 @@ apprise_url_tests = (
# Test complete params - donations
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/'
'?name=tt&identifier=pyt&amount=20&currency=USD&call=donations',
{'instance': plugins.NotifyStreamlabs, }),
{'instance': NotifyStreamlabs, }),
# Test complete params - donations
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/'
'?image_href=https://example.org/rms.jpg'
'&sound_href=https://example.org/rms.mp3',
{'instance': plugins.NotifyStreamlabs, }),
{'instance': NotifyStreamlabs, }),
# Test complete params - alerts
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/'
'?duration=1000&image_href=&'
'sound_href=&alert_type=donation&special_text_color=crimson',
{'instance': plugins.NotifyStreamlabs, }),
{'instance': NotifyStreamlabs, }),
# Test incorrect call
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/'
'?name=tt&identifier=pyt&amount=20&currency=USD&call=rms',
@ -77,7 +77,7 @@ apprise_url_tests = (
'instance': TypeError,
}),
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/?call=donations', {
'instance': plugins.NotifyStreamlabs,
'instance': NotifyStreamlabs,
# A failure has status set to zero
# Test without an 'error' flag
'requests_response_text': {
@ -89,7 +89,7 @@ apprise_url_tests = (
'requests_response_code': 999,
}),
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/?call=alerts', {
'instance': plugins.NotifyStreamlabs,
'instance': NotifyStreamlabs,
# A failure has status set to zero
# Test without an 'error' flag
'requests_response_text': {
@ -101,13 +101,13 @@ apprise_url_tests = (
'requests_response_code': 999,
}),
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/?call=alerts', {
'instance': plugins.NotifyStreamlabs,
'instance': NotifyStreamlabs,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
('strmlabs://IcIcArukDQtuC1is1X1UdKZjTg118Lag2vScOmso/?call=donations', {
'instance': plugins.NotifyStreamlabs,
'instance': NotifyStreamlabs,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -32,6 +32,9 @@ import socket
# Disable logging for a cleaner testing output
import logging
from apprise.plugins.NotifySyslog import NotifySyslog
logging.disable(logging.CRITICAL)
@ -43,9 +46,9 @@ def test_plugin_syslog_by_url(openlog, syslog):
"""
# an invalid URL
assert apprise.plugins.NotifySyslog.parse_url(object) is None
assert apprise.plugins.NotifySyslog.parse_url(42) is None
assert apprise.plugins.NotifySyslog.parse_url(None) is None
assert NotifySyslog.parse_url(object) is None
assert NotifySyslog.parse_url(42) is None
assert NotifySyslog.parse_url(None) is None
obj = apprise.Apprise.instantiate('syslog://')
assert obj.url().startswith('syslog://user') is True
@ -55,10 +58,10 @@ def test_plugin_syslog_by_url(openlog, syslog):
assert isinstance(
apprise.Apprise.instantiate(
'syslog://:@/'), apprise.plugins.NotifySyslog)
'syslog://:@/'), NotifySyslog)
obj = apprise.Apprise.instantiate('syslog://?logpid=no&logperror=yes')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://user') is True
assert re.search(r'logpid=no', obj.url()) is not None
assert re.search(r'logperror=yes', obj.url()) is not None
@ -72,7 +75,7 @@ def test_plugin_syslog_by_url(openlog, syslog):
assert obj.notify("body", notify_type='invalid') is False
obj = apprise.Apprise.instantiate('syslog://_/?facility=local5')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://local5') is True
assert re.search(r'logpid=yes', obj.url()) is not None
assert re.search(r'logperror=no', obj.url()) is not None
@ -83,7 +86,7 @@ def test_plugin_syslog_by_url(openlog, syslog):
# j will cause a search to take place and match to daemon
obj = apprise.Apprise.instantiate('syslog://_/?facility=d')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://daemon') is True
assert re.search(r'logpid=yes', obj.url()) is not None
assert re.search(r'logperror=no', obj.url()) is not None
@ -91,7 +94,7 @@ def test_plugin_syslog_by_url(openlog, syslog):
# Facility can also be specified on the url as a hostname
obj = apprise.Apprise.instantiate('syslog://kern?logpid=no&logperror=y')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://kern') is True
assert re.search(r'logpid=no', obj.url()) is not None
assert re.search(r'logperror=yes', obj.url()) is not None
@ -99,7 +102,7 @@ def test_plugin_syslog_by_url(openlog, syslog):
# Facilities specified as an argument always over-ride host
obj = apprise.Apprise.instantiate('syslog://kern?facility=d')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://daemon') is True
assert re.search(r'syslog://.*mode=local', obj.url())
@ -113,8 +116,8 @@ def test_plugin_syslog_edge_cases(openlog, syslog):
"""
# Default
obj = apprise.plugins.NotifySyslog(facility=None)
assert isinstance(obj, apprise.plugins.NotifySyslog)
obj = NotifySyslog(facility=None)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://user') is True
assert re.search(r'logpid=yes', obj.url()) is not None
assert re.search(r'logperror=no', obj.url()) is not None
@ -122,10 +125,10 @@ def test_plugin_syslog_edge_cases(openlog, syslog):
# Exception should be thrown about the fact no bot token was specified
with pytest.raises(TypeError):
apprise.plugins.NotifySyslog(facility='invalid')
NotifySyslog(facility='invalid')
with pytest.raises(TypeError):
apprise.plugins.NotifySyslog(facility=object)
NotifySyslog(facility=object)
@mock.patch('syslog.syslog')
@ -152,7 +155,7 @@ def test_plugin_syslog_remote(
# localhost does not lookup to any of the facility codes so this
# gets interpreted as a host
obj = apprise.Apprise.instantiate('syslog://localhost')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://localhost') is True
assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None
@ -160,7 +163,7 @@ def test_plugin_syslog_remote(
# Test with port
obj = apprise.Apprise.instantiate('syslog://localhost:518')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://localhost:518') is True
assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None
@ -168,7 +171,7 @@ def test_plugin_syslog_remote(
# Test with default port
obj = apprise.Apprise.instantiate('syslog://localhost:514')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://localhost') is True
assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None
@ -176,7 +179,7 @@ def test_plugin_syslog_remote(
# Specify a facility
obj = apprise.Apprise.instantiate('syslog://localhost/kern')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://localhost/kern') is True
assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None
@ -185,7 +188,7 @@ def test_plugin_syslog_remote(
# Specify a facility requiring a lookup and having the port identified
# resolves any ambiguity
obj = apprise.Apprise.instantiate('syslog://kern:514/d')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://kern/daemon') is True
assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None
@ -195,7 +198,7 @@ def test_plugin_syslog_remote(
# We can attempt to exclusively set the mode as well without a port
# to also remove ambiguity; this falls back to sending as the 'user'
obj = apprise.Apprise.instantiate('syslog://kern/d?mode=remote&logpid=no')
assert isinstance(obj, apprise.plugins.NotifySyslog)
assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://kern/daemon') is True
assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=no', obj.url()) is not None

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyTechulusPush import NotifyTechulusPush
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -45,7 +46,7 @@ apprise_url_tests = (
}),
# APIkey
('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush,
'instance': NotifyTechulusPush,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'push://8...2/',
@ -55,19 +56,19 @@ apprise_url_tests = (
'instance': TypeError,
}),
('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush,
'instance': NotifyTechulusPush,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush,
'instance': NotifyTechulusPush,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush,
'instance': NotifyTechulusPush,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -35,7 +35,7 @@ from apprise import AppriseAttachment
from apprise import AppriseAsset
from apprise import NotifyType
from apprise import NotifyFormat
from apprise import plugins
from apprise.plugins.NotifyTelegram import NotifyTelegram
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -55,81 +55,81 @@ apprise_url_tests = (
}),
# Simple Message
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Simple Message (no images)
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# don't include an image by default
'include_image': False,
}),
# Simple Message with multiple chat names
('tgram://123456789:abcdefg_hijklmnop/id1/id2/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Simple Message with multiple chat names
('tgram://123456789:abcdefg_hijklmnop/?to=id1,id2', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Simple Message with an invalid chat ID
('tgram://123456789:abcdefg_hijklmnop/%$/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# Notify will fail
'response': False,
}),
# Simple Message with multiple chat ids
('tgram://123456789:abcdefg_hijklmnop/id1/id2/23423/-30/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Simple Message with multiple chat ids (no images)
('tgram://123456789:abcdefg_hijklmnop/id1/id2/23423/-30/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# don't include an image by default
'include_image': False,
}),
# Support bot keyword prefix
('tgram://bottest@123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Testing image
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Testing invalid format (fall's back to html)
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=invalid', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Testing empty format (falls back to html)
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Testing valid formats
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=markdown', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=html', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=text', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Test Silent Settings
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?silent=yes', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?silent=no', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Test Web Page Preview Settings
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?preview=yes', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?preview=no', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
}),
# Simple Message without image
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# don't include an image by default
'include_image': False,
}),
@ -142,39 +142,39 @@ apprise_url_tests = (
'instance': None,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# force a failure without an image specified
'include_image': False,
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('tgram://123456789:abcdefg_hijklmnop/id1/id2/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# force a failure with multiple chat_ids
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('tgram://123456789:abcdefg_hijklmnop/id1/id2/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# force a failure without an image specified
'include_image': False,
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# throw a bizzare code forcing us to fail to look it up without
# having an image included
'include_image': False,
@ -183,7 +183,7 @@ apprise_url_tests = (
}),
# Test with image set
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# throw a bizzare code forcing us to fail to look it up without
# having an image included
'include_image': True,
@ -191,13 +191,13 @@ apprise_url_tests = (
'requests_response_code': 999,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
'instance': plugins.NotifyTelegram,
'instance': NotifyTelegram,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them without images set
'include_image': True,
@ -213,7 +213,7 @@ def test_plugin_telegram_urls():
"""
# Disable Throttling to speed testing
plugins.NotifyTelegram.request_rate_per_sec = 0
NotifyTelegram.request_rate_per_sec = 0
# Run our general tests
AppriseURLTester(tests=apprise_url_tests).run_all()
@ -227,7 +227,7 @@ def test_plugin_telegram_general(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifyTelegram.request_rate_per_sec = 0
NotifyTelegram.request_rate_per_sec = 0
# Bot Token
bot_token = '123456789:abcdefg_hijklmnop'
@ -243,16 +243,16 @@ def test_plugin_telegram_general(mock_post):
# Exception should be thrown about the fact no bot token was specified
with pytest.raises(TypeError):
plugins.NotifyTelegram(bot_token=None, targets=chat_ids)
NotifyTelegram(bot_token=None, targets=chat_ids)
# Invalid JSON while trying to detect bot owner
mock_post.return_value.content = '}'
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
obj.notify(title='hello', body='world')
# Invalid JSON while trying to detect bot owner + 400 error
mock_post.return_value.status_code = requests.codes.internal_server_error
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
obj.notify(title='hello', body='world')
# Return status back to how they were
@ -261,11 +261,11 @@ def test_plugin_telegram_general(mock_post):
# Exception should be thrown about the fact an invalid bot token was
# specifed
with pytest.raises(TypeError):
plugins.NotifyTelegram(bot_token=invalid_bot_token, targets=chat_ids)
NotifyTelegram(bot_token=invalid_bot_token, targets=chat_ids)
obj = plugins.NotifyTelegram(
obj = NotifyTelegram(
bot_token=bot_token, targets=chat_ids, include_image=True)
assert isinstance(obj, plugins.NotifyTelegram) is True
assert isinstance(obj, NotifyTelegram) is True
assert len(obj.targets) == 2
# Test Image Sending Exceptions
@ -288,8 +288,8 @@ def test_plugin_telegram_general(mock_post):
assert obj.url(privacy=True).startswith('tgram://1...p/') is True
# Test that we can load the string we generate back:
obj = plugins.NotifyTelegram(**plugins.NotifyTelegram.parse_url(obj.url()))
assert isinstance(obj, plugins.NotifyTelegram) is True
obj = NotifyTelegram(**NotifyTelegram.parse_url(obj.url()))
assert isinstance(obj, NotifyTelegram) is True
# Prepare Mock to fail
response = mock.Mock()
@ -302,13 +302,13 @@ def test_plugin_telegram_general(mock_post):
mock_post.return_value = response
# No image asset
nimg_obj = plugins.NotifyTelegram(bot_token=bot_token, targets=chat_ids)
nimg_obj = NotifyTelegram(bot_token=bot_token, targets=chat_ids)
nimg_obj.asset = AppriseAsset(image_path_mask=False, image_url_mask=False)
# Test that our default settings over-ride base settings since they are
# not the same as the one specified in the base; this check merely
# ensures our plugin inheritance is working properly
assert obj.body_maxlen == plugins.NotifyTelegram.body_maxlen
assert obj.body_maxlen == NotifyTelegram.body_maxlen
# This tests erroneous messages involving multiple chat ids
assert obj.notify(
@ -319,8 +319,8 @@ def test_plugin_telegram_general(mock_post):
body='body', title='title', notify_type=NotifyType.INFO) is False
# This tests erroneous messages involving a single chat id
obj = plugins.NotifyTelegram(bot_token=bot_token, targets='l2g')
nimg_obj = plugins.NotifyTelegram(bot_token=bot_token, targets='l2g')
obj = NotifyTelegram(bot_token=bot_token, targets='l2g')
nimg_obj = NotifyTelegram(bot_token=bot_token, targets='l2g')
nimg_obj.asset = AppriseAsset(image_path_mask=False, image_url_mask=False)
assert obj.notify(
@ -386,7 +386,7 @@ def test_plugin_telegram_general(mock_post):
})
mock_post.return_value.status_code = requests.codes.ok
obj = plugins.NotifyTelegram(bot_token=bot_token, targets='12345')
obj = NotifyTelegram(bot_token=bot_token, targets='12345')
assert len(obj.targets) == 1
assert obj.targets[0] == '12345'
@ -417,7 +417,7 @@ def test_plugin_telegram_general(mock_post):
body='body', title='title', notify_type=NotifyType.INFO,
attach=path) is False
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
# No user detected; this happens after our firsst notification
assert len(obj.targets) == 0
@ -432,7 +432,7 @@ def test_plugin_telegram_general(mock_post):
})
# No user will be detected now
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
# No user detected; this happens after our firsst notification
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
@ -468,7 +468,7 @@ def test_plugin_telegram_general(mock_post):
})
# No user will be detected now
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
# No user detected; this happens after our firsst notification
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
@ -481,7 +481,7 @@ def test_plugin_telegram_general(mock_post):
})
# No user will be detected now
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
# No user detected; this happens after our firsst notification
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
@ -494,28 +494,28 @@ def test_plugin_telegram_general(mock_post):
mock_post.return_value.status_code = requests.codes.internal_server_error
# internal server error prevents notification from being sent
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
assert len(obj.targets) == 0
# Test our bot detection with an unmappable html error
mock_post.return_value.status_code = 999
plugins.NotifyTelegram(bot_token=bot_token, targets=None)
NotifyTelegram(bot_token=bot_token, targets=None)
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
assert len(obj.targets) == 0
# Do it again but this time provide a failure message
mock_post.return_value.content = dumps({'description': 'Failure Message'})
plugins.NotifyTelegram(bot_token=bot_token, targets=None)
NotifyTelegram(bot_token=bot_token, targets=None)
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
assert len(obj.targets) == 0
# Do it again but this time provide a failure message and perform a
# notification without a bot detection by providing at least 1 chat id
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=['@abcd'])
obj = NotifyTelegram(bot_token=bot_token, targets=['@abcd'])
assert nimg_obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is False
@ -523,7 +523,7 @@ def test_plugin_telegram_general(mock_post):
mock_post.side_effect = requests.HTTPError
# No chat_ids specified
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
obj = NotifyTelegram(bot_token=bot_token, targets=None)
assert len(obj.targets) == 0
assert obj.notify(title='hello', body='world') is False
assert len(obj.targets) == 0
@ -531,7 +531,7 @@ def test_plugin_telegram_general(mock_post):
# Test Telegram Group
obj = Apprise.instantiate(
'tgram://123456789:ABCdefghijkl123456789opqyz/-123456789525')
assert isinstance(obj, plugins.NotifyTelegram)
assert isinstance(obj, NotifyTelegram)
assert len(obj.targets) == 1
assert '-123456789525' in obj.targets
@ -543,7 +543,7 @@ def test_plugin_telegram_formatting(mock_post):
"""
# Disable Throttling to speed testing
plugins.NotifyTelegram.request_rate_per_sec = 0
NotifyTelegram.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()
@ -580,11 +580,11 @@ def test_plugin_telegram_formatting(mock_post):
})
mock_post.return_value.status_code = requests.codes.ok
results = plugins.NotifyTelegram.parse_url(
results = NotifyTelegram.parse_url(
'tgram://123456789:abcdefg_hijklmnop/')
instance = plugins.NotifyTelegram(**results)
assert isinstance(instance, plugins.NotifyTelegram)
instance = NotifyTelegram(**results)
assert isinstance(instance, NotifyTelegram)
response = instance.send(title='title', body='body')
assert response is True
@ -886,7 +886,7 @@ def test_plugin_telegram_html_formatting(mock_post):
# on't send anything other than <b>, <i>, <a>,<code> and <pre>
# Disable Throttling to speed testing
plugins.NotifyTelegram.request_rate_per_sec = 0
NotifyTelegram.request_rate_per_sec = 0
# Prepare Mock
mock_post.return_value = requests.Request()
@ -928,7 +928,7 @@ def test_plugin_telegram_html_formatting(mock_post):
assert len(aobj) == 1
assert isinstance(aobj[0], plugins.NotifyTelegram)
assert isinstance(aobj[0], NotifyTelegram)
# Test our HTML Conversion
title = '<title>&apos;information&apos</title>'

View File

@ -28,8 +28,8 @@ from unittest import mock
import requests
import pytest
from json import dumps
from apprise import plugins
from apprise import Apprise
from apprise.plugins.NotifyTwilio import NotifyTwilio
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -57,7 +57,7 @@ apprise_url_tests = (
('twilio://AC{}:{}@{}'.format('a' * 32, 'b' * 32, '3' * 5), {
# using short-code (5 characters) without a target
# We can still instantiate ourselves with a valid short code
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
# Since there are no targets specified we expect a False return on
# send()
'notify_response': False,
@ -69,47 +69,47 @@ apprise_url_tests = (
('twilio://AC{}:{}@{}/123/{}/abcd/'.format(
'a' * 32, 'b' * 32, '3' * 11, '9' * 15), {
# valid everything but target numbers
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
}),
('twilio://AC{}:{}@12345/{}'.format('a' * 32, 'b' * 32, '4' * 11), {
# using short-code (5 characters)
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'twilio://...aaaa:b...b@12345',
}),
('twilio://AC{}:{}@123456/{}'.format('a' * 32, 'b' * 32, '4' * 11), {
# using short-code (6 characters)
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
}),
('twilio://AC{}:{}@{}'.format('a' * 32, 'b' * 32, '5' * 11), {
# using phone no with no target - we text ourselves in
# this case
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
}),
('twilio://_?sid=AC{}&token={}&from={}'.format(
'a' * 32, 'b' * 32, '5' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
}),
('twilio://_?sid=AC{}&token={}&source={}'.format(
'a' * 32, 'b' * 32, '5' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
}),
('twilio://_?sid=AC{}&token={}&from={}&to={}'.format(
'a' * 32, 'b' * 32, '5' * 11, '7' * 13), {
# use to=
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
}),
('twilio://AC{}:{}@{}'.format('a' * 32, 'b' * 32, '6' * 11), {
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('twilio://AC{}:{}@{}'.format('a' * 32, 'b' * 32, '6' * 11), {
'instance': plugins.NotifyTwilio,
'instance': NotifyTwilio,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -155,7 +155,7 @@ def test_plugin_twilio_auth(mock_post, no_throttling):
obj = Apprise.instantiate(
'twilio://{}:{}@{}/{}'
.format(account_sid, auth_token, source, dest))
assert isinstance(obj, plugins.NotifyTwilio) is True
assert isinstance(obj, NotifyTwilio) is True
assert isinstance(obj.url(), str) is True
# Send Notification
@ -165,7 +165,7 @@ def test_plugin_twilio_auth(mock_post, no_throttling):
obj = Apprise.instantiate(
'twilio://{}:{}@{}/{}?apikey={}'
.format(account_sid, auth_token, source, dest, apikey))
assert isinstance(obj, plugins.NotifyTwilio) is True
assert isinstance(obj, NotifyTwilio) is True
assert isinstance(obj.url(), str) is True
# Send Notification
@ -217,12 +217,12 @@ def test_plugin_twilio_edge_cases(mock_post, no_throttling):
# No account_sid specified
with pytest.raises(TypeError):
plugins.NotifyTwilio(
NotifyTwilio(
account_sid=None, auth_token=auth_token, source=source)
# No auth_token specified
with pytest.raises(TypeError):
plugins.NotifyTwilio(
NotifyTwilio(
account_sid=account_sid, auth_token=None, source=source)
# a error response
@ -234,7 +234,7 @@ def test_plugin_twilio_edge_cases(mock_post, no_throttling):
mock_post.return_value = response
# Initialize our object
obj = plugins.NotifyTwilio(
obj = NotifyTwilio(
account_sid=account_sid, auth_token=auth_token, source=source)
# We will fail with the above error code

View File

@ -27,8 +27,8 @@ from unittest import mock
import requests
from json import dumps
from apprise import plugins
from apprise import Apprise
from apprise.plugins.NotifyTwist import NotifyTwist
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -50,14 +50,14 @@ apprise_url_tests = (
}),
('twist://user@example.com/password', {
# Password acceptable as first entry in path
'instance': plugins.NotifyTwist,
'instance': NotifyTwist,
# Expected notify() response is False because internally we would
# have failed to login
'notify_response': False,
}),
('twist://password:user1@example.com', {
# password:login acceptable
'instance': plugins.NotifyTwist,
'instance': NotifyTwist,
# Expected notify() response is False because internally we would
# have failed to login
'notify_response': False,
@ -67,7 +67,7 @@ apprise_url_tests = (
}),
('twist://password:user2@example.com', {
# password:login acceptable
'instance': plugins.NotifyTwist,
'instance': NotifyTwist,
# Expected notify() response is False because internally we would
# have logged in, but we would have failed to look up the #General
# channel and workspace.
@ -79,13 +79,13 @@ apprise_url_tests = (
'notify_response': False,
}),
('twist://password:user2@example.com', {
'instance': plugins.NotifyTwist,
'instance': NotifyTwist,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('twist://password:user2@example.com', {
'instance': plugins.NotifyTwist,
'instance': NotifyTwist,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -109,21 +109,21 @@ def test_plugin_twist_init():
"""
try:
plugins.NotifyTwist(email='invalid', targets=None)
NotifyTwist(email='invalid', targets=None)
assert False
except TypeError:
# Invalid email address
assert True
try:
plugins.NotifyTwist(email='user@domain', targets=None)
NotifyTwist(email='user@domain', targets=None)
assert False
except TypeError:
# No password was specified
assert True
# Simple object initialization
result = plugins.NotifyTwist(
result = NotifyTwist(
password='abc123', email='user@domain.com', targets=None)
assert result.user == 'user'
assert result.host == 'domain.com'
@ -131,23 +131,23 @@ def test_plugin_twist_init():
# Channel Instantiation by name
obj = Apprise.instantiate('twist://password:user@example.com/#Channel')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Channel Instantiation by id (faster if you know the translation)
obj = Apprise.instantiate('twist://password:user@example.com/12345')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Invalid Channel - (max characters is 64), the below drops it
obj = Apprise.instantiate(
'twist://password:user@example.com/{}'.format('a' * 65))
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# No User detect
result = plugins.NotifyTwist.parse_url('twist://example.com')
result = NotifyTwist.parse_url('twist://example.com')
assert result is None
# test usage of to=
result = plugins.NotifyTwist.parse_url(
result = NotifyTwist.parse_url(
'twist://password:user@example.com?to=#channel')
assert isinstance(result, dict)
assert 'user' in result
@ -183,7 +183,7 @@ def test_plugin_twist_auth(mock_post, mock_get, no_throttling):
# Instantiate an object
obj = Apprise.instantiate('twist://password:user@example.com/#Channel')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# not logged in yet
obj.logout()
assert obj.login() is True
@ -249,7 +249,7 @@ def test_plugin_twist_auth(mock_post, mock_get, no_throttling):
# Instantiate an object
obj = Apprise.instantiate('twist://password:user@example.com/#Channel')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Authentication failed
assert obj.get_workspaces() == dict()
@ -258,7 +258,7 @@ def test_plugin_twist_auth(mock_post, mock_get, no_throttling):
assert obj.send('body', 'title') is False
obj = Apprise.instantiate('twist://password:user@example.com/#Channel')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Calling logout on an object already logged out
obj.logout()
@ -317,7 +317,7 @@ def test_plugin_twist_cache(mock_post, mock_get, no_throttling):
obj = Apprise.instantiate(
'twist://password:user@example.com/'
'#ChanB/1:1/TeamA:ChanA/Ignore:Chan/3:1')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Will detect channels except Ignore:Chan
assert obj._channel_migration() is False
@ -403,7 +403,7 @@ def test_plugin_twist_fetch(mock_post, mock_get, no_throttling):
# Instantiate an object
obj = Apprise.instantiate('twist://password:user@example.com/#Channel/34')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Simulate a re-authentication
postokay, response = obj._fetch('threads/add')
@ -453,7 +453,7 @@ def test_plugin_twist_fetch(mock_post, mock_get, no_throttling):
# Instantiate an object
obj = Apprise.instantiate('twist://password:user@example.com/#Channel/34')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Simulate a re-authentication
postokay, response = obj._fetch('threads/add')
@ -503,7 +503,7 @@ def test_plugin_twist_fetch(mock_post, mock_get, no_throttling):
# Instantiate an object
obj = Apprise.instantiate('twist://password:user@example.com/#Channel/34')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Simulate a re-authentication
postokay, response = obj._fetch('threads/add')
@ -521,7 +521,7 @@ def test_plugin_twist_fetch(mock_post, mock_get, no_throttling):
# Instantiate our object
obj = Apprise.instantiate('twist://password:user@example.com/#Channel/34')
assert isinstance(obj, plugins.NotifyTwist)
assert isinstance(obj, NotifyTwist)
# Simulate a re-authentication
postokay, response = obj._fetch('threads/add')

View File

@ -31,9 +31,9 @@ import requests
from json import dumps
from datetime import datetime
from apprise import Apprise
from apprise import plugins
from apprise import NotifyType
from apprise import AppriseAttachment
from apprise.plugins.NotifyTwitter import NotifyTwitter
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -69,7 +69,7 @@ apprise_url_tests = (
}),
('twitter://consumer_key/consumer_secret/access_token/access_secret', {
# No user mean's we message ourselves
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# Expected notify() response False (because we won't be able
# to detect our user)
'notify_response': False,
@ -80,7 +80,7 @@ apprise_url_tests = (
('twitter://consumer_key/consumer_secret/access_token/access_secret'
'?cache=no', {
# No user mean's we message ourselves
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# However we'll be okay if we return a proper response
'requests_response_text': {
'id': 12345,
@ -91,7 +91,7 @@ apprise_url_tests = (
}),
('twitter://consumer_key/consumer_secret/access_token/access_secret', {
# No user mean's we message ourselves
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# However we'll be okay if we return a proper response
'requests_response_text': {
'id': 12345,
@ -103,7 +103,7 @@ apprise_url_tests = (
# A duplicate of the entry above, this will cause cache to be referenced
('twitter://consumer_key/consumer_secret/access_token/access_secret', {
# No user mean's we message ourselves
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# However we'll be okay if we return a proper response
'requests_response_text': {
'id': 12345,
@ -116,7 +116,7 @@ apprise_url_tests = (
# an exception during parsing
('twitter://consumer_key/consumer_secret2/access_token/access_secret', {
# No user mean's we message ourselves
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# However we'll be okay if we return a proper response
'requests_response_text': {
'id': 12345,
@ -128,7 +128,7 @@ apprise_url_tests = (
}),
('twitter://user@consumer_key/csecret2/access_token/access_secret/-/%/', {
# One Invalid User
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# Expected notify() response False (because we won't be able
# to detect our user)
'notify_response': False,
@ -136,7 +136,7 @@ apprise_url_tests = (
('twitter://user@consumer_key/csecret/access_token/access_secret'
'?cache=No&batch=No', {
# No Cache & No Batch
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
'requests_response_text': [{
'id': 12345,
'screen_name': 'user'
@ -144,7 +144,7 @@ apprise_url_tests = (
}),
('twitter://user@consumer_key/csecret/access_token/access_secret', {
# We're good!
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
'requests_response_text': [{
'id': 12345,
'screen_name': 'user'
@ -154,11 +154,11 @@ apprise_url_tests = (
# for this reason, we don't even need to return a valid response
('twitter://user@consumer_key/csecret/access_token/access_secret', {
# We're identifying the same user we already sent to
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
}),
('twitter://ckey/csecret/access_token/access_secret?mode=tweet', {
# A Public Tweet
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
}),
('twitter://user@ckey/csecret/access_token/access_secret?mode=invalid', {
# An invalid mode
@ -167,7 +167,7 @@ apprise_url_tests = (
('twitter://usera@consumer_key/consumer_secret/access_token/'
'access_secret/user/?to=userb', {
# We're good!
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
'requests_response_text': [{
'id': 12345,
'screen_name': 'usera'
@ -180,19 +180,19 @@ apprise_url_tests = (
}],
}),
('twitter://ckey/csecret/access_token/access_secret', {
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('twitter://ckey/csecret/access_token/access_secret', {
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
('twitter://ckey/csecret/access_token/access_secret?mode=tweet', {
'instance': plugins.NotifyTwitter,
'instance': NotifyTwitter,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -244,14 +244,14 @@ def test_plugin_twitter_general(mock_post, mock_get, no_throttling):
mock_post.return_value = request
# Variation Initializations
obj = plugins.NotifyTwitter(
obj = NotifyTwitter(
ckey=ckey,
csecret=csecret,
akey=akey,
asecret=asecret,
targets=screen_name)
assert isinstance(obj, plugins.NotifyTwitter) is True
assert isinstance(obj, NotifyTwitter) is True
assert isinstance(obj.url(), str) is True
# apprise room was found
@ -319,7 +319,7 @@ def test_plugin_twitter_general(mock_post, mock_get, no_throttling):
assert obj.send(body="test") is True
# Flush our cache forcing it's re-creating
del plugins.NotifyTwitter._user_cache
del NotifyTwitter._user_cache
assert obj.send(body="test") is True
# Cause content response to be None
@ -333,7 +333,7 @@ def test_plugin_twitter_general(mock_post, mock_get, no_throttling):
# Return it to a parseable string
request.content = '{}'
results = plugins.NotifyTwitter.parse_url(
results = NotifyTwitter.parse_url(
'twitter://{}/{}/{}/{}?to={}'.format(
ckey, csecret, akey, asecret, screen_name))
assert isinstance(results, dict) is True
@ -349,7 +349,7 @@ def test_plugin_twitter_general(mock_post, mock_get, no_throttling):
# Set ourselves up to handle whoami calls
# Flush out our cache
del plugins.NotifyTwitter._user_cache
del NotifyTwitter._user_cache
response_obj = {
'screen_name': screen_name,
@ -357,7 +357,7 @@ def test_plugin_twitter_general(mock_post, mock_get, no_throttling):
}
request.content = dumps(response_obj)
obj = plugins.NotifyTwitter(
obj = NotifyTwitter(
ckey=ckey,
csecret=csecret,
akey=akey,
@ -366,12 +366,12 @@ def test_plugin_twitter_general(mock_post, mock_get, no_throttling):
assert obj.send(body="test") is True
# Alter the key forcing us to look up a new value of ourselves again
del plugins.NotifyTwitter._user_cache
del plugins.NotifyTwitter._whoami_cache
del NotifyTwitter._user_cache
del NotifyTwitter._whoami_cache
obj.ckey = 'different.then.it.was'
assert obj.send(body="test") is True
del plugins.NotifyTwitter._whoami_cache
del NotifyTwitter._whoami_cache
obj.ckey = 'different.again'
assert obj.send(body="test") is True
@ -383,37 +383,37 @@ def test_plugin_twitter_edge_cases():
"""
with pytest.raises(TypeError):
plugins.NotifyTwitter(
NotifyTwitter(
ckey=None, csecret=None, akey=None, asecret=None)
with pytest.raises(TypeError):
plugins.NotifyTwitter(
NotifyTwitter(
ckey='value', csecret=None, akey=None, asecret=None)
with pytest.raises(TypeError):
plugins.NotifyTwitter(
NotifyTwitter(
ckey='value', csecret='value', akey=None, asecret=None)
with pytest.raises(TypeError):
plugins.NotifyTwitter(
NotifyTwitter(
ckey='value', csecret='value', akey='value', asecret=None)
assert isinstance(
plugins.NotifyTwitter(
NotifyTwitter(
ckey='value', csecret='value', akey='value', asecret='value'),
plugins.NotifyTwitter,
NotifyTwitter,
)
assert isinstance(
plugins.NotifyTwitter(
NotifyTwitter(
ckey='value', csecret='value', akey='value', asecret='value',
user='l2gnux'),
plugins.NotifyTwitter,
NotifyTwitter,
)
# Invalid Target User
with pytest.raises(TypeError):
plugins.NotifyTwitter(
NotifyTwitter(
ckey='value', csecret='value', akey='value', asecret='value',
targets='%G@rB@g3')

View File

@ -27,7 +27,8 @@ from unittest import mock
import pytest
import requests
from json import dumps
from apprise import plugins
from apprise.plugins.NotifyVonage import NotifyVonage
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -63,7 +64,7 @@ apprise_url_tests = (
('vonage://AC{}:{}@{}/123/{}/abcd/'.format(
'f' * 8, 'g' * 16, '3' * 11, '9' * 15), {
# valid everything but target numbers
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'vonage://A...f:****@',
@ -71,31 +72,31 @@ apprise_url_tests = (
('vonage://AC{}:{}@{}'.format('h' * 8, 'i' * 16, '5' * 11), {
# using phone no with no target - we text ourselves in
# this case
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('vonage://_?key=AC{}&secret={}&from={}'.format(
'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('vonage://_?key=AC{}&secret={}&source={}'.format(
'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('vonage://_?key=AC{}&secret={}&from={}&to={}'.format(
'a' * 8, 'b' * 16, '5' * 11, '7' * 13), {
# use to=
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('vonage://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), {
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('vonage://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), {
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -129,7 +130,7 @@ apprise_url_tests = (
('nexmo://AC{}:{}@{}/123/{}/abcd/'.format(
'f' * 8, 'g' * 16, '3' * 11, '9' * 15), {
# valid everything but target numbers
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'vonage://A...f:****@',
@ -137,31 +138,31 @@ apprise_url_tests = (
('nexmo://AC{}:{}@{}'.format('h' * 8, 'i' * 16, '5' * 11), {
# using phone no with no target - we text ourselves in
# this case
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('nexmo://_?key=AC{}&secret={}&from={}'.format(
'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('nexmo://_?key=AC{}&secret={}&source={}'.format(
'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing (use source instead of from)
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('nexmo://_?key=AC{}&secret={}&from={}&to={}'.format(
'a' * 8, 'b' * 16, '5' * 11, '7' * 13), {
# use to=
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
}),
('nexmo://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), {
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('nexmo://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), {
'instance': plugins.NotifyVonage,
'instance': NotifyVonage,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -200,17 +201,17 @@ def test_plugin_vonage_edge_cases(mock_post, no_throttling):
# No apikey specified
with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=None, secret=secret, source=source)
NotifyVonage(apikey=None, secret=secret, source=source)
with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=" ", secret=secret, source=source)
NotifyVonage(apikey=" ", secret=secret, source=source)
# No secret specified
with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=apikey, secret=None, source=source)
NotifyVonage(apikey=apikey, secret=None, source=source)
with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=apikey, secret=" ", source=source)
NotifyVonage(apikey=apikey, secret=" ", source=source)
# a error response
response.status_code = 400
@ -221,7 +222,7 @@ def test_plugin_vonage_edge_cases(mock_post, no_throttling):
mock_post.return_value = response
# Initialize our object
obj = plugins.NotifyVonage(
obj = NotifyVonage(
apikey=apikey, secret=secret, source=source)
# We will fail with the above error code

View File

@ -23,7 +23,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise.plugins.NotifyWebexTeams import NotifyWebexTeams
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -44,7 +44,7 @@ apprise_url_tests = (
}),
('wxteams://{}'.format('a' * 80), {
# token provided - we're good
'instance': plugins.NotifyWebexTeams,
'instance': NotifyWebexTeams,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'wxteams://a...a/',
@ -52,28 +52,28 @@ apprise_url_tests = (
# Support Native URLs
('https://api.ciscospark.com/v1/webhooks/incoming/{}'.format('a' * 80), {
# token provided - we're good
'instance': plugins.NotifyWebexTeams,
'instance': NotifyWebexTeams,
}),
# Support Native URLs with arguments
('https://api.ciscospark.com/v1/webhooks/incoming/{}?format=text'.format(
'a' * 80), {
# token provided - we're good
'instance': plugins.NotifyWebexTeams,
'instance': NotifyWebexTeams,
}),
('wxteams://{}'.format('a' * 80), {
'instance': plugins.NotifyWebexTeams,
'instance': NotifyWebexTeams,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('wxteams://{}'.format('a' * 80), {
'instance': plugins.NotifyWebexTeams,
'instance': NotifyWebexTeams,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('wxteams://{}'.format('a' * 80), {
'instance': plugins.NotifyWebexTeams,
'instance': NotifyWebexTeams,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -23,8 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import requests
from apprise import plugins
from apprise import NotifyType
from apprise.plugins.NotifyXBMC import NotifyXBMC
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -40,63 +40,63 @@ apprise_url_tests = (
'instance': None,
}),
('kodi://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodi://192.168.4.1', {
# Support IPv4 Addresses
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]', {
# Support IPv6 Addresses
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Privacy URL
'privacy_url': 'kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]',
}),
('kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]:8282', {
# Support IPv6 Addresses with port
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Privacy URL
'privacy_url': 'kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]:8282',
}),
('kodi://user:pass@localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kodi://user:****@localhost',
}),
('kodi://localhost:8080', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodi://user:pass@localhost:8080', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodis://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodis://user:pass@localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodis://localhost:8080/path/', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('kodis://user:password@localhost:8080', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'kodis://user:****@localhost:8080',
}),
('kodi://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Experement with different notification types
'notify_type': NotifyType.WARNING,
}),
('kodi://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Experement with different notification types
'notify_type': NotifyType.FAILURE,
}),
('kodis://localhost:443', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# don't include an image by default
'include_image': False,
}),
@ -104,19 +104,19 @@ apprise_url_tests = (
'instance': None,
}),
('kodi://user:pass@localhost:8081', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('kodi://user:pass@localhost:8082', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('kodi://user:pass@localhost:8083', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -130,38 +130,38 @@ apprise_url_tests = (
'instance': None,
}),
('xbmc://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://localhost?duration=14', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://localhost?duration=invalid', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://localhost?duration=-1', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://user:pass@localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://localhost:8080', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://user:pass@localhost:8080', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
}),
('xbmc://user@localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# don't include an image by default
'include_image': False,
}),
('xbmc://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Experement with different notification types
'notify_type': NotifyType.WARNING,
}),
('xbmc://localhost', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Experement with different notification types
'notify_type': NotifyType.FAILURE,
}),
@ -169,19 +169,19 @@ apprise_url_tests = (
'instance': None,
}),
('xbmc://user:pass@localhost:8081', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('xbmc://user:pass@localhost:8082', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('xbmc://user:pass@localhost:8083', {
'instance': plugins.NotifyXBMC,
'instance': NotifyXBMC,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,

View File

@ -23,8 +23,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import pytest
from apprise import plugins
import requests
from apprise.plugins.NotifyZulip import NotifyZulip
from helpers import AppriseURLTester
# Disable logging for a cleaner testing output
@ -57,52 +58,52 @@ apprise_url_tests = (
}),
# Valid everything - botname with a dash
('zulip://bot-name@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
'privacy_url': 'zulip://bot-name@apprise/a...a/',
}),
# Valid everything - no target so default is used
('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'zulip://botname@apprise/a...a/',
}),
# Valid everything - organization as hostname
('zulip://botname@apprise.zulipchat.com/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
}),
# Valid everything - 2 streams specified
('zulip://botname@apprise/{}/channel1/channel2'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
}),
# Valid everything - 2 streams specified (using to=)
('zulip://botname@apprise/{}/?to=channel1/channel2'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
}),
# Valid everything - 2 emails specified
('zulip://botname@apprise/{}/user@example.com/user2@example.com'.format(
'a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
}),
('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
# don't include an image by default
'include_image': False,
}),
('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip,
'instance': NotifyZulip,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
@ -131,5 +132,5 @@ def test_plugin_zulip_edge_cases(no_throttling):
# Invalid organization
with pytest.raises(TypeError):
plugins.NotifyZulip(
NotifyZulip(
botname='test', organization='#', token=token)