Esempio n. 1
0
    def test_questions_collection(self):
        """Test that a single game is successfully created"""
        with sessions.active_session() as session:
            games = models.Game.query.with_session(session).all()
            assert not games

        game.create_game(num_questions=1,
                         session_id="abc",
                         user_id=requests.SESSION_ID)

        with sessions.active_session() as session:
            games = models.Game.query.with_session(session).all()
            assert len(games) == 1
Esempio n. 2
0
    def test_answer_subsequent_questions(self):
        """Test a quiz game with more than one question"""
        with sessions.active_session() as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])
            session.add_all([
                models.Question(body='what part deaux',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='2')
            ])

        game.create_game(num_questions=2, session_id='123', user_id='1234')

        # answer all of the questions
        game.answer_current_question(session_id='123', guess='2')
        game.answer_current_question(session_id='123', guess='2')

        assert game.has_next_question(session_id='123') == False
Esempio n. 3
0
    def test_incorrect_with_no_next_question_response_contains_answer(self):
        """Test that if you are on the last question, we should tell you the correct answer in the response"""
        with sessions.active_session(should_commit=True) as session:
            session.add_all([
                models.Question(body='what',
                                option_one='one',
                                option_two='two',
                                option_three='three',
                                option_four='four',
                                answer='1')
            ])

        game.create_game(num_questions=1,
                         session_id=requests.SESSION_ID,
                         user_id=requests.USER_ID)
        with mock.patch("python_quiz.main.game.create_game"):
            self.test_app.post('/python_quiz',
                               data=json.dumps(requests.start_game_body))

        response = self.test_app.post('/python_quiz',
                                      data=json.dumps(
                                          requests.incorrect_guess_body))
        response_json = json.loads(response.data)
        assert 'The correct answer is one' in response_json['response'][
            'outputSpeech']['ssml']
Esempio n. 4
0
def answer_current_question(session_id, guess):
    """
  Answer the current question based on the current session

  @param session_id: The identifier for the current session
  @type session_id: str

  @param guess: The user's guess for the number they believe is correct: ('1', '2', '3', '4')
  @type guess: str

  @rtype: True if the guess is correct
  """
    with sessions.active_session(should_commit=True) as session:
        current_game = session.query(models.Game)\
          .filter(models.Game.session_id == session_id).order_by(desc(models.Game.created)).first()
        question_id = current_game.question_ids.pop()
        current_question = models.Question.query.with_session(session).get(
            question_id)
        logger.info("question=%s, guess=%s", current_question, guess)
        is_correct = current_question.answer == int(guess)

        if is_correct:
            current_game.count_correct += 1
        else:
            current_game.count_incorrect += 1

        session.add(current_game)
        return is_correct
Esempio n. 5
0
def _query_current_question(session_id, user_id):
    with sessions.active_session(should_commit=False) as session:
        get_or_create_user(user_id, session)
        game = session.query(
            models.Game).filter(models.Game.session_id == session_id).first()
        current_question = session.query(models.Question).get(
            game.question_ids[-1])
        logger.info('game=%s question=%s', game.id, current_question.body)
        return current_question
Esempio n. 6
0
    def test_incorrect_with_next_question_response_contains_answer(self):
        """Test that if you are not on the last question, we should tell you the correct answer in the response"""
        with sessions.active_session(should_commit=True) as session:
            session.add_all([
                models.Question(body='one',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1'),
                models.Question(body='two',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='2'),
                models.Question(body='three',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='3'),
            ])

        game_id = game.create_game(num_questions=3,
                                   session_id=requests.SESSION_ID,
                                   user_id=requests.USER_ID)
        with mock.patch("python_quiz.main.game.create_game"):
            self.test_app.post('/python_quiz',
                               data=json.dumps(requests.start_game_body))

        self.test_app.post('/python_quiz',
                           data=json.dumps(requests.incorrect_guess_body))
        response = self.test_app.post('/python_quiz',
                                      data=json.dumps(
                                          requests.incorrect_guess_body))
        response_json = json.loads(response.data)

        with sessions.active_session():
            current_game = models.Game.query.get(game_id)
            question_id = current_game.question_ids_snapshot[1]
            question = models.Question.query.get(question_id)
            assert 'The correct answer is %s' % question.answer in response_json[
                'response']['outputSpeech']['ssml']
Esempio n. 7
0
def display_card(question_id):
    with sessions.active_session() as session:
        current_question = models.Question.query.with_session(session).get(
            question_id)
        title = '\n'.join(wrap(current_question.body, width=7)) + '?'
        content = '1. {option_one}\n2.{option_two}\n3.{option_three}\n4.{option_four}' \
          .format(option_one=current_question.option_one,
                  option_two=current_question.option_two,
                  option_three=current_question.option_three,
                  option_four=current_question.option_four)
    return title, content
Esempio n. 8
0
    def test_game_flow(self):
        """
    This is really a test of the state machine. Let's say we have 2 questions for a quiz.
    If we have a list of questions as [A, B], what we want to do is...

    - Start the game and ask question B. The list should be untouched, [A, B]
    - Answer the question B which should pop off of the stack and then we should ask question [A]
    - We answer question A, and we're left with an empty list and the game is over.

    This is to fix the bug where we were getting to the point where we wanted to ask question A, but we had an
    empty stack so we would try to pop an empty list. In short, asking a question should not be a mutable operation.
    """
        with sessions.active_session() as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])

        game.create_game(num_questions=2, session_id='123', user_id='1234')

        with self.app.app_context():
            game.respond_to_guess('123', '1')

        with sessions.active_session(should_commit=False):
            game._query_current_question(session_id='123', user_id='1')
        game.answer_current_question(session_id='123', guess='2')

        assert game.has_next_question(session_id='123') == False
