class TestMessageGeneratorForwards(unittest.TestCase): def setUp(self): self.mg = MessageGenerator() self.ug = UserGenerator() self.cg = ChatGenerator() def test_forwarded_message(self): u1 = self.ug.get_user() u2 = self.ug.get_user() c = self.cg.get_chat(type="group") u = self.mg.get_message(user=u1, chat=c, forward_from=u2, text="This is a test") self.assertEqual(u.message.from_user.id, u1.id) self.assertEqual(u.message.forward_from.id, u2.id) self.assertNotEqual(u.message.from_user.id, u.message.forward_from.id) self.assertEqual(u.message.text, "This is a test") self.assertIsInstance(u.message.forward_date, int) import datetime self.mg.get_message(forward_from=u2, forward_date=datetime.datetime.now()) with self.assertRaises(BadUserException): u3 = "This is not a User" u = self.mg.get_message(user=u1, chat=c, forward_from=u3, text="This is a test") def test_forwarded_channel_message(self): c = self.cg.get_chat(type="channel") us = self.ug.get_user() u = self.mg.get_message(text="This is a test", forward_from=us, forward_from_chat=c) self.assertNotEqual(u.message.chat.id, c.id) self.assertNotEqual(u.message.from_user.id, us.id) self.assertEqual(u.message.forward_from.id, us.id) self.assertEqual(u.message.text, "This is a test") self.assertIsInstance(u.message.forward_from_message_id, int) self.assertIsInstance(u.message.forward_date, int) u = self.mg.get_message(text="This is a test", forward_from_chat=c) self.assertNotEqual(u.message.from_user.id, u.message.forward_from.id) self.assertIsInstance(u.message.forward_from, User) self.assertIsInstance(u.message.forward_from_message_id, int) self.assertIsInstance(u.message.forward_date, int) with self.assertRaises(BadChatException): c = "Not a Chat" u = self.mg.get_message(text="This is a test", forward_from_chat=c) with self.assertRaises(BadChatException): c = self.cg.get_chat(type="group") u = self.mg.get_message(text="This is a test", forward_from_chat=c)
def test_with_chat(self): cg = ChatGenerator() group = cg.get_chat(type="group") channel = cg.get_chat(type="channel") u = self.mg.get_channel_post(chat=channel) self.assertEqual(channel.title, u.channel_post.chat.title) with self.assertRaisesRegexp(BadChatException, "telegram\.Chat"): self.mg.get_channel_post(chat="chat") with self.assertRaisesRegexp(BadChatException, "chat\.type"): self.mg.get_channel_post(chat=group)
def test_with_chat(self): cg = ChatGenerator() c = cg.get_chat() u = self.mg.get_message(chat=c) self.assertEqual(u.message.chat.id, u.message.from_user.id) self.assertEqual(u.message.chat.id, c.id) c = cg.get_chat(type="group") u = self.mg.get_message(chat=c) self.assertNotEqual(u.message.from_user.id, u.message.chat.id) self.assertEqual(u.message.chat.id, c.id) with self.assertRaisesRegexp(BadChatException, "get_channel_post"): c = cg.get_chat(type="channel") self.mg.get_message(chat=c) with self.assertRaises(BadChatException): c = "Not a telegram.Chat" self.mg.get_message(chat=c)
def test_with_chat_and_user(self): cg = ChatGenerator() ug = UserGenerator() us = ug.get_user() c = cg.get_chat() u = self.mg.get_message(user=us, chat=c) self.assertNotEqual(u.message.from_user.id, u.message.chat.id) self.assertEqual(u.message.from_user.id, us.id) self.assertEqual(u.message.chat.id, c.id) us = "not a telegram.User" with self.assertRaises(BadUserException): u = self.mg.get_message(user=us) with self.assertRaises(BadUserException): u = self.mg.get_message(chat=c, user="******") c = "Not a telegram.Chat" with self.assertRaises(BadChatException): self.mg.get_message(chat=c) with self.assertRaises(BadChatException): self.mg.get_message(user=u, chat="chat")
class MessageGenerator(PtbGenerator): """ Message generator class. Attributes: bot (ptbtest.Mockbot): Bot to encode with the messages Args: bot (Optional[ptbtest.Mockbot]): supply your own for a custom botname """ def __init__(self, bot=None): PtbGenerator.__init__(self) self.idgen = self._gen_id() self.ug = UserGenerator() self.cg = ChatGenerator() if not bot: self.bot = Mockbot() elif isinstance(bot, Mockbot): self.bot = bot else: raise BadBotException def _gen_id(self): x = 1 while True: yield x x += 1 @update("edited_channel_post") def get_edited_channel_post(self, channel_post=None, **kwargs): """ Parameters: channel_post (Optional(telegram.Message)): The edited_channel_post will the same user, chat and message_id **kwargs: See get_message for the full list Returns: telegram.Update: A telegram update object containing a :py:class:`telegram.Message`. """ id, user, chat = None, None, None if channel_post: if not isinstance(channel_post, Message): raise BadMessageException id = channel_post.message_id user = channel_post.from_user chat = channel_post.chat return self.get_channel_post(id=id, user=user, chat=chat, **kwargs).channel_post @update("channel_post") def get_channel_post(self, chat=None, user=None, **kwargs): """ Parameters: chat (Optional[telegram.Chat]): Chat with type='channel' to use with this update user (Optional[telegram.User]): User for the update. None if omitted **kwargs: See get_message Returns: telegram.Update: A telegram update object containing a :py:class:`telegram.Message. """ if chat: if not isinstance(chat, Chat): raise BadChatException if not chat.type == "channel": raise BadChatException( "Can only use chat.type='channel' for get_channel_post" ) else: chat = ChatGenerator().get_chat(type="channel") return self.get_message(chat=chat, user=user, channel=True, **kwargs).message @update("edited_message") def get_edited_message(self, message=None, **kwargs): """ Parameters: message (Optional(telegram.Message)): The edited_message will have the same user, chat and message_id **kwargs: See get_message for the full list Returns: telegram.Update: A telegram update object containing a :py:class:`telegram.Message`. """ id, user, chat = None, None, None if message: if not isinstance(message, Message): raise BadMessageException id = message.message_id user = message.from_user chat = message.chat return self.get_message(id=id, user=user, chat=chat, **kwargs).message @update("message") def get_message( self, id=None, user=None, chat=None, private=True, forward_from=None, forward_from_chat=None, forward_date=None, reply_to_message=None, text=None, entities=None, audio=None, document=None, photo=None, sticker=None, video=None, voice=None, caption=None, contact=None, location=None, venue=None, new_chat_members=None, left_chat_member=None, new_chat_title=None, new_chat_photo=None, delete_chat_photo=False, group_chat_created=False, supergroup_chat_created=False, migrate_to_chat_id=None, migrate_from_chat_id=None, channel_chat_created=False, pinned_message=None, forward_from_message_id=None, parse_mode=None, channel=False, bot=None, media_group_id=None, poll=None, **kwargs ): """ When called without arguments will return an update object for a message from a private chat with a random user. for modifiers see args. Notes: whenever a list of telegram.PhotoSize objects is expected but not supplied it will always be a list with two random sizes between 40-400 pixels. These will not be valid file id's Parameters: user (Optional[telegram.User]): User the message is from (m.from_user) chat (Optional[telegram.Chat]): Chat the message is from (m.chat). private (Optional[bool]): If the message is private (optionally with the supplied user) default=True text (str): The text for the message, can make use of markdown or html, make sure to specify with parse_mode parse_mode (Optional[str]): "HTML" or "Markdown" parses the text and fills entities entities (Optional[lst(telegram.MessageEntity)]): when text and parsemode are set this will be filled with the entities in the text. # noqa: E501 reply_to_message (Optional[telegram.Message): Messages this one is a reply to forward_from (Optional[telegram.User): User this message is forwarded from forward_from_chat (Optional[telegram.Chat]): channel this message is forwarded from forward_date (Optional[int]): Original sent date forward_from_message_id (Optional[int]): message id from forwarded channel post. new_chat_members (List[telegram.User]): Optional. Information about new members to the chat. (the bot itself may be one of these members). left_chat_member (Optional[telegram.User]): Member left this chat new_chat_title (Optional[str]): New title for the chat new_chat_photo (Optional[lst(telegram.Photosize)] or True): New picture for the group pinned_message (Optional[telegram.Message]): Pinned message for supergroups channel_chat_created (Optional[True]): Not integrated migrate_from_chat_id (Optional[int]): Not integrated migrate_to_chat_id (Optional[int]): Not integrated supergroup_chat_created (Optional[True]): Not integrated group_chat_created (Optional[True]): Not integrated delete_chat_photo (Optional[True]): Not integrated venue (Optional[telegram.Venue or True]): Either the right object or True to generate one location (optional[telegram.Location or True]): Either the right object or True to generate one contact (optional[telegram.Contact or True]): Either the right object or True to generate one caption (Optional[str or True]: Either the right object or True to generate one voice (Optional[telegram.Voice or True]): Either the right object or True to generate one video (Optional[telegram.Video or True]): Either the right object or True to generate one sticker (Optional[telegram.Sticker] or True): Either the right object or True to generate one photo (Optional[lst(telegram.PhotoSize) or True]): Either the right object or True to generate one document (Optional[telegram.Document or True]): Either the right object or True to generate one audio (Optional[telegram.Audio] or True): Either the right object or True to generate one Returns: telegram.Update: A telegram update object containing a :py:class:`telegram.Message`. """ if not channel: user, chat = self._get_user_and_chat(user, chat, private) if reply_to_message and not isinstance(reply_to_message, Message): raise BadMessageException forward_date, forward_from, forward_from_message_id = self._handle_forward( forward_date, forward_from, forward_from_chat, forward_from_message_id ) text, entities = self._handle_text(text, parse_mode) new_chat_photo = self._handle_status( channel_chat_created, chat, delete_chat_photo, group_chat_created, left_chat_member, migrate_from_chat_id, migrate_to_chat_id, new_chat_members, new_chat_photo, new_chat_title, pinned_message, supergroup_chat_created, ) ( audio, contact, document, location, photo, sticker, venue, video, voice, ) = self._handle_attachments( audio, contact, document, location, photo, sticker, user, venue, video, voice, caption, ) if poll: if poll in {POLL_QUIZ, POLL_REGULAR}: poll = self._get_poll(poll) else: raise BadMessageException("Poll can be either regular or quiz") return Message( message_id=id or next(self.idgen), from_user=user, date=datetime.datetime.now(), chat=chat, text=text, forward_from=forward_from, forward_from_chat=forward_from_chat, reply_to_message=reply_to_message, entities=entities, audio=audio, document=document, photo=photo, sticker=sticker, video=video, voice=voice, caption=caption, contact=contact, location=location, venue=venue, new_chat_members=new_chat_members, left_chat_member=left_chat_member, new_chat_title=new_chat_title, new_chat_photo=new_chat_photo, delete_chat_photo=delete_chat_photo, group_chat_created=group_chat_created, supergroup_chat_created=supergroup_chat_created, migrate_to_chat_id=migrate_to_chat_id, migrate_from_chat_id=migrate_from_chat_id, channel_chat_created=channel_chat_created, pinned_message=pinned_message, forward_from_message_id=forward_from_message_id, forward_date=forward_date, bot=bot or self.bot, media_group_id=media_group_id, poll=poll, ) def _handle_attachments( self, audio, contact, document, location, photo, sticker, user, venue, video, voice, caption, ): attachments = [ x for x in [ photo, venue, location, contact, voice, video, sticker, document, audio, ] if x ] if caption and not attachments: raise BadMessageException("Can't have a caption without attachment") if len(attachments) > 1: raise BadMessageException("can't add more than one attachment") if photo: if isinstance(photo, list): if all([isinstance(x, PhotoSize) for x in photo]): pass else: raise BadMessageException( "photo must either be True or list(telegram.PhotoSize)" ) elif isinstance(photo, bool): photo = self._get_photosize() else: raise BadMessageException( "photo must either be True or list(telegram.PhotoSize)" ) if location: if isinstance(location, Location): pass elif isinstance(location, dict): location = Location(**location) elif isinstance(location, bool): location = self._get_location() else: raise BadMessageException( "location must either be True or telegram.Location" ) if venue: if isinstance(venue, Venue): pass elif isinstance(venue, bool): venue = self._get_venue() elif isinstance(venue, dict): venue["location"] = Location(**venue) venue = Venue(**venue) else: raise BadMessageException("venue must either be True or telegram.Venue") if contact: if isinstance(contact, Contact): pass elif isinstance(contact, dict): contact = Contact(**contact) elif isinstance(contact, bool): contact = self._get_contact(user) else: raise BadMessageException( "contact must either be True or telegram.Contact" ) if voice: if isinstance(voice, Voice): pass elif isinstance(voice, bool): voice = self._get_voice() elif isinstance(voice, dict): voice = Voice(**voice) else: raise BadMessageException("voice must either be True or telegram.Voice") if video: if isinstance(video, Video): pass elif isinstance(video, bool): video = self._get_video() elif isinstance(video, dict): video = self._get_video(data=video) else: raise BadMessageException("video must either be True or telegram.Video") if sticker: if isinstance(sticker, Sticker): pass elif isinstance(sticker, bool): sticker = self._get_sticker() elif isinstance(sticker, dict): sticker = self._get_sticker(sticker) else: raise BadMessageException( "sticker must either be True or telegram.Sticker" ) if document: if isinstance(document, Document): pass elif isinstance(document, dict): document = Document(**document) elif isinstance(document, bool): document = self._get_document() else: raise BadMessageException( "document must either be True or telegram.Document" ) if audio: if isinstance(audio, Audio): pass elif isinstance(audio, bool): audio = self._get_audio() elif isinstance(audio, dict): audio = Audio(**audio) else: raise BadMessageException("audio must either be True or telegram.Audio") return audio, contact, document, location, photo, sticker, venue, video, voice def _handle_forward( self, forward_date, forward_from, forward_from_chat, forward_from_message_id ): if forward_from and not isinstance(forward_from, User): raise BadUserException() if forward_from_chat: if not isinstance(forward_from_chat, Chat): raise BadChatException if forward_from_chat.type != "channel": raise BadChatException('forward_from_chat must be of type "channel"') if not forward_from: forward_from = UserGenerator().get_user() if forward_from: if not isinstance(forward_date, datetime.datetime): now = datetime.datetime.now() else: now = forward_date try: # Python 3.3+ forward_date = datetime.datetime.now() except AttributeError: # Python 3 (< 3.3) and Python 2 forward_date = datetime.datetime.now() if ( forward_from_message_id and not isinstance(forward_from_message_id, int) ) or (forward_from_chat and not forward_from_message_id): forward_from_message_id = next(self.idgen) return forward_date, forward_from, forward_from_message_id def _handle_status( self, channel_chat_created, chat, delete_chat_photo, group_chat_created, left_chat_member, migrate_from_chat_id, migrate_to_chat_id, new_chat_members, new_chat_photo, new_chat_title, pinned_message, supergroup_chat_created, ): status_messages = [ new_chat_members, left_chat_member, new_chat_title, new_chat_photo, delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, migrate_from_chat_id, pinned_message, ] if len([x for x in status_messages if x]) > 1: raise BadMessageException("Limit to only one status message per message") if new_chat_members: for new_chat_member in new_chat_members: if not isinstance(new_chat_member, User): raise BadUserException if chat.type == "private": raise BadChatException("Can not add members to private chat") if left_chat_member: if not isinstance(left_chat_member, User): raise BadUserException if chat.type == "private": raise BadChatException("People can not leave a private chat") if new_chat_title: if chat.type == "private": raise BadChatException("Can not change title of private chat") chat.title = new_chat_title if new_chat_photo: if chat.type == "private": raise BadChatException( "Can't change the photo for a private chat a private chat" ) if isinstance(new_chat_photo, list): if all([isinstance(x, PhotoSize) for x in new_chat_photo]): pass else: raise BadMessageException( "new_chat_photo must either be True or list(telegram.PhotoSize)" ) elif isinstance(new_chat_photo, bool) and new_chat_photo: new_chat_photo = self._get_photosize() else: raise BadMessageException( "new_chat_photo must either be True or list(telegram.PhotoSize)" ) if pinned_message: if not isinstance(pinned_message, Message): raise BadMessageException elif chat.type != "supergroup": raise BadChatException("Messages can only be pinned in supergroups") else: pinned_message.reply_to_message = None return new_chat_photo def _get_user_and_chat(self, user, chat, private): if chat: if not isinstance(chat, Chat): raise BadChatException if chat.type == "channel": raise BadChatException("Use get_channel_post to get channel updates.") if user: if not isinstance(user, User): raise BadUserException if chat: if not user: if chat.type == "private": user = self.ug.get_user( first_name=chat.first_name, last_name=chat.last_name, username=chat.username, id=chat.id, ) else: user = self.ug.get_user() elif user and private: chat = self.cg.get_chat(user=user) elif user: chat = self.cg.get_chat(type="group") elif private: user = self.ug.get_user() chat = self.cg.get_chat(user=user) else: user = self.ug.get_user() chat = self.cg.get_chat(type="group") return user, chat def _handle_text(self, text, parse_mode): if text and parse_mode: if parse_mode not in [ "HTML", "Markdown", ]: # , "MarkdownV2"]: # write parser before enabling V2 raise BadMarkupException( "Markdown mode must be HTML or Markdown" ) # or MarkdownV2') elif parse_mode == "HTML": text, entities = EntityParser.parse_html(text) else: text, entities = EntityParser.parse_markdown(text) else: entities = [] return text, entities def _get_photosize(self): tmp = [] import uuid from random import randint for _ in range(2): w, h = randint(40, 400), randint(40, 400) s = w * h * 2 tmp.append( PhotoSize( file_id=str(uuid.uuid4()), file_unique_id=str(uuid.uuid4()), width=w, height=h, file_size=s, ) ) return tmp def _get_location(self): from random import uniform return Location(uniform(-180.0, 180.0), uniform(-90.0, 90.0)) def _get_venue(self): loc = self._get_location() address = "somewherestreet 23" name = "Awesome place" return Venue(loc, name, address) def _get_contact(self, user): return Contact("06123456789", user.first_name) def _get_voice(self): import uuid from random import randint return Voice( file_id=str(uuid.uuid4()), file_unique_id=str(uuid.uuid4()), duration=randint(2, 300), ) def _get_video(self, data=None): import uuid from random import randint if data: data["width"] = randint(40, 400) data["height"] = randint(40, 400) return Video(**data) return Video( file_id=str(uuid.uuid4()), file_unique_id=str(uuid.uuid4()), width=randint(40, 400), height=randint(40, 400), duration=randint(2, 300), ) def _get_sticker(self, data=None): import uuid from random import randint if data is None: data = {} data["file_unique_id"] = data["file_id"] = str(uuid.uuid4()) if "width" not in data: data["width"] = randint(20, 200) data["height"] = randint(20, 200) if "is_animated" not in data: data["is_animated"] = False return Sticker(**data) def _get_document(self): import uuid return Document( file_id=str(uuid.uuid4()), file_unique_id=str(uuid.uuid4()), file_name="somedoc.pdf", ) def _get_audio(self): import uuid from random import randint return Audio( file_id=str(uuid.uuid4()), file_unique_id=str(uuid.uuid4()), duration=randint(1, 120), title="Some song", ) def _get_poll(self, poll_type): import uuid from random import randint if poll_type == POLL_QUIZ: return Poll( id=str(uuid.uuid4()), question="Are you human?", options=[PollOption("Yes", 2), PollOption("No", 5)], total_voter_count=7, is_closed=False, is_anonymous=True, type=POLL_QUIZ, correct_option_id=0, allows_multiple_answers=False, ) else: return Poll( id=str(uuid.uuid4()), question="Are you human?", options=[PollOption("Yes", 2), PollOption("No", 5)], total_voter_count=7, is_closed=False, is_anonymous=True, type=POLL_REGULAR, allows_multiple_answers=False, )
class TestExplore(unittest.TestCase): def setUp(self): # For use within the tests we nee some stuff. Starting with a Mockbot self.bot = Mockbot() # Some generators for users and chats self.ug = UserGenerator() self.cg = ChatGenerator() # And a Messagegenerator and updater (for use with the bot.) self.mg = MessageGenerator(self.bot) self.updater = Updater(bot=self.bot) def test_help(self): # Then register the handler with he updater's dispatcher and start polling self.updater.dispatcher.add_handler( CommandHandler("explore", explore.explore, pass_chat_data=True)) self.updater.start_polling() # We want to simulate a message. Since we don't care wich user sends it we let the MessageGenerator # create random ones update = self.mg.get_message(text="/explore") # We insert the update with the bot so the updater can retrieve it. self.bot.insertUpdate(update) # sent_messages is the list with calls to the bot's outbound actions. Since we hope the message we inserted # only triggered one sendMessage action it's length should be 1. self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.updater.stop() def test_start(self): def start(bot, update): update.message.reply_text('Hi!') self.updater.dispatcher.add_handler(CommandHandler("start", start)) self.updater.start_polling() # Here you can see how we would handle having our own user and chat user = self.ug.get_user(first_name="Test", last_name="The Bot") chat = self.cg.get_chat(user=user) update = self.mg.get_message(user=user, chat=chat, text="/start") self.bot.insertUpdate(update) self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.assertEqual(sent['text'], "Hi!") self.updater.stop() def test_echo(self): def echo(bot, update): update.message.reply_text(update.message.text) self.updater.dispatcher.add_handler(MessageHandler(Filters.text, echo)) self.updater.start_polling() update = self.mg.get_message(text="first message") update2 = self.mg.get_message(text="second message") self.bot.insertUpdate(update) self.bot.insertUpdate(update2) self.assertEqual(len(self.bot.sent_messages), 2) sent = self.bot.sent_messages self.assertEqual(sent[0]['method'], "sendMessage") self.assertEqual(sent[0]['text'], "first message") self.assertEqual(sent[1]['text'], "second message") self.updater.stop()
class Testtimerbot(unittest.TestCase): def setUp(self): # For use within the tests we nee some stuff. Starting with a Mockbot self.bot = Mockbot() # Some generators for users and chats self.cg = ChatGenerator() # And a Messagegenerator and updater (for use with the bot.) self.mg = MessageGenerator(self.bot) self.updater = Updater(bot=self.bot) # type: ignore def test_timer(self): # first declare the callback methods def alarm(context): """Function to send the alarm message""" context.bot.sendMessage(context.job.context["chat_id"], text='Beep!') def set(update, context): """Adds a job to the queue""" chat_id = update.message.chat_id try: args = context.args # args[0] should contain the time for the timer in seconds due = int(args[0]) if due < 0: update.message.reply_text( 'Sorry we can not go back to the past!') return # Add job to queue context.user_data["job"] = context.job_queue.run_once( callback=alarm, when=due, context={"chat_id": chat_id}) update.message.reply_text('Timer successfully set!') except (IndexError, ValueError): update.message.reply_text('Usage: /set <seconds>') def unset(update, context): """Removes the job if the user changed their mind""" if 'job' not in context.user_data: update.message.reply_text('You have no active timer') return job = context.user_data['job'] job.schedule_removal() del context.user_data['job'] update.message.reply_text('Timer successfully unset!') # Now add those handlers to the updater and start polling dp = self.updater.dispatcher dp.add_handler(CommandHandler("set", set)) dp.add_handler(CommandHandler("unset", unset)) self.updater.start_polling() # we want to check if the bot returns a message to the same chat after a period of time # so let's create a chat to use chat = self.cg.get_chat() # let's generate some updates we can use u1 = self.mg.get_message(chat=chat, text="/set", parse_mode="HTML") u2 = self.mg.get_message(chat=chat, text="/set -20", parse_mode="HTML") u3 = self.mg.get_message(chat=chat, text="/set 6", parse_mode="HTML") u4 = self.mg.get_message(chat=chat, text="/unset", parse_mode="HTML") # first check some errors self.bot.insertUpdate(u1) self.bot.insertUpdate(u2) self.bot.insertUpdate(u4) data = self.bot.sent_messages self.assertEqual(len(data), 3) self.assertEqual(data[0]['text'], "Usage: /set <seconds>") self.assertEqual(data[1]['text'], 'Sorry we can not go back to the past!') self.assertEqual(data[2]['text'], 'You have no active timer') # now check if setting and unsetting works (within timer limit) self.bot.insertUpdate(u3) data = self.bot.sent_messages[-1] self.assertEqual(data['text'], 'Timer successfully set!') time.sleep(2) self.bot.insertUpdate(u4) data = self.bot.sent_messages[-1] self.assertEqual(data['text'], 'Timer successfully unset!') # and to be certain we have to wait some more to see if it stops sending the message # we reset the bot so we can be sure nothing more has been sent self.bot.reset() time.sleep(5) data = self.bot.sent_messages self.assertEqual(len(data), 0) # lastly we will make sure an alarm message is sent after the timelimit has passed self.bot.insertUpdate(u3) time.sleep(6) data = self.bot.sent_messages[-1] self.assertEqual(data['text'], 'Beep!') self.assertEqual(data['chat_id'], chat.id) # and stop the updater. self.updater.stop()
class TestChatGenerator(unittest.TestCase): def setUp(self): self.cg = ChatGenerator() def test_without_parameter(self): c = self.cg.get_chat() self.assertIsInstance(c.id, int) self.assertTrue(c.id > 0) self.assertEqual(c.username, c.first_name + c.last_name) self.assertEqual(c.type, "private") def test_group_chat(self): c = self.cg.get_chat(type="group") self.assertTrue(c.id < 0) self.assertEqual(c.type, "group") self.assertFalse(c.all_members_are_administrators) self.assertIsInstance(c.title, str) def test_group_all_members_are_administrators(self): c = self.cg.get_chat(type="group", all_members_are_administrators=True) self.assertEqual(c.type, "group") self.assertTrue(c.all_members_are_administrators) def test_group_chat_with_group_name(self): c = self.cg.get_chat(type="group", title="My Group") self.assertEqual(c.title, "My Group") def test_private_from_user(self): u = UserGenerator().get_user() c = self.cg.get_chat(user=u) self.assertEqual(u.id, c.id) self.assertEqual(c.username, c.first_name + c.last_name) self.assertEqual(u.username, c.username) self.assertEqual(c.type, "private") def test_supergroup(self): c = self.cg.get_chat(type="supergroup") self.assertTrue(c.id < 0) self.assertEqual(c.type, "supergroup") self.assertIsInstance(c.title, str) self.assertTrue(c.username, "".join(c.title.split())) def test_supergroup_with_title(self): c = self.cg.get_chat(type="supergroup", title="Awesome Group") self.assertEqual(c.title, "Awesome Group") self.assertEqual(c.username, "AwesomeGroup") def test_supergroup_with_username(self): c = self.cg.get_chat(type="supergroup", username="******") self.assertEqual(c.username, "mygroup") def test_supergroup_with_username_title(self): c = self.cg.get_chat(type="supergroup", username="******", title="Awesome Group") self.assertEqual(c.title, "Awesome Group") self.assertEqual(c.username, "mygroup") def test_channel(self): c = self.cg.get_chat(type="channel") self.assertIsInstance(c.title, str) self.assertEqual(c.type, "channel") self.assertTrue(c.username, "".join(c.title.split())) def test_channel_with_title(self): c = self.cg.get_chat(type="channel", title="Awesome Group") self.assertEqual(c.title, "Awesome Group") self.assertEqual(c.username, "AwesomeGroup") def test_supergroup_with_username(self): c = self.cg.get_chat(type="channel", username="******") self.assertEqual(c.username, "mygroup") def test_supergroup_with_username_title(self): c = self.cg.get_chat(type="channel", username="******", title="Awesome Group") self.assertEqual(c.title, "Awesome Group") self.assertEqual(c.username, "mygroup")
class TestCommands(unittest.TestCase): def setUp(self): # For use within the tests we nee some stuff. Starting with a Mockbot self.bot = Mockbot() # Some generators for users and chats self.ug = UserGenerator() self.cg = ChatGenerator() # And a Messagegenerator and updater (for use with the bot.) self.mg = MessageGenerator(self.bot) self.updater = Updater(bot=self.bot) GamesController.init() def test_ping(self): # Then register the handler with he updater's dispatcher and start polling self.updater.dispatcher.add_handler( CommandHandler("ping", command_ping)) self.updater.start_polling() # create with random user update = self.mg.get_message(text="/ping") # We insert the update with the bot so the updater can retrieve it. self.bot.insertUpdate(update) # sent_messages is the list with calls to the bot's outbound actions. Since we hope the message we inserted # only triggered one sendMessage action it's length should be 1. self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.assertEqual(sent['text'], "pong - v0.4") # Always stop the updater at the end of a testcase so it won't hang. self.updater.stop() def test_start(self): self.updater.dispatcher.add_handler( CommandHandler("start", command_start)) self.updater.start_polling() update = self.mg.get_message(text="/start") self.bot.insertUpdate(update) self.assertEqual(len(self.bot.sent_messages), 2) start = self.bot.sent_messages[0] self.assertEqual(start['method'], "sendMessage") self.assertIn("Secret Blue is a social deduction game", start['text']) help = self.bot.sent_messages[1] self.assertEqual(help['method'], "sendMessage") self.assertIn("The following commands are available", help['text']) self.updater.stop() def test_symbols(self): self.updater.dispatcher.add_handler( CommandHandler("symbols", command_symbols)) self.updater.start_polling() update = self.mg.get_message(text="/symbols") self.bot.insertUpdate(update) self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.assertIn("The following symbols can appear on the board:", sent['text']) self.updater.stop() def test_board_when_there_is_no_game(self): self.updater.dispatcher.add_handler( CommandHandler("board", command_board)) self.updater.start_polling() update = self.mg.get_message(text="/board") self.bot.insertUpdate(update) self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.assertIn( "There is no game in this chat. Create a new game with /newgame", sent['text']) self.updater.stop() def test_board_when_game_is_not_running(self): game = Game(-999, 12345) GamesController.games[-999] = game self.updater.dispatcher.add_handler( CommandHandler("board", command_board)) self.updater.start_polling() chat = self.cg.get_chat(cid=-999) update = self.mg.get_message(chat=chat, text="/board") self.bot.insertUpdate(update) self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.assertIn( "There is no running game in this chat. Please start the game with /startgame", sent['text']) self.updater.stop() def test_board_when_game_is_running(self): game = Game(-999, 12345) game.board = Board(5, game) GamesController.games[-999] = game self.updater.dispatcher.add_handler( CommandHandler("board", command_board)) self.updater.start_polling() chat = self.cg.get_chat(cid=-999) update = self.mg.get_message(chat=chat, text="/board") self.bot.insertUpdate(update) self.assertEqual(len(self.bot.sent_messages), 1) sent = self.bot.sent_messages[0] self.assertEqual(sent['method'], "sendMessage") self.assertIn("--- Liberal acts ---", sent['text']) self.updater.stop()
class TestConversationbot2(unittest.TestCase): def setUp(self): self.bot = Mockbot() self.cg = ChatGenerator() self.ug = UserGenerator() self.mg = MessageGenerator(self.bot) self.updater = Updater(bot=self.bot) def test_conversation(self): CHOOSING, TYPING_REPLY, TYPING_CHOICE = range(3) reply_keyboard = [['Age', 'Favourite colour'], ['Number of siblings', 'Something else...'], ['Done']] markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True) def facts_to_str(user_data): facts = list() for key, value in user_data.items(): facts.append('%s - %s' % (key, value)) return "\n".join(facts).join(['\n', '\n']) def start(bot, update): update.message.reply_text( "Hi! My name is Doctor Botter. I will hold a more complex conversation with you. " "Why don't you tell me something about yourself?", reply_markup=markup) return CHOOSING def regular_choice(bot, update, user_data): text = update.message.text user_data['choice'] = text update.message.reply_text('Your %s? Yes, I would love to hear about that!' % text.lower()) return TYPING_REPLY def custom_choice(bot, update): update.message.reply_text('Alright, please send me the category first, ' 'for example "Most impressive skill"') return TYPING_CHOICE def received_information(bot, update, user_data): text = update.message.text category = user_data['choice'] user_data[category] = text del user_data['choice'] update.message.reply_text("Neat! Just so you know, this is what you already told me:" "%s" "You can tell me more, or change your opinion on something." % facts_to_str(user_data), reply_markup=markup) return CHOOSING def done(bot, update, user_data): if 'choice' in user_data: del user_data['choice'] update.message.reply_text("I learned these facts about you:" "%s" "Until next time!" % facts_to_str(user_data)) user_data.clear() return ConversationHandler.END conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ CHOOSING: [RegexHandler('^(Age|Favourite colour|Number of siblings)$', regular_choice, pass_user_data=True), RegexHandler('^Something else...$', custom_choice), ], TYPING_CHOICE: [MessageHandler(Filters.text, regular_choice, pass_user_data=True), ], TYPING_REPLY: [MessageHandler(Filters.text, received_information, pass_user_data=True), ], }, fallbacks=[RegexHandler('^Done$', done, pass_user_data=True)] ) dp = self.updater.dispatcher dp.add_handler(conv_handler) self.updater.start_polling() # We are going to test a conversationhandler. Since this is tied in with user and chat we need to # create both for consistancy user = self.ug.get_user() chat = self.cg.get_chat(type="group") user2 = self.ug.get_user() chat2 = self.cg.get_chat(user=user) # let's start the conversation u = self.mg.get_message(user=user, chat=chat, text="/start") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Doctor Botter\. I will") u = self.mg.get_message(user=user, chat=chat, text="Age") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Your age\? Yes") # now let's see what happens when another user in another chat starts conversating with the bot u = self.mg.get_message(user=user2, chat=chat2, text="/start") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Doctor Botter\. I will") self.assertEqual(data['chat_id'], chat2.id) self.assertNotEqual(data['chat_id'], chat.id) # and cancels his conv. u = self.mg.get_message(user=user2, chat=chat2, text="Done") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Until next time!") # cary on with first user u = self.mg.get_message(user=user, chat=chat, text="23") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Age - 23") u = self.mg.get_message(user=user, chat=chat, text="Something else...") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Most impressive skill") u = self.mg.get_message(user=user, chat=chat, text="programming skill") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"Your programming skill\? Yes") u = self.mg.get_message(user=user, chat=chat, text="High") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"programming skill - High") u = self.mg.get_message(user=user, chat=chat, text="Done") self.bot.insertUpdate(u) data = self.bot.sent_messages[-1] self.assertRegexpMatches(data['text'], r"programming skill - High") self.assertRegexpMatches(data['text'], r"Age - 23") self.updater.stop()
class TestInlineKeyboard(unittest.TestCase): def setUp(self): # For use within the tests we nee some stuff. Starting with a Mockbot self.bot = Mockbot() # Some generators for users and chats self.cg = ChatGenerator() # And a Messagegenerator, CallbackQueryGenerator and updater (for use with the bot.) self.mg = MessageGenerator(self.bot) self.cqg = CallbackQueryGenerator(self.bot) self.updater = Updater(bot=self.bot) def test_callback(self): # first insert the callbackhandler, register it and start polling def button(bot, update): query = update.callback_query bot.editMessageText(text="Selected option: %s" % query.data, chat_id=query.message.chat_id, message_id=query.message.message_id) dp = self.updater.dispatcher dp.add_handler(CallbackQueryHandler(button)) self.updater.start_polling() # the start callback in this example generates a message that will be edited, so let's mimick that message # for future reference keyboard = [[ InlineKeyboardButton("Option 1", callback_data='1'), InlineKeyboardButton("Option 2", callback_data='2') ], [InlineKeyboardButton("Option 3", callback_data='3')]] reply_markup = InlineKeyboardMarkup(keyboard) chat = self.cg.get_chat() start_message = self.bot.sendMessage(chat_id=chat.id, text='Please choose:', reply_markup=reply_markup) # now let's create some callback query's to send u1 = self.cqg.get_callback_query(message=start_message, data="1") u2 = self.cqg.get_callback_query(message=start_message, data="2") u3 = self.cqg.get_callback_query(message=start_message, data="3") # And test them one by one self.bot.insertUpdate(u1) data = self.bot.sent_messages[-1] self.assertEqual(data['text'], "Selected option: 1") self.assertEqual(data['chat_id'], start_message.chat.id) self.assertEqual(data['message_id'], start_message.message_id) self.bot.insertUpdate(u2) data = self.bot.sent_messages[-1] self.assertEqual(data['text'], "Selected option: 2") self.assertEqual(data['chat_id'], start_message.chat.id) self.assertEqual(data['message_id'], start_message.message_id) self.bot.insertUpdate(u3) data = self.bot.sent_messages[-1] self.assertEqual(data['text'], "Selected option: 3") self.assertEqual(data['chat_id'], start_message.chat.id) self.assertEqual(data['message_id'], start_message.message_id) # stop polling self.updater.stop()
class TestDCUBABot(unittest.TestCase): @classmethod def setUpClass(self): # For use within the tests we nee some stuff. Starting with a Mockbot self.bot = Mockbot() self.bot.request = telegram.utils.request.Request() # Some generators for users and chats self.ug = UserGenerator() self.cg = ChatGenerator() # And a Messagegenerator,CallbackQueryGenerator and updater (for use with the bot.) self.mg = MessageGenerator(self.bot) self.cqg = CallbackQueryGenerator(self.bot) self.updater = Updater(bot=self.bot) init_db("test.sqlite3") install_commands() add_all_handlers(self.updater.dispatcher) with db_session: for listable_type in Listable.__subclasses__(): for i in range(6): listable_type(name=listable_type._discriminator_ + " " + str(i), url="https://url" + str(i) + ".com", validated=True) self.updater.start_polling() @classmethod def tearDownClass(self): self.updater.stop() os.remove("test.sqlite3") @classmethod def sendCommand(self, command, chat_id=None): user = self.ug.get_user(first_name="Test", last_name="The Bot") if chat_id: chat = self.cg.get_chat(chat_id) else: chat = self.cg.get_chat(user=user) update = self.mg.get_message(user=user, chat=chat, text=command) self.bot.insertUpdate(update) return user, chat # TODO: Cleanup this def assert_bot_response(self, message_text, response_text, chat_id=None, random=False): if isinstance(response_text, str): response_text = [response_text] sent_messages = self.bot.sent_messages sent_messages_before = len(sent_messages) self.sendCommand(message_text, chat_id=chat_id) response_sent_messages = len(sent_messages) - sent_messages_before expected_sent_messages = 0 if not response_text else\ (1 if random else len(response_text)) self.assertEqual(response_sent_messages, expected_sent_messages) for i in range(response_sent_messages): sent = sent_messages[sent_messages_before + i] self.assertEqual(sent['method'], "sendMessage") if not random: self.assertEqual(sent['text'], response_text[i]) else: self.assertIn(sent['text'], response_text) def get_keyboard(self, message): return json.loads(message['reply_markup'])['inline_keyboard'] def button_in_list(self, name, url, list_command): self.sendCommand("/" + list_command) inline_keyboard = self.get_keyboard(self.bot.sent_messages[-1]) for row in inline_keyboard: for button in row: if button["text"] == name and button["url"] == url: return True return False def test_help(self): with db_session: for c in Command.select(): c.description = "" Command(name="comandoSinDescripcion1") Command(name="comandoConDescripcion1", description="Descripción 1") Command(name="comandoSinDescripcion2") Command(name="comandoConDescripcion2", description="Descripción 2") Command(name="comandoSinDescripcion3") Command(name="comandoConDescripcion3", description="Descripción 3") self.assert_bot_response("/help", ("/comandoConDescripcion1 - Descripción 1\n" "/comandoConDescripcion2 - Descripción 2\n" "/comandoConDescripcion3 - Descripción 3\n")) def test_start(self): self.assert_bot_response( "/start", "Hola, ¿qué tal? ¡Mandame /help si no sabés qué puedo hacer!") def test_estasvivo(self): self.assert_bot_response("/estasvivo", "Sí, estoy vivo.") def test_rozendioanalisis(self): self.assert_bot_response("/rozendioanalisis", "¡Sí, Rozen ya dio el final de análisis!") # TODO: Rename def list_test(self, command, listable_type): self.assert_bot_response(command, "Grupos: ") # Assertions on keyboard inline_keyboard = self.get_keyboard(self.bot.sent_messages[-1]) self.assertEqual(len(inline_keyboard), 2) # Number of rows for i in range(2): row = inline_keyboard[i] self.assertEqual((len(row)), 3) # Number of columns for j in range(3): button = row[j] button_number = i * 3 + j self.assertEqual( button['text'], listable_type._discriminator_ + " " + str(button_number)) self.assertEqual(button['url'], "https://url" + str(button_number) + ".com") self.assertEqual(button['callback_data'], button['url']) def test_listar(self): self.list_test("/listar", Obligatoria) def test_listaroptativa(self): self.list_test("/listaroptativa", Optativa) def test_listarotro(self): self.list_test("/listarotro", Otro) def suggestion_test(self, command, list_command, listable_type): name = "Sugerido" url = "sugerido.com" error_message = "Hiciste algo mal, la idea es que pongas:\n" +\ command + " <nombre>|<link>" # Invalid command usages self.assert_bot_response(command, error_message) self.assert_bot_response(command + " " + name, error_message) self.assert_bot_response(command + " " + name + "|", error_message) self.assert_bot_response(command + " |" + url, error_message) self.assert_bot_response(command + " |", error_message) self.assert_bot_response(command + " " + name + "|" + url + "|sobra", error_message) # Make a group suggestion to accept self.assert_bot_response(command + " " + name + "|" + url, [ listable_type.__name__ + ": " + name + "\n" + url, "OK, se lo mando a Rozen." ]) # Assertions on keyboard inline_keyboard = self.get_keyboard(self.bot.sent_messages[-2]) self.assertEqual(len(inline_keyboard), 1) # Number of rows row = inline_keyboard[0] self.assertEqual(len(row), 2) # Number of columns self.assertEqual(row[0]["text"], "Aceptar") self.assertEqual(row[1]["text"], "Rechazar") # The suggested group shouldn't be listed self.assertFalse(self.button_in_list(name, url, list_command)) # Pressing the "Aceptar" button makes the group listable u = self.cqg.get_callback_query(message=self.mg.get_message().message, data=row[0]["callback_data"]) self.bot.insertUpdate(u) self.assertTrue(self.button_in_list(name, url, list_command)) with db_session: delete(l for l in Listable if l.name == name) # Make a group suggestion to reject self.sendCommand(command + " " + name + "|" + url) inline_keyboard = self.get_keyboard(self.bot.sent_messages[-2]) row = inline_keyboard[0] # Pressing the "Rechazar" button doesn't make the group listable u = self.cqg.get_callback_query(message=self.mg.get_message().message, data=row[1]["callback_data"]) self.bot.insertUpdate(u) self.assertFalse(self.button_in_list(name, url, list_command)) # The database is clean of rejected suggestions with db_session: self.assertEqual(count(l for l in Listable if l.name == name), 0) def test_sugerirgrupo(self): self.suggestion_test("/sugerirgrupo", "listar", Obligatoria) def test_sugeriroptativa(self): self.suggestion_test("/sugeriroptativa", "listaroptativa", Optativa) def test_sugerirotro(self): self.suggestion_test("/sugerirotro", "listarotro", Otro) def test_logger(self): with self.assertLogs("DCUBABOT", level='INFO') as cm: user, _ = self.sendCommand("/listar") first_message = 'INFO:DCUBABOT:' + str(user.id) + ': /listar' user, _ = self.sendCommand("/estasvivo") second_message = 'INFO:DCUBABOT:' + str(user.id) + ': /estasvivo' self.assertEqual(cm.output, [first_message, second_message]) def test_cubawiki(self): cubawiki_url = "https://www.cubawiki.com.ar/index.php/Segundo_Parcial_del_10/12/18" positive_chat_id = -123456 negative_chat_id_no_cubawiki = -654321 negative_chat_id_no_entry = -123321 with db_session: Obligatoria(name="Cubawiki", url="test.com", chat_id=positive_chat_id, cubawiki_url=cubawiki_url) Obligatoria(name="Cubawiki", url="test.com", chat_id=negative_chat_id_no_cubawiki) # Positive test case self.assert_bot_response("/cubawiki", cubawiki_url, chat_id=positive_chat_id) # Negative test cases self.assert_bot_response("/cubawiki", None, chat_id=negative_chat_id_no_cubawiki) self.assert_bot_response("/cubawiki", None, chat_id=negative_chat_id_no_entry) with db_session: delete(o for o in Obligatoria if o.name == "Cubawiki") def test_felizdia(self): today = datetime.datetime(2019, 1, 1) self.assertEqual(felizdia_text(today), "Feliz 1 de Enero") today = datetime.datetime(2019, 2, 1) self.assertEqual(felizdia_text(today), "Feliz 1 de Febrero") today = datetime.datetime(2019, 3, 1) self.assertEqual(felizdia_text(today), "Feliz 1 de Marzo") today = datetime.datetime(2019, 4, 4) self.assertEqual(felizdia_text(today), "Feliz 4 de Abril") today = datetime.datetime(2019, 5, 21) self.assertEqual(felizdia_text(today), "Feliz 21 de Mayo") # TODO: Test randomness? def test_noitip(self): noitips = ["me siento boludeadisimo", "Not this shit again", "noitip"] with db_session: for phrase in noitips: Noitip(text=phrase) self.assert_bot_response("/noitip", noitips, random=True) def test_asm(self): with db_session: AsmInstruction(mnemonic="AAD", summary="ASCII Adjust AX Before Division", url="https://www.felixcloutier.com/x86/aad") AsmInstruction(mnemonic="ADD", summary="Add", url="https://www.felixcloutier.com/x86/add") AsmInstruction( mnemonic="ADDPD", summary="Add Packed Double-Precision Floating-Point Values", url="https://www.felixcloutier.com/x86/addpd") AsmInstruction(mnemonic="MOV", summary="Move to/from Control Registers", url="http://www.felixcloutier.com/x86/MOV-1.html") AsmInstruction(mnemonic="MOV", summary="Move to/from Debug Registers", url="http://www.felixcloutier.com/x86/MOV-2.html") AsmInstruction( mnemonic="INT n", summary="Call to Interrupt Procedure", url="http://www.felixcloutier.com/x86/INT%20n:INTO:INT%203.html" ) not_found = "No pude encontrar esa instrucción." possibles = not_found + "\nQuizás quisiste decir:" add_info = ("[ADD] Descripción: Add.\n" "Más info: https://www.felixcloutier.com/x86/add") addpd_info = ( "[ADDPD] Descripción: Add Packed Double-Precision Floating-Point Values.\n" "Más info: https://www.felixcloutier.com/x86/addpd") mov1_info = ("[MOV] Descripción: Move to/from Control Registers.\n" "Más info: http://www.felixcloutier.com/x86/MOV-1.html") mov2_info = ("[MOV] Descripción: Move to/from Debug Registers.\n" "Más info: http://www.felixcloutier.com/x86/MOV-2.html") intn_info = ( "[INT n] Descripción: Call to Interrupt Procedure.\n" "Más info: http://www.felixcloutier.com/x86/INT%20n:INTO:INT%203.html" ) self.assert_bot_response("/asm", "No me pasaste ninguna instrucción.") self.assert_bot_response("/asm add", add_info) self.assert_bot_response("/asm ADDPD", addpd_info) self.assert_bot_response("/asm a", not_found) self.assert_bot_response("/asm Adp", possibles + "\n" + add_info) self.assert_bot_response("/asm ADDPS", possibles + "\n" + addpd_info) self.assert_bot_response( "/asm addP", possibles + "\n" + add_info + "\n" + addpd_info) self.assert_bot_response("/asm MOV", mov1_info + "\n" + mov2_info) self.assert_bot_response("/asm INT n", intn_info)
class TestMessageGeneratorStatusMessages(unittest.TestCase): def setUp(self): self.mg = MessageGenerator() self.ug = UserGenerator() self.cg = ChatGenerator() def test_new_chat_member(self): user = self.ug.get_user() chat = self.cg.get_chat(type="group") u = self.mg.get_message(chat=chat, new_chat_member=user) self.assertEqual(u.message.new_chat_member.id, user.id) with self.assertRaises(BadChatException): self.mg.get_message(new_chat_member=user) with self.assertRaises(BadUserException): self.mg.get_message(chat=chat, new_chat_member="user") def test_left_chat_member(self): user = self.ug.get_user() chat = self.cg.get_chat(type='group') u = self.mg.get_message(chat=chat, left_chat_member=user) self.assertEqual(u.message.left_chat_member.id, user.id) with self.assertRaises(BadChatException): self.mg.get_message(left_chat_member=user) with self.assertRaises(BadUserException): self.mg.get_message(chat=chat, left_chat_member="user") def test_new_chat_title(self): chat = self.cg.get_chat(type="group") u = self.mg.get_message(chat=chat, new_chat_title="New title") self.assertEqual(u.message.chat.title, "New title") self.assertEqual(u.message.chat.title, chat.title) with self.assertRaises(BadChatException): self.mg.get_message(new_chat_title="New title") def test_new_chat_photo(self): chat = self.cg.get_chat(type="group") u = self.mg.get_message(chat=chat, new_chat_photo=True) self.assertIsInstance(u.message.new_chat_photo, list) self.assertIsInstance(u.message.new_chat_photo[0], PhotoSize) photo = [PhotoSize("2", 1, 1, file_size=3)] u = self.mg.get_message(chat=chat, new_chat_photo=photo) self.assertEqual(len(u.message.new_chat_photo), 1) with self.assertRaises(BadChatException): self.mg.get_message(new_chat_photo=True) photo = "foto's!" with self.assertRaises(BadMessageException): self.mg.get_message(chat=chat, new_chat_photo=photo) with self.assertRaises(BadMessageException): self.mg.get_message(chat=chat, new_chat_photo=[1, 2, 3]) def test_pinned_message(self): chat = self.cg.get_chat(type="supergroup") message = self.mg.get_message( chat=chat, text="this will be pinned").message u = self.mg.get_message(chat=chat, pinned_message=message) self.assertEqual(u.message.pinned_message.text, "this will be pinned") with self.assertRaises(BadChatException): self.mg.get_message(pinned_message=message) with self.assertRaises(BadMessageException): self.mg.get_message(chat=chat, pinned_message="message") def test_multiple_statusmessages(self): with self.assertRaises(BadMessageException): self.mg.get_message( private=False, new_chat_member=self.ug.get_user(), new_chat_title="New title")