mirror of
https://github.com/caronc/apprise.git
synced 2024-11-22 08:04:02 +01:00
Improved Apprise encoding and text format support (#566)
This commit is contained in:
parent
5d14259227
commit
a05b042c6d
@ -484,22 +484,43 @@ class Apprise(object):
|
|||||||
|
|
||||||
if len(self) == 0:
|
if len(self) == 0:
|
||||||
# Nothing to notify
|
# Nothing to notify
|
||||||
raise TypeError("No service(s) to notify")
|
msg = "There are service(s) to notify"
|
||||||
|
logger.error(msg)
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
if not (title or body):
|
if not (title or body):
|
||||||
raise TypeError("No message content specified to deliver")
|
msg = "No message content specified to deliver"
|
||||||
|
logger.error(msg)
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
try:
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
# Python 2.7.x Unicode Character Handling
|
# Python 2.7 encoding support isn't the greatest, so we try
|
||||||
# Ensure we're working with utf-8
|
# to ensure that we're ALWAYS dealing with unicode characters
|
||||||
if isinstance(title, unicode): # noqa: F821
|
# prior to entrying the next part. This is especially required
|
||||||
title = title.encode('utf-8')
|
# for Markdown support
|
||||||
|
if title and isinstance(title, str): # noqa: F821
|
||||||
|
title = title.decode(self.asset.encoding)
|
||||||
|
|
||||||
if isinstance(body, unicode): # noqa: F821
|
if body and isinstance(body, str): # noqa: F821
|
||||||
body = body.encode('utf-8')
|
body = body.decode(self.asset.encoding)
|
||||||
|
|
||||||
|
else: # Python 3+
|
||||||
|
if title and isinstance(title, bytes): # noqa: F821
|
||||||
|
title = title.decode(self.asset.encoding)
|
||||||
|
|
||||||
|
if body and isinstance(body, bytes): # noqa: F821
|
||||||
|
body = body.decode(self.asset.encoding)
|
||||||
|
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
msg = 'The content passed into Apprise was not of encoding ' \
|
||||||
|
'type: {}'.format(self.asset.encoding)
|
||||||
|
logger.error(msg)
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
# Tracks conversions
|
# Tracks conversions
|
||||||
conversion_map = dict()
|
conversion_body_map = dict()
|
||||||
|
conversion_title_map = dict()
|
||||||
|
|
||||||
# Prepare attachments if required
|
# Prepare attachments if required
|
||||||
if attach is not None and not isinstance(attach, AppriseAttachment):
|
if attach is not None and not isinstance(attach, AppriseAttachment):
|
||||||
@ -519,9 +540,13 @@ class Apprise(object):
|
|||||||
# If our code reaches here, we either did not define a tag (it
|
# If our code reaches here, we either did not define a tag (it
|
||||||
# was set to None), or we did define a tag and the logic above
|
# was set to None), or we did define a tag and the logic above
|
||||||
# determined we need to notify the service it's associated with
|
# determined we need to notify the service it's associated with
|
||||||
if server.notify_format not in conversion_map:
|
if server.notify_format not in conversion_body_map:
|
||||||
conversion_map[server.notify_format] = convert_between(
|
# Perform Conversion
|
||||||
body_format, server.notify_format, body)
|
(conversion_title_map[server.notify_format],
|
||||||
|
conversion_body_map[server.notify_format]) = \
|
||||||
|
convert_between(
|
||||||
|
body_format, server.notify_format, body=body,
|
||||||
|
title=title)
|
||||||
|
|
||||||
if interpret_escapes:
|
if interpret_escapes:
|
||||||
#
|
#
|
||||||
@ -531,8 +556,13 @@ class Apprise(object):
|
|||||||
try:
|
try:
|
||||||
# Added overhead required due to Python 3 Encoding Bug
|
# Added overhead required due to Python 3 Encoding Bug
|
||||||
# identified here: https://bugs.python.org/issue21331
|
# identified here: https://bugs.python.org/issue21331
|
||||||
conversion_map[server.notify_format] = \
|
conversion_body_map[server.notify_format] = \
|
||||||
conversion_map[server.notify_format]\
|
conversion_body_map[server.notify_format]\
|
||||||
|
.encode('ascii', 'backslashreplace')\
|
||||||
|
.decode('unicode-escape')
|
||||||
|
|
||||||
|
conversion_title_map[server.notify_format] = \
|
||||||
|
conversion_title_map[server.notify_format]\
|
||||||
.encode('ascii', 'backslashreplace')\
|
.encode('ascii', 'backslashreplace')\
|
||||||
.decode('unicode-escape')
|
.decode('unicode-escape')
|
||||||
|
|
||||||
@ -540,39 +570,43 @@ class Apprise(object):
|
|||||||
# This occurs using a very old verion of Python 2.7
|
# This occurs using a very old verion of Python 2.7
|
||||||
# such as the one that ships with CentOS/RedHat 7.x
|
# such as the one that ships with CentOS/RedHat 7.x
|
||||||
# (v2.7.5).
|
# (v2.7.5).
|
||||||
conversion_map[server.notify_format] = \
|
conversion_body_map[server.notify_format] = \
|
||||||
conversion_map[server.notify_format] \
|
conversion_body_map[server.notify_format] \
|
||||||
|
.decode('string_escape')
|
||||||
|
|
||||||
|
conversion_title_map[server.notify_format] = \
|
||||||
|
conversion_title_map[server.notify_format] \
|
||||||
.decode('string_escape')
|
.decode('string_escape')
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Must be of string type
|
# Must be of string type
|
||||||
logger.error('Failed to escape message body')
|
msg = 'Failed to escape message body'
|
||||||
raise TypeError
|
logger.error(msg)
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
if title:
|
if six.PY2:
|
||||||
try:
|
# Python 2.7 strings must be encoded as utf-8 for
|
||||||
# Added overhead required due to Python 3 Encoding
|
# consistency across all platforms
|
||||||
# Bug identified here:
|
if conversion_title_map[server.notify_format] and \
|
||||||
# https://bugs.python.org/issue21331
|
isinstance(
|
||||||
title = title\
|
conversion_title_map[server.notify_format],
|
||||||
.encode('ascii', 'backslashreplace')\
|
unicode): # noqa: F821
|
||||||
.decode('unicode-escape')
|
conversion_title_map[server.notify_format] = \
|
||||||
|
conversion_title_map[server.notify_format]\
|
||||||
|
.encode('utf-8')
|
||||||
|
|
||||||
except UnicodeDecodeError: # pragma: no cover
|
if conversion_body_map[server.notify_format] and \
|
||||||
# This occurs using a very old verion of Python 2.7
|
isinstance(
|
||||||
# such as the one that ships with CentOS/RedHat 7.x
|
conversion_body_map[server.notify_format],
|
||||||
# (v2.7.5).
|
unicode): # noqa: F821
|
||||||
title = title.decode('string_escape')
|
conversion_body_map[server.notify_format] = \
|
||||||
|
conversion_body_map[server.notify_format]\
|
||||||
except AttributeError:
|
.encode('utf-8')
|
||||||
# Must be of string type
|
|
||||||
logger.error('Failed to escape message title')
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
yield handler(
|
yield handler(
|
||||||
server,
|
server,
|
||||||
body=conversion_map[server.notify_format],
|
body=conversion_body_map[server.notify_format],
|
||||||
title=title,
|
title=conversion_title_map[server.notify_format],
|
||||||
notify_type=notify_type,
|
notify_type=notify_type,
|
||||||
attach=attach
|
attach=attach
|
||||||
)
|
)
|
||||||
|
@ -29,6 +29,7 @@ from os.path import join
|
|||||||
from os.path import dirname
|
from os.path import dirname
|
||||||
from os.path import isfile
|
from os.path import isfile
|
||||||
from os.path import abspath
|
from os.path import abspath
|
||||||
|
from locale import getpreferredencoding
|
||||||
from .common import NotifyType
|
from .common import NotifyType
|
||||||
|
|
||||||
|
|
||||||
@ -110,6 +111,9 @@ class AppriseAsset(object):
|
|||||||
# to a new line.
|
# to a new line.
|
||||||
interpret_escapes = False
|
interpret_escapes = False
|
||||||
|
|
||||||
|
# Defines the encoding of the content passed into Apprise
|
||||||
|
encoding = getpreferredencoding()
|
||||||
|
|
||||||
# For more detail see CWE-312 @
|
# For more detail see CWE-312 @
|
||||||
# https://cwe.mitre.org/data/definitions/312.html
|
# https://cwe.mitre.org/data/definitions/312.html
|
||||||
#
|
#
|
||||||
|
@ -36,25 +36,51 @@ else:
|
|||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
|
|
||||||
|
|
||||||
def convert_between(from_format, to_format, body):
|
def convert_between(from_format, to_format, body, title=None):
|
||||||
"""
|
"""
|
||||||
Converts between different notification formats. If no conversion exists,
|
Converts between different notification formats. If no conversion exists,
|
||||||
or the selected one fails, the original text will be returned.
|
or the selected one fails, the original text will be returned.
|
||||||
|
|
||||||
|
This function returns a tuple as (title, body)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
converters = {
|
converters = {
|
||||||
(NotifyFormat.MARKDOWN, NotifyFormat.HTML): markdown,
|
(NotifyFormat.MARKDOWN, NotifyFormat.HTML): markdown_to_html,
|
||||||
(NotifyFormat.TEXT, NotifyFormat.HTML): text_to_html,
|
(NotifyFormat.TEXT, NotifyFormat.HTML): text_to_html,
|
||||||
(NotifyFormat.HTML, NotifyFormat.TEXT): html_to_text,
|
(NotifyFormat.HTML, NotifyFormat.TEXT): html_to_text,
|
||||||
# For now; use same converter for Markdown support
|
# For now; use same converter for Markdown support
|
||||||
(NotifyFormat.HTML, NotifyFormat.MARKDOWN): html_to_text,
|
(NotifyFormat.HTML, NotifyFormat.MARKDOWN): html_to_text,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if NotifyFormat.MARKDOWN in (from_format, to_format):
|
||||||
|
# Tidy any exising pre-formating configuration
|
||||||
|
title = '' if not title else title.lstrip('\r\n \t\v\b*#-')
|
||||||
|
|
||||||
|
else:
|
||||||
|
title = '' if not title else title
|
||||||
|
|
||||||
convert = converters.get((from_format, to_format))
|
convert = converters.get((from_format, to_format))
|
||||||
return convert(body) if convert is not None else body
|
title, body = convert(title=title, body=body) \
|
||||||
|
if convert is not None else (title, body)
|
||||||
|
|
||||||
|
return (title, body)
|
||||||
|
|
||||||
|
|
||||||
def text_to_html(body):
|
def markdown_to_html(body, title=None):
|
||||||
|
"""
|
||||||
|
Handle Markdown conversions
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
# Title
|
||||||
|
'' if not title else markdown(title),
|
||||||
|
|
||||||
|
# Body
|
||||||
|
markdown(body),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def text_to_html(body, title=None):
|
||||||
"""
|
"""
|
||||||
Converts a notification body from plain text to HTML.
|
Converts a notification body from plain text to HTML.
|
||||||
"""
|
"""
|
||||||
@ -86,11 +112,19 @@ def text_to_html(body):
|
|||||||
|
|
||||||
# Execute our map against our body in addition to
|
# Execute our map against our body in addition to
|
||||||
# swapping out new lines and replacing them with <br/>
|
# swapping out new lines and replacing them with <br/>
|
||||||
return re.sub(
|
return (
|
||||||
r'\r*\n', '<br/>\n', re_table.sub(lambda x: re_map[x.group()], body))
|
# Title; swap whitespace with space
|
||||||
|
'' if not title else re.sub(
|
||||||
|
r'[\r\n]+', ' ', re_table.sub(
|
||||||
|
lambda x: re_map[x.group()], title)),
|
||||||
|
|
||||||
|
# Body Formatting
|
||||||
|
re.sub(
|
||||||
|
r'\r*\n', '<br/>\n', re_table.sub(
|
||||||
|
lambda x: re_map[x.group()], body)))
|
||||||
|
|
||||||
|
|
||||||
def html_to_text(body):
|
def html_to_text(body, title=None):
|
||||||
"""
|
"""
|
||||||
Converts a notification body from HTML to plain text.
|
Converts a notification body from HTML to plain text.
|
||||||
"""
|
"""
|
||||||
@ -100,11 +134,20 @@ def html_to_text(body):
|
|||||||
# Python 2.7 requires an additional parsing to un-escape characters
|
# Python 2.7 requires an additional parsing to un-escape characters
|
||||||
body = parser.unescape(body)
|
body = parser.unescape(body)
|
||||||
|
|
||||||
|
if title:
|
||||||
|
if six.PY2:
|
||||||
|
# Python 2.7 requires an additional parsing to un-escape characters
|
||||||
|
title = parser.unescape(title)
|
||||||
|
|
||||||
|
parser.feed(title)
|
||||||
|
parser.close()
|
||||||
|
title = parser.converted
|
||||||
|
|
||||||
parser.feed(body)
|
parser.feed(body)
|
||||||
parser.close()
|
parser.close()
|
||||||
result = parser.converted
|
body = parser.converted
|
||||||
|
|
||||||
return result
|
return ('' if not title else title, body)
|
||||||
|
|
||||||
|
|
||||||
class HTMLConverter(HTMLParser, object):
|
class HTMLConverter(HTMLParser, object):
|
||||||
|
@ -93,6 +93,9 @@ class NotifyTelegram(NotifyBase):
|
|||||||
# 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
|
||||||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_telegram'
|
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_telegram'
|
||||||
|
|
||||||
|
# Default Notify Format
|
||||||
|
notify_format = NotifyFormat.HTML
|
||||||
|
|
||||||
# Telegram uses the http protocol with JSON requests
|
# Telegram uses the http protocol with JSON requests
|
||||||
notify_url = 'https://api.telegram.org/bot'
|
notify_url = 'https://api.telegram.org/bot'
|
||||||
|
|
||||||
@ -543,12 +546,11 @@ class NotifyTelegram(NotifyBase):
|
|||||||
payload['parse_mode'] = 'MARKDOWN'
|
payload['parse_mode'] = 'MARKDOWN'
|
||||||
|
|
||||||
payload['text'] = '{}{}'.format(
|
payload['text'] = '{}{}'.format(
|
||||||
'{}\r\n'.format(title) if title else '',
|
'# {}\r\n'.format(title) if title else '',
|
||||||
body,
|
body,
|
||||||
)
|
)
|
||||||
|
|
||||||
else: # HTML or TEXT
|
else: # TEXT or HTML
|
||||||
|
|
||||||
# Use Telegram's HTML mode
|
# Use Telegram's HTML mode
|
||||||
payload['parse_mode'] = 'HTML'
|
payload['parse_mode'] = 'HTML'
|
||||||
|
|
||||||
@ -592,6 +594,7 @@ class NotifyTelegram(NotifyBase):
|
|||||||
mo.string[mo.start():mo.end()][1:5]], title)
|
mo.string[mo.start():mo.end()][1:5]], title)
|
||||||
|
|
||||||
if self.notify_format == NotifyFormat.TEXT:
|
if self.notify_format == NotifyFormat.TEXT:
|
||||||
|
# Further html escaping required...
|
||||||
telegram_escape_text_dict = {
|
telegram_escape_text_dict = {
|
||||||
# We need to escape characters that conflict with html
|
# We need to escape characters that conflict with html
|
||||||
# entity blocks (< and >) when displaying text
|
# entity blocks (< and >) when displaying text
|
||||||
@ -615,8 +618,9 @@ class NotifyTelegram(NotifyBase):
|
|||||||
lambda mo: telegram_escape_text_dict[
|
lambda mo: telegram_escape_text_dict[
|
||||||
mo.string[mo.start():mo.end()]], title)
|
mo.string[mo.start():mo.end()]], title)
|
||||||
|
|
||||||
|
# prepare our payload based on HTML or TEXT
|
||||||
payload['text'] = '{}{}'.format(
|
payload['text'] = '{}{}'.format(
|
||||||
'<b>{}</b>\r\n'.format(title) if title else '',
|
'<h1>{}</h1>'.format(title) if title else '',
|
||||||
body,
|
body,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -250,6 +250,11 @@ def apprise_test(do_notify):
|
|||||||
assert do_notify(a, title='', body=None) is False
|
assert do_notify(a, title='', body=None) is False
|
||||||
assert do_notify(a, title=None, body='') is False
|
assert do_notify(a, title=None, body='') is False
|
||||||
|
|
||||||
|
assert do_notify(a, title=5, body=b'bytes') is False
|
||||||
|
assert do_notify(a, title=b"bytes", body=10) is False
|
||||||
|
assert do_notify(a, title=object(), body=b'bytes') is False
|
||||||
|
assert do_notify(a, title=b"bytes", body=object()) is False
|
||||||
|
|
||||||
# As long as one is present, we're good
|
# As long as one is present, we're good
|
||||||
assert do_notify(a, title=None, body='present') is True
|
assert do_notify(a, title=None, body='present') is True
|
||||||
assert do_notify(a, title='present', body=None) is True
|
assert do_notify(a, title='present', body=None) is True
|
||||||
|
@ -40,7 +40,7 @@ def test_html_to_text():
|
|||||||
"""
|
"""
|
||||||
A function to simply html conversion tests
|
A function to simply html conversion tests
|
||||||
"""
|
"""
|
||||||
return convert_between(NotifyFormat.HTML, NotifyFormat.TEXT, body)
|
return convert_between(NotifyFormat.HTML, NotifyFormat.TEXT, body)[1]
|
||||||
|
|
||||||
assert to_html("No HTML code here.") == "No HTML code here."
|
assert to_html("No HTML code here.") == "No HTML code here."
|
||||||
|
|
||||||
|
@ -183,10 +183,37 @@ def test_apprise_escaping_py3(mock_post):
|
|||||||
title=object(), body=False, interpret_escapes=True) is False
|
title=object(), body=False, interpret_escapes=True) is False
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
title=False, body=object(), interpret_escapes=True) is False
|
title=False, body=object(), interpret_escapes=True) is False
|
||||||
|
|
||||||
|
# We support bytes
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
title=b'byte title', body=b'byte body',
|
title=b'byte title', body=b'byte body',
|
||||||
|
interpret_escapes=True) is True
|
||||||
|
|
||||||
|
# However they're escaped as 'utf-8' by default unless we tell Apprise
|
||||||
|
# otherwise
|
||||||
|
# Now test hebrew types (outside of default utf-8)
|
||||||
|
# כותרת נפלאה translates to 'A wonderful title'
|
||||||
|
# זו הודעה translates to 'This is a notification'
|
||||||
|
title = 'כותרת נפלאה'.encode('ISO-8859-8')
|
||||||
|
body = '[_[זו הודעה](http://localhost)_'.encode('ISO-8859-8')
|
||||||
|
assert a.notify(
|
||||||
|
title=title, body=body,
|
||||||
interpret_escapes=True) is False
|
interpret_escapes=True) is False
|
||||||
|
|
||||||
|
# However if we let Apprise know in advance the encoding, it will handle
|
||||||
|
# it for us
|
||||||
|
asset = apprise.AppriseAsset(encoding='ISO-8859-8')
|
||||||
|
a = apprise.Apprise(asset=asset)
|
||||||
|
# Create ourselves a test object to work with
|
||||||
|
a.add('json://localhost')
|
||||||
|
assert a.notify(
|
||||||
|
title=title, body=body,
|
||||||
|
interpret_escapes=True) is True
|
||||||
|
|
||||||
|
# We'll restore our configuration back to how it was now
|
||||||
|
a = apprise.Apprise()
|
||||||
|
a.add('json://localhost')
|
||||||
|
|
||||||
# The body is proessed first, so the errors thrown above get tested on
|
# The body is proessed first, so the errors thrown above get tested on
|
||||||
# the body only. Now we run similar tests but only make the title
|
# the body only. Now we run similar tests but only make the title
|
||||||
# bad and always mark the body good
|
# bad and always mark the body good
|
||||||
@ -198,8 +225,9 @@ def test_apprise_escaping_py3(mock_post):
|
|||||||
title=object(), body="valid", interpret_escapes=True) is False
|
title=object(), body="valid", interpret_escapes=True) is False
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
title=False, body="valid", interpret_escapes=True) is True
|
title=False, body="valid", interpret_escapes=True) is True
|
||||||
|
# Bytes are supported
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
title=b'byte title', body="valid", interpret_escapes=True) is False
|
title=b'byte title', body="valid", interpret_escapes=True) is True
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info.major >= 3, reason="Requires Python 2.x+")
|
@pytest.mark.skipif(sys.version_info.major >= 3, reason="Requires Python 2.x+")
|
||||||
@ -311,6 +339,8 @@ def test_apprise_escaping_py2(mock_post):
|
|||||||
title=None, body=4, interpret_escapes=True) is False
|
title=None, body=4, interpret_escapes=True) is False
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
title=4, body=None, interpret_escapes=True) is False
|
title=4, body=None, interpret_escapes=True) is False
|
||||||
|
assert a.notify(
|
||||||
|
title=4, body="valid body", interpret_escapes=True) is False
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
title=object(), body=False, interpret_escapes=True) is False
|
title=object(), body=False, interpret_escapes=True) is False
|
||||||
assert a.notify(
|
assert a.notify(
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import six
|
import six
|
||||||
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
import mock
|
import mock
|
||||||
import requests
|
import requests
|
||||||
@ -34,6 +35,7 @@ from apprise import Apprise
|
|||||||
from apprise import AppriseAttachment
|
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 plugins
|
from apprise import plugins
|
||||||
from helpers import AppriseURLTester
|
from helpers import AppriseURLTester
|
||||||
|
|
||||||
@ -211,20 +213,22 @@ def test_plugin_telegram_urls():
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Disable Throttling to speed testing
|
||||||
|
plugins.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()
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.get')
|
|
||||||
@mock.patch('requests.post')
|
@mock.patch('requests.post')
|
||||||
def test_plugin_telegram_general(mock_post, mock_get):
|
def test_plugin_telegram_general(mock_post):
|
||||||
"""
|
"""
|
||||||
NotifyTelegram() General Tests
|
NotifyTelegram() General Tests
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Disable Throttling to speed testing
|
# Disable Throttling to speed testing
|
||||||
plugins.NotifyBase.request_rate_per_sec = 0
|
plugins.NotifyTelegram.request_rate_per_sec = 0
|
||||||
|
|
||||||
# Bot Token
|
# Bot Token
|
||||||
bot_token = '123456789:abcdefg_hijklmnop'
|
bot_token = '123456789:abcdefg_hijklmnop'
|
||||||
@ -234,11 +238,8 @@ def test_plugin_telegram_general(mock_post, mock_get):
|
|||||||
chat_ids = 'l2g, lead2gold'
|
chat_ids = 'l2g, lead2gold'
|
||||||
|
|
||||||
# Prepare Mock
|
# Prepare Mock
|
||||||
mock_get.return_value = requests.Request()
|
|
||||||
mock_post.return_value = requests.Request()
|
mock_post.return_value = requests.Request()
|
||||||
mock_post.return_value.status_code = requests.codes.ok
|
mock_post.return_value.status_code = requests.codes.ok
|
||||||
mock_get.return_value.status_code = requests.codes.ok
|
|
||||||
mock_get.return_value.content = '{}'
|
|
||||||
mock_post.return_value.content = '{}'
|
mock_post.return_value.content = '{}'
|
||||||
|
|
||||||
# Exception should be thrown about the fact no bot token was specified
|
# Exception should be thrown about the fact no bot token was specified
|
||||||
@ -246,20 +247,17 @@ def test_plugin_telegram_general(mock_post, mock_get):
|
|||||||
plugins.NotifyTelegram(bot_token=None, targets=chat_ids)
|
plugins.NotifyTelegram(bot_token=None, targets=chat_ids)
|
||||||
|
|
||||||
# Invalid JSON while trying to detect bot owner
|
# Invalid JSON while trying to detect bot owner
|
||||||
mock_get.return_value.content = '{'
|
|
||||||
mock_post.return_value.content = '}'
|
mock_post.return_value.content = '}'
|
||||||
obj = plugins.NotifyTelegram(bot_token=bot_token, targets=None)
|
obj = plugins.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_get.return_value.status_code = requests.codes.internal_server_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 = plugins.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
|
||||||
mock_post.return_value.status_code = requests.codes.ok
|
mock_post.return_value.status_code = requests.codes.ok
|
||||||
mock_get.return_value.status_code = requests.codes.ok
|
|
||||||
|
|
||||||
# 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
|
||||||
@ -280,9 +278,7 @@ def test_plugin_telegram_general(mock_post, mock_get):
|
|||||||
assert not obj.send_media(obj.targets[0], NotifyType.INFO)
|
assert not obj.send_media(obj.targets[0], NotifyType.INFO)
|
||||||
|
|
||||||
# Restore their entries
|
# Restore their entries
|
||||||
mock_get.side_effect = None
|
|
||||||
mock_post.side_effect = None
|
mock_post.side_effect = None
|
||||||
mock_get.return_value.content = '{}'
|
|
||||||
mock_post.return_value.content = '{}'
|
mock_post.return_value.content = '{}'
|
||||||
|
|
||||||
# test url call
|
# test url call
|
||||||
@ -304,7 +300,6 @@ def test_plugin_telegram_general(mock_post, mock_get):
|
|||||||
response.content = dumps({
|
response.content = dumps({
|
||||||
'description': 'test',
|
'description': 'test',
|
||||||
})
|
})
|
||||||
mock_get.return_value = response
|
|
||||||
mock_post.return_value = response
|
mock_post.return_value = response
|
||||||
|
|
||||||
# No image asset
|
# No image asset
|
||||||
@ -410,10 +405,9 @@ def test_plugin_telegram_general(mock_post, mock_get):
|
|||||||
assert mock_post.call_count == 1
|
assert mock_post.call_count == 1
|
||||||
payload = loads(mock_post.call_args_list[0][1]['data'])
|
payload = loads(mock_post.call_args_list[0][1]['data'])
|
||||||
|
|
||||||
# Our special characters are escaped properly
|
# Test our payload
|
||||||
assert payload['text'] == \
|
assert payload['text'] == \
|
||||||
'<b>special characters</b>\r\n<p>'\
|
'<h1>special characters</h1><p>\'"This can\'t\t\r\nfail us"\'</p>'
|
||||||
'\'"This can\'t\t\r\nfail us"\'</p>'
|
|
||||||
|
|
||||||
# Test sending attachments
|
# Test sending attachments
|
||||||
attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))
|
attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))
|
||||||
@ -545,3 +539,415 @@ def test_plugin_telegram_general(mock_post, mock_get):
|
|||||||
assert isinstance(obj, plugins.NotifyTelegram)
|
assert isinstance(obj, plugins.NotifyTelegram)
|
||||||
assert len(obj.targets) == 1
|
assert len(obj.targets) == 1
|
||||||
assert '-123456789525' in obj.targets
|
assert '-123456789525' in obj.targets
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(sys.version_info.major <= 2, reason="Requires Python 3.x+")
|
||||||
|
@mock.patch('requests.post')
|
||||||
|
def test_plugin_telegram_formating_py3(mock_post):
|
||||||
|
"""
|
||||||
|
NotifyTelegram() Python v3+ Formatting Tests
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Disable Throttling to speed testing
|
||||||
|
plugins.NotifyTelegram.request_rate_per_sec = 0
|
||||||
|
|
||||||
|
# Prepare Mock
|
||||||
|
mock_post.return_value = requests.Request()
|
||||||
|
mock_post.return_value.status_code = requests.codes.ok
|
||||||
|
mock_post.return_value.content = '{}'
|
||||||
|
|
||||||
|
# Simple success response
|
||||||
|
mock_post.return_value.content = dumps({
|
||||||
|
"ok": True,
|
||||||
|
"result": [{
|
||||||
|
"update_id": 645421321,
|
||||||
|
"message": {
|
||||||
|
"message_id": 2,
|
||||||
|
"from": {
|
||||||
|
"id": 532389719,
|
||||||
|
"is_bot": False,
|
||||||
|
"first_name": "Chris",
|
||||||
|
"language_code": "en-US"
|
||||||
|
},
|
||||||
|
"chat": {
|
||||||
|
"id": 532389719,
|
||||||
|
"first_name": "Chris",
|
||||||
|
"type": "private"
|
||||||
|
},
|
||||||
|
"date": 1519694394,
|
||||||
|
"text": "/start",
|
||||||
|
"entities": [{
|
||||||
|
"offset": 0,
|
||||||
|
"length": 6,
|
||||||
|
"type": "bot_command",
|
||||||
|
}],
|
||||||
|
}},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
mock_post.return_value.status_code = requests.codes.ok
|
||||||
|
|
||||||
|
results = plugins.NotifyTelegram.parse_url(
|
||||||
|
'tgram://123456789:abcdefg_hijklmnop/')
|
||||||
|
|
||||||
|
instance = plugins.NotifyTelegram(**results)
|
||||||
|
assert isinstance(instance, plugins.NotifyTelegram)
|
||||||
|
|
||||||
|
response = instance.send(title='title', body='body')
|
||||||
|
assert response is True
|
||||||
|
# 1 call to look up bot owner, and second for notification
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test our HTML Conversion as TEXT)
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
title = '🚨 Change detected for <i>Apprise Test Title</i>'
|
||||||
|
body = '<a href="http://localhost"><i>Apprise Body Title</i></a>' \
|
||||||
|
' had <a href="http://127.0.0.1">a change</a>'
|
||||||
|
|
||||||
|
assert aobj.notify(title=title, body=body, body_format=NotifyFormat.TEXT)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a TEXT mode
|
||||||
|
assert payload['text'] == \
|
||||||
|
'<h1>🚨 Change detected for <i>Apprise Test Title</i>' \
|
||||||
|
'</h1><a href="http://localhost"><i>Apprise Body Title' \
|
||||||
|
'</i></a> had <a href="http://127.0.0.1">a change' \
|
||||||
|
'</a>'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test our HTML Conversion as TEXT)
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/?format=html')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
assert aobj.notify(title=title, body=body, body_format=NotifyFormat.HTML)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'] == \
|
||||||
|
'<h1>🚨 Change detected for <i>Apprise Test Title</i></h1>' \
|
||||||
|
'<a href="http://localhost"><i>Apprise Body Title</i></a> had ' \
|
||||||
|
'<a href="http://127.0.0.1">a change</a>'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test our MARKDOWN Handling
|
||||||
|
title = '# 🚨 Change detected for _Apprise Test Title_'
|
||||||
|
body = '_[Apprise Body Title](http://localhost)_' \
|
||||||
|
' had [a change](http://127.0.0.1)'
|
||||||
|
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/?format=markdown')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
assert aobj.notify(
|
||||||
|
title=title, body=body, body_format=NotifyFormat.MARKDOWN)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'] == \
|
||||||
|
'# 🚨 Change detected for _Apprise Test Title_\r\n' \
|
||||||
|
'_[Apprise Body Title](http://localhost)_ had ' \
|
||||||
|
'[a change](http://127.0.0.1)'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Upstream to use HTML but input specified as Markdown
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://987654321:abcdefg_hijklmnop/?format=html')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
# HTML forced by the command line, but MARKDOWN spacified as
|
||||||
|
# upstream mode
|
||||||
|
assert aobj.notify(
|
||||||
|
title=title, body=body, body_format=NotifyFormat.MARKDOWN)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot987654321:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot987654321:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'] == \
|
||||||
|
'<h1><p>🚨 Change detected for <em>Apprise Test Title</em></p>' \
|
||||||
|
'</h1><p><em><a href="http://localhost">Apprise Body Title</a></em> ' \
|
||||||
|
'had <a href="http://127.0.0.1">a change</a></p>'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(sys.version_info.major >= 3, reason="Requires Python 2.x+")
|
||||||
|
@mock.patch('requests.post')
|
||||||
|
def test_plugin_telegram_formating_py2(mock_post):
|
||||||
|
"""
|
||||||
|
NotifyTelegram() Python v2 Formatting Tests
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Disable Throttling to speed testing
|
||||||
|
plugins.NotifyTelegram.request_rate_per_sec = 0
|
||||||
|
|
||||||
|
# Prepare Mock
|
||||||
|
mock_post.return_value = requests.Request()
|
||||||
|
mock_post.return_value.status_code = requests.codes.ok
|
||||||
|
mock_post.return_value.content = '{}'
|
||||||
|
|
||||||
|
# Simple success response
|
||||||
|
mock_post.return_value.content = dumps({
|
||||||
|
"ok": True,
|
||||||
|
"result": [{
|
||||||
|
"update_id": 645421321,
|
||||||
|
"message": {
|
||||||
|
"message_id": 2,
|
||||||
|
"from": {
|
||||||
|
"id": 532389719,
|
||||||
|
"is_bot": False,
|
||||||
|
"first_name": "Chris",
|
||||||
|
"language_code": "en-US"
|
||||||
|
},
|
||||||
|
"chat": {
|
||||||
|
"id": 532389719,
|
||||||
|
"first_name": "Chris",
|
||||||
|
"type": "private"
|
||||||
|
},
|
||||||
|
"date": 1519694394,
|
||||||
|
"text": "/start",
|
||||||
|
"entities": [{
|
||||||
|
"offset": 0,
|
||||||
|
"length": 6,
|
||||||
|
"type": "bot_command",
|
||||||
|
}],
|
||||||
|
}},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
mock_post.return_value.status_code = requests.codes.ok
|
||||||
|
|
||||||
|
results = plugins.NotifyTelegram.parse_url(
|
||||||
|
'tgram://123456789:abcdefg_hijklmnop/')
|
||||||
|
|
||||||
|
instance = plugins.NotifyTelegram(**results)
|
||||||
|
assert isinstance(instance, plugins.NotifyTelegram)
|
||||||
|
|
||||||
|
response = instance.send(title='title', body='body')
|
||||||
|
assert response is True
|
||||||
|
# 1 call to look up bot owner, and second for notification
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test our HTML Conversion as TEXT)
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
title = '🚨 Change detected for <i>Apprise Test Title</i>'
|
||||||
|
body = '<a href="http://localhost"><i>Apprise Body Title</i></a>' \
|
||||||
|
' had <a href="http://127.0.0.1">a change</a>'
|
||||||
|
|
||||||
|
assert aobj.notify(title=title, body=body, body_format=NotifyFormat.TEXT)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a TEXT mode
|
||||||
|
assert payload['text'].encode('utf-8') == \
|
||||||
|
'<h1>\xf0\x9f\x9a\xa8 Change detected for <i>' \
|
||||||
|
'Apprise Test Title</i></h1>' \
|
||||||
|
'<a href="http://localhost"><i>' \
|
||||||
|
'Apprise Body Title</i></a> had <a ' \
|
||||||
|
'href="http://127.0.0.1">a change</a>'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test our HTML Conversion as TEXT)
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/?format=html')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
assert aobj.notify(title=title, body=body, body_format=NotifyFormat.HTML)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'].encode('utf-8') == \
|
||||||
|
'<h1>\xf0\x9f\x9a\xa8 Change detected for <i>Apprise Test Title</i>' \
|
||||||
|
'</h1><a href="http://localhost"><i>Apprise Body Title</i></a> had ' \
|
||||||
|
'<a href="http://127.0.0.1">a change</a>'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test our MARKDOWN Handling
|
||||||
|
title = '# 🚨 Change detected for _Apprise Test Title_'
|
||||||
|
body = '_[Apprise Body Title](http://localhost)_' \
|
||||||
|
' had [a change](http://127.0.0.1)'
|
||||||
|
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/?format=markdown')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
assert aobj.notify(
|
||||||
|
title=title, body=body, body_format=NotifyFormat.MARKDOWN)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'].encode('utf-8') == \
|
||||||
|
'# \xf0\x9f\x9a\xa8 Change detected for _Apprise Test Title_\r\n_' \
|
||||||
|
'[Apprise Body Title](http://localhost)_ had ' \
|
||||||
|
'[a change](http://127.0.0.1)'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Upstream to use HTML but input specified as Markdown
|
||||||
|
aobj = Apprise()
|
||||||
|
aobj.add('tgram://987654321:abcdefg_hijklmnop/?format=html')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
# HTML forced by the command line, but MARKDOWN spacified as
|
||||||
|
# upstream mode
|
||||||
|
assert aobj.notify(
|
||||||
|
title=title, body=body, body_format=NotifyFormat.MARKDOWN)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot987654321:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot987654321:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'].encode('utf-8') == \
|
||||||
|
'<h1><p>\xf0\x9f\x9a\xa8 Change detected for ' \
|
||||||
|
'<em>Apprise Test Title</em></p></h1><p><em>' \
|
||||||
|
'<a href="http://localhost">Apprise Body Title</a></em>' \
|
||||||
|
' had <a href="http://127.0.0.1">a change</a></p>'
|
||||||
|
|
||||||
|
# Reset our values
|
||||||
|
mock_post.reset_mock()
|
||||||
|
|
||||||
|
# Now test hebrew types (outside of default utf-8)
|
||||||
|
# כותרת נפלאה translates to 'A wonderful title'
|
||||||
|
# זו הודעה translates to 'This is a notification'
|
||||||
|
title = 'כותרת נפלאה' \
|
||||||
|
.decode('utf-8').encode('ISO-8859-8')
|
||||||
|
body = '[_[זו הודעה](http://localhost)_' \
|
||||||
|
.decode('utf-8').encode('ISO-8859-8')
|
||||||
|
|
||||||
|
asset = AppriseAsset(encoding='utf-8')
|
||||||
|
# Now test default entries
|
||||||
|
aobj = Apprise(asset=asset)
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
# Our notification will fail because we'll have an encoding error
|
||||||
|
assert not aobj.notify(title=title, body=body)
|
||||||
|
# Nothing was even attempted to be notified
|
||||||
|
assert mock_post.call_count == 0
|
||||||
|
|
||||||
|
# Let's use the expected input
|
||||||
|
asset = AppriseAsset(encoding='ISO-8859-8')
|
||||||
|
|
||||||
|
# Now test default entries
|
||||||
|
aobj = Apprise(asset=asset)
|
||||||
|
|
||||||
|
aobj.add('tgram://123456789:abcdefg_hijklmnop/')
|
||||||
|
assert len(aobj) == 1
|
||||||
|
|
||||||
|
# Our notification will work now
|
||||||
|
assert aobj.notify(title=title, body=body)
|
||||||
|
|
||||||
|
# Test our calls
|
||||||
|
assert mock_post.call_count == 2
|
||||||
|
|
||||||
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/getUpdates'
|
||||||
|
assert mock_post.call_args_list[1][0][0] == \
|
||||||
|
'https://api.telegram.org/bot123456789:abcdefg_hijklmnop/sendMessage'
|
||||||
|
|
||||||
|
payload = loads(mock_post.call_args_list[1][1]['data'])
|
||||||
|
|
||||||
|
# Test that everything is escaped properly in a HTML mode
|
||||||
|
assert payload['text'].encode('utf-8') == \
|
||||||
|
'<h1>\xd7\x9b\xd7\x95\xd7\xaa\xd7\xa8\xd7\xaa '\
|
||||||
|
'\xd7\xa0\xd7\xa4\xd7\x9c\xd7\x90\xd7\x94</h1>[_[\xd7\x96\xd7\x95 '\
|
||||||
|
'\xd7\x94\xd7\x95\xd7\x93\xd7\xa2\xd7\x94](http://localhost)_'
|
||||||
|
Loading…
Reference in New Issue
Block a user