Esempio n. 1
0
def test_apprise_config_tagging(tmpdir):
    """
    API: AppriseConfig tagging

    """

    # temporary file to work with
    t = tmpdir.mkdir("tagging").join("apprise")
    buf = "gnome://"
    t.write(buf)

    # Create ourselves a config object
    ac = AppriseConfig()

    # Add an item associated with tag a
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='a') is True
    # Add an item associated with tag b
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='b') is True
    # Add an item associated with tag a or b
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='a,b') is True

    # Now filter: a:
    assert len(ac.servers(tag='a')) == 2
    # Now filter: a or b:
    assert len(ac.servers(tag='a,b')) == 3
    # Now filter: a and b
    assert len(ac.servers(tag=[('a', 'b')])) == 1
    # all matches everything
    assert len(ac.servers(tag='all')) == 3
Esempio n. 2
0
def test_config_base_config_parse_yaml_list():
    """
    API: ConfigBase.config_parse_yaml list parsing

    """

    # general reference used below
    asset = AppriseAsset()

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
# no lists... just no
urls: [milk, pumpkin pie, eggs, juice]

# Including by list is okay
include: [file:///absolute/path/, relative/path, http://test.com]

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were 3 include entries
    assert len(config) == 3
    assert 'file:///absolute/path/' in config
    assert 'relative/path' in config
    assert 'http://test.com' in config
Esempio n. 3
0
def test_apprise_add_config():
    """
    API AppriseConfig.add_config()

    """
    content = """
    # A comment line over top of a URL
    mailto://usera:[email protected]

    # A line with mulitiple tag assignments to it
    taga,tagb=gnome://

    # Event if there is accidental leading spaces, this configuation
    # is accepting of htat and will not exclude them
                tagc=kde://

    # A very poorly structured url
    sns://:@/

    # Just 1 token provided causes exception
    sns://T1JJ3T3L2/
    """
    # Create ourselves a config object
    ac = AppriseConfig()
    assert ac.add_config(content=content)

    # One configuration file should have been found
    assert len(ac) == 1

    # Object can be directly checked as a boolean; response is True
    # when there is at least one entry
    assert ac

    # We should be able to read our 3 servers from that
    assert len(ac.servers()) == 3

    # Get our URL back
    assert isinstance(ac[0].url(), six.string_types)

    # Test invalid content
    assert ac.add_config(content=object()) is False
    assert ac.add_config(content=42) is False
    assert ac.add_config(content=None) is False

    # Still only one server loaded
    assert len(ac) == 1

    # Test having a pre-defined asset object and tag created
    assert ac.add_config(
        content=content, asset=AppriseAsset(), tag='a') is True

    # Now there are 2 servers loaded
    assert len(ac) == 2

    # and 6 urls.. (as we've doubled up)
    assert len(ac.servers()) == 6
Esempio n. 4
0
def test_invalid_apprise_config(tmpdir):
    """
    Parse invalid configuration includes

    """

    class BadConfig(ConfigBase):
        # always allow incusion
        allow_cross_includes = ConfigIncludeMode.ALWAYS

        def __init__(self, **kwargs):
            super(BadConfig, self).__init__(**kwargs)

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

        @staticmethod
        def parse_url(url, *args, **kwargs):
            # always parseable
            return ConfigBase.parse_url(url, verify_host=False)

    # Store our bad configuration in our schema map
    CONFIG_SCHEMA_MAP['bad'] = BadConfig

    # temporary file to work with
    t = tmpdir.mkdir("apprise-bad-obj").join("invalid")
    buf = """
    # Include an invalid schema
    include invalid://

    # An unparsable valid schema
    include https://

    # A valid configuration that will throw an exception
    include bad://

    # Include ourselves (So our recursive includes fails as well)
    include {}

    """.format(str(t))
    t.write(buf)

    # Create ourselves a config object with caching disbled
    ac = AppriseConfig(recursion=2, insecure_includes=True, cache=False)

    # Nothing loaded yet
    assert len(ac) == 0

    # Add our config
    assert ac.add(configs=str(t), asset=AppriseAsset()) is True

    # One configuration file
    assert len(ac) == 1

    # All of the servers were invalid and would not load
    assert len(ac.servers()) == 0
Esempio n. 5
0
def test_apprise_config_tagging(tmpdir):
    """
    API: AppriseConfig tagging

    """

    # temporary file to work with
    t = tmpdir.mkdir("tagging").join("apprise")
    buf = "gnome://"
    t.write(buf)

    # Create ourselves a config object
    ac = AppriseConfig()

    # Add an item associated with tag a
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='a') is True
    # Add an item associated with tag b
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='b') is True
    # Add an item associated with tag a or b
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='a,b') is True

    # Now filter: a:
    assert len(ac.servers(tag='a')) == 2
    # Now filter: a or b:
    assert len(ac.servers(tag='a,b')) == 3
    # Now filter: a and b
    assert len(ac.servers(tag=[('a', 'b')])) == 1
    # all matches everything
    assert len(ac.servers(tag='all')) == 3

    # Test cases using the `always` keyword
    # Create ourselves a config object
    ac = AppriseConfig()

    # Add an item associated with tag a
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='a,always') is True
    # Add an item associated with tag b
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='b') is True
    # Add an item associated with tag a or b
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='c,d') is True

    # Now filter: a:
    assert len(ac.servers(tag='a')) == 1
    # Now filter: a or b:
    assert len(ac.servers(tag='a,b')) == 2
    # Now filter: e
    # we'll match the `always'
    assert len(ac.servers(tag='e')) == 1
    assert len(ac.servers(tag='e', match_always=False)) == 0
    # all matches everything
    assert len(ac.servers(tag='all')) == 3

    # Now filter: d
    # we'll match the `always' tag
    assert len(ac.servers(tag='d')) == 2
    assert len(ac.servers(tag='d', match_always=False)) == 1
