Пример #1
0
def test_smtplib_send_okay(mock_smtplib):
    """
    API: Test a successfully sent email

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.NotifyBase.request_rate_per_sec = 0

    # Defaults to HTML
    obj = Apprise.instantiate('mailto://*****:*****@gmail.com',
                              suppress_exceptions=False)
    assert (isinstance(obj, plugins.NotifyEmail))

    # Support an email simulation where we can correctly quit
    mock_smtplib.starttls.return_value = True
    mock_smtplib.login.return_value = True
    mock_smtplib.sendmail.return_value = True
    mock_smtplib.quit.return_value = True

    assert (obj.notify(body='body', title='test', notify_type=NotifyType.INFO)
            is True)

    # Set Text
    obj = Apprise.instantiate('mailto://*****:*****@gmail.com?format=text',
                              suppress_exceptions=False)
    assert (isinstance(obj, plugins.NotifyEmail))

    assert (obj.notify(body='body', title='test', notify_type=NotifyType.INFO)
            is True)
Пример #2
0
def test_twist_plugin_init():
    """
    API: NotifyTwist init()

    """
    try:
        plugins.NotifyTwist(email='invalid', targets=None)
        assert False
    except TypeError:
        # Invalid email address
        assert True

    try:
        plugins.NotifyTwist(email='user@domain', targets=None)
        assert False
    except TypeError:
        # No password was specified
        assert True

    # Simple object initialization
    result = plugins.NotifyTwist(password='******',
                                 email='*****@*****.**',
                                 targets=None)
    assert result.user == 'user'
    assert result.host == 'domain.com'
    assert result.password == 'abc123'

    # Channel Instantiation by name
    obj = Apprise.instantiate('twist://*****:*****@example.com/#Channel')
    assert isinstance(obj, plugins.NotifyTwist)

    # Channel Instantiation by id (faster if you know the translation)
    obj = Apprise.instantiate('twist://*****:*****@example.com/12345')
    assert isinstance(obj, plugins.NotifyTwist)

    # Invalid Channel - (max characters is 64), the below drops it
    obj = Apprise.instantiate('twist://*****:*****@example.com/{}'.format(
        'a' * 65))
    assert isinstance(obj, plugins.NotifyTwist)

    # No User detect
    result = plugins.NotifyTwist.parse_url('twist://example.com')
    assert result is None

    # test usage of to=
    result = plugins.NotifyTwist.parse_url(
        'twist://*****:*****@example.com?to=#channel')
    assert isinstance(result, dict)
    assert 'user' in result
    assert result['user'] == 'user'
    assert 'host' in result
    assert result['host'] == 'example.com'
    assert 'password' in result
    assert result['password'] == 'password'
    assert 'targets' in result
    assert isinstance(result['targets'], list) is True
    assert len(result['targets']) == 1
    assert '#channel' in result['targets']
Пример #3
0
def test_fcm_plugin(mock_post):
    """
    API: NotifyFCM() General Checks

    """
    # Valid Keyfile
    path = os.path.join(PRIVATE_KEYFILE_DIR, 'service_account.json')

    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Prepare a good response
    response = mock.Mock()
    response.content = json.dumps({
        "access_token": "ya29.c.abcd",
        "expires_in": 3599,
        "token_type": "Bearer",
    })
    response.status_code = requests.codes.ok
    mock_post.return_value = response

    # Test having a valid keyfile, but not a valid project id match
    obj = Apprise.instantiate(
        'fcm://invalid_project_id/device/?keyfile={}'.format(str(path)))
    # we'll fail as a result
    assert obj.notify("test") is False

    # Test our call count
    assert mock_post.call_count == 0

    # Now we test using a valid Project ID but we can't open our file
    obj = Apprise.instantiate(
        'fcm://mock-project-id/device/?keyfile={}'.format(str(path)))

    with mock.patch('io.open', side_effect=OSError):
        # we'll fail as a result
        assert obj.notify("test") is False

    # Test our call count
    assert mock_post.call_count == 0

    # Now we test using a valid Project ID
    obj = Apprise.instantiate(
        'fcm://mock-project-id/device/#topic/?keyfile={}'.format(str(path)))

    # we'll fail as a result
    assert obj.notify("test") is True

    # Test our call count
    assert mock_post.call_count == 3
    assert mock_post.call_args_list[0][0][0] == \
        'https://accounts.google.com/o/oauth2/token'
    assert mock_post.call_args_list[1][0][0] == \
        'https://fcm.googleapis.com/v1/projects/mock-project-id/messages:send'
    assert mock_post.call_args_list[2][0][0] == \
        'https://fcm.googleapis.com/v1/projects/mock-project-id/messages:send'
Пример #4
0
def test_smtplib_init_fail(mock_smtplib):
    """
    API: Test exception handling when calling smtplib.SMTP()

    """

    from apprise.plugins import NotifyEmailBase

    obj = Apprise.instantiate('mailto://*****:*****@gmail.com',
                              suppress_exceptions=False)
    assert (isinstance(obj, plugins.NotifyEmail))

    # Support Exception handling of smtplib.SMTP
    mock_smtplib.side_effect = TypeError('Test')

    try:
        obj.notify(title='test', body='body', notify_type=NotifyType.INFO)

        # We should have thrown an exception
        assert False

    except TypeError:
        # Exception thrown as expected
        assert True

    except Exception:
        # Un-Expected
        assert False

    # A handled and expected exception
    mock_smtplib.side_effect = smtplib.SMTPException('Test')
    assert obj.notify(title='test', body='body',
                      notify_type=NotifyType.INFO) is False
Пример #5
0
def test_email_url_escaping():
    """
    API: Test that user/passwords are properly escaped from URL

    """
    # quote(' %20')
    passwd = '%20%2520'

    # Basically we want to check that ' ' equates to %20 and % equates to %25
    # So the above translates to ' %20' (a space in front of %20).  We want
    # to verify the handling of the password escaping and when it happens.
    # a very bad response would be '  ' (double space)
    obj = plugins.NotifyEmail.parse_url(
        'mailto://*****:*****@gmail.com?format=text'.format(passwd))

    assert isinstance(obj, dict) is True
    assert 'password' in obj

    # Escaping doesn't happen at this stage because we want to leave this to
    # the plugins discretion
    assert obj.get('password') == '%20%2520'

    obj = Apprise.instantiate(
        'mailto://*****:*****@gmail.com?format=text'.format(passwd),
        suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True

    # The password is escapped 'once' at this point
    assert obj.password == ' %20'
Пример #6
0
def test_webbase_lookup(mock_smtp, mock_smtpssl):
    """
    API: Web Based Lookup Tests

    """

    # Insert a test email at the head of our table
    NotifyEmailBase.WEBBASE_LOOKUP_TABLE = (
        (
            # Testing URL
            'Testing Lookup',
            re.compile(r'^(?P<id>[^@]+)@(?P<domain>l2g\.com)$', re.I),
            {
                'port': 123,
                'smtp_host': 'smtp.l2g.com',
                'secure': True,
                'login_type': (NotifyEmailBase.WebBaseLogin.USERID, )
            },
        ), ) + NotifyEmailBase.WEBBASE_LOOKUP_TABLE

    obj = Apprise.instantiate('mailto://*****:*****@l2g.com',
                              suppress_exceptions=True)

    assert (isinstance(obj, plugins.NotifyEmail))
    assert obj.to_addr == '*****@*****.**'
    assert obj.from_addr == '*****@*****.**'
    assert obj.password == 'pass'
    assert obj.user == 'user'
    assert obj.secure is True
    assert obj.port == 123
    assert obj.smtp_host == 'smtp.l2g.com'
def test_discord_attachments(mock_post):
    """
    API: NotifyDiscord() Attachment Checks

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Initialize some generic (but valid) tokens
    webhook_id = 'C' * 24
    webhook_token = 'D' * 64

    # Prepare Mock return object
    response = mock.Mock()
    response.status_code = requests.codes.ok

    # Throw an exception on the second call to requests.post()
    mock_post.side_effect = [response, OSError()]

    # Test our markdown
    obj = Apprise.instantiate('discord://{}/{}/?format=markdown'.format(
        webhook_id, webhook_token))

    # attach our content
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # We'll fail now because of an internal exception
    assert obj.send(body="test", attach=attach) is False
