def run(self, url, meta, mock_post, mock_get): """ Run a specific test """ # Disable Throttling to speed testing plugins.NotifyBase.request_rate_per_sec = 0 # 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) # Our expected privacy url # Don't set this if don't need to check it's value privacy_url = meta.get('privacy_url') # Our regular expression url_matches = meta.get('url_matches') # Allow us to force the server response code to be something other then # the defaults requests_response_code = meta.get( 'requests_response_code', requests.codes.ok if response else requests.codes.not_found, ) # Allow us to force the server response text to be something other then # the defaults requests_response_text = meta.get('requests_response_text') if not isinstance(requests_response_text, six.string_types): # Convert to string requests_response_text = dumps(requests_response_text) # Whether or not we should include an image with our request; unless # otherwise specified, we assume that images are to be included include_image = meta.get('include_image', True) if include_image: # a default asset asset = AppriseAsset() else: # Disable images asset = AppriseAsset(image_path_mask=False, image_url_mask=False) asset.image_url_logo = None test_requests_exceptions = meta.get('test_requests_exceptions', False) # Mock our request object robj = mock.Mock() robj.content = u'' mock_get.return_value = robj mock_post.return_value = robj if test_requests_exceptions is False: # Handle our default response mock_post.return_value.status_code = requests_response_code mock_get.return_value.status_code = requests_response_code # Handle our default text response mock_get.return_value.content = requests_response_text mock_post.return_value.content = requests_response_text mock_get.return_value.text = requests_response_text mock_post.return_value.text = requests_response_text # Ensure there is no side effect set mock_post.side_effect = None mock_get.side_effect = None else: # Handle exception testing; first we turn the boolean flag # into a list of exceptions test_requests_exceptions = self.req_exceptions try: # We can now instantiate our object: obj = Apprise.instantiate(url, asset=asset, suppress_exceptions=False) except Exception as e: # Handle our exception if instance is None: print('%s %s' % (url, str(e))) raise e if not isinstance(e, instance): print('%s %s' % (url, str(e))) raise e # We're okay if we get here return 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 be a {})".format(url, instance)) assert False # We're done because we got the results we expected return if instance is None: # Expected None but didn't get it print('%s instantiated %s (but expected None)' % (url, str(obj))) assert False if not isinstance(obj, instance): print('%s instantiated %s (but expected %s)' % (url, type(instance), str(obj))) assert False if isinstance(obj, plugins.NotifyBase): # Ensure we are not performing any type of thorttling obj.request_rate_per_sec = 0 # We loaded okay; now lets make sure we can reverse # this url assert isinstance(obj.url(), six.string_types) is True # Test url() with privacy=True assert isinstance(obj.url(privacy=True), six.string_types) is True # Some Simple Invalid Instance Testing assert instance.parse_url(None) is None assert instance.parse_url(object) is None assert instance.parse_url(42) is None if privacy_url: # Assess that our privacy url is as expected if not obj.url(privacy=True).startswith(privacy_url): raise AssertionError( "Privacy URL: '{}' != expected '{}'".format( obj.url(privacy=True)[:len(privacy_url)], privacy_url)) if url_matches: # Assess that our URL matches a set regex assert re.search(url_matches, obj.url()) # 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 # Tidy our object del obj_cmp 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) is True assert getattr(key, obj) == val try: self.__notify(url, obj, meta, asset) except AssertionError: # Don't mess with these entries print('%s AssertionError' % url) raise # Tidy our object and allow any possible defined deconstructors to # be executed. del obj
def notify(self, servers, body, title, notify_type=NotifyType.INFO, body_format=NotifyFormat.MARKDOWN): """ processes list of servers specified """ # Decode our data body = decode(body) title = decode(title) # Apprise Asset Object asset = AppriseAsset() asset.app_id = 'NZB-Notify' asset.app_desc = 'NZB Notification' asset.app_url = 'https://github.com/caronc/nzb-notify' asset.image_path_mask = join(dirname(__file__), 'Notify', 'apprise-theme', '{THEME}', 'apprise-{TYPE}-{XY}.png') # Image URL Mask asset.image_url_mask = \ 'https://raw.githubusercontent.com/caronc/nzb-notify/master/' \ 'Notify/apprise-theme/{THEME}/' \ 'apprise-{TYPE}-{XY}{EXTENSION}' # Application Logo asset.image_url_logo = \ 'https://raw.githubusercontent.com/caronc/nzb-notify/master/' \ 'Notify/apprise-theme/{THEME}/' \ 'apprise-logo.png' # Include Image Flag _url = self.parse_url(self.get('IncludeImage')) # Define some globals to use in this function image_path = None image_url = None if _url: # Toggle our include image flag right away to True include_image = True # Get some more details if not re.match('^(https?|file)$', _url['schema'], re.IGNORECASE): self.logger.error( 'An invalid image url protocol (%s://) was specified.' % _url['schema'], ) return False if _url['schema'] == 'file': if not isfile(_url['fullpath']): self.logger.error( 'The specified file %s was not found.' % _url['fullpath'], ) return False image_path = _url['fullpath'] else: # We're dealing with a web request image_url = _url['url'] else: # Dealing with the old way of doing things; just toggling a # true/false flag include_image = self.parse_bool(self.get('IncludeImage'), False) if isinstance(servers, six.string_types): # servers can be a list of URLs, or it can be # a string which will be parsed into this list # we wanted. servers = self.parse_list(self.get('Servers', '')) # Create our apprise object a = Apprise(asset=asset) for server in servers: # Add our URL if not a.add(server): # Validation Failure self.logger.error('Could not initialize %s instance.' % server, ) continue # Notify our servers a.notify(body=body, title=title, notify_type=notify_type, body_format=body_format) # Always return true return True