mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-16 20:29:55 +01:00
* Update AUTHORS.rst * Update AUTHORS.rst * Add bot_data to CallbackContext as global memory * Minor fixes in docstrings * Incorp. req. changes, Flake8 Fixes * Persist before stop * Fix CI errors * Implement #1342 for bot_data * Add check pickle_persistence_only_bot similar to #1462 * Fix test_persistence * Try dispatching error before logging it * Fix test Co-authored-by: Eldinnie <Eldinnie@users.noreply.github.com>
This commit is contained in:
parent
43bfebb150
commit
f6b663f175
21 changed files with 427 additions and 33 deletions
|
@ -25,6 +25,8 @@ class BasePersistence(object):
|
|||
|
||||
All relevant methods must be overwritten. This means:
|
||||
|
||||
* If :attr:`store_bot_data` is ``True`` you must overwrite :meth:`get_bot_data` and
|
||||
:meth:`update_bot_data`.
|
||||
* If :attr:`store_chat_data` is ``True`` you must overwrite :meth:`get_chat_data` and
|
||||
:meth:`update_chat_data`.
|
||||
* If :attr:`store_user_data` is ``True`` you must overwrite :meth:`get_user_data` and
|
||||
|
@ -38,17 +40,22 @@ class BasePersistence(object):
|
|||
persistence class.
|
||||
store_chat_data (:obj:`bool`): Optional. Whether chat_data should be saved by this
|
||||
persistence class.
|
||||
store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this
|
||||
persistence class.
|
||||
|
||||
Args:
|
||||
store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this
|
||||
persistence class. Default is ``True``.
|
||||
store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this
|
||||
persistence class. Default is ``True`` .
|
||||
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
|
||||
persistence class. Default is ``True`` .
|
||||
"""
|
||||
|
||||
def __init__(self, store_user_data=True, store_chat_data=True):
|
||||
def __init__(self, store_user_data=True, store_chat_data=True, store_bot_data=True):
|
||||
self.store_user_data = store_user_data
|
||||
self.store_chat_data = store_chat_data
|
||||
self.store_bot_data = store_bot_data
|
||||
|
||||
def get_user_data(self):
|
||||
""""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
|
@ -70,6 +77,16 @@ class BasePersistence(object):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_bot_data(self):
|
||||
""""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
|
||||
persistence object. It should return the bot_data if stored, or an empty
|
||||
``dict``.
|
||||
|
||||
Returns:
|
||||
:obj:`defaultdict`: The restored bot data.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_conversations(self, name):
|
||||
""""Will be called by :class:`telegram.ext.Dispatcher` when a
|
||||
:class:`telegram.ext.ConversationHandler` is added if
|
||||
|
@ -111,7 +128,16 @@ class BasePersistence(object):
|
|||
|
||||
Args:
|
||||
chat_id (:obj:`int`): The chat the data might have been changed for.
|
||||
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.chat_data` [user_id].
|
||||
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.chat_data` [chat_id].
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def update_bot_data(self, data):
|
||||
"""Will be called by the :class:`telegram.ext.Dispatcher` after a handler has
|
||||
handled an update.
|
||||
|
||||
Args:
|
||||
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.bot_data` .
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ class CallbackContext(object):
|
|||
that you think you added will not be present.
|
||||
|
||||
Attributes:
|
||||
bot_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
update it will be the same ``dict``.
|
||||
chat_data (:obj:`dict`, optional): A dict that can be used to keep any data in. For each
|
||||
update from the same chat id it will be the same ``dict``.
|
||||
|
||||
|
@ -80,6 +82,7 @@ class CallbackContext(object):
|
|||
raise ValueError('CallbackContext should not be used with a non context aware '
|
||||
'dispatcher!')
|
||||
self._dispatcher = dispatcher
|
||||
self._bot_data = dispatcher.bot_data
|
||||
self._chat_data = None
|
||||
self._user_data = None
|
||||
self.args = None
|
||||
|
@ -92,6 +95,15 @@ class CallbackContext(object):
|
|||
""":class:`telegram.ext.Dispatcher`: The dispatcher associated with this context."""
|
||||
return self._dispatcher
|
||||
|
||||
@property
|
||||
def bot_data(self):
|
||||
return self._bot_data
|
||||
|
||||
@bot_data.setter
|
||||
def bot_data(self, value):
|
||||
raise AttributeError("You can not assign a new value to bot_data, see "
|
||||
"https://git.io/fjxKe")
|
||||
|
||||
@property
|
||||
def chat_data(self):
|
||||
return self._chat_data
|
||||
|
@ -119,6 +131,7 @@ class CallbackContext(object):
|
|||
@classmethod
|
||||
def from_update(cls, update, dispatcher):
|
||||
self = cls(dispatcher)
|
||||
|
||||
if update is not None and isinstance(update, Update):
|
||||
chat = update.effective_chat
|
||||
user = update.effective_user
|
||||
|
|
|
@ -31,36 +31,51 @@ from telegram.ext import BasePersistence
|
|||
|
||||
|
||||
class DictPersistence(BasePersistence):
|
||||
"""Using python's dicts and json for making you bot persistent.
|
||||
"""Using python's dicts and json for making your bot persistent.
|
||||
|
||||
Attributes:
|
||||
store_user_data (:obj:`bool`): Whether user_data should be saved by this
|
||||
persistence class.
|
||||
store_chat_data (:obj:`bool`): Whether chat_data should be saved by this
|
||||
persistence class.
|
||||
store_bot_data (:obj:`bool`): Whether bot_data should be saved by this
|
||||
persistence class.
|
||||
|
||||
Args:
|
||||
store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this
|
||||
persistence class. Default is ``True``.
|
||||
store_chat_data (:obj:`bool`, optional): Whether user_data should be saved by this
|
||||
persistence class. Default is ``True``.
|
||||
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
|
||||
persistence class. Default is ``True`` .
|
||||
user_data_json (:obj:`str`, optional): Json string that will be used to reconstruct
|
||||
user_data on creating this persistence. Default is ``""``.
|
||||
chat_data_json (:obj:`str`, optional): Json string that will be used to reconstruct
|
||||
chat_data on creating this persistence. Default is ``""``.
|
||||
bot_data_json (:obj:`str`, optional): Json string that will be used to reconstruct
|
||||
bot_data on creating this persistence. Default is ``""``.
|
||||
conversations_json (:obj:`str`, optional): Json string that will be used to reconstruct
|
||||
conversation on creating this persistence. Default is ``""``.
|
||||
"""
|
||||
|
||||
def __init__(self, store_user_data=True, store_chat_data=True, user_data_json='',
|
||||
chat_data_json='', conversations_json=''):
|
||||
self.store_user_data = store_user_data
|
||||
self.store_chat_data = store_chat_data
|
||||
def __init__(self,
|
||||
store_user_data=True,
|
||||
store_chat_data=True,
|
||||
store_bot_data=True,
|
||||
user_data_json='',
|
||||
chat_data_json='',
|
||||
bot_data_json='',
|
||||
conversations_json=''):
|
||||
super(DictPersistence, self).__init__(store_user_data=store_user_data,
|
||||
store_chat_data=store_chat_data,
|
||||
store_bot_data=store_bot_data)
|
||||
self._user_data = None
|
||||
self._chat_data = None
|
||||
self._bot_data = None
|
||||
self._conversations = None
|
||||
self._user_data_json = None
|
||||
self._chat_data_json = None
|
||||
self._bot_data_json = None
|
||||
self._conversations_json = None
|
||||
if user_data_json:
|
||||
try:
|
||||
|
@ -74,6 +89,14 @@ class DictPersistence(BasePersistence):
|
|||
self._chat_data_json = chat_data_json
|
||||
except (ValueError, AttributeError):
|
||||
raise TypeError("Unable to deserialize chat_data_json. Not valid JSON")
|
||||
if bot_data_json:
|
||||
try:
|
||||
self._bot_data = json.loads(bot_data_json)
|
||||
self._bot_data_json = bot_data_json
|
||||
except (ValueError, AttributeError):
|
||||
raise TypeError("Unable to deserialize bot_data_json. Not valid JSON")
|
||||
if not isinstance(self._bot_data, dict):
|
||||
raise TypeError("bot_data_json must be serialized dict")
|
||||
|
||||
if conversations_json:
|
||||
try:
|
||||
|
@ -108,6 +131,19 @@ class DictPersistence(BasePersistence):
|
|||
else:
|
||||
return json.dumps(self.chat_data)
|
||||
|
||||
@property
|
||||
def bot_data(self):
|
||||
""":obj:`dict`: The bot_data as a dict"""
|
||||
return self._bot_data
|
||||
|
||||
@property
|
||||
def bot_data_json(self):
|
||||
""":obj:`str`: The bot_data serialized as a JSON-string."""
|
||||
if self._bot_data_json:
|
||||
return self._bot_data_json
|
||||
else:
|
||||
return json.dumps(self.bot_data)
|
||||
|
||||
@property
|
||||
def conversations(self):
|
||||
""":obj:`dict`: The conversations as a dict"""
|
||||
|
@ -145,6 +181,18 @@ class DictPersistence(BasePersistence):
|
|||
self._chat_data = defaultdict(dict)
|
||||
return deepcopy(self.chat_data)
|
||||
|
||||
def get_bot_data(self):
|
||||
"""Returns the bot_data created from the ``bot_data_json`` or an empty dict.
|
||||
|
||||
Returns:
|
||||
:obj:`defaultdict`: The restored user data.
|
||||
"""
|
||||
if self.bot_data:
|
||||
pass
|
||||
else:
|
||||
self._bot_data = {}
|
||||
return deepcopy(self.bot_data)
|
||||
|
||||
def get_conversations(self, name):
|
||||
"""Returns the conversations created from the ``conversations_json`` or an empty
|
||||
defaultdict.
|
||||
|
@ -194,3 +242,14 @@ class DictPersistence(BasePersistence):
|
|||
return
|
||||
self._chat_data[chat_id] = data
|
||||
self._chat_data_json = None
|
||||
|
||||
def update_bot_data(self, data):
|
||||
"""Will update the bot_data (if changed).
|
||||
|
||||
Args:
|
||||
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.bot_data`.
|
||||
"""
|
||||
if self._bot_data == data:
|
||||
return
|
||||
self._bot_data = data.copy()
|
||||
self._bot_data_json = None
|
||||
|
|
|
@ -79,6 +79,7 @@ class Dispatcher(object):
|
|||
decorator.
|
||||
user_data (:obj:`defaultdict`): A dictionary handlers can use to store data for the user.
|
||||
chat_data (:obj:`defaultdict`): A dictionary handlers can use to store data for the chat.
|
||||
bot_data (:obj:`dict`): A dictionary handlers can use to store data for the bot.
|
||||
persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to
|
||||
store data that should be persistent over restarts
|
||||
|
||||
|
@ -121,8 +122,8 @@ class Dispatcher(object):
|
|||
TelegramDeprecationWarning, stacklevel=3)
|
||||
|
||||
self.user_data = defaultdict(dict)
|
||||
""":obj:`dict`: A dictionary handlers can use to store data for the user."""
|
||||
self.chat_data = defaultdict(dict)
|
||||
self.bot_data = {}
|
||||
if persistence:
|
||||
if not isinstance(persistence, BasePersistence):
|
||||
raise TypeError("persistence should be based on telegram.ext.BasePersistence")
|
||||
|
@ -135,6 +136,10 @@ class Dispatcher(object):
|
|||
self.chat_data = self.persistence.get_chat_data()
|
||||
if not isinstance(self.chat_data, defaultdict):
|
||||
raise ValueError("chat_data must be of type defaultdict")
|
||||
if self.persistence.store_bot_data:
|
||||
self.bot_data = self.persistence.get_bot_data()
|
||||
if not isinstance(self.bot_data, dict):
|
||||
raise ValueError("bot_data must be of type dict")
|
||||
else:
|
||||
self.persistence = None
|
||||
|
||||
|
@ -327,6 +332,17 @@ class Dispatcher(object):
|
|||
|
||||
"""
|
||||
if self.persistence and isinstance(update, Update):
|
||||
if self.persistence.store_bot_data:
|
||||
try:
|
||||
self.persistence.update_bot_data(self.bot_data)
|
||||
except Exception as e:
|
||||
try:
|
||||
self.dispatch_error(update, e)
|
||||
except Exception:
|
||||
message = 'Saving bot data raised an error and an ' \
|
||||
'uncaught error was raised while handling ' \
|
||||
'the error with an error_handler'
|
||||
self.logger.exception(message)
|
||||
if self.persistence.store_chat_data and update.effective_chat:
|
||||
chat_id = update.effective_chat.id
|
||||
try:
|
||||
|
@ -456,9 +472,11 @@ class Dispatcher(object):
|
|||
self.groups.remove(group)
|
||||
|
||||
def update_persistence(self):
|
||||
"""Update :attr:`user_data` and :attr:`chat_data` in :attr:`persistence`.
|
||||
"""Update :attr:`user_data`, :attr:`chat_data` and :attr:`bot_data` in :attr:`persistence`.
|
||||
"""
|
||||
if self.persistence:
|
||||
if self.persistence.store_bot_data:
|
||||
self.persistence.update_bot_data(self.bot_data)
|
||||
if self.persistence.store_chat_data:
|
||||
for chat_id in self.chat_data:
|
||||
self.persistence.update_chat_data(chat_id, self.chat_data[chat_id])
|
||||
|
|
|
@ -34,6 +34,8 @@ class PicklePersistence(BasePersistence):
|
|||
persistence class.
|
||||
store_chat_data (:obj:`bool`): Optional. Whether user_data should be saved by this
|
||||
persistence class.
|
||||
store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this
|
||||
persistence class.
|
||||
single_file (:obj:`bool`): Optional. When ``False`` will store 3 sperate files of
|
||||
`filename_user_data`, `filename_chat_data` and `filename_conversations`. Default is
|
||||
``True``.
|
||||
|
@ -48,6 +50,8 @@ class PicklePersistence(BasePersistence):
|
|||
persistence class. Default is ``True``.
|
||||
store_chat_data (:obj:`bool`, optional): Whether user_data should be saved by this
|
||||
persistence class. Default is ``True``.
|
||||
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
|
||||
persistence class. Default is ``True`` .
|
||||
single_file (:obj:`bool`, optional): When ``False`` will store 3 sperate files of
|
||||
`filename_user_data`, `filename_chat_data` and `filename_conversations`. Default is
|
||||
``True``.
|
||||
|
@ -56,15 +60,21 @@ class PicklePersistence(BasePersistence):
|
|||
on any transaction *and* on call fo :meth:`flush`. Default is ``False``.
|
||||
"""
|
||||
|
||||
def __init__(self, filename, store_user_data=True, store_chat_data=True, single_file=True,
|
||||
def __init__(self, filename,
|
||||
store_user_data=True,
|
||||
store_chat_data=True,
|
||||
store_bot_data=True,
|
||||
single_file=True,
|
||||
on_flush=False):
|
||||
super(PicklePersistence, self).__init__(store_user_data=store_user_data,
|
||||
store_chat_data=store_chat_data,
|
||||
store_bot_data=store_bot_data)
|
||||
self.filename = filename
|
||||
self.store_user_data = store_user_data
|
||||
self.store_chat_data = store_chat_data
|
||||
self.single_file = single_file
|
||||
self.on_flush = on_flush
|
||||
self.user_data = None
|
||||
self.chat_data = None
|
||||
self.bot_data = None
|
||||
self.conversations = None
|
||||
|
||||
def load_singlefile(self):
|
||||
|
@ -74,11 +84,13 @@ class PicklePersistence(BasePersistence):
|
|||
all = pickle.load(f)
|
||||
self.user_data = defaultdict(dict, all['user_data'])
|
||||
self.chat_data = defaultdict(dict, all['chat_data'])
|
||||
self.bot_data = all['bot_data']
|
||||
self.conversations = all['conversations']
|
||||
except IOError:
|
||||
self.conversations = {}
|
||||
self.user_data = defaultdict(dict)
|
||||
self.chat_data = defaultdict(dict)
|
||||
self.bot_data = {}
|
||||
except pickle.UnpicklingError:
|
||||
raise TypeError("File {} does not contain valid pickle data".format(filename))
|
||||
except Exception:
|
||||
|
@ -98,7 +110,7 @@ class PicklePersistence(BasePersistence):
|
|||
def dump_singlefile(self):
|
||||
with open(self.filename, "wb") as f:
|
||||
all = {'conversations': self.conversations, 'user_data': self.user_data,
|
||||
'chat_data': self.chat_data}
|
||||
'chat_data': self.chat_data, 'bot_data': self.bot_data}
|
||||
pickle.dump(all, f)
|
||||
|
||||
def dump_file(self, filename, data):
|
||||
|
@ -145,6 +157,24 @@ class PicklePersistence(BasePersistence):
|
|||
self.load_singlefile()
|
||||
return deepcopy(self.chat_data)
|
||||
|
||||
def get_bot_data(self):
|
||||
"""Returns the bot_data from the pickle file if it exsists or an empty dict.
|
||||
|
||||
Returns:
|
||||
:obj:`defaultdict`: The restored bot data.
|
||||
"""
|
||||
if self.bot_data:
|
||||
pass
|
||||
elif not self.single_file:
|
||||
filename = "{}_bot_data".format(self.filename)
|
||||
data = self.load_file(filename)
|
||||
if not data:
|
||||
data = {}
|
||||
self.bot_data = data
|
||||
else:
|
||||
self.load_singlefile()
|
||||
return deepcopy(self.bot_data)
|
||||
|
||||
def get_conversations(self, name):
|
||||
"""Returns the conversations from the pickle file if it exsists or an empty defaultdict.
|
||||
|
||||
|
@ -221,6 +251,23 @@ class PicklePersistence(BasePersistence):
|
|||
else:
|
||||
self.dump_singlefile()
|
||||
|
||||
def update_bot_data(self, data):
|
||||
"""Will update the bot_data (if changed) and depending on :attr:`on_flush` save the
|
||||
pickle file.
|
||||
|
||||
Args:
|
||||
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.bot_data`.
|
||||
"""
|
||||
if self.bot_data == data:
|
||||
return
|
||||
self.bot_data = data.copy()
|
||||
if not self.on_flush:
|
||||
if not self.single_file:
|
||||
filename = "{}_bot_data".format(self.filename)
|
||||
self.dump_file(filename, self.bot_data)
|
||||
else:
|
||||
self.dump_singlefile()
|
||||
|
||||
def flush(self):
|
||||
""" Will save all data in memory to pickle file(s).
|
||||
"""
|
||||
|
@ -232,5 +279,7 @@ class PicklePersistence(BasePersistence):
|
|||
self.dump_file("{}_user_data".format(self.filename), self.user_data)
|
||||
if self.chat_data:
|
||||
self.dump_file("{}_chat_data".format(self.filename), self.chat_data)
|
||||
if self.bot_data:
|
||||
self.dump_file("{}_bot_data".format(self.filename), self.bot_data)
|
||||
if self.conversations:
|
||||
self.dump_file("{}_conversations".format(self.filename), self.conversations)
|
||||
|
|
2
telegram/vendor/ptb_urllib3
vendored
2
telegram/vendor/ptb_urllib3
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 1954df03958b164483282330b3a58092c070bc7a
|
||||
Subproject commit d2403a79fc38afbdd9aba8a05d274a83dc8bb412
|
|
@ -107,6 +107,7 @@ def dp(_dp):
|
|||
_dp.update_queue.get(False)
|
||||
_dp.chat_data = defaultdict(dict)
|
||||
_dp.user_data = defaultdict(dict)
|
||||
_dp.bot_data = {}
|
||||
_dp.persistence = None
|
||||
_dp.handlers = {}
|
||||
_dp.groups = []
|
||||
|
|
|
@ -35,6 +35,7 @@ class TestCallbackContext(object):
|
|||
assert callback_context.job is job
|
||||
assert callback_context.chat_data is None
|
||||
assert callback_context.user_data is None
|
||||
assert callback_context.bot_data is cdp.bot_data
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
@ -46,15 +47,18 @@ class TestCallbackContext(object):
|
|||
|
||||
assert callback_context.chat_data == {}
|
||||
assert callback_context.user_data == {}
|
||||
assert callback_context.bot_data is cdp.bot_data
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
||||
callback_context_same_user_chat = CallbackContext.from_update(update, cdp)
|
||||
|
||||
callback_context.bot_data['test'] = 'bot'
|
||||
callback_context.chat_data['test'] = 'chat'
|
||||
callback_context.user_data['test'] = 'user'
|
||||
|
||||
assert callback_context_same_user_chat.bot_data is callback_context.bot_data
|
||||
assert callback_context_same_user_chat.chat_data is callback_context.chat_data
|
||||
assert callback_context_same_user_chat.user_data is callback_context.user_data
|
||||
|
||||
|
@ -63,6 +67,7 @@ class TestCallbackContext(object):
|
|||
|
||||
callback_context_other_user_chat = CallbackContext.from_update(update_other_user_chat, cdp)
|
||||
|
||||
assert callback_context_other_user_chat.bot_data is callback_context.bot_data
|
||||
assert callback_context_other_user_chat.chat_data is not callback_context.chat_data
|
||||
assert callback_context_other_user_chat.user_data is not callback_context.user_data
|
||||
|
||||
|
@ -71,6 +76,7 @@ class TestCallbackContext(object):
|
|||
|
||||
assert callback_context.chat_data is None
|
||||
assert callback_context.user_data is None
|
||||
assert callback_context.bot_data is cdp.bot_data
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
@ -79,6 +85,7 @@ class TestCallbackContext(object):
|
|||
|
||||
assert callback_context.chat_data is None
|
||||
assert callback_context.user_data is None
|
||||
assert callback_context.bot_data is cdp.bot_data
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
@ -93,6 +100,7 @@ class TestCallbackContext(object):
|
|||
assert callback_context.error is error
|
||||
assert callback_context.chat_data == {}
|
||||
assert callback_context.user_data == {}
|
||||
assert callback_context.bot_data is cdp.bot_data
|
||||
assert callback_context.bot is cdp.bot
|
||||
assert callback_context.job_queue is cdp.job_queue
|
||||
assert callback_context.update_queue is cdp.update_queue
|
||||
|
|
|
@ -90,6 +90,7 @@ class TestCallbackQueryHandler(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.callback_query, CallbackQuery))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
|
|
|
@ -87,6 +87,7 @@ class TestChosenInlineResultHandler(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.chosen_inline_result, ChosenInlineResult))
|
||||
|
||||
def test_basic(self, dp, chosen_inline_result):
|
||||
|
|
|
@ -88,6 +88,7 @@ class BaseTest(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and isinstance(context.chat_data, dict)
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.message, Message))
|
||||
|
||||
def callback_context_args(self, update, context):
|
||||
|
|
|
@ -122,6 +122,7 @@ class TestDispatcher(object):
|
|||
def __init__(self):
|
||||
self.store_user_data = False
|
||||
self.store_chat_data = False
|
||||
self.store_bot_data = False
|
||||
|
||||
with pytest.raises(TypeError,
|
||||
match='persistence should be based on telegram.ext.BasePersistence'):
|
||||
|
@ -352,6 +353,13 @@ class TestDispatcher(object):
|
|||
super(BasePersistence, self).__init__()
|
||||
self.store_user_data = True
|
||||
self.store_chat_data = True
|
||||
self.store_bot_data = True
|
||||
|
||||
def get_bot_data(self):
|
||||
return dict()
|
||||
|
||||
def update_bot_data(self, data):
|
||||
raise Exception
|
||||
|
||||
def get_chat_data(self):
|
||||
return defaultdict(dict)
|
||||
|
@ -385,7 +393,7 @@ class TestDispatcher(object):
|
|||
dp.add_handler(CommandHandler('start', start1))
|
||||
dp.add_error_handler(error)
|
||||
dp.process_update(update)
|
||||
assert increment == ["error", "error"]
|
||||
assert increment == ["error", "error", "error"]
|
||||
|
||||
def test_flow_stop_in_error_handler(self, dp, bot):
|
||||
passed = []
|
||||
|
|
|
@ -94,6 +94,7 @@ class TestCallbackQueryHandler(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.inline_query, InlineQuery))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
|
|
|
@ -76,6 +76,7 @@ class TestJobQueue(object):
|
|||
and context.job.context == 2
|
||||
and context.chat_data is None
|
||||
and context.user_data is None
|
||||
and isinstance(context.bot_data, dict)
|
||||
and context.job_queue is context.job.job_queue):
|
||||
self.result += 1
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ class TestMessageHandler(object):
|
|||
and isinstance(context.update_queue, Queue)
|
||||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.chat_data, dict)
|
||||
and isinstance(context.bot_data, dict)
|
||||
and ((isinstance(context.user_data, dict)
|
||||
and (isinstance(update.message, Message)
|
||||
or isinstance(update.edited_message, Message)))
|
||||
|
|
|
@ -38,7 +38,12 @@ from telegram.ext import BasePersistence, Updater, ConversationHandler, MessageH
|
|||
|
||||
@pytest.fixture(scope="function")
|
||||
def base_persistence():
|
||||
return BasePersistence(store_chat_data=True, store_user_data=True)
|
||||
return BasePersistence(store_chat_data=True, store_user_data=True, store_bot_data=True)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def bot_data():
|
||||
return {'test1': 'test2', 'test3': {'test4': 'test5'}}
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
|
@ -60,8 +65,10 @@ def conversations():
|
|||
@pytest.fixture(scope="function")
|
||||
def updater(bot, base_persistence):
|
||||
base_persistence.store_chat_data = False
|
||||
base_persistence.store_bot_data = False
|
||||
base_persistence.store_user_data = False
|
||||
u = Updater(bot=bot, persistence=base_persistence)
|
||||
base_persistence.store_bot_data = True
|
||||
base_persistence.store_chat_data = True
|
||||
base_persistence.store_user_data = True
|
||||
return u
|
||||
|
@ -72,12 +79,16 @@ class TestBasePersistence(object):
|
|||
def test_creation(self, base_persistence):
|
||||
assert base_persistence.store_chat_data
|
||||
assert base_persistence.store_user_data
|
||||
with pytest.raises(NotImplementedError):
|
||||
base_persistence.get_bot_data()
|
||||
with pytest.raises(NotImplementedError):
|
||||
base_persistence.get_chat_data()
|
||||
with pytest.raises(NotImplementedError):
|
||||
base_persistence.get_user_data()
|
||||
with pytest.raises(NotImplementedError):
|
||||
base_persistence.get_conversations("test")
|
||||
with pytest.raises(NotImplementedError):
|
||||
base_persistence.update_bot_data(None)
|
||||
with pytest.raises(NotImplementedError):
|
||||
base_persistence.update_chat_data(None, None)
|
||||
with pytest.raises(NotImplementedError):
|
||||
|
@ -98,15 +109,21 @@ class TestBasePersistence(object):
|
|||
with pytest.raises(NotImplementedError):
|
||||
dp.add_handler(ConversationHandler([], {}, [], persistent=True, name="My Handler"))
|
||||
|
||||
def test_dispatcher_integration_init(self, bot, base_persistence, chat_data, user_data):
|
||||
def test_dispatcher_integration_init(self, bot, base_persistence, chat_data, user_data,
|
||||
bot_data):
|
||||
def get_user_data():
|
||||
return "test"
|
||||
|
||||
def get_chat_data():
|
||||
return "test"
|
||||
|
||||
def get_bot_data():
|
||||
return "test"
|
||||
|
||||
base_persistence.get_user_data = get_user_data
|
||||
base_persistence.get_chat_data = get_chat_data
|
||||
base_persistence.get_bot_data = get_bot_data
|
||||
|
||||
with pytest.raises(ValueError, match="user_data must be of type defaultdict"):
|
||||
u = Updater(bot=bot, persistence=base_persistence)
|
||||
|
||||
|
@ -121,22 +138,34 @@ class TestBasePersistence(object):
|
|||
return chat_data
|
||||
|
||||
base_persistence.get_chat_data = get_chat_data
|
||||
with pytest.raises(ValueError, match="bot_data must be of type dict"):
|
||||
u = Updater(bot=bot, persistence=base_persistence)
|
||||
|
||||
def get_bot_data():
|
||||
return bot_data
|
||||
|
||||
base_persistence.get_bot_data = get_bot_data
|
||||
u = Updater(bot=bot, persistence=base_persistence)
|
||||
assert u.dispatcher.bot_data == bot_data
|
||||
assert u.dispatcher.chat_data == chat_data
|
||||
assert u.dispatcher.user_data == user_data
|
||||
u.dispatcher.chat_data[442233]['test5'] = 'test6'
|
||||
assert u.dispatcher.chat_data[442233]['test5'] == 'test6'
|
||||
|
||||
def test_dispatcher_integration_handlers(self, caplog, bot, base_persistence,
|
||||
chat_data, user_data):
|
||||
chat_data, user_data, bot_data):
|
||||
def get_user_data():
|
||||
return user_data
|
||||
|
||||
def get_chat_data():
|
||||
return chat_data
|
||||
|
||||
def get_bot_data():
|
||||
return bot_data
|
||||
|
||||
base_persistence.get_user_data = get_user_data
|
||||
base_persistence.get_chat_data = get_chat_data
|
||||
base_persistence.get_bot_data = get_bot_data
|
||||
# base_persistence.update_chat_data = lambda x: x
|
||||
# base_persistence.update_user_data = lambda x: x
|
||||
updater = Updater(bot=bot, persistence=base_persistence, use_context=True)
|
||||
|
@ -145,18 +174,25 @@ class TestBasePersistence(object):
|
|||
def callback_known_user(update, context):
|
||||
if not context.user_data['test1'] == 'test2':
|
||||
pytest.fail('user_data corrupt')
|
||||
if not context.bot_data == bot_data:
|
||||
pytest.fail('bot_data corrupt')
|
||||
|
||||
def callback_known_chat(update, context):
|
||||
if not context.chat_data['test3'] == 'test4':
|
||||
pytest.fail('chat_data corrupt')
|
||||
if not context.bot_data == bot_data:
|
||||
pytest.fail('bot_data corrupt')
|
||||
|
||||
def callback_unknown_user_or_chat(update, context):
|
||||
if not context.user_data == {}:
|
||||
pytest.fail('user_data corrupt')
|
||||
if not context.chat_data == {}:
|
||||
pytest.fail('chat_data corrupt')
|
||||
if not context.bot_data == bot_data:
|
||||
pytest.fail('bot_data corrupt')
|
||||
context.user_data[1] = 'test7'
|
||||
context.chat_data[2] = 'test8'
|
||||
context.bot_data['test0'] = 'test0'
|
||||
|
||||
known_user = MessageHandler(Filters.user(user_id=12345), callback_known_user,
|
||||
pass_chat_data=True, pass_user_data=True)
|
||||
|
@ -188,6 +224,10 @@ class TestBasePersistence(object):
|
|||
m.chat = chat2
|
||||
u = Update(2, m)
|
||||
|
||||
def save_bot_data(data):
|
||||
if 'test0' not in data:
|
||||
pytest.fail()
|
||||
|
||||
def save_chat_data(data):
|
||||
if -987654 not in data:
|
||||
pytest.fail()
|
||||
|
@ -198,10 +238,12 @@ class TestBasePersistence(object):
|
|||
|
||||
base_persistence.update_chat_data = save_chat_data
|
||||
base_persistence.update_user_data = save_user_data
|
||||
base_persistence.update_bot_data = save_bot_data
|
||||
dp.process_update(u)
|
||||
|
||||
assert dp.user_data[54321][1] == 'test7'
|
||||
assert dp.chat_data[-987654][2] == 'test8'
|
||||
assert dp.bot_data['test0'] == 'test0'
|
||||
|
||||
def test_persistence_dispatcher_arbitrary_update_types(self, dp, base_persistence, caplog):
|
||||
# Updates used with TypeHandler doesn't necessarily have the proper attributes for
|
||||
|
@ -224,6 +266,17 @@ def pickle_persistence():
|
|||
return PicklePersistence(filename='pickletest',
|
||||
store_user_data=True,
|
||||
store_chat_data=True,
|
||||
store_bot_data=True,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def pickle_persistence_only_bot():
|
||||
return PicklePersistence(filename='pickletest',
|
||||
store_user_data=False,
|
||||
store_chat_data=False,
|
||||
store_bot_data=True,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
|
||||
|
@ -233,6 +286,7 @@ def pickle_persistence_only_chat():
|
|||
return PicklePersistence(filename='pickletest',
|
||||
store_user_data=False,
|
||||
store_chat_data=True,
|
||||
store_bot_data=False,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
|
||||
|
@ -242,36 +296,40 @@ def pickle_persistence_only_user():
|
|||
return PicklePersistence(filename='pickletest',
|
||||
store_user_data=True,
|
||||
store_chat_data=False,
|
||||
store_bot_data=False,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def bad_pickle_files():
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_conversations',
|
||||
'pickletest']:
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_bot_data',
|
||||
'pickletest_conversations', 'pickletest']:
|
||||
with open(name, 'w') as f:
|
||||
f.write('(())')
|
||||
yield True
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_conversations',
|
||||
'pickletest']:
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_bot_data',
|
||||
'pickletest_conversations', 'pickletest']:
|
||||
os.remove(name)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def good_pickle_files(user_data, chat_data, conversations):
|
||||
all = {'user_data': user_data, 'chat_data': chat_data, 'conversations': conversations}
|
||||
def good_pickle_files(user_data, chat_data, bot_data, conversations):
|
||||
all = {'user_data': user_data, 'chat_data': chat_data,
|
||||
'bot_data': bot_data, 'conversations': conversations}
|
||||
with open('pickletest_user_data', 'wb') as f:
|
||||
pickle.dump(user_data, f)
|
||||
with open('pickletest_chat_data', 'wb') as f:
|
||||
pickle.dump(chat_data, f)
|
||||
with open('pickletest_bot_data', 'wb') as f:
|
||||
pickle.dump(bot_data, f)
|
||||
with open('pickletest_conversations', 'wb') as f:
|
||||
pickle.dump(conversations, f)
|
||||
with open('pickletest', 'wb') as f:
|
||||
pickle.dump(all, f)
|
||||
yield True
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_conversations',
|
||||
'pickletest']:
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data', 'pickletest_bot_data',
|
||||
'pickletest_conversations', 'pickletest']:
|
||||
os.remove(name)
|
||||
|
||||
|
||||
|
@ -289,6 +347,8 @@ class TestPickelPersistence(object):
|
|||
assert pickle_persistence.get_user_data() == defaultdict(dict)
|
||||
assert pickle_persistence.get_chat_data() == defaultdict(dict)
|
||||
assert pickle_persistence.get_chat_data() == defaultdict(dict)
|
||||
assert pickle_persistence.get_bot_data() == {}
|
||||
assert pickle_persistence.get_bot_data() == {}
|
||||
assert pickle_persistence.get_conversations('noname') == {}
|
||||
assert pickle_persistence.get_conversations('noname') == {}
|
||||
|
||||
|
@ -296,6 +356,7 @@ class TestPickelPersistence(object):
|
|||
pickle_persistence.single_file = True
|
||||
assert pickle_persistence.get_user_data() == defaultdict(dict)
|
||||
assert pickle_persistence.get_chat_data() == defaultdict(dict)
|
||||
assert pickle_persistence.get_chat_data() == {}
|
||||
assert pickle_persistence.get_conversations('noname') == {}
|
||||
|
||||
def test_with_bad_multi_file(self, pickle_persistence, bad_pickle_files):
|
||||
|
@ -303,6 +364,8 @@ class TestPickelPersistence(object):
|
|||
pickle_persistence.get_user_data()
|
||||
with pytest.raises(TypeError, match='pickletest_chat_data'):
|
||||
pickle_persistence.get_chat_data()
|
||||
with pytest.raises(TypeError, match='pickletest_bot_data'):
|
||||
pickle_persistence.get_bot_data()
|
||||
with pytest.raises(TypeError, match='pickletest_conversations'):
|
||||
pickle_persistence.get_conversations('name')
|
||||
|
||||
|
@ -312,6 +375,8 @@ class TestPickelPersistence(object):
|
|||
pickle_persistence.get_user_data()
|
||||
with pytest.raises(TypeError, match='pickletest'):
|
||||
pickle_persistence.get_chat_data()
|
||||
with pytest.raises(TypeError, match='pickletest'):
|
||||
pickle_persistence.get_bot_data()
|
||||
with pytest.raises(TypeError, match='pickletest'):
|
||||
pickle_persistence.get_conversations('name')
|
||||
|
||||
|
@ -328,6 +393,12 @@ class TestPickelPersistence(object):
|
|||
assert chat_data[-67890][3] == 'test4'
|
||||
assert chat_data[-54321] == {}
|
||||
|
||||
bot_data = pickle_persistence.get_bot_data()
|
||||
assert isinstance(bot_data, dict)
|
||||
assert bot_data['test1'] == 'test2'
|
||||
assert bot_data['test3']['test4'] == 'test5'
|
||||
assert 'test0' not in bot_data
|
||||
|
||||
conversation1 = pickle_persistence.get_conversations('name1')
|
||||
assert isinstance(conversation1, dict)
|
||||
assert conversation1[(123, 123)] == 3
|
||||
|
@ -355,6 +426,12 @@ class TestPickelPersistence(object):
|
|||
assert chat_data[-67890][3] == 'test4'
|
||||
assert chat_data[-54321] == {}
|
||||
|
||||
bot_data = pickle_persistence.get_bot_data()
|
||||
assert isinstance(bot_data, dict)
|
||||
assert bot_data['test1'] == 'test2'
|
||||
assert bot_data['test3']['test4'] == 'test5'
|
||||
assert 'test0' not in bot_data
|
||||
|
||||
conversation1 = pickle_persistence.get_conversations('name1')
|
||||
assert isinstance(conversation1, dict)
|
||||
assert conversation1[(123, 123)] == 3
|
||||
|
@ -387,6 +464,15 @@ class TestPickelPersistence(object):
|
|||
chat_data_test = defaultdict(dict, pickle.load(f))
|
||||
assert chat_data_test == chat_data
|
||||
|
||||
bot_data = pickle_persistence.get_bot_data()
|
||||
bot_data['test6'] = 'test 7'
|
||||
assert not pickle_persistence.bot_data == bot_data
|
||||
pickle_persistence.update_bot_data(bot_data)
|
||||
assert pickle_persistence.bot_data == bot_data
|
||||
with open('pickletest_bot_data', 'rb') as f:
|
||||
bot_data_test = pickle.load(f)
|
||||
assert bot_data_test == bot_data
|
||||
|
||||
conversation1 = pickle_persistence.get_conversations('name1')
|
||||
conversation1[(123, 123)] = 5
|
||||
assert not pickle_persistence.conversations['name1'] == conversation1
|
||||
|
@ -417,6 +503,15 @@ class TestPickelPersistence(object):
|
|||
chat_data_test = defaultdict(dict, pickle.load(f)['chat_data'])
|
||||
assert chat_data_test == chat_data
|
||||
|
||||
bot_data = pickle_persistence.get_bot_data()
|
||||
bot_data['test6'] = 'test 7'
|
||||
assert not pickle_persistence.bot_data == bot_data
|
||||
pickle_persistence.update_bot_data(bot_data)
|
||||
assert pickle_persistence.bot_data == bot_data
|
||||
with open('pickletest', 'rb') as f:
|
||||
bot_data_test = pickle.load(f)['bot_data']
|
||||
assert bot_data_test == bot_data
|
||||
|
||||
conversation1 = pickle_persistence.get_conversations('name1')
|
||||
conversation1[(123, 123)] = 5
|
||||
assert not pickle_persistence.conversations['name1'] == conversation1
|
||||
|
@ -453,6 +548,17 @@ class TestPickelPersistence(object):
|
|||
chat_data_test = defaultdict(dict, pickle.load(f))
|
||||
assert not chat_data_test == chat_data
|
||||
|
||||
bot_data = pickle_persistence.get_bot_data()
|
||||
bot_data['test6'] = 'test 7'
|
||||
assert not pickle_persistence.bot_data == bot_data
|
||||
|
||||
pickle_persistence.update_bot_data(bot_data)
|
||||
assert pickle_persistence.bot_data == bot_data
|
||||
|
||||
with open('pickletest_bot_data', 'rb') as f:
|
||||
bot_data_test = pickle.load(f)
|
||||
assert not bot_data_test == bot_data
|
||||
|
||||
conversation1 = pickle_persistence.get_conversations('name1')
|
||||
conversation1[(123, 123)] = 5
|
||||
assert not pickle_persistence.conversations['name1'] == conversation1
|
||||
|
@ -473,6 +579,10 @@ class TestPickelPersistence(object):
|
|||
chat_data_test = defaultdict(dict, pickle.load(f))
|
||||
assert chat_data_test == chat_data
|
||||
|
||||
with open('pickletest_bot_data', 'rb') as f:
|
||||
bot_data_test = pickle.load(f)
|
||||
assert bot_data_test == bot_data
|
||||
|
||||
with open('pickletest_conversations', 'rb') as f:
|
||||
conversations_test = defaultdict(dict, pickle.load(f))
|
||||
assert conversations_test['name1'] == conversation1
|
||||
|
@ -502,6 +612,15 @@ class TestPickelPersistence(object):
|
|||
chat_data_test = defaultdict(dict, pickle.load(f)['chat_data'])
|
||||
assert not chat_data_test == chat_data
|
||||
|
||||
bot_data = pickle_persistence.get_bot_data()
|
||||
bot_data['test6'] = 'test 7'
|
||||
assert not pickle_persistence.bot_data == bot_data
|
||||
pickle_persistence.update_bot_data(bot_data)
|
||||
assert pickle_persistence.bot_data == bot_data
|
||||
with open('pickletest', 'rb') as f:
|
||||
bot_data_test = pickle.load(f)['bot_data']
|
||||
assert not bot_data_test == bot_data
|
||||
|
||||
conversation1 = pickle_persistence.get_conversations('name1')
|
||||
conversation1[(123, 123)] = 5
|
||||
assert not pickle_persistence.conversations['name1'] == conversation1
|
||||
|
@ -520,11 +639,15 @@ class TestPickelPersistence(object):
|
|||
chat_data_test = defaultdict(dict, pickle.load(f)['chat_data'])
|
||||
assert chat_data_test == chat_data
|
||||
|
||||
with open('pickletest', 'rb') as f:
|
||||
bot_data_test = pickle.load(f)['bot_data']
|
||||
assert bot_data_test == bot_data
|
||||
|
||||
with open('pickletest', 'rb') as f:
|
||||
conversations_test = defaultdict(dict, pickle.load(f)['conversations'])
|
||||
assert conversations_test['name1'] == conversation1
|
||||
|
||||
def test_with_handler(self, bot, update, pickle_persistence, good_pickle_files):
|
||||
def test_with_handler(self, bot, update, bot_data, pickle_persistence, good_pickle_files):
|
||||
u = Updater(bot=bot, persistence=pickle_persistence, use_context=True)
|
||||
dp = u.dispatcher
|
||||
|
||||
|
@ -533,14 +656,19 @@ class TestPickelPersistence(object):
|
|||
pytest.fail()
|
||||
if not context.chat_data == {}:
|
||||
pytest.fail()
|
||||
if not context.bot_data == bot_data:
|
||||
pytest.failt()
|
||||
context.user_data['test1'] = 'test2'
|
||||
context.chat_data['test3'] = 'test4'
|
||||
context.bot_data['test1'] = 'test0'
|
||||
|
||||
def second(update, context):
|
||||
if not context.user_data['test1'] == 'test2':
|
||||
pytest.fail()
|
||||
if not context.chat_data['test3'] == 'test4':
|
||||
pytest.fail()
|
||||
if not context.bot_data['test1'] == 'test0':
|
||||
pytest.fail()
|
||||
|
||||
h1 = MessageHandler(None, first, pass_user_data=True, pass_chat_data=True)
|
||||
h2 = MessageHandler(None, second, pass_user_data=True, pass_chat_data=True)
|
||||
|
@ -552,6 +680,7 @@ class TestPickelPersistence(object):
|
|||
pickle_persistence_2 = PicklePersistence(filename='pickletest',
|
||||
store_user_data=True,
|
||||
store_chat_data=True,
|
||||
store_bot_data=True,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
u = Updater(bot=bot, persistence=pickle_persistence_2)
|
||||
|
@ -565,6 +694,7 @@ class TestPickelPersistence(object):
|
|||
u.running = True
|
||||
dp.user_data[4242424242]['my_test'] = 'Working!'
|
||||
dp.chat_data[-4242424242]['my_test2'] = 'Working2!'
|
||||
dp.bot_data['test'] = 'Working3!'
|
||||
u.signal_handler(signal.SIGINT, None)
|
||||
del (dp)
|
||||
del (u)
|
||||
|
@ -576,10 +706,34 @@ class TestPickelPersistence(object):
|
|||
on_flush=False)
|
||||
assert pickle_persistence_2.get_user_data()[4242424242]['my_test'] == 'Working!'
|
||||
assert pickle_persistence_2.get_chat_data()[-4242424242]['my_test2'] == 'Working2!'
|
||||
assert pickle_persistence_2.get_bot_data()['test'] == 'Working3!'
|
||||
|
||||
def test_flush_on_stop_only_chat(self, bot, update, pickle_persistence_only_chat):
|
||||
def test_flush_on_stop_only_bot(self, bot, update, pickle_persistence_only_bot):
|
||||
os.remove('pickletest_user_data')
|
||||
os.remove('pickletest_chat_data')
|
||||
os.remove('pickletest_bot_data')
|
||||
u = Updater(bot=bot, persistence=pickle_persistence_only_bot)
|
||||
dp = u.dispatcher
|
||||
u.running = True
|
||||
dp.user_data[4242424242]['my_test'] = 'Working!'
|
||||
dp.chat_data[-4242424242]['my_test2'] = 'Working2!'
|
||||
dp.bot_data['my_test3'] = 'Working3!'
|
||||
u.signal_handler(signal.SIGINT, None)
|
||||
del (dp)
|
||||
del (u)
|
||||
del (pickle_persistence_only_bot)
|
||||
pickle_persistence_2 = PicklePersistence(filename='pickletest',
|
||||
store_user_data=False,
|
||||
store_chat_data=False,
|
||||
store_bot_data=True,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
assert pickle_persistence_2.get_user_data() == {}
|
||||
assert pickle_persistence_2.get_chat_data() == {}
|
||||
assert pickle_persistence_2.get_bot_data()['my_test3'] == 'Working3!'
|
||||
|
||||
def test_flush_on_stop_only_chat(self, bot, update, pickle_persistence_only_chat):
|
||||
os.remove('pickletest_bot_data')
|
||||
u = Updater(bot=bot, persistence=pickle_persistence_only_chat)
|
||||
dp = u.dispatcher
|
||||
u.running = True
|
||||
|
@ -592,10 +746,12 @@ class TestPickelPersistence(object):
|
|||
pickle_persistence_2 = PicklePersistence(filename='pickletest',
|
||||
store_user_data=False,
|
||||
store_chat_data=True,
|
||||
store_bot_data=False,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
assert pickle_persistence_2.get_user_data() == {}
|
||||
assert pickle_persistence_2.get_chat_data()[-4242424242]['my_test2'] == 'Working2!'
|
||||
assert pickle_persistence_2.get_bot_data() == {}
|
||||
|
||||
def test_flush_on_stop_only_user(self, bot, update, pickle_persistence_only_user):
|
||||
os.remove('pickletest_chat_data')
|
||||
|
@ -611,10 +767,12 @@ class TestPickelPersistence(object):
|
|||
pickle_persistence_2 = PicklePersistence(filename='pickletest',
|
||||
store_user_data=True,
|
||||
store_chat_data=False,
|
||||
store_bot_data=False,
|
||||
single_file=False,
|
||||
on_flush=False)
|
||||
assert pickle_persistence_2.get_user_data()[4242424242]['my_test'] == 'Working!'
|
||||
assert pickle_persistence_2.get_chat_data()[-4242424242] == {}
|
||||
assert pickle_persistence_2.get_bot_data() == {}
|
||||
|
||||
def test_with_conversationHandler(self, dp, update, good_pickle_files, pickle_persistence):
|
||||
dp.persistence = pickle_persistence
|
||||
|
@ -652,6 +810,7 @@ class TestPickelPersistence(object):
|
|||
def teardown_class(cls):
|
||||
try:
|
||||
for name in ['pickletest_user_data', 'pickletest_chat_data',
|
||||
'pickletest_bot_data',
|
||||
'pickletest_conversations',
|
||||
'pickletest']:
|
||||
os.remove(name)
|
||||
|
@ -669,6 +828,11 @@ def chat_data_json(chat_data):
|
|||
return json.dumps(chat_data)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def bot_data_json(bot_data):
|
||||
return json.dumps(bot_data)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def conversations_json(conversations):
|
||||
return """{"name1": {"[123, 123]": 3, "[456, 654]": 4}, "name2":
|
||||
|
@ -680,33 +844,42 @@ class TestDictPersistence(object):
|
|||
dict_persistence = DictPersistence()
|
||||
assert dict_persistence.get_user_data() == defaultdict(dict)
|
||||
assert dict_persistence.get_chat_data() == defaultdict(dict)
|
||||
assert dict_persistence.get_bot_data() == {}
|
||||
assert dict_persistence.get_conversations('noname') == {}
|
||||
|
||||
def test_bad_json_string_given(self):
|
||||
bad_user_data = 'thisisnojson99900()))('
|
||||
bad_chat_data = 'thisisnojson99900()))('
|
||||
bad_bot_data = 'thisisnojson99900()))('
|
||||
bad_conversations = 'thisisnojson99900()))('
|
||||
with pytest.raises(TypeError, match='user_data'):
|
||||
DictPersistence(user_data_json=bad_user_data)
|
||||
with pytest.raises(TypeError, match='chat_data'):
|
||||
DictPersistence(chat_data_json=bad_chat_data)
|
||||
with pytest.raises(TypeError, match='bot_data'):
|
||||
DictPersistence(bot_data_json=bad_bot_data)
|
||||
with pytest.raises(TypeError, match='conversations'):
|
||||
DictPersistence(conversations_json=bad_conversations)
|
||||
|
||||
def test_invalid_json_string_given(self, pickle_persistence, bad_pickle_files):
|
||||
bad_user_data = '["this", "is", "json"]'
|
||||
bad_chat_data = '["this", "is", "json"]'
|
||||
bad_bot_data = '["this", "is", "json"]'
|
||||
bad_conversations = '["this", "is", "json"]'
|
||||
with pytest.raises(TypeError, match='user_data'):
|
||||
DictPersistence(user_data_json=bad_user_data)
|
||||
with pytest.raises(TypeError, match='chat_data'):
|
||||
DictPersistence(chat_data_json=bad_chat_data)
|
||||
with pytest.raises(TypeError, match='bot_data'):
|
||||
DictPersistence(bot_data_json=bad_bot_data)
|
||||
with pytest.raises(TypeError, match='conversations'):
|
||||
DictPersistence(conversations_json=bad_conversations)
|
||||
|
||||
def test_good_json_input(self, user_data_json, chat_data_json, conversations_json):
|
||||
def test_good_json_input(self, user_data_json, chat_data_json, bot_data_json,
|
||||
conversations_json):
|
||||
dict_persistence = DictPersistence(user_data_json=user_data_json,
|
||||
chat_data_json=chat_data_json,
|
||||
bot_data_json=bot_data_json,
|
||||
conversations_json=conversations_json)
|
||||
user_data = dict_persistence.get_user_data()
|
||||
assert isinstance(user_data, defaultdict)
|
||||
|
@ -720,6 +893,12 @@ class TestDictPersistence(object):
|
|||
assert chat_data[-67890][3] == 'test4'
|
||||
assert chat_data[-54321] == {}
|
||||
|
||||
bot_data = dict_persistence.get_bot_data()
|
||||
assert isinstance(bot_data, dict)
|
||||
assert bot_data['test1'] == 'test2'
|
||||
assert bot_data['test3']['test4'] == 'test5'
|
||||
assert 'test6' not in bot_data
|
||||
|
||||
conversation1 = dict_persistence.get_conversations('name1')
|
||||
assert isinstance(conversation1, dict)
|
||||
assert conversation1[(123, 123)] == 3
|
||||
|
@ -734,26 +913,33 @@ class TestDictPersistence(object):
|
|||
conversation2[(123, 123)]
|
||||
|
||||
def test_dict_outputs(self, user_data, user_data_json, chat_data, chat_data_json,
|
||||
bot_data, bot_data_json,
|
||||
conversations, conversations_json):
|
||||
dict_persistence = DictPersistence(user_data_json=user_data_json,
|
||||
chat_data_json=chat_data_json,
|
||||
bot_data_json=bot_data_json,
|
||||
conversations_json=conversations_json)
|
||||
assert dict_persistence.user_data == user_data
|
||||
assert dict_persistence.chat_data == chat_data
|
||||
assert dict_persistence.bot_data == bot_data
|
||||
assert dict_persistence.conversations == conversations
|
||||
|
||||
def test_json_outputs(self, user_data_json, chat_data_json, conversations_json):
|
||||
def test_json_outputs(self, user_data_json, chat_data_json, bot_data_json, conversations_json):
|
||||
dict_persistence = DictPersistence(user_data_json=user_data_json,
|
||||
chat_data_json=chat_data_json,
|
||||
bot_data_json=bot_data_json,
|
||||
conversations_json=conversations_json)
|
||||
assert dict_persistence.user_data_json == user_data_json
|
||||
assert dict_persistence.chat_data_json == chat_data_json
|
||||
assert dict_persistence.bot_data_json == bot_data_json
|
||||
assert dict_persistence.conversations_json == conversations_json
|
||||
|
||||
def test_json_changes(self, user_data, user_data_json, chat_data, chat_data_json,
|
||||
bot_data, bot_data_json,
|
||||
conversations, conversations_json):
|
||||
dict_persistence = DictPersistence(user_data_json=user_data_json,
|
||||
chat_data_json=chat_data_json,
|
||||
bot_data_json=bot_data_json,
|
||||
conversations_json=conversations_json)
|
||||
user_data_two = user_data.copy()
|
||||
user_data_two.update({4: {5: 6}})
|
||||
|
@ -769,6 +955,14 @@ class TestDictPersistence(object):
|
|||
assert dict_persistence.chat_data_json != chat_data_json
|
||||
assert dict_persistence.chat_data_json == json.dumps(chat_data_two)
|
||||
|
||||
bot_data_two = bot_data.copy()
|
||||
bot_data_two.update({'7': {'8': '9'}})
|
||||
bot_data['7'] = {'8': '9'}
|
||||
dict_persistence.update_bot_data(bot_data)
|
||||
assert dict_persistence.bot_data == bot_data_two
|
||||
assert dict_persistence.bot_data_json != bot_data_json
|
||||
assert dict_persistence.bot_data_json == json.dumps(bot_data_two)
|
||||
|
||||
conversations_two = conversations.copy()
|
||||
conversations_two.update({'name3': {(1, 2): 3}})
|
||||
dict_persistence.update_conversation('name3', (1, 2), 3)
|
||||
|
@ -787,14 +981,19 @@ class TestDictPersistence(object):
|
|||
pytest.fail()
|
||||
if not context.chat_data == {}:
|
||||
pytest.fail()
|
||||
if not context.bot_data == {}:
|
||||
pytest.fail()
|
||||
context.user_data['test1'] = 'test2'
|
||||
context.chat_data[3] = 'test4'
|
||||
context.bot_data['test1'] = 'test2'
|
||||
|
||||
def second(update, context):
|
||||
if not context.user_data['test1'] == 'test2':
|
||||
pytest.fail()
|
||||
if not context.chat_data[3] == 'test4':
|
||||
pytest.fail()
|
||||
if not context.bot_data['test1'] == 'test2':
|
||||
pytest.fail()
|
||||
|
||||
h1 = MessageHandler(None, first, pass_user_data=True, pass_chat_data=True)
|
||||
h2 = MessageHandler(None, second, pass_user_data=True, pass_chat_data=True)
|
||||
|
@ -804,9 +1003,11 @@ class TestDictPersistence(object):
|
|||
del (u)
|
||||
user_data = dict_persistence.user_data_json
|
||||
chat_data = dict_persistence.chat_data_json
|
||||
bot_data = dict_persistence.bot_data_json
|
||||
del (dict_persistence)
|
||||
dict_persistence_2 = DictPersistence(user_data_json=user_data,
|
||||
chat_data_json=chat_data)
|
||||
chat_data_json=chat_data,
|
||||
bot_data_json=bot_data)
|
||||
|
||||
u = Updater(bot=bot, persistence=dict_persistence_2)
|
||||
dp = u.dispatcher
|
||||
|
|
|
@ -87,6 +87,7 @@ class TestPreCheckoutQueryHandler(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.pre_checkout_query, PreCheckoutQuery))
|
||||
|
||||
def test_basic(self, dp, pre_checkout_query):
|
||||
|
|
|
@ -88,6 +88,7 @@ class TestRegexHandler(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and isinstance(context.chat_data, dict)
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.message, Message))
|
||||
|
||||
def callback_context_pattern(self, update, context):
|
||||
|
|
|
@ -88,6 +88,7 @@ class TestShippingQueryHandler(object):
|
|||
and isinstance(context.job_queue, JobQueue)
|
||||
and isinstance(context.user_data, dict)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict)
|
||||
and isinstance(update.shipping_query, ShippingQuery))
|
||||
|
||||
def test_basic(self, dp, shiping_query):
|
||||
|
|
|
@ -80,7 +80,8 @@ class TestStringCommandHandler(object):
|
|||
and isinstance(context.update_queue, Queue)
|
||||
and isinstance(context.job_queue, JobQueue)
|
||||
and context.user_data is None
|
||||
and context.chat_data is None)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict))
|
||||
|
||||
def callback_context_args(self, update, context):
|
||||
self.test_flag = context.args == ['one', 'two']
|
||||
|
|
|
@ -50,7 +50,8 @@ class TestTypeHandler(object):
|
|||
and isinstance(context.update_queue, Queue)
|
||||
and isinstance(context.job_queue, JobQueue)
|
||||
and context.user_data is None
|
||||
and context.chat_data is None)
|
||||
and context.chat_data is None
|
||||
and isinstance(context.bot_data, dict))
|
||||
|
||||
def test_basic(self, dp):
|
||||
handler = TypeHandler(dict, self.callback_basic)
|
||||
|
|
Loading…
Add table
Reference in a new issue