Beispiel #1
0
 def test_game_id_not_found(self):
     score_object = services.get_frame_score(self.queryset, 'abcde12345')
     game_object = game_models.Game('abcde12345')
     game_object.errors = [
         game_models.Error(
             error_code=404,
             error_message='No game was found for the game id: abcde12345.')
     ]
     assert score_object == game_object
Beispiel #2
0
 def test_set_frame_score__invalid_score_format(self):
     score_object = services.set_frame_score(self.queryset,
                                             self.game_registration.game_id,
                                             'XX')
     assert score_object.errors == [
         game_models.Error(error_code=400,
                           error_message='Score format: XX is invalid.')
     ]
     assert score_object.frame_score is None
     assert score_object.first_attempt_score is None
     assert score_object.second_attempt_score is None
     assert score_object.third_attempt_score is None
Beispiel #3
0
 def test_set_frame_score__game_object_not_found(self):
     score_object = services.set_frame_score(self.queryset, 'abcde12345',
                                             'X')
     assert score_object.errors == [
         game_models.Error(
             error_code=404,
             error_message='No game was found for the game id: abcde12345.')
     ]
     assert score_object.frame_score is None
     assert score_object.first_attempt_score is None
     assert score_object.second_attempt_score is None
     assert score_object.third_attempt_score is None
 def test_game_registration_serializer__error(self):
     self.game_object.add_error(
         game_models.Error(error_code=404, error_message='Game not found'))
     serializer_instance = serializers.GameRegistrationSerializer(
         self.game_object)
     errors = {
         'errors': [{
             'error_code': 404,
             'error_message': 'Game not found'
         }]
     }
     expected = collections.OrderedDict(errors)
     assert serializer_instance.data == expected
Beispiel #5
0
def register_game():
    """Registers the game and returns the game instance."""
    try:
        with transaction.atomic(savepoint=False):
            game_object = game_models.GameRegistration()
            game_object.save()
            return game_object
    except DatabaseError:
        logging.exception('Unable to register the game')
        game_object = game_models.GameRegistration()
        game_object.add_error(
            game_models.Error(error_code=500,
                              error_message='Unable to register the game.'))
        return game_object
Beispiel #6
0
 def test_set_frame_score__game_has_been_played(self):
     scores = ['X', '7/', '7-2', '9/', 'X', 'X', 'X', '2-3', '6/', '7/3']
     for score in scores:
         services.set_frame_score(self.queryset,
                                  self.game_registration.game_id, score)
     score_object = services.set_frame_score(self.queryset,
                                             self.game_registration.game_id,
                                             'X')
     assert score_object.errors == [
         game_models.Error(
             error_code=400,
             error_message='Game:\'{}\' has already been played.'.format(
                 self.game_registration.game_id))
     ]
     assert score_object.frame_score is None
     assert score_object.first_attempt_score is None
     assert score_object.second_attempt_score is None
     assert score_object.third_attempt_score is None
Beispiel #7
0
def _get_game_object(game_id, clazz_instance):
    """Returns the game object by game id.

    Returns:
        a tuple of game object and boolean flag indicating that the game object
        was created or not
    """
    try:
        with transaction.atomic(savepoint=False):
            game_object = game_models.GameRegistration.objects.get(pk=game_id)
            return game_object, True
    except game_models.GameRegistration.DoesNotExist:
        logging.error('No game was found for game id : {}'.format(game_id))
        clazz_object = clazz_instance()
        clazz_object.add_error(
            game_models.Error(
                error_code=404,
                error_message='No game was found for the game id: {}.'.format(
                    game_id)))
        return clazz_object, False
 def test_score_per_frame__failure(self):
     score_per_frame = game_models.ScorePerFrame(first_attempt_score=5,
                                                 second_attempt_score=5,
                                                 third_attempt_score=0,
                                                 frame=1,
                                                 frame_version=1,
                                                 frame_score=10)
     score_per_frame.add_error(
         game_models.Error(error_code=400,
                           error_message='Game has already been played.'))
     errors = {
         'errors': [{
             'error_code': 400,
             'error_message': 'Game has already been played.'
         }]
     }
     expected = collections.OrderedDict(errors)
     serializer_instance = serializers.ScorePerFrameSerializer(
         score_per_frame)
     assert serializer_instance.data == expected