Esempio n. 9
0
    def test_incorrect_answer(self):
        """Test the basic assumptions about answering a question incorrectly"""
        with sessions.active_session() as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])

        current_game_id = game.create_game(num_questions=1,
                                           session_id='123',
                                           user_id='1234')
        current_game = session.query(models.Game).get(current_game_id)
        is_correct = game.answer_current_question(
            session_id=current_game.session_id, guess='2')
        assert is_correct != True

        with sessions.active_session() as session:
            new_game = session.query(models.Game).get(current_game_id)
            assert new_game.count_correct == 0
Esempio n. 10
0
def create_game(num_questions, session_id, user_id):
    """
  Instantiate a game and persist it to the database

  @param num_questions: Number of questions to use for the quiz
  @type num_questions: int

  @param session_id: The external identifier of the session
  @type session_id: str

  @param user_id: The identifier of the user, as defined by Amazon
  @type user_id: str

  @return: ID of the game that was created
  @rtype: int
  """
    with sessions.active_session() as session:
        user = get_or_create_user(user_id, session)
        question_id_tuples = session.query(models.Question.id).all()
        all_ids_set = set(
            t[0] for t in
            question_id_tuples)  # each tuple (row) only has one value in it
        asked_questions_set = set(user.asked_questions)
        possible_questions = all_ids_set.difference(asked_questions_set)

        try:
            question_ids = random.sample(possible_questions, num_questions)
        except ValueError:
            # if the sample is bigger than the population, we hit this case
            # which means that there are no possible questions to ask
            question_ids = []

        current_game = models.Game(count=num_questions,
                                   question_ids=question_ids,
                                   question_ids_snapshot=question_ids,
                                   session_id=session_id,
                                   user_id=user.id)
        user.asked_questions.extend(question_ids)
        session.add(current_game)
        session.add(user)
        session.commit()
        current_game_id = current_game.id
        return current_game_id
Esempio n. 11
0
    def test_full_quiz(self):
        """Test starting and ending a quiz"""
        with sessions.active_session() as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])

        game.create_game(num_questions=2,
                         session_id=requests.SESSION_ID,
                         user_id=requests.USER_ID)
        with mock.patch("python_quiz.main.game.create_game"):
            self.test_app.post('/python_quiz',
                               data=json.dumps(requests.start_game_body))

        self.test_app.post('/python_quiz',
                           data=json.dumps(requests.correct_guess_body))
        response = self.test_app.post('/python_quiz',
                                      data=json.dumps(
                                          requests.correct_guess_body))
        end_of_game_response = json.loads(response.data)
        voice_response = end_of_game_response['response']['outputSpeech'][
            'ssml']
        assert "You've answered 2 correct out of 2" in voice_response, "Expected summary to say all questions correct"
Esempio n. 12
0
    def test_unique_games(self):
        """Test that subsequent games don't repeat questions"""
        with sessions.active_session() as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])

        # create a game with a single question
        game.create_game(num_questions=1, session_id='123', user_id='1234')

        # complete the first game
        with self.app.app_context():
            game.respond_to_guess('123', '1')

        game.create_game(num_questions=1, session_id='456', user_id='1234')

        # since the questions a person can be asked are unique, there should not be another question
        # to ask the user, therefore there should not be another question
        assert game.has_next_question(session_id='456') is False
Esempio n. 13
0
    def test_bad_answer_slot_type(self):
        """Test that if a user doesn't respond with the wrong slot type, we tell them that and keep the game going"""
        with sessions.active_session() as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])

        game.create_game(num_questions=2,
                         session_id=requests.SESSION_ID,
                         user_id=requests.USER_ID)
        with mock.patch("python_quiz.main.game.create_game"):
            self.test_app.post('/python_quiz',
                               data=json.dumps(requests.start_game_body))

        response_json = self.test_app.post(
            '/python_quiz',
            data=json.dumps(requests.incorrect_guess_type_body))
        response = json.loads(response_json.data)
        voice_response = response['response']['outputSpeech']['ssml']

        assert '1.' not in voice_response, 'The response for help should not include a question'

        assert response['response'][
            'shouldEndSession'] is False, "The response should be a question"
        with sessions.active_session(should_commit=True) as session:
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])
            session.add_all([
                models.Question(body='what',
                                option_one='1',
                                option_two='2',
                                option_three='3',
                                option_four='4',
                                answer='1')
            ])

        game.create_game(num_questions=2,
                         session_id=requests.SESSION_ID,
                         user_id=requests.USER_ID)
        with mock.patch("python_quiz.main.game.create_game"):
            self.test_app.post('/python_quiz',
                               data=json.dumps(requests.start_game_body))

        self.test_app.post('/python_quiz',
                           data=json.dumps(requests.correct_guess_body))
        self.test_app.post('/python_quiz',
                           data=json.dumps(requests.correct_guess_body))
Esempio n. 14
0
def has_next_question(session_id):
    """Whether there is still a question that has not been asked yet"""
    with sessions.active_session(should_commit=False) as session:
        game = models.Game.query.with_session(session).filter(
            models.Game.session_id == session_id).first()
        return bool(len(game.question_ids))