mirror of
https://github.com/caronc/apprise.git
synced 2024-11-22 16:13:12 +01:00
Twitter plugin code cleanup (#750)
This commit is contained in:
parent
6d3ab9b3fd
commit
81907af448
@ -75,7 +75,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
service_url = 'https://twitter.com/'
|
service_url = 'https://twitter.com/'
|
||||||
|
|
||||||
# The default secure protocol is twitter.
|
# The default secure protocol is twitter.
|
||||||
secure_protocol = 'twitter'
|
secure_protocol = ('twitter', 'tweet')
|
||||||
|
|
||||||
# A URL that takes you to the setup/help of the specific protocol
|
# A URL that takes you to the setup/help of the specific protocol
|
||||||
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_twitter'
|
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_twitter'
|
||||||
@ -221,21 +221,21 @@ class NotifyTwitter(NotifyBase):
|
|||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
# Store our webhook mode
|
# Store our webhook mode
|
||||||
self.mode = None \
|
self.mode = self.template_args['mode']['default'] \
|
||||||
if not isinstance(mode, str) else mode.lower()
|
if not isinstance(mode, str) else mode.lower()
|
||||||
|
|
||||||
# Set Cache Flag
|
|
||||||
self.cache = cache
|
|
||||||
|
|
||||||
# Prepare Image Batch Mode Flag
|
|
||||||
self.batch = batch
|
|
||||||
|
|
||||||
if self.mode not in TWITTER_MESSAGE_MODES:
|
if self.mode not in TWITTER_MESSAGE_MODES:
|
||||||
msg = 'The Twitter message mode specified ({}) is invalid.' \
|
msg = 'The Twitter message mode specified ({}) is invalid.' \
|
||||||
.format(mode)
|
.format(mode)
|
||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
# Set Cache Flag
|
||||||
|
self.cache = cache
|
||||||
|
|
||||||
|
# Prepare Image Batch Mode Flag
|
||||||
|
self.batch = batch
|
||||||
|
|
||||||
# Track any errors
|
# Track any errors
|
||||||
has_error = False
|
has_error = False
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
|
|
||||||
has_error = True
|
has_error = True
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
'Dropped invalid user ({}) specified.'.format(target),
|
'Dropped invalid Twitter user ({}) specified.'.format(target),
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_error and not self.targets:
|
if has_error and not self.targets:
|
||||||
@ -261,6 +261,10 @@ class NotifyTwitter(NotifyBase):
|
|||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
# Initialize our cache values
|
||||||
|
self._whoami_cache = None
|
||||||
|
self._user_cache = {}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def send(self, body, title='', notify_type=NotifyType.INFO, attach=None,
|
def send(self, body, title='', notify_type=NotifyType.INFO, attach=None,
|
||||||
@ -293,7 +297,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
'Preparing Twiter attachment {}'.format(
|
'Preparing Twitter attachment {}'.format(
|
||||||
attachment.url(privacy=True)))
|
attachment.url(privacy=True)))
|
||||||
|
|
||||||
# Upload our image and get our id associated with it
|
# Upload our image and get our id associated with it
|
||||||
@ -536,16 +540,9 @@ class NotifyTwitter(NotifyBase):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Prepare a whoami key; this is to prevent conflict with other
|
if lazy and self._whoami_cache is not None:
|
||||||
# NotifyTwitter declarations that may or may not use a different
|
|
||||||
# set of authentication keys
|
|
||||||
whoami_key = '{}{}{}{}'.format(
|
|
||||||
self.ckey, self.csecret, self.akey, self.asecret)
|
|
||||||
|
|
||||||
if lazy and hasattr(NotifyTwitter, '_whoami_cache') \
|
|
||||||
and whoami_key in getattr(NotifyTwitter, '_whoami_cache'):
|
|
||||||
# Use cached response
|
# Use cached response
|
||||||
return getattr(NotifyTwitter, '_whoami_cache')[whoami_key]
|
return self._whoami_cache
|
||||||
|
|
||||||
# Contains a mapping of screen_name to id
|
# Contains a mapping of screen_name to id
|
||||||
results = {}
|
results = {}
|
||||||
@ -560,22 +557,11 @@ class NotifyTwitter(NotifyBase):
|
|||||||
if postokay:
|
if postokay:
|
||||||
try:
|
try:
|
||||||
results[response['screen_name']] = response['id']
|
results[response['screen_name']] = response['id']
|
||||||
|
self._whoami_cache = {
|
||||||
|
response['screen_name']: response['id'],
|
||||||
|
}
|
||||||
|
|
||||||
if lazy:
|
self._user_cache.update(results)
|
||||||
# Cache our response for future references
|
|
||||||
if not hasattr(NotifyTwitter, '_whoami_cache'):
|
|
||||||
setattr(
|
|
||||||
NotifyTwitter, '_whoami_cache',
|
|
||||||
{whoami_key: results})
|
|
||||||
else:
|
|
||||||
getattr(NotifyTwitter, '_whoami_cache')\
|
|
||||||
.update({whoami_key: results})
|
|
||||||
|
|
||||||
# Update our user cache as well
|
|
||||||
if not hasattr(NotifyTwitter, '_user_cache'):
|
|
||||||
setattr(NotifyTwitter, '_user_cache', results)
|
|
||||||
else:
|
|
||||||
getattr(NotifyTwitter, '_user_cache').update(results)
|
|
||||||
|
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
pass
|
pass
|
||||||
@ -595,10 +581,10 @@ class NotifyTwitter(NotifyBase):
|
|||||||
# Build a unique set of names
|
# Build a unique set of names
|
||||||
names = parse_list(screen_name)
|
names = parse_list(screen_name)
|
||||||
|
|
||||||
if lazy and hasattr(NotifyTwitter, '_user_cache'):
|
if lazy and self._user_cache:
|
||||||
# Use cached response
|
# Use cached response
|
||||||
results = {k: v for k, v in getattr(
|
results = {
|
||||||
NotifyTwitter, '_user_cache').items() if k in names}
|
k: v for k, v in self._user_cache.items() if k in names}
|
||||||
|
|
||||||
# limit our names if they already exist in our cache
|
# limit our names if they already exist in our cache
|
||||||
names = [name for name in names if name not in results]
|
names = [name for name in names if name not in results]
|
||||||
@ -612,7 +598,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
# https://developer.twitter.com/en/docs/accounts-and-users/\
|
# https://developer.twitter.com/en/docs/accounts-and-users/\
|
||||||
# follow-search-get-users/api-reference/get-users-lookup
|
# follow-search-get-users/api-reference/get-users-lookup
|
||||||
for i in range(0, len(names), 100):
|
for i in range(0, len(names), 100):
|
||||||
# Send Twitter DM
|
# Look up our names by their screen_name
|
||||||
postokay, response = self._fetch(
|
postokay, response = self._fetch(
|
||||||
self.twitter_lookup,
|
self.twitter_lookup,
|
||||||
payload={
|
payload={
|
||||||
@ -635,11 +621,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
|
|
||||||
# Cache our response for future use; this saves on un-nessisary extra
|
# Cache our response for future use; this saves on un-nessisary extra
|
||||||
# hits against the Twitter API when we already know the answer
|
# hits against the Twitter API when we already know the answer
|
||||||
if lazy:
|
self._user_cache.update(results)
|
||||||
if not hasattr(NotifyTwitter, '_user_cache'):
|
|
||||||
setattr(NotifyTwitter, '_user_cache', results)
|
|
||||||
else:
|
|
||||||
getattr(NotifyTwitter, '_user_cache').update(results)
|
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@ -686,7 +668,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
# Determine how long we should wait for or if we should wait at
|
# Determine how long we should wait for or if we should wait at
|
||||||
# all. This isn't fool-proof because we can't be sure the client
|
# all. This isn't fool-proof because we can't be sure the client
|
||||||
# time (calling this script) is completely synced up with the
|
# time (calling this script) is completely synced up with the
|
||||||
# Gitter server. One would hope we're on NTP and our clocks are
|
# Twitter server. One would hope we're on NTP and our clocks are
|
||||||
# the same allowing this to role smoothly:
|
# the same allowing this to role smoothly:
|
||||||
|
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
@ -810,7 +792,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
|
|
||||||
return '{schema}://{ckey}/{csecret}/{akey}/{asecret}' \
|
return '{schema}://{ckey}/{csecret}/{akey}/{asecret}' \
|
||||||
'/{targets}/?{params}'.format(
|
'/{targets}/?{params}'.format(
|
||||||
schema=self.secure_protocol,
|
schema=self.secure_protocol[0],
|
||||||
ckey=self.pprint(self.ckey, privacy, safe=''),
|
ckey=self.pprint(self.ckey, privacy, safe=''),
|
||||||
csecret=self.pprint(
|
csecret=self.pprint(
|
||||||
self.csecret, privacy, mode=PrivacyMode.Secret, safe=''),
|
self.csecret, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||||
@ -818,7 +800,7 @@ class NotifyTwitter(NotifyBase):
|
|||||||
asecret=self.pprint(
|
asecret=self.pprint(
|
||||||
self.asecret, privacy, mode=PrivacyMode.Secret, safe=''),
|
self.asecret, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||||
targets='/'.join(
|
targets='/'.join(
|
||||||
[NotifyTwitter.quote('@{}'.format(target), safe='')
|
[NotifyTwitter.quote('@{}'.format(target), safe='@')
|
||||||
for target in self.targets]),
|
for target in self.targets]),
|
||||||
params=NotifyTwitter.urlencode(params))
|
params=NotifyTwitter.urlencode(params))
|
||||||
|
|
||||||
@ -862,6 +844,9 @@ class NotifyTwitter(NotifyBase):
|
|||||||
results['mode'] = \
|
results['mode'] = \
|
||||||
NotifyTwitter.unquote(results['qsd']['mode'])
|
NotifyTwitter.unquote(results['qsd']['mode'])
|
||||||
|
|
||||||
|
elif results['schema'].startswith('tweet'):
|
||||||
|
results['mode'] = TwitterMessageMode.TWEET
|
||||||
|
|
||||||
results['targets'] = []
|
results['targets'] = []
|
||||||
|
|
||||||
# if a user has been defined, add it to the list of targets
|
# if a user has been defined, add it to the list of targets
|
||||||
|
@ -64,11 +64,11 @@ apprise_url_tests = (
|
|||||||
# Missing Keys
|
# Missing Keys
|
||||||
'instance': TypeError,
|
'instance': TypeError,
|
||||||
}),
|
}),
|
||||||
('twitter://consumer_key/consumer_secret/access_token/', {
|
('twitter://consumer_key/consumer_secret/atoken1/', {
|
||||||
# Missing Access Secret
|
# Missing Access Secret
|
||||||
'instance': TypeError,
|
'instance': TypeError,
|
||||||
}),
|
}),
|
||||||
('twitter://consumer_key/consumer_secret/access_token/access_secret', {
|
('twitter://consumer_key/consumer_secret/atoken2/access_secret', {
|
||||||
# No user mean's we message ourselves
|
# No user mean's we message ourselves
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# Expected notify() response False (because we won't be able
|
# Expected notify() response False (because we won't be able
|
||||||
@ -76,9 +76,9 @@ apprise_url_tests = (
|
|||||||
'notify_response': False,
|
'notify_response': False,
|
||||||
|
|
||||||
# Our expected url(privacy=True) startswith() response:
|
# Our expected url(privacy=True) startswith() response:
|
||||||
'privacy_url': 'twitter://c...y/****/a...n/****',
|
'privacy_url': 'twitter://c...y/****/a...2/****',
|
||||||
}),
|
}),
|
||||||
('twitter://consumer_key/consumer_secret/access_token/access_secret'
|
('twitter://consumer_key/consumer_secret/atoken3/access_secret'
|
||||||
'?cache=no', {
|
'?cache=no', {
|
||||||
# No user mean's we message ourselves
|
# No user mean's we message ourselves
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
@ -90,7 +90,7 @@ apprise_url_tests = (
|
|||||||
'media_id': 123,
|
'media_id': 123,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
('twitter://consumer_key/consumer_secret/access_token/access_secret', {
|
('twitter://consumer_key/consumer_secret/atoken4/access_secret', {
|
||||||
# No user mean's we message ourselves
|
# No user mean's we message ourselves
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# However we'll be okay if we return a proper response
|
# However we'll be okay if we return a proper response
|
||||||
@ -102,7 +102,7 @@ apprise_url_tests = (
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
# A duplicate of the entry above, this will cause cache to be referenced
|
# A duplicate of the entry above, this will cause cache to be referenced
|
||||||
('twitter://consumer_key/consumer_secret/access_token/access_secret', {
|
('twitter://consumer_key/consumer_secret/atoken5/access_secret', {
|
||||||
# No user mean's we message ourselves
|
# No user mean's we message ourselves
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# However we'll be okay if we return a proper response
|
# However we'll be okay if we return a proper response
|
||||||
@ -115,7 +115,7 @@ apprise_url_tests = (
|
|||||||
}),
|
}),
|
||||||
# handle cases where the screen_name is missing from the response causing
|
# handle cases where the screen_name is missing from the response causing
|
||||||
# an exception during parsing
|
# an exception during parsing
|
||||||
('twitter://consumer_key/consumer_secret2/access_token/access_secret', {
|
('twitter://consumer_key/consumer_secret2/atoken6/access_secret', {
|
||||||
# No user mean's we message ourselves
|
# No user mean's we message ourselves
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# However we'll be okay if we return a proper response
|
# However we'll be okay if we return a proper response
|
||||||
@ -127,14 +127,14 @@ apprise_url_tests = (
|
|||||||
# due to a mangled response_text we'll fail
|
# due to a mangled response_text we'll fail
|
||||||
'notify_response': False,
|
'notify_response': False,
|
||||||
}),
|
}),
|
||||||
('twitter://user@consumer_key/csecret2/access_token/access_secret/-/%/', {
|
('twitter://user@consumer_key/csecret2/atoken7/access_secret/-/%/', {
|
||||||
# One Invalid User
|
# One Invalid User
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# Expected notify() response False (because we won't be able
|
# Expected notify() response False (because we won't be able
|
||||||
# to detect our user)
|
# to detect our user)
|
||||||
'notify_response': False,
|
'notify_response': False,
|
||||||
}),
|
}),
|
||||||
('twitter://user@consumer_key/csecret/access_token/access_secret'
|
('twitter://user@consumer_key/csecret/atoken8/access_secret'
|
||||||
'?cache=No&batch=No', {
|
'?cache=No&batch=No', {
|
||||||
# No Cache & No Batch
|
# No Cache & No Batch
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
@ -143,7 +143,7 @@ apprise_url_tests = (
|
|||||||
'screen_name': 'user'
|
'screen_name': 'user'
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
('twitter://user@consumer_key/csecret/access_token/access_secret', {
|
('twitter://user@consumer_key/csecret/atoken9/access_secret', {
|
||||||
# We're good!
|
# We're good!
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
'requests_response_text': [{
|
'requests_response_text': [{
|
||||||
@ -151,21 +151,20 @@ apprise_url_tests = (
|
|||||||
'screen_name': 'user'
|
'screen_name': 'user'
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
# A duplicate of the entry above, this will cause cache to be referenced
|
('twitter://user@consumer_key/csecret/atoken11/access_secret', {
|
||||||
# for this reason, we don't even need to return a valid response
|
|
||||||
('twitter://user@consumer_key/csecret/access_token/access_secret', {
|
|
||||||
# We're identifying the same user we already sent to
|
# We're identifying the same user we already sent to
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
|
'notify_response': False,
|
||||||
}),
|
}),
|
||||||
('twitter://ckey/csecret/access_token/access_secret?mode=tweet', {
|
('tweet://ckey/csecret/atoken12/access_secret', {
|
||||||
# A Public Tweet
|
# A Public Tweet
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
}),
|
}),
|
||||||
('twitter://user@ckey/csecret/access_token/access_secret?mode=invalid', {
|
('twitter://user@ckey/csecret/atoken13/access_secret?mode=invalid', {
|
||||||
# An invalid mode
|
# An invalid mode
|
||||||
'instance': TypeError,
|
'instance': TypeError,
|
||||||
}),
|
}),
|
||||||
('twitter://usera@consumer_key/consumer_secret/access_token/'
|
('twitter://usera@consumer_key/consumer_secret/atoken14/'
|
||||||
'access_secret/user/?to=userb', {
|
'access_secret/user/?to=userb', {
|
||||||
# We're good!
|
# We're good!
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
@ -180,19 +179,19 @@ apprise_url_tests = (
|
|||||||
'id': 123,
|
'id': 123,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
('twitter://ckey/csecret/access_token/access_secret', {
|
('twitter://ckey/csecret/atoken15/access_secret', {
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# throw a bizzare code forcing us to fail to look it up
|
# throw a bizzare code forcing us to fail to look it up
|
||||||
'response': False,
|
'response': False,
|
||||||
'requests_response_code': 999,
|
'requests_response_code': 999,
|
||||||
}),
|
}),
|
||||||
('twitter://ckey/csecret/access_token/access_secret', {
|
('twitter://ckey/csecret/atoken16/access_secret', {
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# Throws a series of connection and transfer exceptions when this flag
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
# is set and tests that we gracfully handle them
|
# is set and tests that we gracfully handle them
|
||||||
'test_requests_exceptions': True,
|
'test_requests_exceptions': True,
|
||||||
}),
|
}),
|
||||||
('twitter://ckey/csecret/access_token/access_secret?mode=tweet', {
|
('twitter://ckey/csecret/atoken17/access_secret?mode=tweet', {
|
||||||
'instance': NotifyTwitter,
|
'instance': NotifyTwitter,
|
||||||
# Throws a series of connection and transfer exceptions when this flag
|
# Throws a series of connection and transfer exceptions when this flag
|
||||||
# is set and tests that we gracfully handle them
|
# is set and tests that we gracfully handle them
|
||||||
@ -320,7 +319,7 @@ def test_plugin_twitter_general(mock_post, mock_get):
|
|||||||
assert obj.send(body="test") is True
|
assert obj.send(body="test") is True
|
||||||
|
|
||||||
# Flush our cache forcing it's re-creating
|
# Flush our cache forcing it's re-creating
|
||||||
del NotifyTwitter._user_cache
|
NotifyTwitter._user_cache = {}
|
||||||
assert obj.send(body="test") is True
|
assert obj.send(body="test") is True
|
||||||
|
|
||||||
# Cause content response to be None
|
# Cause content response to be None
|
||||||
@ -350,7 +349,7 @@ def test_plugin_twitter_general(mock_post, mock_get):
|
|||||||
# Set ourselves up to handle whoami calls
|
# Set ourselves up to handle whoami calls
|
||||||
|
|
||||||
# Flush out our cache
|
# Flush out our cache
|
||||||
del NotifyTwitter._user_cache
|
NotifyTwitter._user_cache = {}
|
||||||
|
|
||||||
response_obj = {
|
response_obj = {
|
||||||
'screen_name': screen_name,
|
'screen_name': screen_name,
|
||||||
@ -367,12 +366,12 @@ def test_plugin_twitter_general(mock_post, mock_get):
|
|||||||
assert obj.send(body="test") is True
|
assert obj.send(body="test") is True
|
||||||
|
|
||||||
# Alter the key forcing us to look up a new value of ourselves again
|
# Alter the key forcing us to look up a new value of ourselves again
|
||||||
del NotifyTwitter._user_cache
|
NotifyTwitter._user_cache = {}
|
||||||
del NotifyTwitter._whoami_cache
|
NotifyTwitter._whoami_cache = None
|
||||||
obj.ckey = 'different.then.it.was'
|
obj.ckey = 'different.then.it.was'
|
||||||
assert obj.send(body="test") is True
|
assert obj.send(body="test") is True
|
||||||
|
|
||||||
del NotifyTwitter._whoami_cache
|
NotifyTwitter._whoami_cache = None
|
||||||
obj.ckey = 'different.again'
|
obj.ckey = 'different.again'
|
||||||
assert obj.send(body="test") is True
|
assert obj.send(body="test") is True
|
||||||
|
|
||||||
@ -440,10 +439,17 @@ def test_plugin_twitter_dm_attachments(mock_get, mock_post):
|
|||||||
'id': 9876,
|
'id': 9876,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Epoch time:
|
||||||
|
epoch = datetime.utcfromtimestamp(0)
|
||||||
|
|
||||||
# Prepare a good DM response
|
# Prepare a good DM response
|
||||||
good_dm_response = mock.Mock()
|
good_dm_response = mock.Mock()
|
||||||
good_dm_response.content = dumps(good_dm_response_obj)
|
good_dm_response.content = dumps(good_dm_response_obj)
|
||||||
good_dm_response.status_code = requests.codes.ok
|
good_dm_response.status_code = requests.codes.ok
|
||||||
|
good_dm_response.headers = {
|
||||||
|
'x-rate-limit-reset': (datetime.utcnow() - epoch).total_seconds(),
|
||||||
|
'x-rate-limit-remaining': 1,
|
||||||
|
}
|
||||||
|
|
||||||
# Prepare bad response
|
# Prepare bad response
|
||||||
bad_response = mock.Mock()
|
bad_response = mock.Mock()
|
||||||
@ -540,7 +546,10 @@ def test_plugin_twitter_dm_attachments(mock_get, mock_post):
|
|||||||
body='body', title='title', notify_type=NotifyType.INFO,
|
body='body', title='title', notify_type=NotifyType.INFO,
|
||||||
attach=attach) is False
|
attach=attach) is False
|
||||||
|
|
||||||
assert mock_get.call_count == 0
|
assert mock_get.call_count == 1
|
||||||
|
assert mock_get.call_args_list[0][0][0] == \
|
||||||
|
'https://api.twitter.com/1.1/account/verify_credentials.json'
|
||||||
|
|
||||||
# No get request as cached response is used
|
# No get request as cached response is used
|
||||||
assert mock_post.call_count == 2
|
assert mock_post.call_count == 2
|
||||||
assert mock_post.call_args_list[0][0][0] == \
|
assert mock_post.call_args_list[0][0][0] == \
|
||||||
|
Loading…
Reference in New Issue
Block a user