Beispiel #9
0
 def test_set_frame_score__race_condition_version_raises_error(self):
     services.set_frame_score(self.queryset, self.game_registration.game_id,
                              'X')
     with mock.patch('django.db.models.query.QuerySet.values_list',
                     return_value=mock_query.MockSet((0,))), \
             mock.patch('django.db.models.query.QuerySet.aggregate',
                        return_value={'frame_max': 0}):
         score_object = services.set_frame_score(
             self.queryset, self.game_registration.game_id, '2-3')
         assert score_object.errors == [
             game_models.Error(
                 error_code=500,
                 error_message=('Unable to save score: \'2-3\' for '
                                'game: \'{game}\'.'.format(
                                    game=self.game_registration.game_id)))
         ]
         assert score_object.frame_score is None
         assert score_object.first_attempt_score is None
         assert score_object.second_attempt_score is None
         assert score_object.third_attempt_score is None
Beispiel #10
0
    def test_register_name__error(self):
        """Tests if the game registration fails."""
        error_list = []

        def add_error(err):
            error_list.append(err)

        expected_mock = mock.Mock()
        expected_mock.add_error = mock.MagicMock(side_effect=add_error)
        save_method = mock.MagicMock(
            side_effect=django_db.DatabaseError('test'))
        expected_mock.save = save_method
        with mock.patch('game.models.GameRegistration',
                        side_effect=lambda: expected_mock):
            game_object = services.register_game()
            assert game_object == expected_mock
            assert game_object.save.call_count == 1
            assert game_object.add_error.call_count == 1
            assert error_list == [
                game_models.Error(error_code=500,
                                  error_message='Unable to register the game.')
            ]
Beispiel #11
0
def set_frame_score(score_queryset, game_id, score):
    """Sets the frame score for a valid game.

    The implementation executes the following:

    1. load the game object associated with game id; if the game does not exist
    then raise a 404 error.

    2. fetch the number of frames that have been played so far. If the number of
    frames played equals "10", i.e. the game is over, then a 400 error is raised

    3. If the score format is valid, then and no frames have been played, then
       a frame is created and the score calculated.
    """
    try:
        with transaction.atomic(savepoint=False):
            # If the game has not been created, then return a 404.
            game_object, game_object_created = _get_game_object(
                game_id, game_models.ScorePerFrame)
            if not game_object_created:
                # Error object is returned
                return game_object

            if not _is_valid_score(score):
                frame_score = game_models.ScorePerFrame()
                frame_score.add_error(
                    game_models.Error(
                        error_code=400,
                        error_message='Score format: {} is invalid.'.format(
                            score)))
                return frame_score

            spf_qs = score_queryset.filter(game=game_object)
            if not spf_qs or len(spf_qs) == 0:
                # First frame.

                (first_score, second_score,
                 third_score) = _parse_score(score, 1)
                bowling_frame = game_object.game_score.create(
                    frame=1,
                    first_attempt_score=first_score,
                    second_attempt_score=second_score,
                    third_attempt_score=third_score,
                    frame_version=1)
                return bowling_frame

            # If the game has been completed, then return a 400.
            number_of_played_frames = spf_qs.aggregate(
                django_models.Max('frame')).get('frame__max', 0)

            if number_of_played_frames == 10:
                frame_score = game_models.ScorePerFrame()
                frame_score.add_error(
                    game_models.Error(
                        error_code=400,
                        error_message='Game:\'{}\' has already been played.'.
                        format(game_id)))
                return frame_score

            # Parse the score, and check if the version has been created.
            (first_score, second_score,
             third_score) = _parse_score(score, number_of_played_frames + 1)
            version_number_tuple = spf_qs.filter(game=game_object).filter(
                frame=number_of_played_frames +
                1).values_list('frame_version').first()
            (version_number, ) = (version_number_tuple if version_number_tuple
                                  is not None else (0, ))
            # Update the frame by to indicate a new frame is being played.
            score_per_frame = game_object.game_score.create(
                first_attempt_score=first_score,
                second_attempt_score=second_score,
                third_attempt_score=third_score,
                frame=number_of_played_frames + 1,
                frame_version=version_number + 1)
            return score_per_frame
    except:
        logging.exception(('Unable to save the frame for score {}'
                           ' and game:{}.'.format(score, game_id)))
        frame_score = game_models.ScorePerFrame()
        frame_score.add_error(
            game_models.Error(
                error_code=500,
                error_message=('Unable to save score: \'{score}\' for game: '
                               '\'{game}\'.'.format(game=game_id,
                                                    score=score))))
        return frame_score