mirror of https://github.com/caronc/apprise
smpp dependency cleanup and test case prep
parent
875c8349fe
commit
52a53d6f33
|
@ -14,3 +14,6 @@ paho-mqtt != 2.0.*
|
||||||
|
|
||||||
# Pretty Good Privacy (PGP) Provides mailto:// and deltachat:// support
|
# Pretty Good Privacy (PGP) Provides mailto:// and deltachat:// support
|
||||||
PGPy
|
PGPy
|
||||||
|
|
||||||
|
# Provides smpp:// support
|
||||||
|
python-smpp
|
||||||
|
|
|
@ -28,9 +28,18 @@
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
import smpplib
|
try:
|
||||||
import smpplib.consts
|
import smpplib
|
||||||
import smpplib.gsm
|
import smpplib.consts
|
||||||
|
import smpplib.gsm
|
||||||
|
|
||||||
|
# We're good to go!
|
||||||
|
NOTIFY_SMPP_ENABLED = True
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
# cryptography is required in order for this package to work
|
||||||
|
NOTIFY_SMPP_ENABLED = False
|
||||||
|
|
||||||
|
|
||||||
from .base import NotifyBase
|
from .base import NotifyBase
|
||||||
from ..common import NotifyType
|
from ..common import NotifyType
|
||||||
|
@ -38,18 +47,29 @@ from ..locale import gettext_lazy as _
|
||||||
from ..utils.parse import is_phone_no, parse_phone_no
|
from ..utils.parse import is_phone_no, parse_phone_no
|
||||||
|
|
||||||
|
|
||||||
class NotifySmpp(NotifyBase):
|
class NotifySMPP(NotifyBase):
|
||||||
"""
|
"""
|
||||||
A wrapper for SMPP Notifications
|
A wrapper for SMPP Notifications
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Set our global enabled flag
|
||||||
|
enabled = NOTIFY_SMPP_ENABLED
|
||||||
|
|
||||||
|
requirements = {
|
||||||
|
# Define our required packaging in order to work
|
||||||
|
'packages_required': 'python-snpp'
|
||||||
|
}
|
||||||
|
|
||||||
# The default descriptive name associated with the Notification
|
# The default descriptive name associated with the Notification
|
||||||
service_name = _('SMPP')
|
service_name = _('SMPP')
|
||||||
|
|
||||||
# The services URL
|
# The services URL
|
||||||
service_url = 'https://smpp.org/'
|
service_url = 'https://smpp.org/'
|
||||||
|
|
||||||
|
# The default protocol
|
||||||
protocol = 'smpp'
|
protocol = 'smpp'
|
||||||
|
|
||||||
|
# The default secure protocol
|
||||||
secure_protocol = 'smpps'
|
secure_protocol = 'smpps'
|
||||||
|
|
||||||
# A URL that takes you to the setup/help of the specific protocol
|
# A URL that takes you to the setup/help of the specific protocol
|
||||||
|
@ -175,7 +195,7 @@ class NotifySmpp(NotifyBase):
|
||||||
port=self.port,
|
port=self.port,
|
||||||
source=self.source,
|
source=self.source,
|
||||||
targets='/'.join(
|
targets='/'.join(
|
||||||
[NotifySmpp.quote(t, safe='')
|
[NotifySMPP.quote(t, safe='')
|
||||||
for t in chain(self.targets, self._invalid_targets)]),
|
for t in chain(self.targets, self._invalid_targets)]),
|
||||||
params=self.urlencode(params),
|
params=self.urlencode(params),
|
||||||
)
|
)
|
||||||
|
@ -249,27 +269,27 @@ class NotifySmpp(NotifyBase):
|
||||||
# We're done early as we couldn't load the results
|
# We're done early as we couldn't load the results
|
||||||
return results
|
return results
|
||||||
|
|
||||||
results['targets'] = NotifySmpp.split_path(results['fullpath'])
|
results['targets'] = NotifySMPP.split_path(results['fullpath'])
|
||||||
|
|
||||||
# Support the 'to' variable so that we can support targets this way too
|
# Support the 'to' variable so that we can support targets this way too
|
||||||
# 'to' makes it easier to use yaml configuration
|
# 'to' makes it easier to use yaml configuration
|
||||||
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
||||||
results['targets'] += \
|
results['targets'] += \
|
||||||
NotifySmpp.parse_phone_no(results['qsd']['to'])
|
NotifySMPP.parse_phone_no(results['qsd']['to'])
|
||||||
|
|
||||||
# store any additional payload extras defined
|
# store any additional payload extras defined
|
||||||
results['payload'] = {NotifySmpp.unquote(x): NotifySmpp.unquote(y)
|
results['payload'] = {NotifySMPP.unquote(x): NotifySMPP.unquote(y)
|
||||||
for x, y in results['qsd:'].items()}
|
for x, y in results['qsd:'].items()}
|
||||||
|
|
||||||
# Add our GET parameters in the event the user wants to pass them
|
# Add our GET parameters in the event the user wants to pass them
|
||||||
results['params'] = {NotifySmpp.unquote(x): NotifySmpp.unquote(y)
|
results['params'] = {NotifySMPP.unquote(x): NotifySMPP.unquote(y)
|
||||||
for x, y in results['qsd-'].items()}
|
for x, y in results['qsd-'].items()}
|
||||||
|
|
||||||
# Support the 'from' and 'source' variable so that we can support
|
# Support the 'from' and 'source' variable so that we can support
|
||||||
# targets this way too.
|
# targets this way too.
|
||||||
# 'from' makes it easier to use yaml configuration
|
# 'from' makes it easier to use yaml configuration
|
||||||
if 'from' in results['qsd'] and len(results['qsd']['from']):
|
if 'from' in results['qsd'] and len(results['qsd']['from']):
|
||||||
results['source'] = NotifySmpp.unquote(results['qsd']['from'])
|
results['source'] = NotifySMPP.unquote(results['qsd']['from'])
|
||||||
elif results['targets']:
|
elif results['targets']:
|
||||||
# from phone number is the first entry in the list otherwise
|
# from phone number is the first entry in the list otherwise
|
||||||
results['source'] = results['targets'].pop(0)
|
results['source'] = results['targets'].pop(0)
|
||||||
|
|
|
@ -27,13 +27,11 @@
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from json import dumps
|
import sys
|
||||||
from unittest import mock
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import requests
|
from apprise import Apprise
|
||||||
|
from apprise.plugins.smpp import NotifySMPP
|
||||||
from apprise.plugins.smpp import NotifySmpp
|
|
||||||
from helpers import AppriseURLTester
|
from helpers import AppriseURLTester
|
||||||
|
|
||||||
logging.disable(logging.CRITICAL)
|
logging.disable(logging.CRITICAL)
|
||||||
|
@ -66,32 +64,32 @@ apprise_url_tests = (
|
||||||
}),
|
}),
|
||||||
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, 'a' * 32), {
|
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, 'a' * 32), {
|
||||||
# valid everything but target numbers
|
# valid everything but target numbers
|
||||||
'instance': NotifySmpp,
|
'instance': NotifySMPP,
|
||||||
# We have no one to notify
|
# We have no one to notify
|
||||||
'notify_response': False,
|
'notify_response': False,
|
||||||
}),
|
}),
|
||||||
('smpp://user:pass@host:port/{}'.format('1' * 10), {
|
('smpp://user:pass@host:port/{}'.format('1' * 10), {
|
||||||
# everything valid
|
# everything valid
|
||||||
'instance': NotifySmpp,
|
'instance': NotifySMPP,
|
||||||
# We have no one to notify
|
# We have no one to notify
|
||||||
'notify_response': False,
|
'notify_response': False,
|
||||||
}),
|
}),
|
||||||
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10), {
|
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10), {
|
||||||
'instance': NotifySmpp,
|
'instance': NotifySMPP,
|
||||||
}),
|
}),
|
||||||
('smpp://_?&from={}&to={},{}'.format(
|
('smpp://_?&from={}&to={},{}'.format(
|
||||||
'1' * 10, '1' * 10, '1' * 10), {
|
'1' * 10, '1' * 10, '1' * 10), {
|
||||||
# use get args to accomplish the same thing
|
# use get args to accomplish the same thing
|
||||||
'instance': NotifySmpp,
|
'instance': NotifySMPP,
|
||||||
}),
|
}),
|
||||||
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10), {
|
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10), {
|
||||||
'instance': NotifySmpp,
|
'instance': NotifySMPP,
|
||||||
# throw a bizarre code forcing us to fail to look it up
|
# throw a bizarre code forcing us to fail to look it up
|
||||||
'response': False,
|
'response': False,
|
||||||
'requests_response_code': 999,
|
'requests_response_code': 999,
|
||||||
}),
|
}),
|
||||||
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10), {
|
('smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10), {
|
||||||
'instance': NotifySmpp,
|
'instance': NotifySMPP,
|
||||||
# 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 gracefully handle them
|
# is set and tests that we gracefully handle them
|
||||||
'test_requests_exceptions': True,
|
'test_requests_exceptions': True,
|
||||||
|
@ -99,46 +97,28 @@ apprise_url_tests = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
'python-smpp' in sys.modules,
|
||||||
|
reason="Requires that python-smpp NOT be installed")
|
||||||
|
def test_plugin_fcm_cryptography_import_error():
|
||||||
|
"""
|
||||||
|
NotifySimplePush() python-smpp loading failure
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Attempt to instantiate our object
|
||||||
|
obj = Apprise.instantiate(
|
||||||
|
'smpp://user:pass@host:port/{}/{}'.format('1' * 10, '1' * 10))
|
||||||
|
|
||||||
|
# It's not possible because our cryptography depedancy is missing
|
||||||
|
assert obj is None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
'python-smpp' not in sys.modules, reason="Requires python-smpp")
|
||||||
def test_plugin_smpp_urls():
|
def test_plugin_smpp_urls():
|
||||||
"""
|
"""
|
||||||
NotifySmpp() Apprise URLs
|
NotifySMPP() Apprise URLs
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Run our general tests
|
# Run our general tests
|
||||||
AppriseURLTester(tests=apprise_url_tests).run_all()
|
AppriseURLTester(tests=apprise_url_tests).run_all()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.post')
|
|
||||||
def test_plugin_smpp_edge_cases(mock_post):
|
|
||||||
"""
|
|
||||||
NotifySmpp() Edge Cases
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Prepare our response
|
|
||||||
response = requests.Request()
|
|
||||||
response.status_code = requests.codes.ok
|
|
||||||
|
|
||||||
# Prepare Mock
|
|
||||||
mock_post.return_value = response
|
|
||||||
|
|
||||||
# Initialize some generic (but valid) apikeys
|
|
||||||
apikey = 'b' * 32
|
|
||||||
source = '+1 (555) 123-3456'
|
|
||||||
|
|
||||||
# No apikey specified
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
NotifySmpp(source=source)
|
|
||||||
|
|
||||||
# a error response
|
|
||||||
response.status_code = 400
|
|
||||||
response.content = dumps({
|
|
||||||
'code': 21211,
|
|
||||||
'message': "The 'To' number +1234567 is not a valid phone number.",
|
|
||||||
})
|
|
||||||
mock_post.return_value = response
|
|
||||||
|
|
||||||
# Initialize our object
|
|
||||||
obj = NotifySmpp(source=source)
|
|
||||||
|
|
||||||
# We will fail with the above error code
|
|
||||||
assert obj.notify('title', 'body', 'info') is False
|
|
||||||
|
|
Loading…
Reference in New Issue