def test_plugin_homeassistant_general(mock_post):
    """
    NotifyHomeAssistant() General Checks

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    response = mock.Mock()
    response.content = ''
    response.status_code = requests.codes.ok

    # Prepare Mock
    mock_post.return_value = response

    # Variation Initializations
    obj = Apprise.instantiate('hassio://localhost/accesstoken')
    assert isinstance(obj, plugins.NotifyHomeAssistant) is True
    assert isinstance(obj.url(), six.string_types) is True

    # Send Notification
    assert obj.send(body="test") is True

    assert mock_post.call_count == 1
    assert mock_post.call_args_list[0][0][0] == \
        'http://localhost:8123/api/services/persistent_notification/create'
Пример #9
0
def test_plugin_fcm_cryptography_import_error():
    """
    NotifySimplePush() Cryptography loading failure
    """

    # Attempt to instantiate our object
    obj = Apprise.instantiate('spush://{}'.format('Y' * 14))

    # It's not possible because our cryptography depedancy is missing
    assert obj is None
Пример #10
0
def test_plugin(mock_oauth, mock_api):
    """
    API: NotifyTwitter Plugin() (pt1)

    """

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        # Allow us to force the server response code to be something other then
        # the defaults
        response = meta.get(
            'response', True if response else False)

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            if instance is None:
                # Check that we got what we came for
                assert obj is instance
                continue

            assert(isinstance(obj, instance))

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert(hasattr(key, obj))
                    assert(getattr(key, obj) == val)

            # check that we're as expected
            assert obj.notify(
                title='test', body='body',
                notify_type=NotifyType.INFO) == response

        except AssertionError:
            # Don't mess with these entries
            raise

        except Exception as e:
            # Handle our exception
            assert(instance is not None)
            assert(isinstance(e, instance))
Пример #11
0
def test_email_dict_variations():
    """
    API: Test email dictionary variations to ensure parsing is correct

    """
    # Test variations of username required to be an email address
    # [email protected]
    obj = Apprise.instantiate({
        'schema': 'mailto',
        'user': '******',
        'password': '******',
        'host': 'example.com'}, suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True
Пример #12
0
def test_webbase_lookup(mock_smtp, mock_smtpssl):
    """
    API: Web Based Lookup Tests

    """

    # Insert a test email at the head of our table
    NotifyEmailBase.EMAIL_TEMPLATES = (
        (
            # Testing URL
            'Testing Lookup',
            re.compile(r'^(?P<id>[^@]+)@(?P<domain>l2g\.com)$', re.I),
            {
                'port': 123,
                'smtp_host': 'smtp.l2g.com',
                'secure': True,
                'login_type': (NotifyEmailBase.WebBaseLogin.USERID, )
            },
        ),
    ) + NotifyEmailBase.EMAIL_TEMPLATES

    obj = Apprise.instantiate(
        'mailto://*****:*****@l2g.com', suppress_exceptions=True)

    assert isinstance(obj, plugins.NotifyEmail)
    assert len(obj.targets) == 1
    assert (False, '*****@*****.**') in obj.targets
    assert obj.from_addr == '*****@*****.**'
    assert obj.password == 'pass'
    assert obj.user == 'user'
    assert obj.secure is True
    assert obj.port == 123
    assert obj.smtp_host == 'smtp.l2g.com'

    # We get the same results if an email is identified as the username
    # because the USERID variable forces that we can't use an email
    obj = Apprise.instantiate(
        'mailto://*****:*****@[email protected]', suppress_exceptions=True)
    assert obj.user == 'user'
Пример #13
0
def test_discord_attachments(mock_post):
    """
    API: NotifyDiscord() Attachment Checks

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Initialize some generic (but valid) tokens
    webhook_id = 'C' * 24
    webhook_token = 'D' * 64

    # Prepare Mock return object
    mock_post.return_value = requests.Request()
    mock_post.return_value.status_code = requests.codes.ok

    # Test our markdown
    obj = Apprise.instantiate('discord://{}/{}/?format=markdown'.format(
        webhook_id, webhook_token))

    # attach our content
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    assert obj.notify(
        body='body', title='title', notify_type=NotifyType.INFO,
        attach=attach) is True

    # An invalid attachment will cause a failure
    path = os.path.join(TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
    attach = AppriseAttachment(path)
    assert obj.notify(
        body='body', title='title', notify_type=NotifyType.INFO,
        attach=path) is False

    # Throw an exception on the second call to requests.post()
    mock_post.return_value = None
    response = mock.Mock()
    response.status_code = requests.codes.ok
    mock_post.side_effect = [response, OSError()]

    # update our attachment to be valid
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))
    # Test our markdown

    # We'll fail now because of an internal exception
    assert obj.send(body="test", attach=attach) is False
