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__ # Add our module name to our __all__
__all__.append(plugin_name) __all__.append(plugin_name)
# Load our module into memory so it's accessible to all
globals()[plugin_name] = plugin
fn = getattr(plugin, 'schemas', None) fn = getattr(plugin, 'schemas', None)
schemas = set([]) if not callable(fn) else fn(plugin) 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 # Iterate over our module map so we can clear out our __all__ and globals
for plugin_name in common.NOTIFY_MODULE_MAP.keys(): for plugin_name in common.NOTIFY_MODULE_MAP.keys():
# Clear out globals
del globals()[plugin_name]
# Remove element from plugins # Remove element from plugins
__all__.remove(plugin_name) __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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
from .rest import AppriseURLTester from .rest import AppriseURLTester
from .module import module_reload from .module import reload_plugin
__all__ = [ __all__ = [
'AppriseURLTester', '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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import re
import os
import sys import sys
from importlib import reload 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) set filename to plugin to be reloaded (for example NotifyGnome.py)
The following libraries need to be reloaded to prevent The following libraries need to be reloaded to prevent
@ -44,13 +42,13 @@ def module_reload(filename):
""" """
module_name = 'apprise.plugins.{}'.format( module_name = f"apprise.plugins.{name}"
re.match(r'^(.+)(\.py)?$', os.path.basename(filename), re.I).group(1))
reload(sys.modules['apprise.common']) reload(sys.modules['apprise.common'])
reload(sys.modules['apprise.attachment']) reload(sys.modules['apprise.attachment'])
reload(sys.modules['apprise.config']) reload(sys.modules['apprise.config'])
reload(sys.modules[module_name]) if module_name in sys.modules:
reload(sys.modules[module_name])
reload(sys.modules['apprise.plugins']) reload(sys.modules['apprise.plugins'])
reload(sys.modules['apprise.Apprise']) reload(sys.modules['apprise.Apprise'])
reload(sys.modules['apprise.utils']) reload(sys.modules['apprise.utils'])

View File

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

View File

@ -27,11 +27,13 @@ import pytest
from apprise.AppriseAsset import AppriseAsset from apprise.AppriseAsset import AppriseAsset
from apprise.config.ConfigBase import ConfigBase from apprise.config.ConfigBase import ConfigBase
from apprise import ConfigFormat from apprise import ConfigFormat
from apprise import plugins
import yaml import yaml
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
import logging import logging
from apprise.plugins.NotifyEmail import NotifyEmail
logging.disable(logging.CRITICAL) 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 # Now we compare our results and verify they are the same
assert len(yaml_result) == len(text_result) assert len(yaml_result) == len(text_result)
assert isinstance(yaml_result[0], plugins.NotifyEmail) assert isinstance(yaml_result[0], NotifyEmail)
assert isinstance(text_result[0], plugins.NotifyEmail) assert isinstance(text_result[0], NotifyEmail)
assert 'mytag' in text_result[0] assert 'mytag' in text_result[0]
assert 'mytag' in yaml_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, # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
from apprise.plugins.NotifyAppriseAPI import NotifyAppriseAPI
from helpers import AppriseURLTester from helpers import AppriseURLTester
from apprise import plugins
import requests import requests
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -54,101 +54,101 @@ apprise_url_tests = (
}), }),
# A valid URL with Token # A valid URL with Token
('apprise://localhost/%s' % ('a' * 32), { ('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprise://localhost/a...a/', 'privacy_url': 'apprise://localhost/a...a/',
}), }),
# A valid URL with Token (using port) # A valid URL with Token (using port)
('apprise://localhost:8080/%s' % ('b' * 32), { ('apprise://localhost:8080/%s' % ('b' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprise://localhost:8080/b...b/', 'privacy_url': 'apprise://localhost:8080/b...b/',
}), }),
# A secure (https://) reference # A secure (https://) reference
('apprises://localhost/%s' % ('c' * 32), { ('apprises://localhost/%s' % ('c' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://localhost/c...c/', 'privacy_url': 'apprises://localhost/c...c/',
}), }),
# Native URL suport (https) # Native URL suport (https)
('https://example.com/path/notify/%s' % ('d' * 32), { ('https://example.com/path/notify/%s' % ('d' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://example.com/path/d...d/', 'privacy_url': 'apprises://example.com/path/d...d/',
}), }),
# Native URL suport (http) # Native URL suport (http)
('http://example.com/notify/%s' % ('d' * 32), { ('http://example.com/notify/%s' % ('d' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprise://example.com/d...d/', 'privacy_url': 'apprise://example.com/d...d/',
}), }),
# support to= keyword # support to= keyword
('apprises://localhost/?to=%s' % ('e' * 32), { ('apprises://localhost/?to=%s' % ('e' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
'privacy_url': 'apprises://localhost/e...e/', 'privacy_url': 'apprises://localhost/e...e/',
}), }),
# support token= keyword (even when passed with to=, token over-rides) # support token= keyword (even when passed with to=, token over-rides)
('apprise://localhost/?token=%s&to=%s' % ('f' * 32, 'abcd'), { ('apprise://localhost/?token=%s&to=%s' % ('f' * 32, 'abcd'), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://localhost/f...f/', 'privacy_url': 'apprise://localhost/f...f/',
}), }),
# Test tags # Test tags
('apprise://localhost/?token=%s&tags=admin,team' % ('abcd'), { ('apprise://localhost/?token=%s&tags=admin,team' % ('abcd'), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://localhost/a...d/', 'privacy_url': 'apprise://localhost/a...d/',
}), }),
# Test Format string # Test Format string
('apprise://user@localhost/mytoken0/?format=markdown', { ('apprise://user@localhost/mytoken0/?format=markdown', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://user@localhost/m...0/', 'privacy_url': 'apprise://user@localhost/m...0/',
}), }),
('apprise://user@localhost/mytoken1/', { ('apprise://user@localhost/mytoken1/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://user@localhost/m...1/', 'privacy_url': 'apprise://user@localhost/m...1/',
}), }),
('apprise://localhost:8080/mytoken/', { ('apprise://localhost:8080/mytoken/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
}), }),
('apprise://user:pass@localhost:8080/mytoken2/', { ('apprise://user:pass@localhost:8080/mytoken2/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
'privacy_url': 'apprise://user:****@localhost:8080/m...2/', 'privacy_url': 'apprise://user:****@localhost:8080/m...2/',
}), }),
('apprises://localhost/mytoken/', { ('apprises://localhost/mytoken/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
}), }),
('apprises://user:pass@localhost/mytoken3/', { ('apprises://user:pass@localhost/mytoken3/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://user:****@localhost/m...3/', 'privacy_url': 'apprises://user:****@localhost/m...3/',
}), }),
('apprises://localhost:8080/mytoken4/', { ('apprises://localhost:8080/mytoken4/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://localhost:8080/m...4/', 'privacy_url': 'apprises://localhost:8080/m...4/',
}), }),
('apprises://user:password@localhost:8080/mytoken5/', { ('apprises://user:password@localhost:8080/mytoken5/', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'apprises://user:****@localhost:8080/m...5/', 'privacy_url': 'apprises://user:****@localhost:8080/m...5/',
}), }),
('apprises://localhost:8080/path?+HeaderKey=HeaderValue', { ('apprises://localhost:8080/path?+HeaderKey=HeaderValue', {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
}), }),
('apprise://localhost/%s' % ('a' * 32), { ('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('apprise://localhost/%s' % ('a' * 32), { ('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('apprise://localhost/%s' % ('a' * 32), { ('apprise://localhost/%s' % ('a' * 32), {
'instance': plugins.NotifyAppriseAPI, 'instance': NotifyAppriseAPI,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,8 +22,9 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
from apprise import plugins
import requests import requests
from apprise.plugins.NotifyFaast import NotifyFaast
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -40,30 +41,30 @@ apprise_url_tests = (
}), }),
# Auth Token specified # Auth Token specified
('faast://%s' % ('a' * 32), { ('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast, 'instance': NotifyFaast,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'faast://a...a', 'privacy_url': 'faast://a...a',
}), }),
('faast://%s' % ('a' * 32), { ('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast, 'instance': NotifyFaast,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
('faast://%s' % ('a' * 32), { ('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast, 'instance': NotifyFaast,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('faast://%s' % ('a' * 32), { ('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast, 'instance': NotifyFaast,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('faast://%s' % ('a' * 32), { ('faast://%s' % ('a' * 32), {
'instance': plugins.NotifyFaast, 'instance': NotifyFaast,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

@ -37,7 +37,7 @@ import pytest
import requests import requests
import json import json
from apprise import Apprise from apprise import Apprise
from apprise import plugins from apprise.plugins.NotifyFCM import NotifyFCM
from helpers import AppriseURLTester from helpers import AppriseURLTester
try: try:
@ -76,18 +76,18 @@ apprise_url_tests = (
}), }),
('fcm://apikey/', { ('fcm://apikey/', {
# no project id specified so we operate in legacy mode # 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 # but there are no targets specified so we return False
'notify_response': False, 'notify_response': False,
}), }),
('fcm://apikey/device', { ('fcm://apikey/device', {
# Valid device # Valid device
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
'privacy_url': 'fcm://a...y/device', 'privacy_url': 'fcm://a...y/device',
}), }),
('fcm://apikey/#topic', { ('fcm://apikey/#topic', {
# Valid topic # Valid topic
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
'privacy_url': 'fcm://a...y/%23topic', 'privacy_url': 'fcm://a...y/%23topic',
}), }),
('fcm://apikey/device?mode=invalid', { ('fcm://apikey/device?mode=invalid', {
@ -96,39 +96,39 @@ apprise_url_tests = (
}), }),
('fcm://apikey/#topic1/device/%20/', { ('fcm://apikey/#topic1/device/%20/', {
# Valid topic, valid device, and invalid entry # Valid topic, valid device, and invalid entry
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://apikey?to=#topic1,device', { ('fcm://apikey?to=#topic1,device', {
# Test to= # Test to=
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://?apikey=abc123&to=device', { ('fcm://?apikey=abc123&to=device', {
# Test apikey= to= # Test apikey= to=
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://?apikey=abc123&to=device&image=yes', { ('fcm://?apikey=abc123&to=device&image=yes', {
# Test image boolean # Test image boolean
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://?apikey=abc123&to=device&color=no', { ('fcm://?apikey=abc123&to=device&color=no', {
# Disable colors # Disable colors
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://?apikey=abc123&to=device&color=aabbcc', { ('fcm://?apikey=abc123&to=device&color=aabbcc', {
# custom colors # custom colors
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://?apikey=abc123&to=device' ('fcm://?apikey=abc123&to=device'
'&image_url=http://example.com/interesting.jpg', { '&image_url=http://example.com/interesting.jpg', {
# Test image_url # Test image_url
'instance': plugins.NotifyFCM}), 'instance': NotifyFCM}),
('fcm://?apikey=abc123&to=device' ('fcm://?apikey=abc123&to=device'
'&image_url=http://example.com/interesting.jpg&image=no', { '&image_url=http://example.com/interesting.jpg&image=no', {
# Test image_url but set to no # Test image_url but set to no
'instance': plugins.NotifyFCM}), 'instance': NotifyFCM}),
('fcm://?apikey=abc123&to=device&+key=value&+key2=value2', { ('fcm://?apikey=abc123&to=device&+key=value&+key2=value2', {
# Test apikey= to= and data arguments # Test apikey= to= and data arguments
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
}), }),
('fcm://%20?to=device&keyfile=/invalid/path', { ('fcm://%20?to=device&keyfile=/invalid/path', {
# invalid Project ID # invalid Project ID
@ -136,13 +136,13 @@ apprise_url_tests = (
}), }),
('fcm://project_id?to=device&keyfile=/invalid/path', { ('fcm://project_id?to=device&keyfile=/invalid/path', {
# Test to= and auto detection of oauth mode # Test to= and auto detection of oauth mode
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# we'll fail to send our notification as a result # we'll fail to send our notification as a result
'response': False, 'response': False,
}), }),
('fcm://?to=device&project=project_id&keyfile=/invalid/path', { ('fcm://?to=device&project=project_id&keyfile=/invalid/path', {
# Test project= & to= and auto detection of oauth mode # Test project= & to= and auto detection of oauth mode
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# we'll fail to send our notification as a result # we'll fail to send our notification as a result
'response': False, 'response': False,
}), }),
@ -153,18 +153,18 @@ apprise_url_tests = (
('fcm://project_id?to=device&mode=oauth2&keyfile=/invalid/path', { ('fcm://project_id?to=device&mode=oauth2&keyfile=/invalid/path', {
# Same test as above except we explicitly set our oauth2 mode # Same test as above except we explicitly set our oauth2 mode
# Test to= and auto detection of oauth mode # Test to= and auto detection of oauth mode
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# we'll fail to send our notification as a result # we'll fail to send our notification as a result
'response': False, 'response': False,
}), }),
('fcm://apikey/#topic1/device/?mode=legacy', { ('fcm://apikey/#topic1/device/?mode=legacy', {
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('fcm://apikey/#topic1/device/?mode=legacy', { ('fcm://apikey/#topic1/device/?mode=legacy', {
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -173,7 +173,7 @@ apprise_url_tests = (
os.path.join( os.path.join(
os.path.dirname(__file__), 'var', 'fcm', os.path.dirname(__file__), 'var', 'fcm',
'service_account.json')), { 'service_account.json')), {
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
@ -182,7 +182,7 @@ apprise_url_tests = (
os.path.join( os.path.join(
os.path.dirname(__file__), 'var', 'fcm', os.path.dirname(__file__), 'var', 'fcm',
'service_account.json')), { 'service_account.json')), {
'instance': plugins.NotifyFCM, 'instance': NotifyFCM,
# Throws a series of connection and transfer exceptions when # Throws a series of connection and transfer exceptions when
# this flag is set and tests that we gracfully handle them # this flag is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 # 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 # 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: # 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 assert obj is not None

View File

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

View File

@ -27,8 +27,9 @@ import pytest
from unittest import mock from unittest import mock
import requests import requests
from apprise.plugins.NotifyGitter import NotifyGitter
from helpers import AppriseURLTester from helpers import AppriseURLTester
from apprise import plugins
from json import dumps from json import dumps
from datetime import datetime from datetime import datetime
@ -58,12 +59,12 @@ apprise_url_tests = (
}), }),
# Token + channel # Token + channel
('gitter://%s/apprise' % ('b' * 40), { ('gitter://%s/apprise' % ('b' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
'response': False, 'response': False,
}), }),
# include image in post # include image in post
('gitter://%s/apprise?image=Yes' % ('c' * 40), { ('gitter://%s/apprise?image=Yes' % ('c' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
'response': False, 'response': False,
# Our expected url(privacy=True) startswith() response: # 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) # Don't include image in post (this is the default anyway)
('gitter://%s/apprise?image=Yes' % ('d' * 40), { ('gitter://%s/apprise?image=Yes' % ('d' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
'response': False, 'response': False,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
# Don't include image in post (this is the default anyway) # Don't include image in post (this is the default anyway)
('gitter://%s/apprise?image=No' % ('e' * 40), { ('gitter://%s/apprise?image=No' % ('e' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
'response': False, 'response': False,
}), }),
('gitter://%s/apprise' % ('f' * 40), { ('gitter://%s/apprise' % ('f' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('gitter://%s/apprise' % ('g' * 40), { ('gitter://%s/apprise' % ('g' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('gitter://%s/apprise' % ('h' * 40), { ('gitter://%s/apprise' % ('h' * 40), {
'instance': plugins.NotifyGitter, 'instance': NotifyGitter,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -163,8 +164,8 @@ def test_plugin_gitter_general(mock_post, mock_get, no_throttling):
mock_post.return_value = request mock_post.return_value = request
# Variation Initializations # Variation Initializations
obj = plugins.NotifyGitter(token=token, targets='apprise') obj = NotifyGitter(token=token, targets='apprise')
assert isinstance(obj, plugins.NotifyGitter) is True assert isinstance(obj, NotifyGitter) is True
assert isinstance(obj.url(), str) is True assert isinstance(obj.url(), str) is True
# apprise room was found # apprise room was found
@ -233,7 +234,7 @@ def test_plugin_gitter_general(mock_post, mock_get, no_throttling):
request.content = '{}' request.content = '{}'
# Support the 'to' as a target # Support the 'to' as a target
results = plugins.NotifyGitter.parse_url( results = NotifyGitter.parse_url(
'gitter://{}?to={}'.format(token, 'apprise')) 'gitter://{}?to={}'.format(token, 'apprise'))
assert isinstance(results, dict) is True assert isinstance(results, dict) is True
assert 'apprise' in results['targets'] 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 assert obj.send(body="test") is True
# Variation Initializations # Variation Initializations
obj = plugins.NotifyGitter(token=token, targets='apprise') obj = NotifyGitter(token=token, targets='apprise')
assert isinstance(obj, plugins.NotifyGitter) is True assert isinstance(obj, NotifyGitter) is True
assert isinstance(obj.url(), str) is True assert isinstance(obj.url(), str) is True
# apprise room was not found # apprise room was not found
assert obj.send(body="test") is False assert obj.send(body="test") is False
@ -277,7 +278,7 @@ def test_plugin_gitter_edge_cases():
# Initializes the plugin with an invalid token # Initializes the plugin with an invalid token
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyGitter(token=None, targets=targets) NotifyGitter(token=None, targets=targets)
# Whitespace also acts as an invalid token value # Whitespace also acts as an invalid token value
with pytest.raises(TypeError): 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 sys
import types import types
import apprise import apprise
from helpers import module_reload from helpers import reload_plugin
from importlib import reload 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.DBusGMainLoop.side_effect = None
mock_mainloop.glib.NativeMainLoop.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) # Create our instance (identify all supported types)
obj = apprise.Apprise.instantiate('dbus://', suppress_exceptions=False) 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 isinstance(obj.url(), str) is True
assert obj.url().startswith('dbus://_/') assert obj.url().startswith('dbus://_/')
obj = apprise.Apprise.instantiate('kde://', suppress_exceptions=False) 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 isinstance(obj.url(), str) is True
assert obj.url().startswith('kde://_/') assert obj.url().startswith('kde://_/')
obj = apprise.Apprise.instantiate('qt://', suppress_exceptions=False) 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 isinstance(obj.url(), str) is True
assert obj.url().startswith('qt://_/') assert obj.url().startswith('qt://_/')
obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False) 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 isinstance(obj.url(), str) is True
assert obj.url().startswith('glib://_/') assert obj.url().startswith('glib://_/')
obj.duration = 0 obj.duration = 0
# Test our class loading using a series of arguments # Test our class loading using a series of arguments
with pytest.raises(TypeError): with pytest.raises(TypeError):
apprise.plugins.NotifyDBus(**{'schema': 'invalid'}) NotifyDBus(**{'schema': 'invalid'})
# Set our X and Y coordinate and try the notification # Set our X and Y coordinate and try the notification
assert apprise.plugins.NotifyDBus( assert NotifyDBus(
x_axis=0, y_axis=0, **{'schema': 'dbus'})\ x_axis=0, y_axis=0, **{'schema': 'dbus'})\
.notify(title='', body='body', .notify(title='', body='body',
notify_type=apprise.NotifyType.INFO) is True 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 # Test our arguments through the instantiate call
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?image=True', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.url().startswith('dbus://_/') assert obj.url().startswith('dbus://_/')
assert re.search('image=yes', obj.url()) 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( obj = apprise.Apprise.instantiate(
'dbus://_/?image=False', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.url().startswith('dbus://_/') assert obj.url().startswith('dbus://_/')
assert re.search('image=no', obj.url()) 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 # Test priority (alias to urgency) handling
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?priority=invalid', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -188,7 +189,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?priority=high', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -196,7 +197,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?priority=2', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -205,7 +206,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Test urgency handling # Test urgency handling
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=invalid', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -213,7 +214,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=high', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -221,7 +222,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=2', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -229,7 +230,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?urgency=', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', title='title', body='body',
@ -238,7 +239,7 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Test x/y # Test x/y
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'dbus://_/?x=5&y=5', suppress_exceptions=False) '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 isinstance(obj.url(), str) is True
assert obj.notify( assert obj.notify(
title='title', body='body', 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 notify_type=apprise.NotifyType.INFO) is False
# Test the setting of a the urgency # 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 # 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: # Emulate require_version function:
gi.require_version.side_effect = ImportError() gi.require_version.side_effect = ImportError()
module_reload('NotifyDBus') reload_plugin('NotifyDBus')
from apprise.plugins.NotifyDBus import NotifyDBus
# Create our instance # Create our instance
obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False) 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 obj.duration = 0
# Test url() call # Test url() call
@ -383,11 +385,12 @@ def test_plugin_dbus_general(mock_mainloop, mock_byte, mock_bytearray,
# Emulate require_version function: # Emulate require_version function:
gi.require_version.side_effect = ValueError() gi.require_version.side_effect = ValueError()
module_reload('NotifyDBus') reload_plugin('NotifyDBus')
from apprise.plugins.NotifyDBus import NotifyDBus
# Create our instance # Create our instance
obj = apprise.Apprise.instantiate('glib://', suppress_exceptions=False) 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 obj.duration = 0
# Test url() call # 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') sys.modules['dbus'] = compile('raise ImportError()', 'dbus', 'exec')
# Reload our modules # Reload our modules
module_reload('NotifyDBus') reload_plugin('NotifyDBus')
# We can no longer instantiate an instance because dbus has been # We can no longer instantiate an instance because dbus has been
# officialy marked unavailable and thus the module is marked # 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: # let's just put our old configuration back:
sys.modules['dbus'] = _session_bus sys.modules['dbus'] = _session_bus
# Reload our modules # Reload our modules
module_reload('NotifyDBus') reload_plugin('NotifyDBus')

View File

@ -28,8 +28,8 @@ import types
from unittest import mock from unittest import mock
import apprise import apprise
from helpers import module_reload
from apprise.plugins.NotifyGnome import GnomeUrgency from apprise.plugins.NotifyGnome import GnomeUrgency
from helpers import reload_plugin
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
import logging import logging
@ -53,7 +53,7 @@ def test_plugin_gnome_general():
# for the purpose of testing and capture the handling of the # for the purpose of testing and capture the handling of the
# library when it is missing # library when it is missing
del sys.modules[gi_name] del sys.modules[gi_name]
module_reload('NotifyGnome') reload_plugin('NotifyGnome')
# We need to fake our gnome environment for testing purposes since # We need to fake our gnome environment for testing purposes since
# the gi library isn't available in Travis CI # the gi library isn't available in Travis CI
@ -88,7 +88,9 @@ def test_plugin_gnome_general():
notify_obj.show.return_value = True notify_obj.show.return_value = True
mock_notify.new.return_value = notify_obj mock_notify.new.return_value = notify_obj
mock_pixbuf.new_from_file.return_value = True mock_pixbuf.new_from_file.return_value = True
module_reload('NotifyGnome')
reload_plugin('NotifyGnome')
from apprise.plugins.NotifyGnome import NotifyGnome
# Create our instance # Create our instance
obj = apprise.Apprise.instantiate('gnome://', suppress_exceptions=False) obj = apprise.Apprise.instantiate('gnome://', suppress_exceptions=False)
@ -113,34 +115,35 @@ def test_plugin_gnome_general():
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?image=True', suppress_exceptions=False) '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', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?image=False', suppress_exceptions=False) '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', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
# Test Priority (alias of urgency) # Test Priority (alias of urgency)
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?priority=invalid', suppress_exceptions=False) '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.urgency == 1
assert obj.notify(title='title', body='body', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?priority=high', suppress_exceptions=False) '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.urgency == 2
assert obj.notify(title='title', body='body', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?priority=2', suppress_exceptions=False) '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.urgency == 2
assert obj.notify(title='title', body='body', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
@ -149,20 +152,20 @@ def test_plugin_gnome_general():
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?urgency=invalid', suppress_exceptions=False) 'gnome://_/?urgency=invalid', suppress_exceptions=False)
assert obj.urgency == 1 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', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?urgency=high', suppress_exceptions=False) 'gnome://_/?urgency=high', suppress_exceptions=False)
assert obj.urgency == 2 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', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'gnome://_/?urgency=2', suppress_exceptions=False) '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.urgency == 2
assert obj.notify(title='title', body='body', assert obj.notify(title='title', body='body',
notify_type=apprise.NotifyType.INFO) is True notify_type=apprise.NotifyType.INFO) is True
@ -263,14 +266,14 @@ def test_plugin_gnome_general():
notify_type=apprise.NotifyType.INFO) is False notify_type=apprise.NotifyType.INFO) is False
# Test the setting of a the urgency (through priority keyword) # 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 # Verify this all works in the event a ValueError is also thronw
# out of the call to gi.require_version() # out of the call to gi.require_version()
# Emulate require_version function: # Emulate require_version function:
gi.require_version.side_effect = ValueError() gi.require_version.side_effect = ValueError()
module_reload('NotifyGnome') reload_plugin('NotifyGnome')
# We can now no longer load our instance # We can now no longer load our instance
# The object internally is marked disabled # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyGoogleChat import NotifyGoogleChat
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -48,34 +49,34 @@ apprise_url_tests = (
}), }),
# Credentials are good # Credentials are good
('gchat://workspace/key/token', { ('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat, 'instance': NotifyGoogleChat,
'privacy_url': 'gchat://w...e/k...y/t...n', 'privacy_url': 'gchat://w...e/k...y/t...n',
}), }),
# Test arguments # Test arguments
('gchat://?workspace=ws&key=mykey&token=mytoken', { ('gchat://?workspace=ws&key=mykey&token=mytoken', {
'instance': plugins.NotifyGoogleChat, 'instance': NotifyGoogleChat,
'privacy_url': 'gchat://w...s/m...y/m...n', 'privacy_url': 'gchat://w...s/m...y/m...n',
}), }),
# Google Native Webhohok URL # Google Native Webhohok URL
('https://chat.googleapis.com/v1/spaces/myworkspace/messages' ('https://chat.googleapis.com/v1/spaces/myworkspace/messages'
'?key=mykey&token=mytoken', { '?key=mykey&token=mytoken', {
'instance': plugins.NotifyGoogleChat, 'instance': NotifyGoogleChat,
'privacy_url': 'gchat://m...e/m...y/m...n'}), 'privacy_url': 'gchat://m...e/m...y/m...n'}),
('gchat://workspace/key/token', { ('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat, 'instance': NotifyGoogleChat,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('gchat://workspace/key/token', { ('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat, 'instance': NotifyGoogleChat,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('gchat://workspace/key/token', { ('gchat://workspace/key/token', {
'instance': plugins.NotifyGoogleChat, 'instance': NotifyGoogleChat,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

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

View File

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

View File

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

View File

@ -26,8 +26,8 @@ import pytest
from unittest import mock from unittest import mock
import requests import requests
from apprise import plugins
from apprise import NotifyType from apprise import NotifyType
from apprise.plugins.NotifyIFTTT import NotifyIFTTT
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # 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 # A nicely formed ifttt url with 1 event and a new key/value store
('ifttt://WebHookID@EventID/?+TemplateKey=TemplateVal', { ('ifttt://WebHookID@EventID/?+TemplateKey=TemplateVal', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'ifttt://W...D', 'privacy_url': 'ifttt://W...D',
}), }),
# Test to= in which case we set the host to the webhook id # Test to= in which case we set the host to the webhook id
('ifttt://WebHookID?to=EventID,EventID2', { ('ifttt://WebHookID?to=EventID,EventID2', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
}), }),
# Removing certain keys: # Removing certain keys:
('ifttt://WebHookID@EventID/?-Value1=&-Value2', { ('ifttt://WebHookID@EventID/?-Value1=&-Value2', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
}), }),
# A nicely formed ifttt url with 2 events defined: # A nicely formed ifttt url with 2 events defined:
('ifttt://WebHookID@EventID/EventID2/', { ('ifttt://WebHookID@EventID/EventID2/', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
}), }),
# Support Native URL references # Support Native URL references
('https://maker.ifttt.com/use/WebHookID/', { ('https://maker.ifttt.com/use/WebHookID/', {
@ -71,27 +71,27 @@ apprise_url_tests = (
'instance': TypeError, 'instance': TypeError,
}), }),
('https://maker.ifttt.com/use/WebHookID/EventID/', { ('https://maker.ifttt.com/use/WebHookID/EventID/', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
}), }),
# Native URL with arguments # Native URL with arguments
('https://maker.ifttt.com/use/WebHookID/EventID/?-Value1=', { ('https://maker.ifttt.com/use/WebHookID/EventID/?-Value1=', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
}), }),
# Test website connection failures # Test website connection failures
('ifttt://WebHookID@EventID', { ('ifttt://WebHookID@EventID', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('ifttt://WebHookID@EventID', { ('ifttt://WebHookID@EventID', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('ifttt://WebHookID@EventID', { ('ifttt://WebHookID@EventID', {
'instance': plugins.NotifyIFTTT, 'instance': NotifyIFTTT,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -131,72 +131,72 @@ def test_plugin_ifttt_edge_cases(mock_post, mock_get, no_throttling):
# No webhook_id specified # No webhook_id specified
with pytest.raises(TypeError): 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 # Initializes the plugin with an invalid webhook id
with pytest.raises(TypeError): 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 # Whitespace also acts as an invalid webhook id
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyIFTTT(webhook_id=" ", events=events) NotifyIFTTT(webhook_id=" ", events=events)
# No events specified # No events specified
with pytest.raises(TypeError): 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) obj = NotifyIFTTT(webhook_id=webhook_id, events=events)
assert isinstance(obj, plugins.NotifyIFTTT) is True assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify( assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True body='body', title='title', notify_type=NotifyType.INFO) is True
# Test the addition of tokens # Test the addition of tokens
obj = plugins.NotifyIFTTT( obj = NotifyIFTTT(
webhook_id=webhook_id, events=events, webhook_id=webhook_id, events=events,
add_tokens={'Test': 'ValueA', 'Test2': 'ValueB'}) add_tokens={'Test': 'ValueA', 'Test2': 'ValueB'})
assert isinstance(obj, plugins.NotifyIFTTT) is True assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify( assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True body='body', title='title', notify_type=NotifyType.INFO) is True
# Invalid del_tokens entry # Invalid del_tokens entry
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyIFTTT( NotifyIFTTT(
webhook_id=webhook_id, events=events, 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( assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True body='body', title='title', notify_type=NotifyType.INFO) is True
# Test removal of tokens by a list # Test removal of tokens by a list
obj = plugins.NotifyIFTTT( obj = NotifyIFTTT(
webhook_id=webhook_id, events=events, webhook_id=webhook_id, events=events,
add_tokens={ add_tokens={
'MyKey': 'MyValue' 'MyKey': 'MyValue'
}, },
del_tokens=( del_tokens=(
plugins.NotifyIFTTT.ifttt_default_title_key, NotifyIFTTT.ifttt_default_title_key,
plugins.NotifyIFTTT.ifttt_default_body_key, NotifyIFTTT.ifttt_default_body_key,
plugins.NotifyIFTTT.ifttt_default_type_key)) NotifyIFTTT.ifttt_default_type_key))
assert isinstance(obj, plugins.NotifyIFTTT) is True assert isinstance(obj, NotifyIFTTT) is True
assert obj.notify( assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO) is True body='body', title='title', notify_type=NotifyType.INFO) is True
# Test removal of tokens as dict # Test removal of tokens as dict
obj = plugins.NotifyIFTTT( obj = NotifyIFTTT(
webhook_id=webhook_id, events=events, webhook_id=webhook_id, events=events,
add_tokens={ add_tokens={
'MyKey': 'MyValue' 'MyKey': 'MyValue'
}, },
del_tokens={ del_tokens={
plugins.NotifyIFTTT.ifttt_default_title_key: None, NotifyIFTTT.ifttt_default_title_key: None,
plugins.NotifyIFTTT.ifttt_default_body_key: None, NotifyIFTTT.ifttt_default_body_key: None,
plugins.NotifyIFTTT.ifttt_default_type_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 pytest
import requests import requests
import apprise import apprise
from apprise import plugins
from apprise import NotifyType from apprise import NotifyType
from helpers import AppriseURLTester from helpers import AppriseURLTester
from apprise.plugins.NotifyJoin import JoinPriority from apprise.plugins.NotifyJoin import JoinPriority, NotifyJoin
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
import logging import logging
@ -47,69 +46,69 @@ apprise_url_tests = (
}), }),
# APIkey; no device # APIkey; no device
('join://%s' % ('a' * 32), { ('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# API Key + device (using to=) # API Key + device (using to=)
('join://%s?to=%s' % ('a' * 32, 'd' * 32), { ('join://%s?to=%s' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'join://a...a/', 'privacy_url': 'join://a...a/',
}), }),
# API Key + priority setting # API Key + priority setting
('join://%s?priority=high' % ('a' * 32), { ('join://%s?priority=high' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# API Key + invalid priority setting # API Key + invalid priority setting
('join://%s?priority=invalid' % ('a' * 32), { ('join://%s?priority=invalid' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# API Key + priority setting (empty) # API Key + priority setting (empty)
('join://%s?priority=' % ('a' * 32), { ('join://%s?priority=' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# API Key + device # API Key + device
('join://%s@%s?image=True' % ('a' * 32, 'd' * 32), { ('join://%s@%s?image=True' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# No image # No image
('join://%s@%s?image=False' % ('a' * 32, 'd' * 32), { ('join://%s@%s?image=False' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# API Key + Device Name # API Key + Device Name
('join://%s/%s' % ('a' * 32, 'My Device'), { ('join://%s/%s' % ('a' * 32, 'My Device'), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
# API Key + device # API Key + device
('join://%s/%s' % ('a' * 32, 'd' * 32), { ('join://%s/%s' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
# API Key + 2 devices # API Key + 2 devices
('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'e' * 32), { ('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'e' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
# API Key + 1 device and 1 group # API Key + 1 device and 1 group
('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'group.chrome'), { ('join://%s/%s/%s' % ('a' * 32, 'd' * 32, 'group.chrome'), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
}), }),
('join://%s' % ('a' * 32), { ('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('join://%s' % ('a' * 32), { ('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('join://%s' % ('a' * 32), { ('join://%s' % ('a' * 32), {
'instance': plugins.NotifyJoin, 'instance': NotifyJoin,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -141,21 +140,21 @@ def test_plugin_join_edge_cases(mock_post, mock_get, no_throttling):
apikey = 'a' * 32 apikey = 'a' * 32
# Initializes the plugin with devices set to a string # 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 # 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 # Initializes the plugin with an invalid apikey
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyJoin(apikey=None) NotifyJoin(apikey=None)
# Whitespace also acts as an invalid apikey # Whitespace also acts as an invalid apikey
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyJoin(apikey=" ") NotifyJoin(apikey=" ")
# Initializes the plugin with devices set to a set # 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 # Prepare our mock responses
req = requests.Request() req = requests.Request()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,8 @@
# THE SOFTWARE. # THE SOFTWARE.
import pytest import pytest
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyMattermost import NotifyMattermost
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -47,64 +48,64 @@ apprise_url_tests = (
'instance': TypeError, 'instance': TypeError,
}), }),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
}), }),
('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?channel=test', { ('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?channel=test', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
}), }),
('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?to=test', { ('mmost://user@localhost/3ccdd113474722377935511fc85d3dd4?to=test', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'mmost://user@localhost/3...4/', 'privacy_url': 'mmost://user@localhost/3...4/',
}), }),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4' ('mmost://localhost/3ccdd113474722377935511fc85d3dd4'
'?to=test&image=True', { '?to=test&image=True', {
'instance': plugins.NotifyMattermost}), 'instance': NotifyMattermost}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4' \ ('mmost://localhost/3ccdd113474722377935511fc85d3dd4' \
'?to=test&image=False', { '?to=test&image=False', {
'instance': plugins.NotifyMattermost}), 'instance': NotifyMattermost}),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4' \ ('mmost://localhost/3ccdd113474722377935511fc85d3dd4' \
'?to=test&image=True', { '?to=test&image=True', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
# don't include an image by default # don't include an image by default
'include_image': False}), 'include_image': False}),
('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'mmost://localhost:8080/3...4/', 'privacy_url': 'mmost://localhost:8080/3...4/',
}), }),
('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost:8080/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
}), }),
('mmost://localhost:invalid-port/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost:invalid-port/3ccdd113474722377935511fc85d3dd4', {
'instance': None, 'instance': None,
}), }),
('mmosts://localhost/3ccdd113474722377935511fc85d3dd4', { ('mmosts://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
}), }),
# Test our paths # Test our paths
('mmosts://localhost/a/path/3ccdd113474722377935511fc85d3dd4', { ('mmosts://localhost/a/path/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
}), }),
('mmosts://localhost/////3ccdd113474722377935511fc85d3dd4///', { ('mmosts://localhost/////3ccdd113474722377935511fc85d3dd4///', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
}), }),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('mmost://localhost/3ccdd113474722377935511fc85d3dd4', { ('mmost://localhost/3ccdd113474722377935511fc85d3dd4', {
'instance': plugins.NotifyMattermost, 'instance': NotifyMattermost,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -130,6 +131,6 @@ def test_plugin_mattermost_edge_cases(no_throttling):
# Invalid Authorization Token # Invalid Authorization Token
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyMattermost(None) NotifyMattermost(None)
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyMattermost(" ") NotifyMattermost(" ")

View File

@ -26,7 +26,8 @@ from unittest import mock
import pytest import pytest
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyMessageBird import NotifyMessageBird
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -49,42 +50,42 @@ apprise_url_tests = (
}), }),
('msgbird://{}/15551232000'.format('a' * 25), { ('msgbird://{}/15551232000'.format('a' * 25), {
# target phone number becomes who we text too; all is good # target phone number becomes who we text too; all is good
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'msgbird://a...a/15551232000', 'privacy_url': 'msgbird://a...a/15551232000',
}), }),
('msgbird://{}/15551232000/abcd'.format('a' * 25), { ('msgbird://{}/15551232000/abcd'.format('a' * 25), {
# valid credentials # valid credentials
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
# Since there are no targets specified we expect a False return on # Since there are no targets specified we expect a False return on
# send() # send()
'notify_response': False, 'notify_response': False,
}), }),
('msgbird://{}/15551232000/123'.format('a' * 25), { ('msgbird://{}/15551232000/123'.format('a' * 25), {
# valid credentials # valid credentials
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
# Since there are no targets specified we expect a False return on # Since there are no targets specified we expect a False return on
# send() # send()
'notify_response': False, 'notify_response': False,
}), }),
('msgbird://{}/?from=15551233000&to=15551232000'.format('a' * 25), { ('msgbird://{}/?from=15551233000&to=15551232000'.format('a' * 25), {
# reference to to= and from= # reference to to= and from=
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
}), }),
('msgbird://{}/15551232000'.format('a' * 25), { ('msgbird://{}/15551232000'.format('a' * 25), {
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('msgbird://{}/15551232000'.format('a' * 25), { ('msgbird://{}/15551232000'.format('a' * 25), {
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('msgbird://{}/15551232000'.format('a' * 25), { ('msgbird://{}/15551232000'.format('a' * 25), {
'instance': plugins.NotifyMessageBird, 'instance': NotifyMessageBird,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -122,6 +123,6 @@ def test_plugin_messagebird_edge_cases(mock_post, no_throttling):
# No apikey specified # No apikey specified
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyMessageBird(apikey=None, source=source) NotifyMessageBird(apikey=None, source=source)
with pytest.raises(TypeError): 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 # Disable logging for a cleaner testing output
import logging import logging
from apprise.plugins.NotifyMQTT import NotifyMQTT
logging.disable(logging.CRITICAL) logging.disable(logging.CRITICAL)
@ -76,7 +79,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# Instantiate our object # Instantiate our object
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost:1234/my/topic', suppress_exceptions=False) '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') assert obj.url().startswith('mqtt://localhost:1234/my/topic')
# Detect our defaults # Detect our defaults
assert re.search(r'qos=0', obj.url()) 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 # leverage the to= argument to identify our topic
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost?to=my/topic', suppress_exceptions=False) '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') assert obj.url().startswith('mqtt://localhost/my/topic')
# Detect our defaults # Detect our defaults
assert re.search(r'qos=0', obj.url()) assert re.search(r'qos=0', obj.url())
@ -123,7 +126,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# the URL # the URL
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost?qos=1&version=v3.1', suppress_exceptions=False) '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 obj.url().startswith('mqtt://localhost')
assert re.search(r'qos=1', obj.url()) assert re.search(r'qos=1', obj.url())
assert re.search(r'version=v3.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 # A Secure URL
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtts://user:pass@localhost/my/topic', suppress_exceptions=False) '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.url().startswith('mqtts://user:pass@localhost/my/topic')
assert obj.notify(body="test=test") is True assert obj.notify(body="test=test") is True
# Clear CA Certificates # Clear CA Certificates
ca_certs_backup = \ ca_certs_backup = \
list(apprise.plugins.NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS) list(NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS)
apprise.plugins.NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS = [] NotifyMQTT.CA_CERTIFICATE_FILE_LOCATIONS = []
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtts://user:pass@localhost/my/topic', suppress_exceptions=False) '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.url().startswith('mqtts://user:pass@localhost/my/topic')
# A notification is not possible now (without ca_certs) # A notification is not possible now (without ca_certs)
assert obj.notify(body="test=test") is False assert obj.notify(body="test=test") is False
# Restore our certificates (for future tests) # 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 # A single user (not password) + no verifying of host
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtts://user@localhost/my/topic,my/other/topic?verify=False', 'mqtts://user@localhost/my/topic,my/other/topic?verify=False',
suppress_exceptions=False) suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT) assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtts://user@localhost') assert obj.url().startswith('mqtts://user@localhost')
assert re.search(r'my/other/topic', obj.url()) assert re.search(r'my/other/topic', obj.url())
assert re.search(r'my/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( obj = apprise.Apprise.instantiate(
'mqtts://user@localhost/my/topic?session=yes&client_id=apprise', 'mqtts://user@localhost/my/topic?session=yes&client_id=apprise',
suppress_exceptions=False) suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT) assert isinstance(obj, NotifyMQTT)
assert obj.url().startswith('mqtts://user@localhost') assert obj.url().startswith('mqtts://user@localhost')
assert re.search(r'my/topic', obj.url()) assert re.search(r'my/topic', obj.url())
assert re.search(r'client_id=apprise', 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 _mock_client.connect.return_value = 2
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False) '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 assert obj.notify(body="test=test") is False
# Restore our values # Restore our values
_mock_client.connect.return_value = 0 _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 _mock_client.is_connected.return_value = False
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False) '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 assert obj.notify(body="test=test") is False
# Restore our values # Restore our values
_mock_client.reconnect.return_value = 0 _mock_client.reconnect.return_value = 0
@ -200,7 +203,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
publish_result.rc = 2 publish_result.rc = 2
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False) '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 assert obj.notify(body="test=test") is False
# Restore our values # Restore our values
publish_result.rc = 0 publish_result.rc = 0
@ -220,7 +223,7 @@ def test_plugin_mqtt_general(mock_client, no_throttling):
# Exception handling # Exception handling
obj = apprise.Apprise.instantiate( obj = apprise.Apprise.instantiate(
'mqtt://localhost/my/topic', suppress_exceptions=False) 'mqtt://localhost/my/topic', suppress_exceptions=False)
assert isinstance(obj, apprise.plugins.NotifyMQTT) assert isinstance(obj, NotifyMQTT)
_mock_client.connect.return_value = None _mock_client.connect.return_value = None
for side_effect in ( for side_effect in (

View File

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

View File

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

View File

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

View File

@ -23,7 +23,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyNotica import NotifyNotica
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -40,90 +41,90 @@ apprise_url_tests = (
}), }),
# Native URL # Native URL
('https://notica.us/?%s' % ('z' * 6), { ('https://notica.us/?%s' % ('z' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://z...z/', 'privacy_url': 'notica://z...z/',
}), }),
# Native URL with additional arguments # Native URL with additional arguments
('https://notica.us/?%s&overflow=upstream' % ('z' * 6), { ('https://notica.us/?%s&overflow=upstream' % ('z' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://z...z/', 'privacy_url': 'notica://z...z/',
}), }),
# Token specified # Token specified
('notica://%s' % ('a' * 6), { ('notica://%s' % ('a' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://a...a/', 'privacy_url': 'notica://a...a/',
}), }),
# Self-Hosted configuration # Self-Hosted configuration
('notica://localhost/%s' % ('b' * 6), { ('notica://localhost/%s' % ('b' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
}), }),
('notica://user@localhost/%s' % ('c' * 6), { ('notica://user@localhost/%s' % ('c' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
}), }),
('notica://user:pass@localhost/%s/' % ('d' * 6), { ('notica://user:pass@localhost/%s/' % ('d' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://user:****@localhost/d...d', 'privacy_url': 'notica://user:****@localhost/d...d',
}), }),
('notica://user:pass@localhost/a/path/%s/' % ('r' * 6), { ('notica://user:pass@localhost/a/path/%s/' % ('r' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://user:****@localhost/a/path/r...r', 'privacy_url': 'notica://user:****@localhost/a/path/r...r',
}), }),
('notica://localhost:8080/%s' % ('a' * 6), { ('notica://localhost:8080/%s' % ('a' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
}), }),
('notica://user:pass@localhost:8080/%s' % ('b' * 6), { ('notica://user:pass@localhost:8080/%s' % ('b' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
}), }),
('noticas://localhost/%s' % ('j' * 6), { ('noticas://localhost/%s' % ('j' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
'privacy_url': 'noticas://localhost/j...j', 'privacy_url': 'noticas://localhost/j...j',
}), }),
('noticas://user:pass@localhost/%s' % ('e' * 6), { ('noticas://user:pass@localhost/%s' % ('e' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'noticas://user:****@localhost/e...e', 'privacy_url': 'noticas://user:****@localhost/e...e',
}), }),
('noticas://localhost:8080/path/%s' % ('5' * 6), { ('noticas://localhost:8080/path/%s' % ('5' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
'privacy_url': 'noticas://localhost:8080/path/5...5', 'privacy_url': 'noticas://localhost:8080/path/5...5',
}), }),
('noticas://user:pass@localhost:8080/%s' % ('6' * 6), { ('noticas://user:pass@localhost:8080/%s' % ('6' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
}), }),
('notica://%s' % ('b' * 6), { ('notica://%s' % ('b' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
# Test Header overrides # Test Header overrides
('notica://localhost:8080//%s/?+HeaderKey=HeaderValue' % ('7' * 6), { ('notica://localhost:8080//%s/?+HeaderKey=HeaderValue' % ('7' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
}), }),
('notica://%s' % ('c' * 6), { ('notica://%s' % ('c' * 6), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('notica://%s' % ('d' * 7), { ('notica://%s' % ('d' * 7), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('notica://%s' % ('e' * 8), { ('notica://%s' % ('e' * 8), {
'instance': plugins.NotifyNotica, 'instance': NotifyNotica,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyNotifico import NotifyNotifico
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -48,62 +49,62 @@ apprise_url_tests = (
}), }),
('notifico://1234/ckhrjW8w672m6HG', { ('notifico://1234/ckhrjW8w672m6HG', {
# A project id and message hook provided # A project id and message hook provided
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
}), }),
('notifico://1234/ckhrjW8w672m6HG?prefix=no', { ('notifico://1234/ckhrjW8w672m6HG?prefix=no', {
# Disable our prefix # Disable our prefix
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
}), }),
('notifico://1234/ckhrjW8w672m6HG?color=yes', { ('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
'notify_type': 'info', 'notify_type': 'info',
}), }),
('notifico://1234/ckhrjW8w672m6HG?color=yes', { ('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
'notify_type': 'success', 'notify_type': 'success',
}), }),
('notifico://1234/ckhrjW8w672m6HG?color=yes', { ('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
'notify_type': 'warning', 'notify_type': 'warning',
}), }),
('notifico://1234/ckhrjW8w672m6HG?color=yes', { ('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
'notify_type': 'failure', 'notify_type': 'failure',
}), }),
('notifico://1234/ckhrjW8w672m6HG?color=yes', { ('notifico://1234/ckhrjW8w672m6HG?color=yes', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
'notify_type': 'invalid', 'notify_type': 'invalid',
}), }),
('notifico://1234/ckhrjW8w672m6HG?color=no', { ('notifico://1234/ckhrjW8w672m6HG?color=no', {
# Test our color flag by having it set to off # Test our color flag by having it set to off
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'notifico://1...4/c...G', 'privacy_url': 'notifico://1...4/c...G',
}), }),
# Support Native URLs # Support Native URLs
('https://n.tkte.ch/h/2144/uJmKaBW9WFk42miB146ci3Kj', { ('https://n.tkte.ch/h/2144/uJmKaBW9WFk42miB146ci3Kj', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
}), }),
('notifico://1234/ckhrjW8w672m6HG', { ('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
('notifico://1234/ckhrjW8w672m6HG', { ('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('notifico://1234/ckhrjW8w672m6HG', { ('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('notifico://1234/ckhrjW8w672m6HG', { ('notifico://1234/ckhrjW8w672m6HG', {
'instance': plugins.NotifyNotifico, 'instance': NotifyNotifico,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
from apprise import plugins from apprise.plugins.NotifyPagerDuty import NotifyPagerDuty
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -61,47 +61,47 @@ apprise_url_tests = (
}), }),
('pagerduty://myroutekey@myapikey', { ('pagerduty://myroutekey@myapikey', {
# minimum requirements met # minimum requirements met
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'pagerduty://****@****/A...e/N...n?', 'privacy_url': 'pagerduty://****@****/A...e/N...n?',
}), }),
('pagerduty://myroutekey@myapikey?image=no', { ('pagerduty://myroutekey@myapikey?image=no', {
# minimum requirements met and disable images # minimum requirements met and disable images
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
}), }),
('pagerduty://myroutekey@myapikey?region=eu', { ('pagerduty://myroutekey@myapikey?region=eu', {
# european region # european region
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
}), }),
# Custom values # Custom values
('pagerduty://myroutekey@myapikey?+key=value&+key2=value2', { ('pagerduty://myroutekey@myapikey?+key=value&+key2=value2', {
# minimum requirements and support custom key/value pairs # minimum requirements and support custom key/value pairs
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
}), }),
('pagerduty://myroutekey@myapikey/mysource/mycomponent', { ('pagerduty://myroutekey@myapikey/mysource/mycomponent', {
# a valid url # a valid url
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'pagerduty://****@****/m...e/m...t?', 'privacy_url': 'pagerduty://****@****/m...e/m...t?',
}), }),
('pagerduty://routekey@apikey/ms/mc?group=mygroup&class=myclass', { ('pagerduty://routekey@apikey/ms/mc?group=mygroup&class=myclass', {
# class/group testing # class/group testing
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
}), }),
('pagerduty://?integrationkey=r&apikey=a&source=s&component=c' ('pagerduty://?integrationkey=r&apikey=a&source=s&component=c'
'&group=g&class=c&image=no&click=http://localhost', { '&group=g&class=c&image=no&click=http://localhost', {
# all parameters # all parameters
'instance': plugins.NotifyPagerDuty}), 'instance': NotifyPagerDuty}),
('pagerduty://somerkey@someapikey/bizzare/code', { ('pagerduty://somerkey@someapikey/bizzare/code', {
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('pagerduty://myroutekey@myapikey/mysource/mycomponent', { ('pagerduty://myroutekey@myapikey/mysource/mycomponent', {
'instance': plugins.NotifyPagerDuty, 'instance': NotifyPagerDuty,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyParsePlatform import NotifyParsePlatform
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -53,14 +54,14 @@ apprise_url_tests = (
}), }),
# app_id + master_key (using arguments=) # app_id + master_key (using arguments=)
('parseps://localhost?app_id=%s&master_key=%s' % ('a' * 32, 'd' * 32), { ('parseps://localhost?app_id=%s&master_key=%s' % ('a' * 32, 'd' * 32), {
'instance': plugins.NotifyParsePlatform, 'instance': NotifyParsePlatform,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'parseps://a...a:d...d@localhost', 'privacy_url': 'parseps://a...a:d...d@localhost',
}), }),
# Set a device id + custom port # Set a device id + custom port
('parsep://app_id:master_key@localhost:8080?device=ios', { ('parsep://app_id:master_key@localhost:8080?device=ios', {
'instance': plugins.NotifyParsePlatform, 'instance': NotifyParsePlatform,
}), }),
# invalid device id # invalid device id
('parsep://app_id:master_key@localhost?device=invalid', { ('parsep://app_id:master_key@localhost?device=invalid', {
@ -68,22 +69,22 @@ apprise_url_tests = (
}), }),
# Normal Query # Normal Query
('parseps://app_id:master_key@localhost', { ('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform, 'instance': NotifyParsePlatform,
}), }),
('parseps://app_id:master_key@localhost', { ('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform, 'instance': NotifyParsePlatform,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('parseps://app_id:master_key@localhost', { ('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform, 'instance': NotifyParsePlatform,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('parseps://app_id:master_key@localhost', { ('parseps://app_id:master_key@localhost', {
'instance': plugins.NotifyParsePlatform, 'instance': NotifyParsePlatform,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins from apprise.plugins.NotifyPopcornNotify import NotifyPopcornNotify
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -42,40 +42,40 @@ apprise_url_tests = (
}), }),
('popcorn://{}/1232348923489234923489234289-32423'.format('a' * 9), { ('popcorn://{}/1232348923489234923489234289-32423'.format('a' * 9), {
# invalid phone number # invalid phone number
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
'notify_response': False, 'notify_response': False,
}), }),
('popcorn://{}/abc'.format('b' * 9), { ('popcorn://{}/abc'.format('b' * 9), {
# invalid email # invalid email
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
'notify_response': False, 'notify_response': False,
}), }),
('popcorn://{}/15551232000/user@example.com'.format('c' * 9), { ('popcorn://{}/15551232000/user@example.com'.format('c' * 9), {
# value phone and email # value phone and email
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
}), }),
('popcorn://{}/15551232000/user@example.com?batch=yes'.format('w' * 9), { ('popcorn://{}/15551232000/user@example.com?batch=yes'.format('w' * 9), {
# value phone and email with batch mode set # value phone and email with batch mode set
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
}), }),
('popcorn://{}/?to=15551232000'.format('w' * 9), { ('popcorn://{}/?to=15551232000'.format('w' * 9), {
# reference to to= # reference to to=
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
}), }),
('popcorn://{}/15551232000'.format('x' * 9), { ('popcorn://{}/15551232000'.format('x' * 9), {
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('popcorn://{}/15551232000'.format('y' * 9), { ('popcorn://{}/15551232000'.format('y' * 9), {
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('popcorn://{}/15551232000'.format('z' * 9), { ('popcorn://{}/15551232000'.format('z' * 9), {
'instance': plugins.NotifyPopcornNotify, 'instance': NotifyPopcornNotify,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,8 @@
# THE SOFTWARE. # THE SOFTWARE.
import pytest import pytest
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyRyver import NotifyRyver
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -54,57 +55,57 @@ apprise_url_tests = (
('ryver://apprise/ckhrjW8w672m6HG?mode=slack', { ('ryver://apprise/ckhrjW8w672m6HG?mode=slack', {
# No username specified; this is still okay as we use whatever # No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our slack mode # the user told the webhook to use; set our slack mode
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
}), }),
('ryver://apprise/ckhrjW8w672m6HG?mode=ryver', { ('ryver://apprise/ckhrjW8w672m6HG?mode=ryver', {
# No username specified; this is still okay as we use whatever # No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our ryver mode # the user told the webhook to use; set our ryver mode
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
}), }),
# Legacy webhook mode setting: # Legacy webhook mode setting:
# Legacy webhook mode setting: # Legacy webhook mode setting:
('ryver://apprise/ckhrjW8w672m6HG?webhook=slack', { ('ryver://apprise/ckhrjW8w672m6HG?webhook=slack', {
# No username specified; this is still okay as we use whatever # No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our slack mode # the user told the webhook to use; set our slack mode
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
}), }),
('ryver://apprise/ckhrjW8w672m6HG?webhook=ryver', { ('ryver://apprise/ckhrjW8w672m6HG?webhook=ryver', {
# No username specified; this is still okay as we use whatever # No username specified; this is still okay as we use whatever
# the user told the webhook to use; set our ryver mode # the user told the webhook to use; set our ryver mode
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'ryver://apprise/c...G', 'privacy_url': 'ryver://apprise/c...G',
}), }),
# Support Native URLs # Support Native URLs
('https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG', { ('https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
}), }),
# Support Native URLs with arguments # Support Native URLs with arguments
('https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG' ('https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG'
'?webhook=ryver', '?webhook=ryver',
{ {
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
}), }),
('ryver://caronc@apprise/ckhrjW8w672m6HG', { ('ryver://caronc@apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
('ryver://apprise/ckhrjW8w672m6HG', { ('ryver://apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('ryver://apprise/ckhrjW8w672m6HG', { ('ryver://apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('ryver://apprise/ckhrjW8w672m6HG', { ('ryver://apprise/ckhrjW8w672m6HG', {
'instance': plugins.NotifyRyver, 'instance': NotifyRyver,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -130,14 +131,14 @@ def test_plugin_ryver_edge_cases(no_throttling):
# No token # No token
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyRyver(organization="abc", token=None) NotifyRyver(organization="abc", token=None)
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyRyver(organization="abc", token=" ") NotifyRyver(organization="abc", token=" ")
# No organization # No organization
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyRyver(organization=None, token="abc") NotifyRyver(organization=None, token="abc")
with pytest.raises(TypeError): 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 pytest
import requests import requests
from apprise import plugins
from apprise.plugins.NotifySendGrid import NotifySendGrid
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -59,54 +60,54 @@ apprise_url_tests = (
('sendgrid://abcd:user@example.com', { ('sendgrid://abcd:user@example.com', {
# No To/Target Address(es) specified; so we sub in the same From # No To/Target Address(es) specified; so we sub in the same From
# address # address
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
}), }),
('sendgrid://abcd:user@example.com/newuser@example.com', { ('sendgrid://abcd:user@example.com/newuser@example.com', {
# A good email # A good email
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
}), }),
('sendgrid://abcd:user@example.com/newuser@example.com' ('sendgrid://abcd:user@example.com/newuser@example.com'
'?bcc=l2g@nuxref.com', { '?bcc=l2g@nuxref.com', {
# A good email with Blind Carbon Copy # A good email with Blind Carbon Copy
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
}), }),
('sendgrid://abcd:user@example.com/newuser@example.com' ('sendgrid://abcd:user@example.com/newuser@example.com'
'?cc=l2g@nuxref.com', { '?cc=l2g@nuxref.com', {
# A good email with Carbon Copy # A good email with Carbon Copy
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
}), }),
('sendgrid://abcd:user@example.com/newuser@example.com' ('sendgrid://abcd:user@example.com/newuser@example.com'
'?to=l2g@nuxref.com', { '?to=l2g@nuxref.com', {
# A good email with Carbon Copy # A good email with Carbon Copy
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
}), }),
('sendgrid://abcd:user@example.com/newuser@example.com' ('sendgrid://abcd:user@example.com/newuser@example.com'
'?template={}'.format(UUID4), { '?template={}'.format(UUID4), {
# A good email with a template + no substitutions # A good email with a template + no substitutions
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
}), }),
('sendgrid://abcd:user@example.com/newuser@example.com' ('sendgrid://abcd:user@example.com/newuser@example.com'
'?template={}&+sub=value&+sub2=value2'.format(UUID4), { '?template={}&+sub=value&+sub2=value2'.format(UUID4), {
# A good email with a template + substitutions # A good email with a template + substitutions
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'sendgrid://a...d:user@example.com/', 'privacy_url': 'sendgrid://a...d:user@example.com/',
}), }),
('sendgrid://abcd:user@example.ca/newuser@example.ca', { ('sendgrid://abcd:user@example.ca/newuser@example.ca', {
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('sendgrid://abcd:user@example.uk/newuser@example.uk', { ('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 # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('sendgrid://abcd:user@example.au/newuser@example.au', { ('sendgrid://abcd:user@example.au/newuser@example.au', {
'instance': plugins.NotifySendGrid, 'instance': NotifySendGrid,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -134,25 +135,25 @@ def test_plugin_sendgrid_edge_cases(mock_post, mock_get, no_throttling):
# no apikey # no apikey
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifySendGrid( NotifySendGrid(
apikey=None, from_email='user@example.com') apikey=None, from_email='user@example.com')
# invalid from email # invalid from email
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifySendGrid( NotifySendGrid(
apikey='abcd', from_email='!invalid') apikey='abcd', from_email='!invalid')
# no email # no email
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifySendGrid(apikey='abcd', from_email=None) NotifySendGrid(apikey='abcd', from_email=None)
# Invalid To email address # Invalid To email address
plugins.NotifySendGrid( NotifySendGrid(
apikey='abcd', from_email='user@example.com', targets="!invalid") apikey='abcd', from_email='user@example.com', targets="!invalid")
# Test invalid bcc/cc entries mixed with good ones # Test invalid bcc/cc entries mixed with good ones
assert isinstance(plugins.NotifySendGrid( assert isinstance(NotifySendGrid(
apikey='abcd', apikey='abcd',
from_email='l2g@example.com', from_email='l2g@example.com',
bcc=('abc@def.com', '!invalid'), 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, # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
from apprise import plugins from apprise.plugins.NotifyServerChan import NotifyServerChan
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -41,19 +41,19 @@ apprise_url_tests = (
}), }),
('schan://12345678', { ('schan://12345678', {
# access token # access token
'instance': plugins.NotifyServerChan, 'instance': NotifyServerChan,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'schan://1...8', 'privacy_url': 'schan://1...8',
}), }),
('schan://{}'.format('a' * 8), { ('schan://{}'.format('a' * 8), {
'instance': plugins.NotifyServerChan, 'instance': NotifyServerChan,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('schan://{}'.format('a' * 8), { ('schan://{}'.format('a' * 8), {
'instance': plugins.NotifyServerChan, 'instance': NotifyServerChan,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,10 +29,10 @@ from unittest import mock
import requests import requests
from json import dumps from json import dumps
from apprise import plugins
from apprise import Apprise from apprise import Apprise
from apprise import AppriseAttachment from apprise import AppriseAttachment
from apprise import NotifyType from apprise import NotifyType
from apprise.plugins.NotifySparkPost import NotifySparkPost
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -64,7 +64,7 @@ apprise_url_tests = (
}), }),
# No To email address, but everything else is valid # No To email address, but everything else is valid
('sparkpost://user@localhost.localdomain/{}'.format('c' * 32), { ('sparkpost://user@localhost.localdomain/{}'.format('c' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -75,7 +75,7 @@ apprise_url_tests = (
}), }),
('sparkpost://user@localhost.localdomain/{}?format=markdown' ('sparkpost://user@localhost.localdomain/{}?format=markdown'
.format('d' * 32), { .format('d' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -86,7 +86,7 @@ apprise_url_tests = (
}), }),
('sparkpost://user@localhost.localdomain/{}?format=html' ('sparkpost://user@localhost.localdomain/{}?format=html'
.format('d' * 32), { .format('d' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -97,7 +97,7 @@ apprise_url_tests = (
}), }),
('sparkpost://user@localhost.localdomain/{}?format=text' ('sparkpost://user@localhost.localdomain/{}?format=text'
.format('d' * 32), { .format('d' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -108,7 +108,7 @@ apprise_url_tests = (
}), }),
# valid url with region specified (case insensitve) # valid url with region specified (case insensitve)
('sparkpost://user@localhost.localdomain/{}?region=uS'.format('d' * 32), { ('sparkpost://user@localhost.localdomain/{}?region=uS'.format('d' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -119,7 +119,7 @@ apprise_url_tests = (
}), }),
# valid url with region specified (case insensitve) # valid url with region specified (case insensitve)
('sparkpost://user@localhost.localdomain/{}?region=EU'.format('e' * 32), { ('sparkpost://user@localhost.localdomain/{}?region=EU'.format('e' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -131,7 +131,7 @@ apprise_url_tests = (
# headers # headers
('sparkpost://user@localhost.localdomain/{}' ('sparkpost://user@localhost.localdomain/{}'
'?+X-Customer-Campaign-ID=Apprise'.format('f' * 32), { '?+X-Customer-Campaign-ID=Apprise'.format('f' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -143,7 +143,7 @@ apprise_url_tests = (
# template tokens # template tokens
('sparkpost://user@localhost.localdomain/{}' ('sparkpost://user@localhost.localdomain/{}'
'?:name=Chris&:status=admin'.format('g' * 32), { '?:name=Chris&:status=admin'.format('g' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -155,7 +155,7 @@ apprise_url_tests = (
# bcc and cc # bcc and cc
('sparkpost://user@localhost.localdomain/{}' ('sparkpost://user@localhost.localdomain/{}'
'?bcc=user@example.com&cc=user2@example.com'.format('h' * 32), { '?bcc=user@example.com&cc=user2@example.com'.format('h' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -172,7 +172,7 @@ apprise_url_tests = (
# One 'To' Email address # One 'To' Email address
('sparkpost://user@localhost.localdomain/{}/test@example.com'.format( ('sparkpost://user@localhost.localdomain/{}/test@example.com'.format(
'a' * 32), { 'a' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -184,7 +184,7 @@ apprise_url_tests = (
# Invalid 'To' Email address # Invalid 'To' Email address
('sparkpost://user@localhost.localdomain/{}/invalid'.format( ('sparkpost://user@localhost.localdomain/{}/invalid'.format(
'i' * 32), { 'i' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
# Expected notify() response # Expected notify() response
'notify_response': False, 'notify_response': False,
}), }),
@ -194,7 +194,7 @@ apprise_url_tests = (
'/'.join(('user1@example.com', 'invalid', 'User2:user2@example.com')), '/'.join(('user1@example.com', 'invalid', 'User2:user2@example.com')),
','.join(('user3@example.com', 'i@v', 'User1:user1@example.com')), ','.join(('user3@example.com', 'i@v', 'User1:user1@example.com')),
','.join(('user4@example.com', 'g@r@b', 'Da:user5@example.com'))), { ','.join(('user4@example.com', 'g@r@b', 'Da:user5@example.com'))), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -205,7 +205,7 @@ apprise_url_tests = (
}), }),
('sparkpost://user@localhost.localdomain/' ('sparkpost://user@localhost.localdomain/'
'{}?to=test@example.com'.format('k' * 32), { '{}?to=test@example.com'.format('k' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -217,7 +217,7 @@ apprise_url_tests = (
# One To Email address, a from name specified too # One To Email address, a from name specified too
('sparkpost://user@localhost.localdomain/{}/' ('sparkpost://user@localhost.localdomain/{}/'
'test@example.com?name="Frodo"'.format('l' * 32), { 'test@example.com?name="Frodo"'.format('l' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': { 'requests_response_text': {
"results": { "results": {
"total_rejected_recipients": 0, "total_rejected_recipients": 0,
@ -228,23 +228,23 @@ apprise_url_tests = (
}), }),
# Test invalid JSON response # Test invalid JSON response
('sparkpost://user@localhost.localdomain/{}'.format('m' * 32), { ('sparkpost://user@localhost.localdomain/{}'.format('m' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
'requests_response_text': "{", 'requests_response_text': "{",
}), }),
('sparkpost://user@localhost.localdomain/{}'.format('n' * 32), { ('sparkpost://user@localhost.localdomain/{}'.format('n' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('sparkpost://user@localhost.localdomain/{}'.format('o' * 32), { ('sparkpost://user@localhost.localdomain/{}'.format('o' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('sparkpost://user@localhost.localdomain/{}'.format('p' * 32), { ('sparkpost://user@localhost.localdomain/{}'.format('p' * 32), {
'instance': plugins.NotifySparkPost, 'instance': NotifySparkPost,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 NotifySparkPost.sparkpost_retry_wait_sec = 0.1
plugins.NotifySparkPost.sparkpost_retry_attempts = 3 NotifySparkPost.sparkpost_retry_attempts = 3
# API Key # API Key
apikey = 'abc123' 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 # Exception should be thrown about the fact no user was specified
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifySparkPost( NotifySparkPost(
apikey=apikey, targets=targets, host=host) apikey=apikey, targets=targets, host=host)
# Exception should be thrown about the fact no private key was specified # Exception should be thrown about the fact no private key was specified
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifySparkPost( NotifySparkPost(
apikey=None, targets=targets, user=user, host=host) apikey=None, targets=targets, user=user, host=host)
okay_response = requests.Request() okay_response = requests.Request()
@ -317,7 +317,7 @@ def test_plugin_sparkpost_throttling(mock_post, no_throttling):
obj = Apprise.instantiate( obj = Apprise.instantiate(
'sparkpost://user@localhost.localdomain/{}'.format(apikey)) '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 # We'll successfully perform the notification as we're within
# our retry limit # our retry limit
@ -337,8 +337,8 @@ def test_plugin_sparkpost_attachments(mock_post, no_throttling):
NotifySparkPost() Attachments NotifySparkPost() Attachments
""" """
plugins.NotifySparkPost.sparkpost_retry_wait_sec = 0.1 NotifySparkPost.sparkpost_retry_wait_sec = 0.1
plugins.NotifySparkPost.sparkpost_retry_attempts = 3 NotifySparkPost.sparkpost_retry_attempts = 3
okay_response = requests.Request() okay_response = requests.Request()
okay_response.status_code = requests.codes.ok okay_response.status_code = requests.codes.ok
@ -358,7 +358,7 @@ def test_plugin_sparkpost_attachments(mock_post, no_throttling):
obj = Apprise.instantiate( obj = Apprise.instantiate(
'sparkpost://user@localhost.localdomain/{}'.format(apikey)) 'sparkpost://user@localhost.localdomain/{}'.format(apikey))
assert isinstance(obj, plugins.NotifySparkPost) assert isinstance(obj, NotifySparkPost)
# Test Valid Attachment # Test Valid Attachment
path = os.path.join(TEST_VAR_DIR, 'apprise-test.gif') 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( obj = Apprise.instantiate(
'sparkpost://no-reply@example.com/{}/' 'sparkpost://no-reply@example.com/{}/'
'user1@example.com/user2@example.com?batch=yes'.format(apikey)) '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 # Force our batch to break into separate messages
obj.default_batch_size = 1 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise.plugins.NotifySpontit import NotifySpontit
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -50,26 +51,26 @@ apprise_url_tests = (
}), }),
# Provide a valid user and API Key # Provide a valid user and API Key
('spontit://%s@%s' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'spontit://{}@b...b/'.format('u' * 11), 'privacy_url': 'spontit://{}@b...b/'.format('u' * 11),
}), }),
# Provide a valid user and API Key, but provide an invalid channel # Provide a valid user and API Key, but provide an invalid channel
('spontit://%s@%s/#!!' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s/#!!' % ('u' * 11, 'b' * 100), {
# An instance is still created, but the channel won't be notified # 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 # Provide a valid user, API Key and a valid channel
('spontit://%s@%s/#abcd' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s/#abcd' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
}), }),
# Provide a valid user, API Key, and a subtitle # Provide a valid user, API Key, and a subtitle
('spontit://%s@%s/?subtitle=Test' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s/?subtitle=Test' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
}), }),
# Provide a valid user, API Key, and a lengthy subtitle # Provide a valid user, API Key, and a lengthy subtitle
('spontit://%s@%s/?subtitle=%s' % ('u' * 11, 'b' * 100, 'c' * 300), { ('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 # Provide a valid user and API Key, but provide a valid channel (that is
# not ours). # not ours).
@ -77,30 +78,30 @@ apprise_url_tests = (
# specifying channel entries. For Apprise we need to encode this # specifying channel entries. For Apprise we need to encode this
# so we convert the slash (/) into %2F # so we convert the slash (/) into %2F
('spontit://{}@{}/#1245%2Fabcd'.format('u' * 11, 'b' * 100), { ('spontit://{}@{}/#1245%2Fabcd'.format('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
}), }),
# Provide multipe channels # Provide multipe channels
('spontit://{}@{}/#1245%2Fabcd/defg'.format('u' * 11, 'b' * 100), { ('spontit://{}@{}/#1245%2Fabcd/defg'.format('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
}), }),
# Provide multipe channels through the use of the to= variable # Provide multipe channels through the use of the to= variable
('spontit://{}@{}/?to=#1245/abcd'.format('u' * 11, 'b' * 100), { ('spontit://{}@{}/?to=#1245/abcd'.format('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
}), }),
('spontit://%s@%s' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('spontit://%s@%s' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('spontit://%s@%s' % ('u' * 11, 'b' * 100), { ('spontit://%s@%s' % ('u' * 11, 'b' * 100), {
'instance': plugins.NotifySpontit, 'instance': NotifySpontit,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

@ -32,6 +32,9 @@ import socket
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
import logging import logging
from apprise.plugins.NotifySyslog import NotifySyslog
logging.disable(logging.CRITICAL) logging.disable(logging.CRITICAL)
@ -43,9 +46,9 @@ def test_plugin_syslog_by_url(openlog, syslog):
""" """
# an invalid URL # an invalid URL
assert apprise.plugins.NotifySyslog.parse_url(object) is None assert NotifySyslog.parse_url(object) is None
assert apprise.plugins.NotifySyslog.parse_url(42) is None assert NotifySyslog.parse_url(42) is None
assert apprise.plugins.NotifySyslog.parse_url(None) is None assert NotifySyslog.parse_url(None) is None
obj = apprise.Apprise.instantiate('syslog://') obj = apprise.Apprise.instantiate('syslog://')
assert obj.url().startswith('syslog://user') is True assert obj.url().startswith('syslog://user') is True
@ -55,10 +58,10 @@ def test_plugin_syslog_by_url(openlog, syslog):
assert isinstance( assert isinstance(
apprise.Apprise.instantiate( apprise.Apprise.instantiate(
'syslog://:@/'), apprise.plugins.NotifySyslog) 'syslog://:@/'), NotifySyslog)
obj = apprise.Apprise.instantiate('syslog://?logpid=no&logperror=yes') 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 obj.url().startswith('syslog://user') is True
assert re.search(r'logpid=no', obj.url()) is not None assert re.search(r'logpid=no', obj.url()) is not None
assert re.search(r'logperror=yes', 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 assert obj.notify("body", notify_type='invalid') is False
obj = apprise.Apprise.instantiate('syslog://_/?facility=local5') 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 obj.url().startswith('syslog://local5') is True
assert re.search(r'logpid=yes', obj.url()) is not None assert re.search(r'logpid=yes', obj.url()) is not None
assert re.search(r'logperror=no', 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 # j will cause a search to take place and match to daemon
obj = apprise.Apprise.instantiate('syslog://_/?facility=d') 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 obj.url().startswith('syslog://daemon') is True
assert re.search(r'logpid=yes', obj.url()) is not None assert re.search(r'logpid=yes', obj.url()) is not None
assert re.search(r'logperror=no', 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 # Facility can also be specified on the url as a hostname
obj = apprise.Apprise.instantiate('syslog://kern?logpid=no&logperror=y') 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 obj.url().startswith('syslog://kern') is True
assert re.search(r'logpid=no', obj.url()) is not None assert re.search(r'logpid=no', obj.url()) is not None
assert re.search(r'logperror=yes', 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 # Facilities specified as an argument always over-ride host
obj = apprise.Apprise.instantiate('syslog://kern?facility=d') 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 obj.url().startswith('syslog://daemon') is True
assert re.search(r'syslog://.*mode=local', obj.url()) assert re.search(r'syslog://.*mode=local', obj.url())
@ -113,8 +116,8 @@ def test_plugin_syslog_edge_cases(openlog, syslog):
""" """
# Default # Default
obj = apprise.plugins.NotifySyslog(facility=None) obj = NotifySyslog(facility=None)
assert isinstance(obj, apprise.plugins.NotifySyslog) assert isinstance(obj, NotifySyslog)
assert obj.url().startswith('syslog://user') is True assert obj.url().startswith('syslog://user') is True
assert re.search(r'logpid=yes', obj.url()) is not None assert re.search(r'logpid=yes', obj.url()) is not None
assert re.search(r'logperror=no', 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 # Exception should be thrown about the fact no bot token was specified
with pytest.raises(TypeError): with pytest.raises(TypeError):
apprise.plugins.NotifySyslog(facility='invalid') NotifySyslog(facility='invalid')
with pytest.raises(TypeError): with pytest.raises(TypeError):
apprise.plugins.NotifySyslog(facility=object) NotifySyslog(facility=object)
@mock.patch('syslog.syslog') @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 # localhost does not lookup to any of the facility codes so this
# gets interpreted as a host # gets interpreted as a host
obj = apprise.Apprise.instantiate('syslog://localhost') 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 obj.url().startswith('syslog://localhost') is True
assert re.search(r'syslog://.*mode=remote', obj.url()) assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None assert re.search(r'logpid=yes', obj.url()) is not None
@ -160,7 +163,7 @@ def test_plugin_syslog_remote(
# Test with port # Test with port
obj = apprise.Apprise.instantiate('syslog://localhost:518') 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 obj.url().startswith('syslog://localhost:518') is True
assert re.search(r'syslog://.*mode=remote', obj.url()) assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None assert re.search(r'logpid=yes', obj.url()) is not None
@ -168,7 +171,7 @@ def test_plugin_syslog_remote(
# Test with default port # Test with default port
obj = apprise.Apprise.instantiate('syslog://localhost:514') 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 obj.url().startswith('syslog://localhost') is True
assert re.search(r'syslog://.*mode=remote', obj.url()) assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None assert re.search(r'logpid=yes', obj.url()) is not None
@ -176,7 +179,7 @@ def test_plugin_syslog_remote(
# Specify a facility # Specify a facility
obj = apprise.Apprise.instantiate('syslog://localhost/kern') 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 obj.url().startswith('syslog://localhost/kern') is True
assert re.search(r'syslog://.*mode=remote', obj.url()) assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None 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 # Specify a facility requiring a lookup and having the port identified
# resolves any ambiguity # resolves any ambiguity
obj = apprise.Apprise.instantiate('syslog://kern:514/d') 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 obj.url().startswith('syslog://kern/daemon') is True
assert re.search(r'syslog://.*mode=remote', obj.url()) assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=yes', obj.url()) is not None 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 # 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' # to also remove ambiguity; this falls back to sending as the 'user'
obj = apprise.Apprise.instantiate('syslog://kern/d?mode=remote&logpid=no') 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 obj.url().startswith('syslog://kern/daemon') is True
assert re.search(r'syslog://.*mode=remote', obj.url()) assert re.search(r'syslog://.*mode=remote', obj.url())
assert re.search(r'logpid=no', obj.url()) is not None 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise.plugins.NotifyTechulusPush import NotifyTechulusPush
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -45,7 +46,7 @@ apprise_url_tests = (
}), }),
# APIkey # APIkey
('push://%s' % UUID4, { ('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush, 'instance': NotifyTechulusPush,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'push://8...2/', 'privacy_url': 'push://8...2/',
@ -55,19 +56,19 @@ apprise_url_tests = (
'instance': TypeError, 'instance': TypeError,
}), }),
('push://%s' % UUID4, { ('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush, 'instance': NotifyTechulusPush,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('push://%s' % UUID4, { ('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush, 'instance': NotifyTechulusPush,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('push://%s' % UUID4, { ('push://%s' % UUID4, {
'instance': plugins.NotifyTechulusPush, 'instance': NotifyTechulusPush,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,

View File

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

View File

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

View File

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

View File

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

View File

@ -27,7 +27,8 @@ from unittest import mock
import pytest import pytest
import requests import requests
from json import dumps from json import dumps
from apprise import plugins
from apprise.plugins.NotifyVonage import NotifyVonage
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -63,7 +64,7 @@ apprise_url_tests = (
('vonage://AC{}:{}@{}/123/{}/abcd/'.format( ('vonage://AC{}:{}@{}/123/{}/abcd/'.format(
'f' * 8, 'g' * 16, '3' * 11, '9' * 15), { 'f' * 8, 'g' * 16, '3' * 11, '9' * 15), {
# valid everything but target numbers # valid everything but target numbers
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'vonage://A...f:****@', 'privacy_url': 'vonage://A...f:****@',
@ -71,31 +72,31 @@ apprise_url_tests = (
('vonage://AC{}:{}@{}'.format('h' * 8, 'i' * 16, '5' * 11), { ('vonage://AC{}:{}@{}'.format('h' * 8, 'i' * 16, '5' * 11), {
# using phone no with no target - we text ourselves in # using phone no with no target - we text ourselves in
# this case # this case
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
}), }),
('vonage://_?key=AC{}&secret={}&from={}'.format( ('vonage://_?key=AC{}&secret={}&from={}'.format(
'a' * 8, 'b' * 16, '5' * 11), { 'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing # use get args to acomplish the same thing
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
}), }),
('vonage://_?key=AC{}&secret={}&source={}'.format( ('vonage://_?key=AC{}&secret={}&source={}'.format(
'a' * 8, 'b' * 16, '5' * 11), { 'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing (use source instead of from) # 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( ('vonage://_?key=AC{}&secret={}&from={}&to={}'.format(
'a' * 8, 'b' * 16, '5' * 11, '7' * 13), { 'a' * 8, 'b' * 16, '5' * 11, '7' * 13), {
# use to= # use to=
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
}), }),
('vonage://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), { ('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 # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('vonage://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), { ('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 # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -129,7 +130,7 @@ apprise_url_tests = (
('nexmo://AC{}:{}@{}/123/{}/abcd/'.format( ('nexmo://AC{}:{}@{}/123/{}/abcd/'.format(
'f' * 8, 'g' * 16, '3' * 11, '9' * 15), { 'f' * 8, 'g' * 16, '3' * 11, '9' * 15), {
# valid everything but target numbers # valid everything but target numbers
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'vonage://A...f:****@', 'privacy_url': 'vonage://A...f:****@',
@ -137,31 +138,31 @@ apprise_url_tests = (
('nexmo://AC{}:{}@{}'.format('h' * 8, 'i' * 16, '5' * 11), { ('nexmo://AC{}:{}@{}'.format('h' * 8, 'i' * 16, '5' * 11), {
# using phone no with no target - we text ourselves in # using phone no with no target - we text ourselves in
# this case # this case
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
}), }),
('nexmo://_?key=AC{}&secret={}&from={}'.format( ('nexmo://_?key=AC{}&secret={}&from={}'.format(
'a' * 8, 'b' * 16, '5' * 11), { 'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing # use get args to acomplish the same thing
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
}), }),
('nexmo://_?key=AC{}&secret={}&source={}'.format( ('nexmo://_?key=AC{}&secret={}&source={}'.format(
'a' * 8, 'b' * 16, '5' * 11), { 'a' * 8, 'b' * 16, '5' * 11), {
# use get args to acomplish the same thing (use source instead of from) # 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( ('nexmo://_?key=AC{}&secret={}&from={}&to={}'.format(
'a' * 8, 'b' * 16, '5' * 11, '7' * 13), { 'a' * 8, 'b' * 16, '5' * 11, '7' * 13), {
# use to= # use to=
'instance': plugins.NotifyVonage, 'instance': NotifyVonage,
}), }),
('nexmo://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), { ('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 # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('nexmo://AC{}:{}@{}'.format('a' * 8, 'b' * 16, '6' * 11), { ('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 # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -200,17 +201,17 @@ def test_plugin_vonage_edge_cases(mock_post, no_throttling):
# No apikey specified # No apikey specified
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=None, secret=secret, source=source) NotifyVonage(apikey=None, secret=secret, source=source)
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=" ", secret=secret, source=source) NotifyVonage(apikey=" ", secret=secret, source=source)
# No secret specified # No secret specified
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=apikey, secret=None, source=source) NotifyVonage(apikey=apikey, secret=None, source=source)
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyVonage(apikey=apikey, secret=" ", source=source) NotifyVonage(apikey=apikey, secret=" ", source=source)
# a error response # a error response
response.status_code = 400 response.status_code = 400
@ -221,7 +222,7 @@ def test_plugin_vonage_edge_cases(mock_post, no_throttling):
mock_post.return_value = response mock_post.return_value = response
# Initialize our object # Initialize our object
obj = plugins.NotifyVonage( obj = NotifyVonage(
apikey=apikey, secret=secret, source=source) apikey=apikey, secret=secret, source=source)
# We will fail with the above error code # 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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins from apprise.plugins.NotifyWebexTeams import NotifyWebexTeams
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -44,7 +44,7 @@ apprise_url_tests = (
}), }),
('wxteams://{}'.format('a' * 80), { ('wxteams://{}'.format('a' * 80), {
# token provided - we're good # token provided - we're good
'instance': plugins.NotifyWebexTeams, 'instance': NotifyWebexTeams,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'wxteams://a...a/', 'privacy_url': 'wxteams://a...a/',
@ -52,28 +52,28 @@ apprise_url_tests = (
# Support Native URLs # Support Native URLs
('https://api.ciscospark.com/v1/webhooks/incoming/{}'.format('a' * 80), { ('https://api.ciscospark.com/v1/webhooks/incoming/{}'.format('a' * 80), {
# token provided - we're good # token provided - we're good
'instance': plugins.NotifyWebexTeams, 'instance': NotifyWebexTeams,
}), }),
# Support Native URLs with arguments # Support Native URLs with arguments
('https://api.ciscospark.com/v1/webhooks/incoming/{}?format=text'.format( ('https://api.ciscospark.com/v1/webhooks/incoming/{}?format=text'.format(
'a' * 80), { 'a' * 80), {
# token provided - we're good # token provided - we're good
'instance': plugins.NotifyWebexTeams, 'instance': NotifyWebexTeams,
}), }),
('wxteams://{}'.format('a' * 80), { ('wxteams://{}'.format('a' * 80), {
'instance': plugins.NotifyWebexTeams, 'instance': NotifyWebexTeams,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('wxteams://{}'.format('a' * 80), { ('wxteams://{}'.format('a' * 80), {
'instance': plugins.NotifyWebexTeams, 'instance': NotifyWebexTeams,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('wxteams://{}'.format('a' * 80), { ('wxteams://{}'.format('a' * 80), {
'instance': plugins.NotifyWebexTeams, 'instance': NotifyWebexTeams,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import requests import requests
from apprise import plugins
from apprise import NotifyType from apprise import NotifyType
from apprise.plugins.NotifyXBMC import NotifyXBMC
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -40,63 +40,63 @@ apprise_url_tests = (
'instance': None, 'instance': None,
}), }),
('kodi://localhost', { ('kodi://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodi://192.168.4.1', { ('kodi://192.168.4.1', {
# Support IPv4 Addresses # Support IPv4 Addresses
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]', { ('kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]', {
# Support IPv6 Addresses # Support IPv6 Addresses
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Privacy URL # Privacy URL
'privacy_url': 'kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]', 'privacy_url': 'kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]',
}), }),
('kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]:8282', { ('kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]:8282', {
# Support IPv6 Addresses with port # Support IPv6 Addresses with port
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Privacy URL # Privacy URL
'privacy_url': 'kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]:8282', 'privacy_url': 'kodi://[2001:db8:002a:3256:adfe:05c0:0003:0006]:8282',
}), }),
('kodi://user:pass@localhost', { ('kodi://user:pass@localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'kodi://user:****@localhost', 'privacy_url': 'kodi://user:****@localhost',
}), }),
('kodi://localhost:8080', { ('kodi://localhost:8080', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodi://user:pass@localhost:8080', { ('kodi://user:pass@localhost:8080', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodis://localhost', { ('kodis://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodis://user:pass@localhost', { ('kodis://user:pass@localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodis://localhost:8080/path/', { ('kodis://localhost:8080/path/', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('kodis://user:password@localhost:8080', { ('kodis://user:password@localhost:8080', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'kodis://user:****@localhost:8080', 'privacy_url': 'kodis://user:****@localhost:8080',
}), }),
('kodi://localhost', { ('kodi://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Experement with different notification types # Experement with different notification types
'notify_type': NotifyType.WARNING, 'notify_type': NotifyType.WARNING,
}), }),
('kodi://localhost', { ('kodi://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Experement with different notification types # Experement with different notification types
'notify_type': NotifyType.FAILURE, 'notify_type': NotifyType.FAILURE,
}), }),
('kodis://localhost:443', { ('kodis://localhost:443', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
@ -104,19 +104,19 @@ apprise_url_tests = (
'instance': None, 'instance': None,
}), }),
('kodi://user:pass@localhost:8081', { ('kodi://user:pass@localhost:8081', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('kodi://user:pass@localhost:8082', { ('kodi://user:pass@localhost:8082', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('kodi://user:pass@localhost:8083', { ('kodi://user:pass@localhost:8083', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -130,38 +130,38 @@ apprise_url_tests = (
'instance': None, 'instance': None,
}), }),
('xbmc://localhost', { ('xbmc://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://localhost?duration=14', { ('xbmc://localhost?duration=14', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://localhost?duration=invalid', { ('xbmc://localhost?duration=invalid', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://localhost?duration=-1', { ('xbmc://localhost?duration=-1', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://user:pass@localhost', { ('xbmc://user:pass@localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://localhost:8080', { ('xbmc://localhost:8080', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://user:pass@localhost:8080', { ('xbmc://user:pass@localhost:8080', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
}), }),
('xbmc://user@localhost', { ('xbmc://user@localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
('xbmc://localhost', { ('xbmc://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Experement with different notification types # Experement with different notification types
'notify_type': NotifyType.WARNING, 'notify_type': NotifyType.WARNING,
}), }),
('xbmc://localhost', { ('xbmc://localhost', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Experement with different notification types # Experement with different notification types
'notify_type': NotifyType.FAILURE, 'notify_type': NotifyType.FAILURE,
}), }),
@ -169,19 +169,19 @@ apprise_url_tests = (
'instance': None, 'instance': None,
}), }),
('xbmc://user:pass@localhost:8081', { ('xbmc://user:pass@localhost:8081', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('xbmc://user:pass@localhost:8082', { ('xbmc://user:pass@localhost:8082', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('xbmc://user:pass@localhost:8083', { ('xbmc://user:pass@localhost:8083', {
'instance': plugins.NotifyXBMC, 'instance': NotifyXBMC,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, '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 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
import pytest import pytest
from apprise import plugins
import requests import requests
from apprise.plugins.NotifyZulip import NotifyZulip
from helpers import AppriseURLTester from helpers import AppriseURLTester
# Disable logging for a cleaner testing output # Disable logging for a cleaner testing output
@ -57,52 +58,52 @@ apprise_url_tests = (
}), }),
# Valid everything - botname with a dash # Valid everything - botname with a dash
('zulip://bot-name@apprise/{}'.format('a' * 32), { ('zulip://bot-name@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
'privacy_url': 'zulip://bot-name@apprise/a...a/', 'privacy_url': 'zulip://bot-name@apprise/a...a/',
}), }),
# Valid everything - no target so default is used # Valid everything - no target so default is used
('zulip://botname@apprise/{}'.format('a' * 32), { ('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
# Our expected url(privacy=True) startswith() response: # Our expected url(privacy=True) startswith() response:
'privacy_url': 'zulip://botname@apprise/a...a/', 'privacy_url': 'zulip://botname@apprise/a...a/',
}), }),
# Valid everything - organization as hostname # Valid everything - organization as hostname
('zulip://botname@apprise.zulipchat.com/{}'.format('a' * 32), { ('zulip://botname@apprise.zulipchat.com/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
}), }),
# Valid everything - 2 streams specified # Valid everything - 2 streams specified
('zulip://botname@apprise/{}/channel1/channel2'.format('a' * 32), { ('zulip://botname@apprise/{}/channel1/channel2'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
}), }),
# Valid everything - 2 streams specified (using to=) # Valid everything - 2 streams specified (using to=)
('zulip://botname@apprise/{}/?to=channel1/channel2'.format('a' * 32), { ('zulip://botname@apprise/{}/?to=channel1/channel2'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
}), }),
# Valid everything - 2 emails specified # Valid everything - 2 emails specified
('zulip://botname@apprise/{}/user@example.com/user2@example.com'.format( ('zulip://botname@apprise/{}/user@example.com/user2@example.com'.format(
'a' * 32), { 'a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
}), }),
('zulip://botname@apprise/{}'.format('a' * 32), { ('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
# don't include an image by default # don't include an image by default
'include_image': False, 'include_image': False,
}), }),
('zulip://botname@apprise/{}'.format('a' * 32), { ('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
# force a failure # force a failure
'response': False, 'response': False,
'requests_response_code': requests.codes.internal_server_error, 'requests_response_code': requests.codes.internal_server_error,
}), }),
('zulip://botname@apprise/{}'.format('a' * 32), { ('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
# throw a bizzare code forcing us to fail to look it up # throw a bizzare code forcing us to fail to look it up
'response': False, 'response': False,
'requests_response_code': 999, 'requests_response_code': 999,
}), }),
('zulip://botname@apprise/{}'.format('a' * 32), { ('zulip://botname@apprise/{}'.format('a' * 32), {
'instance': plugins.NotifyZulip, 'instance': NotifyZulip,
# Throws a series of connection and transfer exceptions when this flag # Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them # is set and tests that we gracfully handle them
'test_requests_exceptions': True, 'test_requests_exceptions': True,
@ -131,5 +132,5 @@ def test_plugin_zulip_edge_cases(no_throttling):
# Invalid organization # Invalid organization
with pytest.raises(TypeError): with pytest.raises(TypeError):
plugins.NotifyZulip( NotifyZulip(
botname='test', organization='#', token=token) botname='test', organization='#', token=token)