def test_truncate_long_answers(self, bot, chat_id, empty_orchestra, monkeypatch, empty_member): poll_message = None def send_poll(*args, **kwargs): nonlocal poll_message poll_message = fake_poll() poll_message.poll.options = [PollOption(o, 0) for o in kwargs['options']] return poll_message monkeypatch.setattr(bot, 'send_poll', send_poll) for i in range(10): empty_orchestra.register_member(Member(i, nickname=str(i), last_name=150 * str(i))) empty_orchestra.register_member(empty_member) questioner = Questioner( user_id=int(chat_id), orchestra=empty_orchestra, hint_attributes=['nickname'], question_attributes=['last_name'], number_of_questions=42, bot=bot, multiple_choice=True, ) questioner.ask_question() assert questioner.number_of_questions_asked == 1 for option in poll_message.poll.options: assert option.text[-4:] == ' ...'
def test_questionable(self, populated_orchestra, bot, chat_id, empty_member): orchestra = populated_orchestra orchestra.register_member(empty_member) questioner = Questioner( user_id=int(chat_id), orchestra=populated_orchestra, hint_attributes=['first_name'], question_attributes=['instruments'], number_of_questions=42, bot=bot, multiple_choice=True, ) assert len(populated_orchestra.questionable()) > 1 assert questioner.questionable() == [('first_name', 'instruments')]
def test_no_current_question(self, bot, chat_id, populated_orchestra, empty_member): populated_orchestra.register_member(empty_member) questioner = Questioner( user_id=int(chat_id), orchestra=populated_orchestra, hint_attributes=[], question_attributes=[], number_of_questions=42, bot=bot, ) update = Update(123, poll_answer=PollAnswer(chat_id, User(chat_id, '', False), [1])) assert not questioner.check_update(update) with pytest.raises(RuntimeError, match='current question'): questioner.handle_update(update)
def test_no_more_questions_to_ask(self, bot, chat_id, empty_orchestra, empty_member): empty_orchestra.register_member(empty_member) for i in range(4): empty_orchestra.register_member(Member(i, nickname=str(i), last_name=str(i))) questioner = Questioner( user_id=int(chat_id), orchestra=empty_orchestra, hint_attributes=['nickname'], question_attributes=['last_name'], number_of_questions=42, bot=bot, ) questioner.number_of_questions_asked = 42 with pytest.raises(RuntimeError, match='No more questions to ask!'): questioner.ask_question()
def number_questions(update: Update, context: CallbackContext) -> str: """ Parses the corresponding response for the number of questions. Also starts the game by initializing the :class:`components.Questioner` and asking the first question. If the configuration was invalid, ends the conversation. Args: update: The update. context: The context as provided by the :class:`telegram.ext.Dispatcher`. """ message = update.effective_message data = update.callback_query.data user_id = update.effective_user.id update.callback_query.answer() game_settings = cast(GameSettings, context.user_data[GAME_KEY]) game_settings.number_of_questions = int(data) try: questioner = Questioner( user_id=user_id, orchestra=context.bot_data[ORCHESTRA_KEY], hint_attributes=game_settings.hint_attributes, question_attributes=game_settings.question_attributes, number_of_questions=game_settings.number_of_questions, bot=context.bot, multiple_choice=game_settings.multiple_choice, ) QUESTION_HANDLER.set_questioner(user_id, questioner) message.delete() questioner.ask_question() return GAME except ValueError: message.edit_text( 'Die gewählte Spielkonfiguration ist leider ungültig. Bitte versuche es erneut.' ) context.user_data[CONVERSATION_KEY] = False return ConversationHandler.END
def test_init(self, bot, populated_orchestra, empty_member): orchestra = populated_orchestra orchestra.register_member(empty_member) questioner = Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=[], question_attributes=[], number_of_questions=42, bot=bot, multiple_choice=True, ) assert questioner.member == empty_member assert questioner.orchestra is orchestra assert questioner.bot is bot assert questioner.multiple_choice is True assert questioner.score.answers == 0 assert not questioner.current_question assert not questioner.check_update(Update(123)) assert not questioner.check_update( Update(123, poll_answer=PollAnswer(123, User(123, '', False), [1])) )
def test_init_errors(self, bot, populated_orchestra, empty_orchestra, empty_member): orchestra = populated_orchestra orchestra.register_member(empty_member) with pytest.raises(ValueError, match='Number of questions'): Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=[], question_attributes=[], number_of_questions=-1, bot=bot, ) with pytest.raises(ValueError, match='Allowing the same'): Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=['age'], question_attributes=['age'], number_of_questions=42, bot=bot, ) with pytest.raises(ValueError, match='Unsupported hint'): Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=['foo'], question_attributes=[], number_of_questions=42, bot=bot, ) with pytest.raises(ValueError, match='Unsupported question'): Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=[], question_attributes=['bar'], number_of_questions=42, bot=bot, ) with pytest.raises(ValueError, match='Attribute last_name'): Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=['last_name'], question_attributes=[], number_of_questions=42, bot=bot, ) with pytest.raises(ValueError, match='Attribute last_name'): Questioner( user_id=empty_member.user_id, orchestra=orchestra, hint_attributes=[], question_attributes=['last_name'], number_of_questions=42, bot=bot, ) empty_orchestra.register_member(empty_member) with pytest.raises(ValueError, match='No valid hint-question combination available.'): Questioner( user_id=empty_member.user_id, orchestra=empty_orchestra, hint_attributes=[], question_attributes=[], number_of_questions=42, bot=bot, )
def test_ask_question_location( self, bot, chat_id, populated_orchestra, empty_member, monkeypatch, runs ): answer_message_text = '' def send_message(*args, **kwargs): nonlocal answer_message_text answer_message_text = kwargs['text'] return answer_message_text def send_pass(*args, **kwargs): pass orchestra = populated_orchestra orchestra.register_member(empty_member) questioner = Questioner( user_id=int(chat_id), orchestra=orchestra, hint_attributes=[], question_attributes=['address'], number_of_questions=42, bot=bot, multiple_choice=False, ) monkeypatch.setattr(questioner.bot, 'send_message', send_message) monkeypatch.setattr(questioner.bot, 'send_photo', send_pass) monkeypatch.setattr(questioner.bot, 'send_media_group', send_pass) try: questioner.ask_question() except RuntimeError as e: if 'currently not hintable' in str(e): pytest.xfail('This test may be flaky depending on the orchestra constellation') assert questioner.number_of_questions_asked == 1 assert questioner.current_question assert not questioner.current_question.poll update = Update( 123, message=Message( message_id=123, from_user=User(123, 'foo', False), date=None, chat=Chat(123, Chat.PRIVATE), location=Location(27.988191, 86.924518), bot=bot, ), ) assert not questioner.check_update(update) update = Update( 123, message=Message( message_id=123, from_user=User(chat_id, 'foo', False), date=None, chat=Chat(chat_id, Chat.PRIVATE), location=Location(27.988191, 86.924518), bot=bot, ), ) assert questioner.check_update(update) questioner.handle_update(update) assert questioner.score.answers == 1 assert questioner.score.correct == 0 if not questioner.current_question.multiple_choice: assert 'nicht korrekt' in answer_message_text longitude = questioner.current_question.member.longitude latitude = questioner.current_question.member.latitude update = Update( 123, message=Message( message_id=123, from_user=User(chat_id, 'foo', False), date=None, chat=Chat(chat_id, Chat.PRIVATE), location=Location(longitude, latitude), bot=bot, ), ) assert questioner.check_update(update) questioner.handle_update(update) assert questioner.score.answers == 2 assert questioner.score.correct == 1 if not questioner.current_question.multiple_choice: assert 'richtig!' in answer_message_text
def test_ask_question_free_text( self, bot, chat_id, populated_orchestra, empty_member, monkeypatch, runs ): poll_message = None answer_message_text = '' def send_poll(*args, **kwargs): nonlocal poll_message poll_message = fake_poll() return poll_message def send_message(*args, **kwargs): nonlocal answer_message_text answer_message_text = kwargs['text'] return answer_message_text def send_pass(*args, **kwargs): pass orchestra = populated_orchestra orchestra.register_member(empty_member) questioner = Questioner( user_id=int(chat_id), orchestra=orchestra, hint_attributes=[], question_attributes=[], number_of_questions=42, bot=bot, multiple_choice=False, ) monkeypatch.setattr(questioner.bot, 'send_poll', send_poll) monkeypatch.setattr(questioner.bot, 'send_message', send_message) monkeypatch.setattr(questioner.bot, 'send_photo', send_pass) monkeypatch.setattr(questioner.bot, 'send_media_group', send_pass) try: questioner.ask_question() except RuntimeError as e: if 'currently not hintable' in str(e): pytest.xfail('This test may be flaky depending on the orchestra constellation') assert questioner.number_of_questions_asked == 1 assert questioner.current_question if questioner.current_question.multiple_choice: assert questioner.current_question.attribute == Question.PHOTO assert questioner.current_question.poll is poll_message.poll else: assert not questioner.current_question.poll if questioner.current_question.multiple_choice: update = Update( 123, poll_answer=PollAnswer( poll_message.poll.id, User(123, 'foo', False), [(poll_message.poll.correct_option_id + 1) % 4], ), ) else: update = Update( 123, message=Message( message_id=123, from_user=User(123, 'foo', False), chat=Chat(123, Chat.PRIVATE), date=None, text='some very false answer', bot=bot, ), ) assert not questioner.check_update(update) if questioner.current_question.multiple_choice: update = Update( 123, poll_answer=PollAnswer( poll_message.poll.id, User(chat_id, 'foo', False), [(poll_message.poll.correct_option_id + 1) % 4], ), ) else: update = Update( 123, message=Message( message_id=123, from_user=User(chat_id, 'foo', False), date=None, chat=Chat(chat_id, Chat.PRIVATE), text='some very false answer', bot=bot, ), ) assert questioner.check_update(update) questioner.handle_update(update) assert questioner.score.answers == 1 assert questioner.score.correct == 0 if not questioner.current_question.multiple_choice: assert 'nicht korrekt' in answer_message_text if questioner.current_question.multiple_choice: update = Update( 123, poll_answer=PollAnswer( poll_message.poll.id, User(chat_id, 'foo', False), [poll_message.poll.correct_option_id], ), ) else: if isinstance(questioner.current_question.correct_answer, list): text = str(random.choice(questioner.current_question.correct_answer)) else: text = questioner.current_question.correct_answer update = Update( 123, message=Message( message_id=123, from_user=User(chat_id, 'foo', False), date=None, chat=Chat(chat_id, Chat.PRIVATE), text=text, bot=bot, ), ) assert questioner.check_update(update) questioner.handle_update(update) assert questioner.score.answers == 2 assert questioner.score.correct == 1 if not questioner.current_question.multiple_choice: assert 'richtig!' in answer_message_text
def test_ask_question_multiple_choice( self, bot, chat_id, populated_orchestra, empty_member, monkeypatch, runs ): poll_message = None def send_poll(*args, **kwargs): nonlocal poll_message poll_message = fake_poll() return poll_message def send_pass(*args, **kwargs): pass orchestra = populated_orchestra orchestra.register_member(empty_member) questioner = Questioner( user_id=int(chat_id), orchestra=orchestra, hint_attributes=[], question_attributes=[], number_of_questions=42, bot=bot, multiple_choice=True, ) monkeypatch.setattr(questioner.bot, 'send_poll', send_poll) monkeypatch.setattr(questioner.bot, 'send_photo', send_pass) monkeypatch.setattr(questioner.bot, 'send_media_group', send_pass) questioner.ask_question() assert questioner.number_of_questions_asked == 1 assert questioner.current_question assert questioner.current_question.poll is poll_message.poll update = Update( 123, poll_answer=PollAnswer( poll_message.poll.id, User(123, 'foo', False), [(poll_message.poll.correct_option_id + 1) % 4], ), ) assert not questioner.check_update(update) update = Update( 123, poll_answer=PollAnswer( '4654654', User(chat_id, 'foo', False), [(poll_message.poll.correct_option_id + 1) % 4], ), ) assert not questioner.check_update(update) update = Update( 123, poll_answer=PollAnswer( poll_message.poll.id, User(chat_id, 'foo', False), [(poll_message.poll.correct_option_id + 1) % 4], ), ) assert questioner.check_update(update) questioner.handle_update(update) assert questioner.score.answers == 1 assert questioner.score.correct == 0 update = Update( 123, poll_answer=PollAnswer( poll_message.poll.id, User(chat_id, 'foo', False), [poll_message.poll.correct_option_id], ), ) assert questioner.check_update(update) questioner.handle_update(update) assert questioner.score.answers == 2 assert questioner.score.correct == 1