Esempio n. 6
0
def test_config_base_config_parse_yaml():
    """
    API: ConfigBase.config_parse_yaml object

    """

    # general reference used below
    asset = AppriseAsset()

    # Garbage Handling
    assert isinstance(ConfigBase.config_parse_yaml(object()), list)
    assert isinstance(ConfigBase.config_parse_yaml(None), list)
    assert isinstance(ConfigBase.config_parse_yaml(''), list)

    # Invalid Version
    result = ConfigBase.config_parse_yaml("version: 2a", asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid Syntax (throws a ScannerError)
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls
""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Missing url token
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # No urls defined
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url defined
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

# Invalid URL definition; yet the answer to life at the same time
urls: 43
""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url/schema
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
  - invalid://

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url/schema
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
  - invalid://:
    - a: b

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url/schema
    result = ConfigBase.config_parse_yaml("""
urls:
  - just some free text that isn't valid:
    - a garbage entry to go with it

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url/schema
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
  - not even a proper url

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url/schema
    result = ConfigBase.config_parse_yaml("""
# no lists... just no
urls: [milk, pumpkin pie, eggs, juice]

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Invalid url/schema
    result = ConfigBase.config_parse_yaml("""
urls:
  # a very invalid sns entry
  - sns://T1JJ3T3L2/
  - sns://:@/:
    - invalid: test
  - sns://T1JJ3T3L2/:
    - invalid: test

  # some strangness
  -
    -
      - test

""",
                                          asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # Valid Configuration
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

#
# Define your notification urls:
#
urls:
  - pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
  - mailto://test:[email protected]
""",
                                          asset=asset)

    # We expect to parse 2 entries from the above
    assert isinstance(result, list)
    assert len(result) == 2
    assert len(result[0].tags) == 0

    # Valid Configuration
    result = ConfigBase.config_parse_yaml("""
urls:
  - json://localhost:
    - tag: my-custom-tag, my-other-tag

  # How to stack multiple entries:
  - mailto://:
    - user: jeff
      pass: 123abc
      from: [email protected]

    - user: jack
      pass: pass123
      from: [email protected]

      # This is an illegal entry; the schema can not be changed
      schema: json

  # accidently left a colon at the end of the url; no problem
  # we'll accept it
  - mailto://oscar:[email protected]:

  # A telegram entry (returns a None in parse_url())
  - tgram://invalid

""",
                                          asset=asset)

    # We expect to parse 4 entries from the above because the tgram:// entry
    # would have failed to be loaded
    assert isinstance(result, list)
    assert len(result) == 4
    assert len(result[0].tags) == 2

    # Global Tags
    result = ConfigBase.config_parse_yaml("""
# Global Tags stacked as a list
tag:
  - admin
  - devops

urls:
  - json://localhost
  - dbus://
""",
                                          asset=asset)

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 2

    # all entries will have our global tags defined in them
    for entry in result:
        assert 'admin' in entry.tags
        assert 'devops' in entry.tags

    # Global Tags
    result = ConfigBase.config_parse_yaml("""
# Global Tags
tag: admin, devops

urls:
  # The following tags will get added to the global set
  - json://localhost:
    - tag: string-tag, my-other-tag, text

  # Tags can be presented in this list format too:
  - dbus://:
    - tag:
      - list-tag
      - dbus
""",
                                          asset=asset)

    # all entries will have our global tags defined in them
    for entry in result:
        assert 'admin' in entry.tags
        assert 'devops' in entry.tags

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 2

    # json:// has 2 globals + 3 defined
    assert len(result[0].tags) == 5
    assert 'text' in result[0].tags

    # json:// has 2 globals + 2 defined
    assert len(result[1].tags) == 4
    assert 'list-tag' in result[1].tags

    # An invalid set of entries
    result = ConfigBase.config_parse_yaml("""
urls:
  # The following tags will get added to the global set
  - json://localhost:
    -
      -
        - entry
""",
                                          asset=asset)

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # An asset we'll manipulate
    asset = AppriseAsset()

    # Global Tags
    result = ConfigBase.config_parse_yaml("""
# Test the creation of our apprise asset object
asset:
  app_id: AppriseTest
  app_desc: Apprise Test Notifications
  app_url: http://nuxref.com

  # Support setting empty values
  image_url_mask:
  image_url_logo:

  image_path_mask: tmp/path

  # invalid entry
  theme:
    -
      -
        - entry

  # Now for some invalid entries
  invalid: entry
  __init__: can't be over-ridden
  nolists:
    - we don't support these entries
    - in the apprise object

urls:
  - json://localhost:
""",
                                          asset=asset)

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 1
    assert asset.app_id == "AppriseTest"
    assert asset.app_desc == "Apprise Test Notifications"
    assert asset.app_url == "http://nuxref.com"

    # the theme was not updated and remains the same as it was
    assert asset.theme == AppriseAsset().theme

    # Empty string assignment
    assert isinstance(asset.image_url_mask, six.string_types) is True
    assert asset.image_url_mask == ""
    assert isinstance(asset.image_url_logo, six.string_types) is True
    assert asset.image_url_logo == ""

    # For on-lookers looking through this file; here is a perfectly formatted
    # YAML configuration file for your reference so you can see it without
    # all of the errors like the ones identified above
    result = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed. Thus this is a
# completely optional field. It's a good idea to just add this line because it
# will help with future ambiguity (if it ever occurs).
version: 1

# Define an Asset object if you wish (Optional)
asset:
  app_id: AppriseTest
  app_desc: Apprise Test Notifications
  app_url: http://nuxref.com

# Optionally define some global tags to associate with ALL of your
# urls below.
tag: admin, devops

# Define your URLs (Mandatory!)
urls:
  # Either on-line each entry like this:
  - json://localhost

  # Or add a colon to the end of the URL where you can optionally provide
  # over-ride entries.  One of the most likely entry to be used here
  # is the tag entry.  This gets extended to the global tag (if defined)
  # above
  - xml://localhost:
    - tag: customer

  # The more elements you specify under a URL the more times the URL will
  # get replicated and used. Hence this entry actually could be considered
  # 2 URLs being called with just the destination email address changed:
  - mailto://george:[email protected]:
     - to: [email protected]
     - to: [email protected]

  # Again... to re-iterate, the above mailto:// would actually fire two (2)
  # separate emails each with a different destination address specified.
  # Be careful when defining your arguments and differentiating between
  # when to use the dash (-) and when not to.  Each time you do, you will
  # cause another instance to be created.

  # Defining more then 1 element to a muti-set is easy, it looks like this:
  - mailto://jackson:[email protected]:
     - to: [email protected]
       tag: jeff, customer

     - to: [email protected]
       tag: chris, customer
""",
                                          asset=asset)

    # okay, here is how we get our total based on the above (read top-down)
    # +1  json:// entry
    # +1  xml:// entry
    # +2  mailto:// entry to [email protected] and [email protected]
    # +2  mailto:// entry to [email protected] and [email protected]
    # = 6
    assert len(result) == 6

    # all six entries will have our global tags defined in them
    for entry in result:
        assert 'admin' in entry.tags
        assert 'devops' in entry.tags

    # Entries can be directly accessed as they were added

    # our json:// had no additional tags added; so just the global ones
    # So just 2; admin and devops (these were already validated above in the
    # for loop
    assert len(result[0].tags) == 2

    # our xml:// object has 1 tag added (customer)
    assert len(result[1].tags) == 3
    assert 'customer' in result[1].tags

    # You get the idea, here is just a direct mapping to the remaining entries
    # in the same order they appear above
    assert len(result[2].tags) == 2
    assert len(result[3].tags) == 2

    assert len(result[4].tags) == 4
    assert 'customer' in result[4].tags
    assert 'jeff' in result[4].tags

    assert len(result[5].tags) == 4
    assert 'customer' in result[5].tags
    assert 'chris' in result[5].tags
Esempio n. 7
0
def test_config_base_config_parse_text():
    """
    API: ConfigBase.config_parse_text object

    """

    # Garbage Handling
    assert isinstance(ConfigBase.config_parse_text(object()), list)
    assert isinstance(ConfigBase.config_parse_text(None), list)
    assert isinstance(ConfigBase.config_parse_text(''), list)

    # Valid Configuration
    result = ConfigBase.config_parse_text("""
    # A comment line over top of a URL
    mailto://userb:[email protected]

    # A line with mulitiple tag assignments to it
    taga,tagb=kde://
    """,
                                          asset=AppriseAsset())

    # We expect to parse 2 entries from the above
    assert isinstance(result, list)
    assert len(result) == 2
    assert len(result[0].tags) == 0

    # Our second element will have tags associated with it
    assert len(result[1].tags) == 2
    assert 'taga' in result[1].tags
    assert 'tagb' in result[1].tags

    # Here is a similar result set however this one has an invalid line
    # in it which invalidates the entire file
    result = ConfigBase.config_parse_text("""
    # A comment line over top of a URL
    mailto://userc:[email protected]

    # A line with mulitiple tag assignments to it
    taga,tagb=windows://

    I am an invalid line that does not follow any of the Apprise file rules!
    """)

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # More invalid data
    result = ConfigBase.config_parse_text("""
    # An invalid URL
    invalid://user:[email protected]

    # A tag without a url
    taga=

    # A very poorly structured url
    sns://:@/

    # Just 1 token provided
    sns://T1JJ3T3L2/
    """)

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # Here is an empty file
    result = ConfigBase.config_parse_text('')

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0
Esempio n. 8
0
def test_apprise_config(tmpdir):
    """
    API: AppriseConfig basic testing

    """

    # Create ourselves a config object
    ac = AppriseConfig()

    # There are no servers loaded
    assert len(ac) == 0

    # Object can be directly checked as a boolean; response is False
    # when there are no entries loaded
    assert not ac

    # lets try anyway
    assert len(ac.servers()) == 0

    t = tmpdir.mkdir("simple-formatting").join("apprise")
    t.write("""
    # A comment line over top of a URL
    mailto://usera:[email protected]

    # A line with mulitiple tag assignments to it
    taga,tagb=gnome://

    # Event if there is accidental leading spaces, this configuation
    # is accepting of htat and will not exclude them
                tagc=kde://

    # A very poorly structured url
    sns://:@/

    # Just 1 token provided causes exception
    sns://T1JJ3T3L2/
    """)

    # Create ourselves a config object
    ac = AppriseConfig(paths=str(t))

    # One configuration file should have been found
    assert len(ac) == 1

    # Object can be directly checked as a boolean; response is True
    # when there is at least one entry
    assert ac

    # We should be able to read our 3 servers from that
    assert len(ac.servers()) == 3

    # Get our URL back
    assert isinstance(ac[0].url(), six.string_types)

    # Test cases where our URL is invalid
    t = tmpdir.mkdir("strange-lines").join("apprise")
    t.write("""
    # basicly this consists of defined tags and no url
    tag=
    """)

    # Create ourselves a config object
    ac = AppriseConfig(paths=str(t), asset=AppriseAsset())

    # One configuration file should have been found
    assert len(ac) == 1

    # No urls were set
    assert len(ac.servers()) == 0

    # Create a ConfigBase object
    cb = ConfigBase()

    # Test adding of all entries
    assert ac.add(configs=cb, asset=AppriseAsset(), tag='test') is True

    # Test adding of all entries
    assert ac.add(
        configs=['file://?', ], asset=AppriseAsset(), tag='test') is False

    # Test the adding of garbage
    assert ac.add(configs=object()) is False

    # Try again but enforce our format
    ac = AppriseConfig(paths='file://{}?format=text'.format(str(t)))

    # One configuration file should have been found
    assert len(ac) == 1

    # No urls were set
    assert len(ac.servers()) == 0

    #
    # Test Internatialization and the handling of unicode characters
    #
    istr = """
        # Iñtërnâtiônàlization Testing
        windows://"""

    if six.PY2:
        # decode string into unicode
        istr = istr.decode('utf-8')

    # Write our content to our file
    t = tmpdir.mkdir("internationalization").join("apprise")
    with io.open(str(t), 'wb') as f:
        f.write(istr.encode('latin-1'))

    # Create ourselves a config object
    ac = AppriseConfig(paths=str(t))

    # One configuration file should have been found
    assert len(ac) == 1

    # This will fail because our default encoding is utf-8; however the file
    # we opened was not; it was latin-1 and could not be parsed.
    assert len(ac.servers()) == 0

    # Test iterator
    count = 0
    for entry in ac:
        count += 1
    assert len(ac) == count

    # We can fix this though; set our encoding to latin-1
    ac = AppriseConfig(paths='file://{}?encoding=latin-1'.format(str(t)))

    # One configuration file should have been found
    assert len(ac) == 1

    # Our URL should be found
    assert len(ac.servers()) == 1

    # Get our URL back
    assert isinstance(ac[0].url(), six.string_types)

    # pop an entry from our list
    assert isinstance(ac.pop(0), ConfigBase) is True

    # Determine we have no more configuration entries loaded
    assert len(ac) == 0

    #
    # Test buffer handling (and overflow)
    t = tmpdir.mkdir("buffer-handling").join("apprise")
    buf = "gnome://"
    t.write(buf)

    # Reset our config object
    ac.clear()

    # Create ourselves a config object
    ac = AppriseConfig(paths=str(t))

    # update our length to be the size of our actual file
    ac[0].max_buffer_size = len(buf)

    # One configuration file should have been found
    assert len(ac) == 1

    assert len(ac.servers()) == 1

    # update our buffer size to be slightly smaller then what we allow
    ac[0].max_buffer_size = len(buf) - 1

    # Content is automatically cached; so even though we adjusted the buffer
    # above, our results have been cached so we get a 1 response.
    assert len(ac.servers()) == 1
Esempio n. 9
0
def test_apprise_config_with_apprise_obj(tmpdir):
    """
    API: ConfigBase.parse_inaccessible_text_file

    """

    # temporary file to work with
    t = tmpdir.mkdir("apprise-obj").join("apprise")
    buf = """
    good://hostname
    localhost=good://localhost
    """
    t.write(buf)

    # Define our good:// url
    class GoodNotification(NotifyBase):
        def __init__(self, **kwargs):
            super(GoodNotification, self).__init__(
                notify_format=NotifyFormat.HTML, **kwargs)

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

        def url(self):
            # support url()
            return ''

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

    # Create ourselves a config object with caching disbled
    ac = AppriseConfig(cache=False)

    # Nothing loaded yet
    assert len(ac) == 0

    # Add an item associated with tag a
    assert ac.add(configs=str(t), asset=AppriseAsset(), tag='a') is True

    # One configuration file
    assert len(ac) == 1

    # 2 services found in it
    assert len(ac.servers()) == 2

    # Pop one of them (at index 0)
    ac.server_pop(0)

    # Verify that it no longer listed
    assert len(ac.servers()) == 1

    # Test our ability to add Config objects to our apprise object
    a = Apprise()

    # Add our configuration object
    assert a.add(servers=ac) is True

    # Detect our 1 entry (originally there were 2 but we deleted one)
    assert len(a) == 1

    # Notify our service
    assert a.notify(body='apprise configuration power!') is True

    # Add our configuration object
    assert a.add(
        servers=[AppriseConfig(str(t)), AppriseConfig(str(t))]) is True

    # Detect our 5 loaded entries now; 1 from first config, and another
    # 2x2 based on adding our list above
    assert len(a) == 5

    # We can't add garbage
    assert a.add(servers=object()) is False
    assert a.add(servers=[object(), object()]) is False

    # Our length is unchanged
    assert len(a) == 5

    # reference index 0 of our list
    ref = a[0]
    assert isinstance(ref, NotifyBase) is True

    # Our length is unchanged
    assert len(a) == 5

    # pop the index
    ref_popped = a.pop(0)

    # Verify our response
    assert isinstance(ref_popped, NotifyBase) is True

    # Our length drops by 1
    assert len(a) == 4

    # Content popped is the same as one referenced by index
    # earlier
    assert ref == ref_popped

    # pop an index out of range
    try:
        a.pop(len(a))
        # We'll thrown an IndexError and not make it this far
        assert False

    except IndexError:
        # As expected
        assert True

    # Our length remains unchanged
    assert len(a) == 4

    # Reference content out of range
    try:
        a[len(a)]

        # We'll thrown an IndexError and not make it this far
        assert False

    except IndexError:
        # As expected
        assert True

    # reference index at the end of our list
    ref = a[len(a) - 1]

    # Verify our response
    assert isinstance(ref, NotifyBase) is True

    # Our length stays the same
    assert len(a) == 4

    # We can pop from the back of the list without a problem too
    ref_popped = a.pop(len(a) - 1)

    # Verify our response
    assert isinstance(ref_popped, NotifyBase) is True

    # Content popped is the same as one referenced by index
    # earlier
    assert ref == ref_popped

    # Our length drops by 1
    assert len(a) == 3

    # Now we'll test adding another element to the list so that it mixes up
    # our response object.
    # Below we add 3 different types, a ConfigBase, NotifyBase, and URL
    assert a.add(
        servers=[
            ConfigFile(path=(str(t))),
            'good://another.host',
            GoodNotification(**{'host': 'nuxref.com'})]) is True

    # Our length increases by 4 (2 entries in the config file, + 2 others)
    assert len(a) == 7

    # reference index at the end of our list
    ref = a[len(a) - 1]

    # Verify our response
    assert isinstance(ref, NotifyBase) is True

    # We can pop from the back of the list without a problem too
    ref_popped = a.pop(len(a) - 1)

    # Verify our response
    assert isinstance(ref_popped, NotifyBase) is True

    # Content popped is the same as one referenced by index
    # earlier
    assert ref == ref_popped

    # Our length drops by 1
    assert len(a) == 6

    # pop our list
    while len(a) > 0:
        assert isinstance(a.pop(len(a) - 1), NotifyBase) is True
Esempio n. 10
0
def test_config_base_config_parse_yaml():
    """
    API: ConfigBase.config_parse_yaml object

    """

    # general reference used below
    asset = AppriseAsset()

    # Garbage Handling
    for garbage in (object(), None, '', 42):
        # A response is always correctly returned
        result = ConfigBase.config_parse_yaml(garbage)
        # response is a tuple...
        assert isinstance(result, tuple)
        # containing 2 items (plugins, config)
        assert len(result) == 2
        # In the case of garbage in, we get garbage out; both lists are empty
        assert result == (list(), list())

    # Invalid Version
    result, config = ConfigBase.config_parse_yaml("version: 2a", asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid Syntax (throws a ScannerError)
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls
""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Missing url token
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # No urls defined
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid url defined
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

# Invalid URL definition; yet the answer to life at the same time
urls: 43
""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
  - invalid://

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
  - invalid://:
    - a: b

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
# Include entry with nothing associated with it
include:

urls:
  - just some free text that isn't valid:
    - a garbage entry to go with it

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

urls:
  - not even a proper url

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
# no lists... just no
urls: [milk, pumpkin pie, eggs, juice]

# Including by list is okay
include: [file:///absolute/path/, relative/path, http://test.com]

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were 3 include entries
    assert len(config) == 3
    assert 'file:///absolute/path/' in config
    assert 'relative/path' in config
    assert 'http://test.com' in config

    # Invalid url/schema
    result, config = ConfigBase.config_parse_yaml("""
urls:
  # a very invalid sns entry
  - sns://T1JJ3T3L2/
  - sns://:@/:
    - invalid: test
  - sns://T1JJ3T3L2/:
    - invalid: test

  # some strangeness
  -
    -
      - test

""",
                                                  asset=asset)

    # Invalid data gets us an empty result set
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # Valid Configuration
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed
version: 1

# Including by dict
include:
  # File includes
  - file:///absolute/path/
  - relative/path
  # Trailing colon shouldn't disrupt include
  - http://test.com:

  # invalid (numeric)
  - 4

  # some strangeness
  -
    -
      - test

#
# Define your notification urls:
#
urls:
  - pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
  - mailto://test:[email protected]
  - https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG
  - https://not.a.native.url/
""",
                                                  asset=asset)

    # We expect to parse 3 entries from the above
    # The Ryver one is in a native form and the 4th one is invalid
    assert isinstance(result, list)
    assert len(result) == 3
    assert len(result[0].tags) == 0

    # There were 3 include entries
    assert len(config) == 3
    assert 'file:///absolute/path/' in config
    assert 'relative/path' in config
    assert 'http://test.com' in config

    # Valid Configuration
    result, config = ConfigBase.config_parse_yaml("""
# A single line include is supported
include: http://localhost:8080/notify/apprise

urls:
  - json://localhost:
    - tag: my-custom-tag, my-other-tag

  # How to stack multiple entries:
  - mailto://user:[email protected]:
    - to: [email protected]
    - to: [email protected]

      # This is an illegal entry; the schema can not be changed
      schema: json

  # accidently left a colon at the end of the url; no problem
  # we'll accept it
  - mailto://oscar:[email protected]:

  # A Ryver URL (using Native format); still accepted
  - https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG:

  # An invalid URL with colon (ignored)
  - https://not.a.native.url/:

  # A telegram entry (returns a None in parse_url())
  - tgram://invalid

""",
                                                  asset=asset)

    # We expect to parse 4 entries from the above because the tgram:// entry
    # would have failed to be loaded
    assert isinstance(result, list)
    assert len(result) == 5
    assert len(result[0].tags) == 2

    # Our single line included
    assert len(config) == 1
    assert 'http://localhost:8080/notify/apprise' in config

    # Global Tags
    result, config = ConfigBase.config_parse_yaml("""
# Global Tags stacked as a list
tag:
  - admin
  - devops

urls:
  - json://localhost
  - dbus://
""",
                                                  asset=asset)

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 2

    # There were no include entries defined
    assert len(config) == 0

    # all entries will have our global tags defined in them
    for entry in result:
        assert 'admin' in entry.tags
        assert 'devops' in entry.tags

    # Global Tags
    result, config = ConfigBase.config_parse_yaml("""
# Global Tags
tag: admin, devops

urls:
  # The following tags will get added to the global set
  - json://localhost:
    - tag: string-tag, my-other-tag, text

  # Tags can be presented in this list format too:
  - dbus://:
    - tag:
      - list-tag
      - dbus
""",
                                                  asset=asset)

    # all entries will have our global tags defined in them
    for entry in result:
        assert 'admin' in entry.tags
        assert 'devops' in entry.tags

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 2

    # json:// has 2 globals + 3 defined
    assert len(result[0].tags) == 5
    assert 'text' in result[0].tags

    # json:// has 2 globals + 2 defined
    assert len(result[1].tags) == 4
    assert 'list-tag' in result[1].tags

    # There were no include entries defined
    assert len(config) == 0

    # An invalid set of entries
    result, config = ConfigBase.config_parse_yaml("""
urls:
  # The following tags will get added to the global set
  - json://localhost:
    -
      -
        - entry
""",
                                                  asset=asset)

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # An asset we'll manipulate
    asset = AppriseAsset()

    # Global Tags
    result, config = ConfigBase.config_parse_yaml("""
# Test the creation of our apprise asset object
asset:
  app_id: AppriseTest
  app_desc: Apprise Test Notifications
  app_url: http://nuxref.com

  # Support setting empty values
  image_url_mask:
  image_url_logo:

  image_path_mask: tmp/path

  # invalid entry
  theme:
    -
      -
        - entry

  # Now for some invalid entries
  invalid: entry
  __init__: can't be over-ridden
  nolists:
    - we don't support these entries
    - in the apprise object

urls:
  - json://localhost:
""",
                                                  asset=asset)

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 1

    # There were no include entries defined
    assert len(config) == 0

    assert asset.app_id == "AppriseTest"
    assert asset.app_desc == "Apprise Test Notifications"
    assert asset.app_url == "http://nuxref.com"

    # the theme was not updated and remains the same as it was
    assert asset.theme == AppriseAsset().theme

    # Empty string assignment
    assert isinstance(asset.image_url_mask, six.string_types) is True
    assert asset.image_url_mask == ""
    assert isinstance(asset.image_url_logo, six.string_types) is True
    assert asset.image_url_logo == ""

    # For on-lookers looking through this file; here is a perfectly formatted
    # YAML configuration file for your reference so you can see it without
    # all of the errors like the ones identified above
    result, config = ConfigBase.config_parse_yaml("""
# if no version is specified then version 1 is presumed. Thus this is a
# completely optional field. It's a good idea to just add this line because it
# will help with future ambiguity (if it ever occurs).
version: 1

# Define an Asset object if you wish (Optional)
asset:
  app_id: AppriseTest
  app_desc: Apprise Test Notifications
  app_url: http://nuxref.com

# Optionally define some global tags to associate with ALL of your
# urls below.
tag: admin, devops

# Define your URLs (Mandatory!)
urls:
  # Either on-line each entry like this:
  - json://localhost

  # Or add a colon to the end of the URL where you can optionally provide
  # over-ride entries.  One of the most likely entry to be used here
  # is the tag entry.  This gets extended to the global tag (if defined)
  # above
  - xml://localhost:
    - tag: customer

  # The more elements you specify under a URL the more times the URL will
  # get replicated and used. Hence this entry actually could be considered
  # 2 URLs being called with just the destination email address changed:
  - mailto://george:[email protected]:
     - to: [email protected]
     - to: [email protected]

  # Again... to re-iterate, the above mailto:// would actually fire two (2)
  # separate emails each with a different destination address specified.
  # Be careful when defining your arguments and differentiating between
  # when to use the dash (-) and when not to.  Each time you do, you will
  # cause another instance to be created.

  # Defining more then 1 element to a muti-set is easy, it looks like this:
  - mailto://jackson:[email protected]:
     - to: [email protected]
       tag: jeff, customer

     - to: [email protected]
       tag: chris, customer
""",
                                                  asset=asset)

    # okay, here is how we get our total based on the above (read top-down)
    # +1  json:// entry
    # +1  xml:// entry
    # +2  mailto:// entry to [email protected] and [email protected]
    # +2  mailto:// entry to [email protected] and [email protected]
    # = 6
    assert len(result) == 6

    # all six entries will have our global tags defined in them
    for entry in result:
        assert 'admin' in entry.tags
        assert 'devops' in entry.tags

    # Entries can be directly accessed as they were added

    # our json:// had no additional tags added; so just the global ones
    # So just 2; admin and devops (these were already validated above in the
    # for loop
    assert len(result[0].tags) == 2

    # our xml:// object has 1 tag added (customer)
    assert len(result[1].tags) == 3
    assert 'customer' in result[1].tags

    # You get the idea, here is just a direct mapping to the remaining entries
    # in the same order they appear above
    assert len(result[2].tags) == 2
    assert len(result[3].tags) == 2

    assert len(result[4].tags) == 4
    assert 'customer' in result[4].tags
    assert 'jeff' in result[4].tags

    assert len(result[5].tags) == 4
    assert 'customer' in result[5].tags
    assert 'chris' in result[5].tags

    # There were no include entries defined
    assert len(config) == 0

    # Valid Configuration (multi inline configuration entries)
    result, config = ConfigBase.config_parse_yaml("""
# A configuration file that contains 2 includes separated by a comma and/or
# space:
include: http://localhost:8080/notify/apprise, http://localhost/apprise/cfg

""",
                                                  asset=asset)

    # We will have loaded no results
    assert isinstance(result, list)
    assert len(result) == 0

    # But our two configuration files will be present:
    assert len(config) == 2
    assert 'http://localhost:8080/notify/apprise' in config
    assert 'http://localhost/apprise/cfg' in config

    # Valid Configuration (another way of specifying more then one include)
    result, config = ConfigBase.config_parse_yaml("""
# A configuration file that contains 4 includes on their own
# lines beneath the keyword `include`:
include:
   http://localhost:8080/notify/apprise
   http://localhost/apprise/cfg01
   http://localhost/apprise/cfg02
   http://localhost/apprise/cfg03

""",
                                                  asset=asset)

    # We will have loaded no results
    assert isinstance(result, list)
    assert len(result) == 0

    # But our 4 configuration files will be present:
    assert len(config) == 4
    assert 'http://localhost:8080/notify/apprise' in config
    assert 'http://localhost/apprise/cfg01' in config
    assert 'http://localhost/apprise/cfg02' in config
    assert 'http://localhost/apprise/cfg03' in config

    # Valid Configuration (we allow comma separated entries for
    # each defined bullet)
    result, config = ConfigBase.config_parse_yaml("""
# A configuration file that contains 4 includes on their own
# lines beneath the keyword `include`:
include:
   - http://localhost:8080/notify/apprise, http://localhost/apprise/cfg01
     http://localhost/apprise/cfg02
   - http://localhost/apprise/cfg03

""",
                                                  asset=asset)

    # We will have loaded no results
    assert isinstance(result, list)
    assert len(result) == 0

    # But our 4 configuration files will be present:
    assert len(config) == 4
    assert 'http://localhost:8080/notify/apprise' in config
    assert 'http://localhost/apprise/cfg01' in config
    assert 'http://localhost/apprise/cfg02' in config
    assert 'http://localhost/apprise/cfg03' in config
Esempio n. 11
0
def test_config_base_config_parse_text():
    """
    API: ConfigBase.config_parse_text object

    """

    # Garbage Handling
    for garbage in (object(), None, 42):
        # A response is always correctly returned
        result = ConfigBase.config_parse_text(garbage)
        # response is a tuple...
        assert isinstance(result, tuple)
        # containing 2 items (plugins, config)
        assert len(result) == 2
        # In the case of garbage in, we get garbage out; both lists are empty
        assert result == (list(), list())

    # Valid Configuration
    result, config = ConfigBase.config_parse_text("""
    # A comment line over top of a URL
    mailto://userb:[email protected]

    # Test a URL using it's native format; in this case Ryver
    https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG

    # Invalid URL as it's not associated with a plugin
    # or a native url
    https://not.a.native.url/

    # A line with mulitiple tag assignments to it
    taga,tagb=kde://

    # An include statement to Apprise API with trailing spaces:
    include http://localhost:8080/notify/apprise

    # A relative include statement (with trailing spaces)
    include apprise.cfg     """,
                                                  asset=AppriseAsset())

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert isinstance(config, list)
    assert len(result) == 3
    assert len(result[0].tags) == 0

    # Our last element will have 2 tags associated with it
    assert len(result[-1].tags) == 2
    assert 'taga' in result[-1].tags
    assert 'tagb' in result[-1].tags

    assert len(config) == 2
    assert 'http://localhost:8080/notify/apprise' in config
    assert 'apprise.cfg' in config

    # Here is a similar result set however this one has an invalid line
    # in it which invalidates the entire file
    result, config = ConfigBase.config_parse_text("""
    # A comment line over top of a URL
    mailto://userc:[email protected]

    # A line with mulitiple tag assignments to it
    taga,tagb=windows://

    I am an invalid line that does not follow any of the Apprise file rules!
    """)

    # We expect to parse 0 entries from the above because the invalid line
    # invalidates the entire configuration file. This is for security reasons;
    # we don't want to point at files load content in them just because they
    # resemble an Apprise configuration.
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0

    # More invalid data
    result, config = ConfigBase.config_parse_text("""
    # An invalid URL
    invalid://user:[email protected]

    # A tag without a url
    taga=

    # A very poorly structured url
    sns://:@/

    # Just 1 token provided
    sns://T1JJ3T3L2/

    # Even with the above invalid entries, we can still
    # have valid include lines
    include file:///etc/apprise.cfg

    # An invalid include (nothing specified afterwards)
    include

    # An include of a config type we don't support
    include invalid://
    """)

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # There was 1 valid entry
    assert len(config) == 0

    # Test case where a comment is on it's own line with nothing else
    result, config = ConfigBase.config_parse_text("#")
    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # There were no include entries defined
    assert len(config) == 0
Esempio n. 12
0
def test_config_base_config_parse():
    """
    API: ConfigBase.config_parse

    """

    # Garbage Handling
    for garbage in (object(), None, 42):
        # A response is always correctly returned
        result = ConfigBase.config_parse(garbage)
        # response is a tuple...
        assert isinstance(result, tuple)
        # containing 2 items (plugins, config)
        assert len(result) == 2
        # In the case of garbage in, we get garbage out; both lists are empty
        assert result == (list(), list())

    # Valid Text Configuration
    result = ConfigBase.config_parse("""
    # A comment line over top of a URL
    mailto://userb:[email protected]
    """,
                                     asset=AppriseAsset())
    # We expect to parse 1 entry from the above
    assert isinstance(result, tuple)
    assert len(result) == 2
    # The first element is the number of notification services processed
    assert len(result[0]) == 1
    # If we index into the item, we can check to see the tags associate
    # with it
    assert len(result[0][0].tags) == 0

    # The second is the number of configuration include lines parsed
    assert len(result[1]) == 0

    # Valid Configuration
    result = ConfigBase.config_parse("""
# if no version is specified then version 1 is presumed
version: 1

#
# Define your notification urls:
#
urls:
  - pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
  - mailto://test:[email protected]
  - syslog://:
      - tag: devops, admin
    """,
                                     asset=AppriseAsset())

    # We expect to parse 3 entries from the above
    assert isinstance(result, tuple)
    assert len(result) == 2
    assert isinstance(result[0], list)
    assert len(result[0]) == 3
    assert len(result[0][0].tags) == 0
    assert len(result[0][1].tags) == 0
    assert len(result[0][2].tags) == 2

    # Test case where we pass in a bad format
    result = ConfigBase.config_parse("""
    ; A comment line over top of a URL
    mailto://userb:[email protected]
    """,
                                     config_format='invalid-format')

    # This is not parseable despite the valid text
    assert isinstance(result, tuple)
    assert isinstance(result[0], list)
    assert len(result[0]) == 0

    result, _ = ConfigBase.config_parse("""
    ; A comment line over top of a URL
    mailto://userb:[email protected]
    """,
                                        config_format=ConfigFormat.TEXT)

    # Parseable
    assert isinstance(result, list)
    assert len(result) == 1
Esempio n. 13
0
def test_config_base_config_parse_text():
    """
    API: ConfigBase.config_parse_text object

    """

    # Garbage Handling
    assert isinstance(ConfigBase.config_parse_text(object()), list)
    assert isinstance(ConfigBase.config_parse_text(None), list)
    assert isinstance(ConfigBase.config_parse_text(''), list)

    # Valid Configuration
    result = ConfigBase.config_parse_text("""
    # A comment line over top of a URL
    mailto://userb:[email protected]

    # Test a URL using it's native format; in this case Ryver
    https://apprise.ryver.com/application/webhook/ckhrjW8w672m6HG

    # Invalid URL as it's not associated with a plugin
    # or a native url
    https://not.a.native.url/

    # A line with mulitiple tag assignments to it
    taga,tagb=kde://
    """, asset=AppriseAsset())

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 3
    assert len(result[0].tags) == 0

    # Our last element will have 2 tags associated with it
    assert len(result[-1].tags) == 2
    assert 'taga' in result[-1].tags
    assert 'tagb' in result[-1].tags

    # Here is a similar result set however this one has an invalid line
    # in it which invalidates the entire file
    result = ConfigBase.config_parse_text("""
    # A comment line over top of a URL
    mailto://userc:[email protected]

    # A line with mulitiple tag assignments to it
    taga,tagb=windows://

    I am an invalid line that does not follow any of the Apprise file rules!
    """)

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # More invalid data
    result = ConfigBase.config_parse_text("""
    # An invalid URL
    invalid://user:[email protected]

    # A tag without a url
    taga=

    # A very poorly structured url
    sns://:@/

    # Just 1 token provided
    sns://T1JJ3T3L2/
    """)

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # Here is an empty file
    result = ConfigBase.config_parse_text('')

    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # Test case where a comment is on it's own line with nothing else
    result = ConfigBase.config_parse_text("#")
    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0

    # Test case of empty file
    result = ConfigBase.config_parse_text("")
    # We expect to parse 0 entries from the above
    assert isinstance(result, list)
    assert len(result) == 0
Esempio n. 14
0
def test_apprise_attachment():
    """
    API: AppriseAttachment basic testing

    """

    # Create ourselves an attachment object
    aa = AppriseAttachment()

    # There are no attachents loaded
    assert len(aa) == 0

    # Object can be directly checked as a boolean; response is False
    # when there are no entries loaded
    assert not aa

    # An attachment object using a custom Apprise Asset object
    # Set a cache expiry of 5 minutes (300 seconds)
    aa = AppriseAttachment(asset=AppriseAsset(), cache=300)

    # still no attachments added
    assert len(aa) == 0

    # Add a file by it's path
    path = join(TEST_VAR_DIR, 'apprise-test.gif')
    assert aa.add(path)

    # There is now 1 attachment
    assert len(aa) == 1

    # our attachment took on our cache value
    assert aa[0].cache == 300

    # we can test the object as a boolean and get a value of True now
    assert aa

    # Add another entry already in it's AttachBase format
    response = AppriseAttachment.instantiate(path, cache=True)
    assert isinstance(response, AttachBase)
    assert aa.add(response, asset=AppriseAsset())

    # There is now 2 attachments
    assert len(aa) == 2

    # Cache is initialized to True
    assert aa[1].cache is True

    # Reset our object
    aa = AppriseAttachment()

    # We can add by lists as well in a variety of formats
    attachments = (
        path,
        'file://{}?name=newfilename.gif?cache=120'.format(path),
        AppriseAttachment.instantiate(
            'file://{}?name=anotherfilename.gif'.format(path), cache=100),
    )

    # Add them
    assert aa.add(attachments, cache=False)

    # There is now 3 attachments
    assert len(aa) == 3

    # Take on our fixed cache value of False.
    # The last entry will have our set value of 100
    assert aa[0].cache is False
    # Even though we set a value of 120, we take on the value of False because
    # it was forced on the instantiate call
    assert aa[1].cache is False
    assert aa[2].cache == 100

    # We can pop the last element off of the list as well
    attachment = aa.pop()
    assert isinstance(attachment, AttachBase)
    # we can test of the attachment is valid using a boolean check:
    assert attachment
    assert len(aa) == 2
    assert attachment.path == path
    assert attachment.name == 'anotherfilename.gif'
    assert attachment.mimetype == 'image/gif'

    # elements can also be directly indexed
    assert isinstance(aa[0], AttachBase)
    assert isinstance(aa[1], AttachBase)

    with pytest.raises(IndexError):
        aa[2]

    # We can iterate over attachments too:
    for count, a in enumerate(aa):
        assert isinstance(a, AttachBase)

        # we'll never iterate more then the number of entries in our object
        assert count < len(aa)

    # Get the file-size of our image
    expected_size = getsize(path) * len(aa)

    # verify that's what we get as a result
    assert aa.size() == expected_size

    # Attachments can also be loaded during the instantiation of the
    # AppriseAttachment object
    aa = AppriseAttachment(attachments)

    # There is now 3 attachments
    assert len(aa) == 3

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

    assert aa.add(AppriseAttachment.instantiate(
        'file://{}?name=andanother.png&cache=Yes'.format(path)))
    assert aa.add(AppriseAttachment.instantiate(
        'file://{}?name=andanother.png&cache=No'.format(path)))
    AppriseAttachment.instantiate(
        'file://{}?name=andanother.png&cache=600'.format(path))
    assert aa.add(AppriseAttachment.instantiate(
        'file://{}?name=andanother.png&cache=600'.format(path)))

    assert len(aa) == 3
    assert aa[0].cache is True
    assert aa[1].cache is False
    assert aa[2].cache == 600

    # Negative cache are not allowed
    assert not aa.add(AppriseAttachment.instantiate(
        'file://{}?name=andanother.png&cache=-600'.format(path)))

    # Invalid cache value
    assert not aa.add(AppriseAttachment.instantiate(
        'file://{}?name=andanother.png'.format(path), cache='invalid'))

    # No length change
    assert len(aa) == 3

    # Reset our object
    aa.clear()

    # if instantiating attachments from the class, it will throw a TypeError
    # if attachments couldn't be loaded
    with pytest.raises(TypeError):
        AppriseAttachment('garbage://')

    # Garbage in produces garbage out
    assert aa.add(None) is False
    assert aa.add(object()) is False
    assert aa.add(42) is False

    # length remains unchanged
    assert len(aa) == 0

    # We can add by lists as well in a variety of formats
    attachments = (
        None,
        object(),
        42,
        'garbage://',
    )

    # Add our attachments
    assert aa.add(attachments) is False

    # length remains unchanged
    assert len(aa) == 0

    # test cases when file simply doesn't exist
    aa = AppriseAttachment('file://non-existant-file.png')
    # Our length is still 1
    assert len(aa) == 1
    # Our object will still return a True
    assert aa

    # However our indexed entry will not
    assert not aa[0]

    # length will return 0
    assert len(aa[0]) == 0

    # Total length will also return 0
    assert aa.size() == 0
Esempio n. 15
0
def test_config_base_config_parse():
    """
    API: ConfigBase.config_parse

    """

    # Garbage Handling
    assert isinstance(ConfigBase.config_parse(object()), list)
    assert isinstance(ConfigBase.config_parse(None), list)
    assert isinstance(ConfigBase.config_parse(''), list)
    assert isinstance(ConfigBase.config_parse(12), list)

    # Valid Text Configuration
    result = ConfigBase.config_parse("""
    # A comment line over top of a URL
    mailto://userb:[email protected]
    """, asset=AppriseAsset())
    # We expect to parse 1 entry from the above
    assert isinstance(result, list)
    assert len(result) == 1
    assert len(result[0].tags) == 0

    # Valid Configuration
    result = ConfigBase.config_parse("""
# if no version is specified then version 1 is presumed
version: 1

#
# Define your notification urls:
#
urls:
  - pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
  - mailto://test:[email protected]
  - syslog://:
      - tag: devops, admin
    """, asset=AppriseAsset())

    # We expect to parse 3 entries from the above
    assert isinstance(result, list)
    assert len(result) == 3
    assert len(result[0].tags) == 0
    assert len(result[1].tags) == 0
    assert len(result[2].tags) == 2

    # Test case where we pass in a bad format
    result = ConfigBase.config_parse("""
    ; A comment line over top of a URL
    mailto://userb:[email protected]
    """, config_format='invalid-format')

    # This is not parseable despite the valid text
    assert isinstance(result, list)
    assert len(result) == 0

    result = ConfigBase.config_parse("""
    ; A comment line over top of a URL
    mailto://userb:[email protected]
    """, config_format=ConfigFormat.TEXT)

    # Parseable
    assert isinstance(result, list)
    assert len(result) == 1
Esempio n. 16
0
def test_config_file(tmpdir):
    """
    API: ConfigFile() object

    """

    assert ConfigFile.parse_url('garbage://') is None

    # Test cases where our URL is invalid
    t = tmpdir.mkdir("testing").join("apprise")
    t.write("gnome://")

    assert ConfigFile.parse_url('file://?') is None

    # Create an Apprise asset we can reference
    asset = AppriseAsset()

    # Initialize our object
    cf = ConfigFile(path=str(t), format='text', asset=asset)

    # one entry added
    assert len(cf) == 1

    assert isinstance(cf.url(), six.string_types) is True

    # Verify that we're using the same asset
    assert cf[0].asset is asset

    # Testing of pop
    cf = ConfigFile(path=str(t), format='text')

    ref = cf[0]
    assert isinstance(ref, NotifyBase) is True

    ref_popped = cf.pop(0)
    assert isinstance(ref_popped, NotifyBase) is True

    assert ref == ref_popped

    assert len(cf) == 0

    # reference to calls on initial reference
    cf = ConfigFile(path=str(t), format='text')
    assert isinstance(cf.pop(0), NotifyBase) is True

    cf = ConfigFile(path=str(t), format='text')
    assert isinstance(cf[0], NotifyBase) is True
    # Second reference actually uses cache
    assert isinstance(cf[0], NotifyBase) is True

    cf = ConfigFile(path=str(t), format='text')
    # Itereator creation (nothing needed to assert here)
    iter(cf)
    # Second reference actually uses cache
    iter(cf)

    # Cache Handling; cache each request for 30 seconds
    results = ConfigFile.parse_url('file://{}?cache=30'.format(str(t)))
    assert isinstance(results, dict)
    cf = ConfigFile(**results)
    assert isinstance(cf.url(), six.string_types) is True
    assert isinstance(cf.read(), six.string_types) is True