Пример #14
0
def test_plugin_ses_attachments(mock_post):
    """
    NotifySES() Attachment Checks

    """
    # Disable Throttling to speed testing
    plugins.NotifySES.request_rate_per_sec = 0

    # Prepare Mock return object
    response = mock.Mock()
    response.content = AWS_SES_GOOD_RESPONSE
    response.status_code = requests.codes.ok
    mock_post.return_value = response

    # prepare our attachment
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # Test our markdown
    obj = Apprise.instantiate('ses://%s/%s/%s/%s/' %
                              ('*****@*****.**', TEST_ACCESS_KEY_ID,
                               TEST_ACCESS_KEY_SECRET, TEST_REGION))

    # Send a good attachment
    assert obj.notify(body="test", attach=attach) is True

    # Reset our mock object
    mock_post.reset_mock()

    # Add another attachment so we drop into the area of the PushBullet code
    # that sends remaining attachments (if more detected)
    attach.add(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # Send our attachments
    assert obj.notify(body="test", attach=attach) is True

    # Test our call count
    assert mock_post.call_count == 1

    # Reset our mock object
    mock_post.reset_mock()

    # An invalid attachment will cause a failure
    path = os.path.join(TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
    attach = AppriseAttachment(path)
    assert obj.notify(body="test", attach=attach) is False
Пример #15
0
def test_smtplib_send_okay(mock_smtplib):
    """
    API: Test a successfully sent email

    """

    from apprise.plugins import NotifyEmailBase

    obj = Apprise.instantiate('mailto://*****:*****@gmail.com',
                              suppress_exceptions=False)
    assert (isinstance(obj, plugins.NotifyEmail))

    # Support an email simulation where we can correctly quit
    mock_smtplib.starttls.return_value = True
    mock_smtplib.login.return_value = True
    mock_smtplib.sendmail.return_value = True
    mock_smtplib.quit.return_value = True

    obj.notify(title='test', body='body', notify_type=NotifyType.INFO)
Пример #16
0
def test_plugin_simplepush_general(mock_post):
    """
    NotifySimplePush() General Tests
    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Prepare a good response
    response = mock.Mock()
    response.content = json.dumps({
        'status': 'OK',
    })
    response.status_code = requests.codes.ok
    mock_post.return_value = response

    obj = Apprise.instantiate('spush://{}'.format('Y' * 14))

    # Verify our content works as expected
    assert obj.notify(title="test", body="test") is True
Пример #17
0
def test_smtplib_init_fail(mock_smtplib):
    """
    API: Test exception handling when calling smtplib.SMTP()

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.NotifyBase.request_rate_per_sec = 0

    obj = Apprise.instantiate('mailto://*****:*****@gmail.com',
                              suppress_exceptions=False)
    assert (isinstance(obj, plugins.NotifyEmail))

    # Support Exception handling of smtplib.SMTP
    mock_smtplib.side_effect = RuntimeError('Test')

    assert obj.notify(body='body', title='test',
                      notify_type=NotifyType.INFO) is False

    # A handled and expected exception
    mock_smtplib.side_effect = smtplib.SMTPException('Test')
    assert obj.notify(body='body', title='test',
                      notify_type=NotifyType.INFO) is False
Пример #18
0
def test_plugin_emby_sessions(mock_post, mock_get, mock_logout, mock_login):
    """
    NotifyEmby() sessions()

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Prepare Mock
    mock_get.return_value = requests.Request()
    mock_post.return_value = requests.Request()

    # This is done so we don't obstruct our access_token and user_id values
    mock_login.return_value = True
    mock_logout.return_value = True

    obj = Apprise.instantiate('emby://*****:*****@localhost')
    assert isinstance(obj, plugins.NotifyEmby)
    obj.access_token = 'abc'
    obj.user_id = '123'

    # Test our exception handling
    for _exception in AppriseURLTester.req_exceptions:
        mock_post.side_effect = _exception
        mock_get.side_effect = _exception
        # We'll fail to log in each time
        sessions = obj.sessions()
        assert isinstance(sessions, dict) is True
        assert len(sessions) == 0

    # Disable Exceptions
    mock_post.side_effect = None
    mock_get.side_effect = None

    # Our login flat out fails if we don't have proper parseable content
    mock_post.return_value.content = u''
    mock_get.return_value.content = mock_post.return_value.content

    # KeyError handling
    mock_post.return_value.status_code = 999
    mock_get.return_value.status_code = 999
    sessions = obj.sessions()
    assert isinstance(sessions, dict) is True
    assert len(sessions) == 0

    # General Internal Server Error
    mock_post.return_value.status_code = requests.codes.internal_server_error
    mock_get.return_value.status_code = requests.codes.internal_server_error
    sessions = obj.sessions()
    assert isinstance(sessions, dict) is True
    assert len(sessions) == 0

    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

    # Disable the port completely
    obj.port = None

    sessions = obj.sessions()
    assert isinstance(sessions, dict) is True
    assert len(sessions) == 0

    # Let's get some results
    mock_post.return_value.content = dumps([
        {
            u'Id': u'abc123',
        },
        {
            u'Id': u'def456',
        },
        {
            u'InvalidEntry': None,
        },
    ])
    mock_get.return_value.content = mock_post.return_value.content

    sessions = obj.sessions(user_controlled=True)
    assert isinstance(sessions, dict) is True
    assert len(sessions) == 2

    # Test it without setting user-controlled sessions
    sessions = obj.sessions(user_controlled=False)
    assert isinstance(sessions, dict) is True
    assert len(sessions) == 2

    # Triggers an authentication failure
    obj.user_id = None
    mock_login.return_value = False
    sessions = obj.sessions()
    assert isinstance(sessions, dict) is True
    assert len(sessions) == 0
Пример #19
0
def test_smtplib_internationalization(mock_smtp):
    """
    API: Test email handling using internationalization

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Defaults to HTML
    obj = Apprise.instantiate(
        'mailto://*****:*****@gmail.com?name=Например%20так',
        suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail)

    class SMTPMock(object):
        def sendmail(self, *args, **kwargs):
            """
            over-ride sendmail calls so we can check our our
            internationalization formatting went
            """

            match_subject = re.search(
                r'\n?(?P<line>Subject: (?P<subject>(.+?)))\n(?:[a-z0-9-]+:)',
                args[2], re.I | re.M | re.S)
            assert match_subject is not None

            match_from = re.search(
                r'^(?P<line>From: (?P<name>.+) <(?P<email>[^>]+)>)$', args[2],
                re.I | re.M)
            assert match_from is not None

            # Verify our output was correctly stored
            assert match_from.group('email') == '*****@*****.**'

            if six.PY2:  # Python 2.x (backwards compatible)
                assert decode_header(match_from.group('name'))[0][0]\
                    .decode('utf-8') == u'Например так'

                assert decode_header(match_subject.group('subject'))[0][0]\
                    .decode('utf-8') == u'دعونا نجعل العالم مكانا أفضل.'

            else:  # Python 3+
                assert decode_header(match_from.group('name'))[0][0]\
                    .decode('utf-8') == 'Например так'

                assert decode_header(match_subject.group('subject'))[0][0]\
                    .decode('utf-8') == 'دعونا نجعل العالم مكانا أفضل.'

        # Dummy Function
        def quit(self, *args, **kwargs):
            return True

        # Dummy Function
        def starttls(self, *args, **kwargs):
            return True

        # Dummy Function
        def login(self, *args, **kwargs):
            return True

    # Prepare our object we will test our generated email against
    mock_smtp.return_value = SMTPMock()

    # Further test encoding through the message content as well
    assert obj.notify(
        # Google Translated to Arabic: "Let's make the world a better place."
        title='دعونا نجعل العالم مكانا أفضل.',
        # Google Translated to Hungarian: "One line of code at a time.'
        body='Egy sor kódot egyszerre.',
        notify_type=NotifyType.INFO) is True
Пример #20
0
def test_plugin(mock_refresh, mock_send):
    """
    API: NotifyPushjet Plugin() (pt1)

    """

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        # Allow us to force the server response code to be something other then
        # the defaults
        response = meta.get(
            'response', True if response else False)

        test_notify_exceptions = meta.get(
            'test_notify_exceptions', False)

        test_exceptions = (
            plugins.pushjet.errors.AccessError(
                0, 'pushjet.AccessError() not handled'),
            plugins.pushjet.errors.NonexistentError(
                0, 'pushjet.NonexistentError() not handled'),
            plugins.pushjet.errors.SubscriptionError(
                0, 'gntp.SubscriptionError() not handled'),
            plugins.pushjet.errors.RequestError(
                'pushjet.RequestError() not handled'),
        )

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            if obj is None:
                if instance is not None:
                    # We're done (assuming this is what we were expecting)
                    print("{} didn't instantiate itself "
                          "(we expected it to)".format(url))
                    assert False
                continue

            if instance is None:
                # Expected None but didn't get it
                print('%s instantiated %s (but expected None)' % (
                    url, str(obj)))
                assert(False)

            assert(isinstance(obj, instance))

            if isinstance(obj, plugins.NotifyBase):
                # We loaded okay; now lets make sure we can reverse this url
                assert(isinstance(obj.url(), six.string_types) is True)

                # Instantiate the exact same object again using the URL from
                # the one that was already created properly
                obj_cmp = Apprise.instantiate(obj.url())

                # Our object should be the same instance as what we had
                # originally expected above.
                if not isinstance(obj_cmp, plugins.NotifyBase):
                    # Assert messages are hard to trace back with the way
                    # these tests work. Just printing before throwing our
                    # assertion failure makes things easier to debug later on
                    print('TEST FAIL: {} regenerated as {}'.format(
                        url, obj.url()))
                    assert(False)

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert(hasattr(key, obj))
                    assert(getattr(key, obj) == val)

            try:
                if test_notify_exceptions is False:
                    # Store our response
                    mock_send.return_value = response
                    mock_send.side_effect = None

                    # check that we're as expected
                    assert obj.notify(
                        title='test', body='body',
                        notify_type=NotifyType.INFO) == response

                else:
                    for exception in test_exceptions:
                        mock_send.side_effect = exception
                        mock_send.return_value = None
                        try:
                            assert obj.notify(
                                title='test', body='body',
                                notify_type=NotifyType.INFO) is False

                        except AssertionError:
                            # Don't mess with these entries
                            raise

                        except Exception:
                            # We can't handle this exception type
                            raise

            except AssertionError:
                # Don't mess with these entries
                print('%s AssertionError' % url)
                raise

            except Exception as e:
                # Check that we were expecting this exception to happen
                if not isinstance(e, response):
                    raise

        except AssertionError:
            # Don't mess with these entries
            print('%s AssertionError' % url)
            raise

        except Exception as e:
            # Handle our exception
            if(instance is None):
                raise

            if not isinstance(e, instance):
                raise
Пример #21
0
def test_email_plugin(mock_smtp, mock_smtpssl):
    """
    API: NotifyEmail Plugin()

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.NotifyBase.request_rate_per_sec = 0

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        test_smtplib_exceptions = meta.get('test_smtplib_exceptions', False)

        # Our mock of our socket action
        mock_socket = mock.Mock()
        mock_socket.starttls.return_value = True
        mock_socket.login.return_value = True

        # Create a mock SMTP Object
        mock_smtp.return_value = mock_socket
        mock_smtpssl.return_value = mock_socket

        if test_smtplib_exceptions:
            # Handle exception testing; first we turn the boolean flag ito
            # a list of exceptions
            test_smtplib_exceptions = (
                smtplib.SMTPHeloError(0,
                                      'smtplib.SMTPHeloError() not handled'),
                smtplib.SMTPException(0,
                                      'smtplib.SMTPException() not handled'),
                RuntimeError(0, 'smtplib.HTTPError() not handled'),
                smtplib.SMTPRecipientsRefused(
                    'smtplib.SMTPRecipientsRefused() not handled'),
                smtplib.SMTPSenderRefused(
                    0, 'smtplib.SMTPSenderRefused() not handled',
                    '*****@*****.**'),
                smtplib.SMTPDataError(0,
                                      'smtplib.SMTPDataError() not handled'),
                smtplib.SMTPServerDisconnected(
                    'smtplib.SMTPServerDisconnected() not handled'),
            )

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            if obj is None:
                # We're done (assuming this is what we were expecting)
                assert instance is None
                continue

            if instance is None:
                # Expected None but didn't get it
                print('%s instantiated %s (but expected None)' %
                      (url, str(obj)))
                assert (False)

            assert (isinstance(obj, instance))

            if isinstance(obj, plugins.NotifyBase.NotifyBase):
                # We loaded okay; now lets make sure we can reverse this url
                assert (isinstance(obj.url(), six.string_types) is True)

                # Instantiate the exact same object again using the URL from
                # the one that was already created properly
                obj_cmp = Apprise.instantiate(obj.url())

                # Our object should be the same instance as what we had
                # originally expected above.
                if not isinstance(obj_cmp, plugins.NotifyBase.NotifyBase):
                    # Assert messages are hard to trace back with the way
                    # these tests work. Just printing before throwing our
                    # assertion failure makes things easier to debug later on
                    print('TEST FAIL: {} regenerated as {}'.format(
                        url, obj.url()))
                    assert (False)

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert (hasattr(key, obj))
                    assert (getattr(key, obj) == val)

            try:
                if test_smtplib_exceptions is False:
                    # check that we're as expected
                    assert obj.notify(title='test',
                                      body='body',
                                      notify_type=NotifyType.INFO) == response

                else:
                    for exception in test_smtplib_exceptions:
                        mock_socket.sendmail.side_effect = exception
                        try:
                            assert obj.notify(
                                title='test',
                                body='body',
                                notify_type=NotifyType.INFO) is False

                        except AssertionError:
                            # Don't mess with these entries
                            raise

                        except Exception:
                            # We can't handle this exception type
                            raise

            except AssertionError:
                # Don't mess with these entries
                print('%s AssertionError' % url)
                raise

            except Exception as e:
                # Check that we were expecting this exception to happen
                if not isinstance(e, response):
                    raise

        except AssertionError:
            # Don't mess with these entries
            print('%s AssertionError' % url)
            raise

        except Exception as e:
            # Handle our exception
            if (instance is None):
                raise

            if not isinstance(e, instance):
                raise
Пример #22
0
def test_apprise():
    """
    API: Apprise() object

    """
    # Caling load matix a second time which is an internal function causes it
    # to skip over content already loaded into our matrix and thefore accesses
    # other if/else parts of the code that aren't otherwise called
    __load_matrix()

    a = Apprise()

    # no items
    assert (len(a) == 0)

    # Create an Asset object
    asset = AppriseAsset(theme='default')

    # We can load the device using our asset
    a = Apprise(asset=asset)

    # We can load our servers up front as well
    servers = [
        'faast://abcdefghijklmnop-abcdefg',
        'kodi://kodi.server.local',
    ]

    a = Apprise(servers=servers)

    # 2 servers loaded
    assert (len(a) == 2)

    # We can retrieve our URLs this way:
    assert (len(a.urls()) == 2)

    # We can add another server
    assert (a.add('mmosts://mattermost.server.local/'
                  '3ccdd113474722377935511fc85d3dd4') is True)
    assert (len(a) == 3)

    # We can pop an object off of our stack by it's indexed value:
    obj = a.pop(0)
    assert (isinstance(obj, NotifyBase) is True)
    assert (len(a) == 2)

    # We can retrieve elements from our list too by reference:
    assert (isinstance(a[0].url(), six.string_types) is True)

    # We can iterate over our list too:
    count = 0
    for o in a:
        assert (isinstance(o.url(), six.string_types) is True)
        count += 1
    # verify that we did indeed iterate over each element
    assert (len(a) == count)

    # We can empty our set
    a.clear()
    assert (len(a) == 0)

    # An invalid schema
    assert (a.add('this is not a parseable url at all') is False)
    assert (len(a) == 0)

    # An unsupported schema
    assert (a.add('invalid://we.just.do.not.support.this.plugin.type') is
            False)
    assert (len(a) == 0)

    # A poorly formatted URL
    assert (a.add('json://user:@@@:bad?no.good') is False)
    assert (len(a) == 0)

    # Add a server with our asset we created earlier
    assert (a.add(
        'mmosts://mattermost.server.local/'
        '3ccdd113474722377935511fc85d3dd4',
        asset=asset) is True)

    # Clear our server listings again
    a.clear()

    # No servers to notify
    assert (a.notify(title="my title", body="my body") is False)

    class BadNotification(NotifyBase):
        def __init__(self, **kwargs):
            super(BadNotification, self).__init__(**kwargs)

            # We fail whenever we're initialized
            raise TypeError()

        def url(self):
            # Support URL
            return ''

    class GoodNotification(NotifyBase):
        def __init__(self, **kwargs):
            super(GoodNotification,
                  self).__init__(notify_format=NotifyFormat.HTML, **kwargs)

        def url(self):
            # Support URL
            return ''

        def notify(self, **kwargs):
            # Pretend everything is okay
            return True

    # Store our bad notification in our schema map
    SCHEMA_MAP['bad'] = BadNotification

    # Store our good notification in our schema map
    SCHEMA_MAP['good'] = GoodNotification

    # Just to explain what is happening here, we would have parsed the
    # url properly but failed when we went to go and create an instance
    # of it.
    assert (a.add('bad://localhost') is False)
    assert (len(a) == 0)

    assert (a.add('good://localhost') is True)
    assert (len(a) == 1)

    # Bad Notification Type is still allowed as it is presumed the user
    # know's what their doing
    assert (a.notify(title="my title", body="my body", notify_type='bad') is
            True)

    # No Title/Body combo's
    assert (a.notify(title=None, body=None) is False)
    assert (a.notify(title='', body=None) is False)
    assert (a.notify(title=None, body='') is False)

    # As long as one is present, we're good
    assert (a.notify(title=None, body='present') is True)
    assert (a.notify(title='present', body=None) is True)
    assert (a.notify(title="present", body="present") is True)

    # Clear our server listings again
    a.clear()

    class ThrowNotification(NotifyBase):
        def notify(self, **kwargs):
            # Pretend everything is okay
            raise TypeError()

        def url(self):
            # Support URL
            return ''

    class RuntimeNotification(NotifyBase):
        def notify(self, **kwargs):
            # Pretend everything is okay
            raise RuntimeError()

        def url(self):
            # Support URL
            return ''

    class FailNotification(NotifyBase):
        def notify(self, **kwargs):
            # Pretend everything is okay
            return False

        def url(self):
            # Support URL
            return ''

    # Store our bad notification in our schema map
    SCHEMA_MAP['throw'] = ThrowNotification

    # Store our good notification in our schema map
    SCHEMA_MAP['fail'] = FailNotification

    # Store our good notification in our schema map
    SCHEMA_MAP['runtime'] = RuntimeNotification

    assert (a.add('runtime://localhost') is True)
    assert (a.add('throw://localhost') is True)
    assert (a.add('fail://localhost') is True)
    assert (len(a) == 3)

    # Test when our notify both throws an exception and or just
    # simply returns False
    assert (a.notify(title="present", body="present") is False)

    # Create a Notification that throws an unexected exception
    class ThrowInstantiateNotification(NotifyBase):
        def __init__(self, **kwargs):
            # Pretend everything is okay
            raise TypeError()

        def url(self):
            # Support URL
            return ''

    SCHEMA_MAP['throw'] = ThrowInstantiateNotification

    # Reset our object
    a.clear()
    assert (len(a) == 0)

    # Instantiate a bad object
    plugin = a.instantiate(object, tag="bad_object")
    assert plugin is None

    # Instantiate a good object
    plugin = a.instantiate('good://localhost', tag="good")
    assert (isinstance(plugin, NotifyBase))

    # Test simple tagging inside of the object
    assert ("good" in plugin)
    assert ("bad" not in plugin)

    # the in (__contains__ override) is based on or'ed content; so although
    # 'bad' isn't tagged as being in the plugin, 'good' is, so the return
    # value of this is True
    assert (["bad", "good"] in plugin)
    assert (set(["bad", "good"]) in plugin)
    assert (("bad", "good") in plugin)

    # We an add already substatiated instances into our Apprise object
    a.add(plugin)
    assert (len(a) == 1)

    # We can add entries as a list too (to add more then one)
    a.add([plugin, plugin, plugin])
    assert (len(a) == 4)

    # Reset our object again
    a.clear()
    try:
        a.instantiate('throw://localhost', suppress_exceptions=False)
        assert (False)

    except TypeError:
        assert (True)
    assert (len(a) == 0)

    assert (a.instantiate('throw://localhost', suppress_exceptions=True) is
            None)
    assert (len(a) == 0)

    #
    # We rince and repeat the same tests as above, however we do them
    # using the dict version
    #

    # Reset our object
    a.clear()
    assert (len(a) == 0)

    # Instantiate a good object
    plugin = a.instantiate({'schema': 'good', 'host': 'localhost'}, tag="good")
    assert (isinstance(plugin, NotifyBase))

    # Test simple tagging inside of the object
    assert ("good" in plugin)
    assert ("bad" not in plugin)

    # the in (__contains__ override) is based on or'ed content; so although
    # 'bad' isn't tagged as being in the plugin, 'good' is, so the return
    # value of this is True
    assert (["bad", "good"] in plugin)
    assert (set(["bad", "good"]) in plugin)
    assert (("bad", "good") in plugin)

    # We an add already substatiated instances into our Apprise object
    a.add(plugin)
    assert (len(a) == 1)

    # We can add entries as a list too (to add more then one)
    a.add([plugin, plugin, plugin])
    assert (len(a) == 4)

    # Reset our object again
    a.clear()
    try:
        a.instantiate({
            'schema': 'throw',
            'host': 'localhost'
        },
                      suppress_exceptions=False)
        assert (False)

    except TypeError:
        assert (True)
    assert (len(a) == 0)

    assert (a.instantiate({
        'schema': 'throw',
        'host': 'localhost'
    },
                          suppress_exceptions=True) is None)
    assert (len(a) == 0)
Пример #23
0
def test_plugin_pushover_attachments(mock_post, tmpdir):
    """
    NotifyPushover() Attachment Checks

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Initialize some generic (but valid) tokens
    user_key = 'u' * 30
    api_token = 'a' * 30

    # Prepare a good response
    response = mock.Mock()
    response.content = dumps(
        {"status": 1, "request": "647d2300-702c-4b38-8b2f-d56326ae460b"})
    response.status_code = requests.codes.ok

    # Prepare a bad response
    bad_response = mock.Mock()
    response.content = dumps(
        {"status": 1, "request": "647d2300-702c-4b38-8b2f-d56326ae460b"})
    bad_response.status_code = requests.codes.internal_server_error

    # Assign our good response
    mock_post.return_value = response

    # prepare our attachment
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # Instantiate our object
    obj = Apprise.instantiate(
        'pover://{}@{}/'.format(user_key, api_token))
    assert isinstance(obj, plugins.NotifyPushover)

    # Test our attachment
    assert obj.notify(body="test", attach=attach) is True

    # Test our call count
    assert mock_post.call_count == 1
    assert mock_post.call_args_list[0][0][0] == \
        'https://api.pushover.net/1/messages.json'

    # Reset our mock object for multiple tests
    mock_post.reset_mock()

    # Test multiple attachments
    assert attach.add(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))
    assert obj.notify(body="test", attach=attach) is True

    # Test our call count
    assert mock_post.call_count == 2
    assert mock_post.call_args_list[0][0][0] == \
        'https://api.pushover.net/1/messages.json'
    assert mock_post.call_args_list[1][0][0] == \
        'https://api.pushover.net/1/messages.json'

    # Reset our mock object for multiple tests
    mock_post.reset_mock()

    image = tmpdir.mkdir("pover_image").join("test.jpg")
    image.write('a' * plugins.NotifyPushover.attach_max_size_bytes)

    attach = AppriseAttachment.instantiate(str(image))
    assert obj.notify(body="test", attach=attach) is True

    # Test our call count
    assert mock_post.call_count == 1
    assert mock_post.call_args_list[0][0][0] == \
        'https://api.pushover.net/1/messages.json'

    # Reset our mock object for multiple tests
    mock_post.reset_mock()

    # Add 1 more byte to the file (putting it over the limit)
    image.write('a' * (plugins.NotifyPushover.attach_max_size_bytes + 1))

    attach = AppriseAttachment.instantiate(str(image))
    assert obj.notify(body="test", attach=attach) is False

    # Test our call count
    assert mock_post.call_count == 0

    # Test case when file is missing
    attach = AppriseAttachment.instantiate(
        'file://{}?cache=False'.format(str(image)))
    os.unlink(str(image))
    assert obj.notify(
        body='body', title='title', attach=attach) is False

    # Test our call count
    assert mock_post.call_count == 0

    # Test unsuported files:
    image = tmpdir.mkdir("pover_unsupported").join("test.doc")
    image.write('a' * 256)
    attach = AppriseAttachment.instantiate(str(image))

    # Content is silently ignored
    assert obj.notify(body="test", attach=attach) is True

    # prepare our attachment
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # Throw an exception on the first call to requests.post()
    for side_effect in (requests.RequestException(), OSError(), bad_response):
        mock_post.side_effect = [side_effect, side_effect]

        # We'll fail now because of our error handling
        assert obj.send(body="test", attach=attach) is False

        # Same case without an attachment
        assert obj.send(body="test") is False
Пример #24
0
def test_email_url_variations():
    """
    API: Test email variations to ensure parsing is correct

    """
    # Test variations of username required to be an email address
    # [email protected]
    obj = Apprise.instantiate('mailto://{user}:{passwd}@example.com'.format(
        user='******', passwd='abcd123'),
                              suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True

    assert obj.password == 'abcd123'
    assert obj.user == '*****@*****.**'

    # test username specified in the url body (as an argument)
    # this always over-rides the entry at the front of the url
    obj = Apprise.instantiate(
        'mailto://*****:*****@example.com?user={user}'.format(
            user='******', passwd='abcd123'),
        suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True

    assert obj.password == 'abcd123'
    assert obj.user == '*****@*****.**'

    # test user and password specified in the url body (as an argument)
    # this always over-rides the entries at the front of the url
    obj = Apprise.instantiate(
        'mailto://*****:*****@example.com?user={user}&pass={passwd}'.format(
            user='******', passwd='abcd123'),
        suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True

    assert obj.password == 'abcd123'
    assert obj.user == '*****@*****.**'
    assert len(obj.targets) == 1
    assert '*****@*****.**' in obj.targets
    assert obj.targets[0] == obj.from_addr

    # test user and password specified in the url body (as an argument)
    # this always over-rides the entries at the front of the url
    # this is similar to the previous test except we're only specifying
    # this information in the kwargs
    obj = Apprise.instantiate(
        'mailto://example.com?user={user}&pass={passwd}'.format(
            user='******', passwd='abcd123'),
        suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True

    assert obj.password == 'abcd123'
    assert obj.user == '*****@*****.**'
    assert len(obj.targets) == 1
    assert '*****@*****.**' in obj.targets
    assert obj.targets[0] == obj.from_addr
    assert obj.smtp_host == 'example.com'

    # test a complicated example
    obj = Apprise.instantiate(
        'mailtos://{user}:{passwd}@{host}:{port}'
        '?smtp={smtp_host}&format=text&from={this}&to={that}'.format(
            user='******',
            passwd='abcd123',
            host='example.com',
            port=1234,
            this='*****@*****.**',
            that='*****@*****.**',
            smtp_host='smtp.example.edu'),
        suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail) is True

    assert obj.password == 'abcd123'
    assert obj.user == '*****@*****.**'
    assert obj.host == 'example.com'
    assert obj.port == 1234
    assert obj.smtp_host == 'smtp.example.edu'
    assert len(obj.targets) == 1
    assert '*****@*****.**' in obj.targets
    assert obj.from_addr == '*****@*****.**'
Пример #25
0
def test_plugin_emby_logout(mock_post, mock_get, mock_login):
    """
    NotifyEmby() logout()

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Prepare Mock
    mock_get.return_value = requests.Request()
    mock_post.return_value = requests.Request()

    # This is done so we don't obstruct our access_token and user_id values
    mock_login.return_value = True

    obj = Apprise.instantiate('emby://*****:*****@localhost')
    assert isinstance(obj, plugins.NotifyEmby)
    obj.access_token = 'abc'
    obj.user_id = '123'

    # Test our exception handling
    for _exception in AppriseURLTester.req_exceptions:
        mock_post.side_effect = _exception
        mock_get.side_effect = _exception
        # We'll fail to log in each time
        obj.logout()
        obj.access_token = 'abc'
        obj.user_id = '123'

    # Disable Exceptions
    mock_post.side_effect = None
    mock_get.side_effect = None

    # Our login flat out fails if we don't have proper parseable content
    mock_post.return_value.content = u''
    mock_get.return_value.content = mock_post.return_value.content

    # KeyError handling
    mock_post.return_value.status_code = 999
    mock_get.return_value.status_code = 999
    obj.logout()
    obj.access_token = 'abc'
    obj.user_id = '123'

    # General Internal Server Error
    mock_post.return_value.status_code = requests.codes.internal_server_error
    mock_get.return_value.status_code = requests.codes.internal_server_error
    obj.logout()
    obj.access_token = 'abc'
    obj.user_id = '123'

    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

    # Disable the port completely
    obj.port = None

    # Perform logout
    obj.logout()

    # Calling logout on an object already logged out
    obj.logout()

    # Test Python v3.5 LookupError Bug: https://bugs.python.org/issue29288
    mock_post.side_effect = LookupError()
    mock_get.side_effect = LookupError()
    obj.access_token = 'abc'
    obj.user_id = '123'

    # Tidy object
    del obj
Пример #26
0
def test_plugin_emby_general(mock_post, mock_get, mock_logout, mock_login,
                             mock_sessions):
    """
    NotifyEmby General Tests

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    req = requests.Request()
    req.status_code = requests.codes.ok
    req.content = ''
    mock_get.return_value = req
    mock_post.return_value = req

    # This is done so we don't obstruct our access_token and user_id values
    mock_login.return_value = True
    mock_logout.return_value = True
    mock_sessions.return_value = {'abcd': {}}

    obj = Apprise.instantiate('emby://*****:*****@localhost?modal=False')
    assert isinstance(obj, plugins.NotifyEmby)
    assert obj.notify('title', 'body', 'info') is True
    obj.access_token = 'abc'
    obj.user_id = '123'

    # Test Modal support
    obj = Apprise.instantiate('emby://*****:*****@localhost?modal=True')
    assert isinstance(obj, plugins.NotifyEmby)
    assert obj.notify('title', 'body', 'info') is True
    obj.access_token = 'abc'
    obj.user_id = '123'

    # Test our exception handling
    for _exception in AppriseURLTester.req_exceptions:
        mock_post.side_effect = _exception
        mock_get.side_effect = _exception
        # We'll fail to log in each time
        assert obj.notify('title', 'body', 'info') is False

    # Disable Exceptions
    mock_post.side_effect = None
    mock_get.side_effect = None

    # Our login flat out fails if we don't have proper parseable content
    mock_post.return_value.content = u''
    mock_get.return_value.content = mock_post.return_value.content

    # KeyError handling
    mock_post.return_value.status_code = 999
    mock_get.return_value.status_code = 999
    assert obj.notify('title', 'body', 'info') is False

    # General Internal Server Error
    mock_post.return_value.status_code = requests.codes.internal_server_error
    mock_get.return_value.status_code = requests.codes.internal_server_error
    assert obj.notify('title', 'body', 'info') is False

    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

    # Disable the port completely
    obj.port = None
    assert obj.notify('title', 'body', 'info') is True

    # An Empty return set (no query is made, but notification will still
    # succeed
    mock_sessions.return_value = {}
    assert obj.notify('title', 'body', 'info') is True

    # Tidy our object
    del obj
Пример #27
0
def test_smtplib_send_okay(mock_smtplib):
    """
    API: Test a successfully sent email

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Defaults to HTML
    obj = Apprise.instantiate('mailto://*****:*****@gmail.com',
                              suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail)

    # Support an email simulation where we can correctly quit
    mock_smtplib.starttls.return_value = True
    mock_smtplib.login.return_value = True
    mock_smtplib.sendmail.return_value = True
    mock_smtplib.quit.return_value = True

    assert obj.notify(body='body', title='test',
                      notify_type=NotifyType.INFO) is True

    # Set Text
    obj = Apprise.instantiate('mailto://*****:*****@gmail.com?format=text',
                              suppress_exceptions=False)
    assert isinstance(obj, plugins.NotifyEmail)

    assert obj.notify(body='body', title='test',
                      notify_type=NotifyType.INFO) is True

    # Create an apprise object to work with as well
    a = Apprise()
    assert a.add('mailto://*****:*****@gmail.com?format=text')

    # Send Attachment with success
    attach = os.path.join(TEST_VAR_DIR, 'apprise-test.gif')
    assert obj.notify(
        body='body', title='test', notify_type=NotifyType.INFO,
        attach=attach) is True

    # same results happen from our Apprise object
    assert a.notify(body='body', title='test', attach=attach) is True

    # test using an Apprise Attachment object
    assert obj.notify(body='body',
                      title='test',
                      notify_type=NotifyType.INFO,
                      attach=AppriseAttachment(attach)) is True

    # same results happen from our Apprise object
    assert a.notify(
        body='body', title='test', attach=AppriseAttachment(attach)) is True

    max_file_size = AttachBase.max_file_size
    # Now do a case where the file can't be sent

    AttachBase.max_file_size = 1
    assert obj.notify(
        body='body', title='test', notify_type=NotifyType.INFO,
        attach=attach) is False

    # same results happen from our Apprise object
    assert a.notify(body='body', title='test', attach=attach) is False

    # Restore value
    AttachBase.max_file_size = max_file_size
Пример #28
0
def test_email_plugin(mock_smtp, mock_smtpssl):
    """
    API: NotifyEmail Plugin()

    """

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected exception
        exception = meta.get('exception', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        test_smtplib_exceptions = meta.get('test_smtplib_exceptions', False)

        # Our mock of our socket action
        mock_socket = mock.Mock()
        mock_socket.starttls.return_value = True
        mock_socket.login.return_value = True

        # Create a mock SMTP Object
        mock_smtp.return_value = mock_socket
        mock_smtpssl.return_value = mock_socket

        if test_smtplib_exceptions:
            # Handle exception testing; first we turn the boolean flag ito
            # a list of exceptions
            test_smtplib_exceptions = (
                smtplib.SMTPHeloError(0,
                                      'smtplib.SMTPHeloError() not handled'),
                smtplib.SMTPException(0,
                                      'smtplib.SMTPException() not handled'),
                RuntimeError(0, 'smtplib.HTTPError() not handled'),
                smtplib.SMTPRecipientsRefused(
                    'smtplib.SMTPRecipientsRefused() not handled'),
                smtplib.SMTPSenderRefused(
                    0, 'smtplib.SMTPSenderRefused() not handled',
                    '*****@*****.**'),
                smtplib.SMTPDataError(0,
                                      'smtplib.SMTPDataError() not handled'),
                smtplib.SMTPServerDisconnected(
                    'smtplib.SMTPServerDisconnected() not handled'),
            )

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            assert (exception is None)

            if obj is None:
                # We're done
                continue

            if instance is None:
                # Expected None but didn't get it
                print('%s instantiated %s' % (url, str(obj)))
                assert (False)

            assert (isinstance(obj, instance))

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert (hasattr(key, obj))
                    assert (getattr(key, obj) == val)

            try:
                if test_smtplib_exceptions is False:
                    # check that we're as expected
                    assert obj.notify(title='test',
                                      body='body',
                                      notify_type=NotifyType.INFO) == response

                else:
                    for exception in test_smtplib_exceptions:
                        mock_socket.sendmail.side_effect = exception
                        try:
                            assert obj.notify(
                                title='test',
                                body='body',
                                notify_type=NotifyType.INFO) is False

                        except AssertionError:
                            # Don't mess with these entries
                            raise

                        except Exception as e:
                            # We can't handle this exception type
                            print('%s / %s' % (url, str(e)))
                            assert False

            except AssertionError:
                # Don't mess with these entries
                raise

            except Exception as e:
                # Check that we were expecting this exception to happen
                assert isinstance(e, response)

        except AssertionError:
            # Don't mess with these entries
            print('%s AssertionError' % url)
            raise

        except Exception as e:
            # Handle our exception
            print('%s / %s' % (url, str(e)))
            assert (exception is not None)
            assert (isinstance(e, exception))
Пример #29
0
def test_pushbullet_attachments(mock_post):
    """
    API: NotifyPushBullet() Attachment Checks

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.request_rate_per_sec = 0

    # Initialize some generic (but valid) tokens
    access_token = 't' * 32

    # Prepare Mock return object
    response = mock.Mock()
    response.content = dumps({
        "file_name": "cat.jpg",
        "file_type": "image/jpeg",
        "file_url": "https://dl.pushb.com/abc/cat.jpg",
        "upload_url": "https://upload.pushbullet.com/abcd123",
    })
    response.status_code = requests.codes.ok
    mock_post.return_value = response

    # prepare our attachment
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # Test our markdown
    obj = Apprise.instantiate(
        'pbul://{}/?format=markdown'.format(access_token))

    # Send a good attachment
    assert obj.notify(body="test", attach=attach) is True

    # Add another attachment so we drop into the area of the PushBullet code
    # that sends remaining attachments (if more detected)
    attach.add(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # Send our attachments
    assert obj.notify(body="test", attach=attach) is True

    # An invalid attachment will cause a failure
    path = os.path.join(TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
    attach = AppriseAttachment(path)
    assert obj.notify(body="test", attach=attach) is False

    # Throw an exception on the first call to requests.post()
    mock_post.return_value = None
    mock_post.side_effect = requests.RequestException()

    # We'll fail now because of an internal exception
    assert obj.send(body="test", attach=attach) is False

    # Throw an exception on the second call to requests.post()
    mock_post.side_effect = [response, OSError()]

    # We'll fail now because of an internal exception
    assert obj.send(body="test", attach=attach) is False

    # Throw an exception on the third call to requests.post()
    mock_post.side_effect = [
        response, response, requests.RequestException()]

    # We'll fail now because of an internal exception
    assert obj.send(body="test", attach=attach) is False

    # Throw an exception on the forth call to requests.post()
    mock_post.side_effect = [
        response, response, response, requests.RequestException()]

    # We'll fail now because of an internal exception
    assert obj.send(body="test", attach=attach) is False

    # Test case where we don't get a valid response back
    response.content = '}'
    mock_post.side_effect = response

    # We'll fail because of an invalid json object
    assert obj.send(body="test", attach=attach) is False

    #
    # Test bad responses
    #

    # Prepare a bad response
    response.content = dumps({
        "file_name": "cat.jpg",
        "file_type": "image/jpeg",
        "file_url": "https://dl.pushb.com/abc/cat.jpg",
        "upload_url": "https://upload.pushbullet.com/abcd123",
    })
    bad_response = mock.Mock()
    bad_response.content = response.content
    bad_response.status_code = 400

    # Throw an exception on the third call to requests.post()
    mock_post.return_value = bad_response

    # prepare our attachment
    attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))

    # We'll fail now because we were unable to send the attachment
    assert obj.send(body="test", attach=attach) is False

    # Throw an exception on the second call
    mock_post.side_effect = [response, bad_response, response]
    assert obj.send(body="test", attach=attach) is False

    # Throw an OSError
    mock_post.side_effect = [response, OSError()]
    assert obj.send(body="test", attach=attach) is False

    # Throw an exception on the third call
    mock_post.side_effect = [response, response, bad_response]
    assert obj.send(body="test", attach=attach) is False

    # Throw an exception on the fourth call
    mock_post.side_effect = [response, response, response, bad_response]
    assert obj.send(body="test", attach=attach) is False

    # A good message
    mock_post.side_effect = [response, response, response, response]
    assert obj.send(body="test", attach=attach) is True
Пример #30
0
def test_plugin(mock_refresh, mock_send):
    """
    API: NotifyPushjet Plugin() (pt1)

    """

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        # Allow us to force the server response code to be something other then
        # the defaults
        response = meta.get('response', True if response else False)

        test_notify_exceptions = meta.get('test_notify_exceptions', False)

        test_exceptions = (
            plugins.pushjet.errors.AccessError(
                0, 'pushjet.AccessError() not handled'),
            plugins.pushjet.errors.NonexistentError(
                0, 'pushjet.NonexistentError() not handled'),
            plugins.pushjet.errors.SubscriptionError(
                0, 'gntp.SubscriptionError() not handled'),
            plugins.pushjet.errors.RequestError(
                'pushjet.RequestError() not handled'),
        )

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            if instance is None:
                # Check that we got what we came for
                assert obj is instance
                continue

            assert (isinstance(obj, instance))

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert (hasattr(key, obj))
                    assert (getattr(key, obj) == val)

            try:
                if test_notify_exceptions is False:
                    # Store our response
                    mock_send.return_value = response
                    mock_send.side_effect = None

                    # check that we're as expected
                    assert obj.notify(title='test',
                                      body='body',
                                      notify_type=NotifyType.INFO) == response

                else:
                    for exception in test_exceptions:
                        mock_send.side_effect = exception
                        mock_send.return_value = None
                        try:
                            assert obj.notify(
                                title='test',
                                body='body',
                                notify_type=NotifyType.INFO) is False

                        except AssertionError:
                            # Don't mess with these entries
                            raise

                        except Exception as e:
                            # We can't handle this exception type
                            assert False

            except AssertionError:
                # Don't mess with these entries
                raise

            except Exception as e:
                # Check that we were expecting this exception to happen
                assert isinstance(e, response)

        except AssertionError:
            # Don't mess with these entries
            raise

        except Exception as e:
            # Handle our exception
            assert (instance is not None)
            assert (isinstance(e, instance))