示例#1
0
async def test_refresh_token_returns_an_error_for_a_missing_tokens(sanic_server):
    await User.collection.delete_many({})
    user = User(**{"username": "******", "password": "******"})
    await user.commit()

    payload = {
        "username": "******",
        "password": "******"
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_TOKEN_QUEUE,
        request_exchange=REQUEST_TOKEN_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_TOKEN_EXCHANGE
    )
    response = await client.send(payload=payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    tokens = response[Response.CONTENT_FIELD_NAME]

    assert len(tokens.keys()) == 2
    assert sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME'] in tokens.keys()
    assert sanic_server.app.config['JWT_REFRESH_TOKEN_FIELD_NAME'] in tokens.keys()

    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload={})

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME not in response.keys()
    errors = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in errors.keys()
    assert errors[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert len(errors[Response.ERROR_DETAILS_FIELD_NAME]) == 2

    assert 'access_token' in errors[Response.ERROR_DETAILS_FIELD_NAME].keys()
    assert len(errors[Response.ERROR_DETAILS_FIELD_NAME]['access_token']) == 1
    assert errors[Response.ERROR_DETAILS_FIELD_NAME]['access_token'][0] == 'Missing data for ' \
                                                                           'required field.'

    assert 'refresh_token' in errors[Response.ERROR_DETAILS_FIELD_NAME].keys()
    assert len(errors[Response.ERROR_DETAILS_FIELD_NAME]['refresh_token']) == 1
    assert errors[Response.ERROR_DETAILS_FIELD_NAME]['refresh_token'][0] == 'Missing data for ' \
                                                                            'required field.'

    await User.collection.delete_one({'id': user.id})
示例#2
0
async def test_refresh_token_returns_error_for_not_existing_user(sanic_server):
    await User.collection.delete_many({})
    user = User(**{"username": "******", "password": "******"})
    await user.commit()

    payload = {
        "username": "******",
        "password": "******"
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_TOKEN_QUEUE,
        request_exchange=REQUEST_TOKEN_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_TOKEN_EXCHANGE
    )
    response = await client.send(payload=payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    tokens = response[Response.CONTENT_FIELD_NAME]

    assert len(tokens.keys()) == 2
    assert sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME'] in tokens.keys()
    assert sanic_server.app.config['JWT_REFRESH_TOKEN_FIELD_NAME'] in tokens.keys()

    await User.collection.delete_many({})
    await asyncio_sleep(0.1)

    refresh_payload = {
        sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME']: tokens['access_token'],
        sanic_server.app.config['JWT_REFRESH_TOKEN_FIELD_NAME']: tokens['refresh_token'],
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload=refresh_payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME not in response.keys()
    errors = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in errors.keys()
    assert errors[Response.ERROR_TYPE_FIELD_NAME] == NOT_FOUND_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in errors.keys()
    assert errors[Response.ERROR_DETAILS_FIELD_NAME] == "User wasn't found."

    await User.collection.delete_many({'id': user.id})
async def test_verify_token_return_error_for_expired_access_token(
        sanic_server):
    await User.collection.delete_many({})
    user = User(**{"username": "******", "password": "******"})
    await user.commit()

    payload = {"username": "******", "password": "******"}
    with freeze_time("2000-01-01"):
        client = RpcAmqpClient(sanic_server.app,
                               routing_key=REQUEST_TOKEN_QUEUE,
                               request_exchange=REQUEST_TOKEN_EXCHANGE,
                               response_queue='',
                               response_exchange=RESPONSE_TOKEN_EXCHANGE)
        response = await client.send(payload=payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    tokens = response[Response.CONTENT_FIELD_NAME]

    assert len(tokens.keys()) == 2
    assert sanic_server.app.config[
        'JWT_ACCESS_TOKEN_FIELD_NAME'] in tokens.keys()
    assert sanic_server.app.config[
        'JWT_REFRESH_TOKEN_FIELD_NAME'] in tokens.keys()

    verify_payload = {
        sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME']:
        tokens['access_token']
    }
    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=verify_payload)

    assert len(response.keys()) == 2
    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME not in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == TOKEN_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert error[Response.ERROR_DETAILS_FIELD_NAME] == 'Signature has expired.'

    await User.collection.delete_one({'id': user.id})
async def test_rpc_amqp_client_returns_ok_with_custom_event_loop(event_loop):
    app = Application(config=FakeConfig(), loop=event_loop)
    register_worker = FakeRegisterMicroserviceWorker(app)
    extension = AmqpExtension(app)
    extension.register_worker(register_worker)

    await extension.init(event_loop)

    client = RpcAmqpClient(app=app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE_NAME,
                           loop=event_loop)
    response = await client.send(payload={
        'name': 'microservice',
        'version': '1.0.0'
    })

    assert Response.CONTENT_FIELD_NAME in response.keys()
    assert response[Response.CONTENT_FIELD_NAME] == 'OK'

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert response[Response.EVENT_FIELD_NAME] is None

    await extension.deinit(event_loop)
示例#5
0
async def test_worker_registers_a_new_server_successfully(sanic_server):
    await GameServer.collection.delete_many({})

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(
        payload={
            'host': '127.0.0.1',
            'port': 9000,
            'available-slots': 100,
            'credentials': {
                'token': 'super_secret_token'
            },
            'game-mode': '1v1'
        })

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert len(content.keys()) == 1
    assert 'id' in content.keys()

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 1

    await GameServer.collection.delete_many({})
async def test_users_post_returns_validation_error_for_not_matched_password(sanic_server):
    payload = {
        "username": "******",
        "password": "******",
        "confirm_password": "******"
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload=payload)

    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.EVENT_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME].keys()) == 1

    details = error[Response.ERROR_DETAILS_FIELD_NAME]
    assert 'confirm_password' in details.keys()
    assert len(details['confirm_password']) == 1
    assert details['confirm_password'][0] == 'Confirm password must equal to a new password.'
async def test_users_post_returns_validation_error_for_non_unique_username(sanic_server):
    await User.collection.delete_many({})
    await User(**{"username": "******", "password": "******"}).commit()

    payload = {
        "username": "******",
        "password": "******",
        "confirm_password": "******"
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload=payload)

    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.EVENT_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME].keys()) == 1

    assert 'username' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['username']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['username'][0] == 'Username must be unique.'

    await User.collection.delete_many({})
async def test_users_post_successfully_creates_a_new_user(sanic_server):
    await User.collection.delete_many({})

    payload = {
        "username": "******",
        "password": "******",
        "confirm_password": "******"
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload=payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert len(content.keys()) == 2

    assert "id" in content

    assert "username" in content
    assert content["username"] == payload["username"]

    await User.collection.delete_many({})
async def test_users_post_returns_validation_error_for_missing_fields(sanic_server):
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload={})

    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.EVENT_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME].keys()) == 3

    details = error[Response.ERROR_DETAILS_FIELD_NAME]
    assert 'username' in details.keys()
    assert len(details['username']) == 1
    assert details['username'][0] == 'Missing data for required field.'

    assert 'password' in details.keys()
    assert len(details['password']) == 1
    assert details['password'][0] == 'Missing data for required field.'

    assert 'confirm_password' in details.keys()
    assert len(details['confirm_password']) == 1
    assert details['confirm_password'][0] == 'Missing data for required field.'
示例#10
0
async def test_worker_returns_validation_for_invalid_player_id(sanic_server):
    await PlayerStatistic.collection.delete_many({})

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload={'player_id': "INVALID_OBJECT_ID"})

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 1

    assert 'player_id' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['player_id']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['player_id'][
        0] == 'Invalid ObjectId.'

    players_count = await PlayerStatistic.collection.count_documents({})
    assert players_count == 0

    await PlayerStatistic.collection.delete_many({})
示例#11
0
async def test_worker_returns_a_new_initialized_player(sanic_server):
    await PlayerStatistic.collection.delete_many({})

    player_id = str(ObjectId())
    init_data = {'player_id': player_id}
    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=init_data)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert len(list(content.keys())) == 6
    assert set(content.keys()) == {
        'id', 'player_id', 'total_games', 'wins', 'loses', 'rating'
    }

    assert content['player_id'] == player_id
    assert content['total_games'] == 0
    assert content['wins'] == 0
    assert content['loses'] == 0
    assert content['rating'] == 0

    players_count = await PlayerStatistic.collection.count_documents({})
    assert players_count == 1

    await PlayerStatistic.collection.delete_many({})
async def test_rpc_amqp_client_returns_an_error(event_loop):
    app = Application(config=FakeConfig(), loop=event_loop)
    register_worker = FakeRegisterMicroserviceWorker(app)
    extension = AmqpExtension(app)
    extension.register_worker(register_worker)

    await extension.init(event_loop)

    client = RpcAmqpClient(app=app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE_NAME)
    response = await client.send(payload={})

    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.ERROR_TYPE_FIELD_NAME in response[
        Response.ERROR_FIELD_NAME].keys()
    assert response[Response.ERROR_FIELD_NAME][
        Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR  # NOQA

    assert Response.ERROR_DETAILS_FIELD_NAME in response[
        Response.ERROR_FIELD_NAME].keys()
    assert response[Response.ERROR_FIELD_NAME][
        Response.ERROR_DETAILS_FIELD_NAME] == VALIDATION_ERROR_DECR  # NOQA

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert response[Response.EVENT_FIELD_NAME] is None

    await extension.deinit(event_loop)
示例#13
0
async def test_worker_returns_not_found_error_for_non_existing_game_server(
        sanic_server):
    await GameServer.collection.delete_many({})

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    data = {'id': '5b6a085123cf24aef53b4c78', 'freed-slots': 10}
    response = await client.send(payload=data)

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == NOT_FOUND_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert error[Response.ERROR_DETAILS_FIELD_NAME] == 'The requested game server ' \
                                                       'was not found.'

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 0

    await GameServer.collection.delete_many({})
示例#14
0
async def test_worker_returns_a_validation_error_for_missing_fields(
        sanic_server):
    await GameServer.collection.delete_many({})

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload={})

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 2

    for field in ['id', 'freed-slots']:
        assert field in error[Response.ERROR_DETAILS_FIELD_NAME]
        assert len(error[Response.ERROR_DETAILS_FIELD_NAME][field]) == 1
        assert error[Response.ERROR_DETAILS_FIELD_NAME][field][0] == 'Missing data for ' \
                                                                     'required field.'

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 0

    await GameServer.collection.delete_many({})
async def test_verify_token_return_a_validation_error_for_a_missing_access_token(
        sanic_server):
    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload={})

    assert Response.ERROR_FIELD_NAME in response.keys()
    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME not in response.keys()

    errors = response[Response.ERROR_FIELD_NAME]
    assert len(errors.keys()) == 2
    assert 'is_valid' not in errors.keys()

    assert Response.ERROR_TYPE_FIELD_NAME in errors.keys()
    assert errors[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in errors.keys()

    access_token_field = sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME']
    assert access_token_field in errors[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(
        errors[Response.ERROR_DETAILS_FIELD_NAME][access_token_field]) == 1
    assert errors[Response.ERROR_DETAILS_FIELD_NAME][access_token_field][0] == 'Missing data for ' \
                                                                               'required field.'
示例#16
0
async def test_refresh_token_returns_new_access_token(sanic_server):
    await User.collection.delete_many({})
    user = User(**{"username": "******", "password": "******"})
    await user.commit()

    payload = {
        "username": "******",
        "password": "******"
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_TOKEN_QUEUE,
        request_exchange=REQUEST_TOKEN_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_TOKEN_EXCHANGE
    )
    response = await client.send(payload=payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    tokens = response[Response.CONTENT_FIELD_NAME]

    assert len(tokens.keys()) == 2
    assert sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME'] in tokens.keys()
    assert sanic_server.app.config['JWT_REFRESH_TOKEN_FIELD_NAME'] in tokens.keys()

    refresh_payload = {
        sanic_server.app.config['JWT_ACCESS_TOKEN_FIELD_NAME']: tokens['access_token'],
        sanic_server.app.config['JWT_REFRESH_TOKEN_FIELD_NAME']: tokens['refresh_token'],
    }
    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload=refresh_payload)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert 'access_token' in content.keys()
    assert 'refresh_token' not in content.keys()

    await User.collection.delete_one({'id': user.id})
async def test_worker_returns_an_updated_grouped_players(test_app):
    client = RpcAmqpClient(
        test_app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    payload = {
        "game-mode": "duel",
        "new-player": {
            "id": "0146563d-0f45-4062-90a7-b13a583defad",
            "response-queue": "player-2-queue",
            "event-name": "find-game",
            "detail": {
                "rating": 2680,
                "content": {
                    "id": "0146563d-0f45-4062-90a7-b13a583defad",
                    "games": 531,
                    "wins": 279
                }
            }
        },
        "grouped-players": {
            "team 1": [
                {
                    "id": "56acbeb4-687d-4c8b-a881-0b9abdda64e4",
                    "response-queue": "player-1-queue",
                    "event-name": "find-game",
                    "detail": {
                        "rating": 2702,
                        "content": {
                            "id": "56acbeb4-687d-4c8b-a881-0b9abdda64e4",
                            "games": 161,
                            "wins": 91
                        }
                    }
                }
            ],
            "team 2": []
        }
    }
    response = await client.send(payload=payload)

    assert Response.CONTENT_FIELD_NAME in response.keys()
    assert Response.EVENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert 'added' in content.keys()
    assert content['added'] is True

    assert 'is_filled' in response['content'].keys()
    assert content['is_filled'] is True

    assert 'grouped-players' in content.keys()
    assert len(content['grouped-players']['team 1']) == 1
    assert payload['new-player'] not in content['grouped-players']['team 1']
    assert len(content['grouped-players']['team 2']) == 1
    assert payload['new-player'] in content['grouped-players']['team 2']
async def test_worker_returns_a_validation_error_for_invalid_game_mode(test_app):
    client = RpcAmqpClient(
        test_app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    payload = {
        "game-mode": "UNKNOWN_MODE",
        "new-player": {
            "id": "0146563d-0f45-4062-90a7-b13a583defad",
            "response-queue": "player-2-queue",
            "event-name": "find-game",
            "detail": {
                "rating": 2680,
                "content": {
                    "id": "0146563d-0f45-4062-90a7-b13a583defad",
                    "games": 531,
                    "wins": 279
                }
            }
        },
        "grouped-players": {
            "team 1": [
                {
                    "id": "56acbeb4-687d-4c8b-a881-0b9abdda64e4",
                    "response-queue": "player-1-queue",
                    "event-name": "find-game",
                    "detail": {
                        "rating": 2702,
                        "content": {
                            "id": "56acbeb4-687d-4c8b-a881-0b9abdda64e4",
                            "games": 161,
                            "wins": 91
                        }
                    }
                }
            ],
            "team 2": []
        }
    }
    response = await client.send(payload=payload)

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 1

    assert 'game-mode' in error['details']
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['game-mode']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['game-mode'][0] == 'The specified game mode ' \
                                                                       'is not available.'
async def test_worker_returns_an_error_for_extra_fields_by_default(
        sanic_server):
    await PlayerStatistic.collection.delete_many({})

    player_id = str(ObjectId())
    create_data = {
        'player_id': player_id,
        'total_games': 10,
        'wins': 5,
        'loses': 5,
        'rating': 2500
    }
    object = PlayerStatistic(**create_data)
    await object.commit()

    players_count = await PlayerStatistic.collection.count_documents({})
    assert players_count == 1

    update_data = deepcopy(create_data)
    update_data.update({
        'total_games': 12,
        'wins': 6,
        'loses': 6,
        'rating': 2500,
        'winrate': 50,
        'nickname': 'user'
    })
    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=update_data)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert len(list(error.keys())) == 2
    assert set(error.keys()) == {'type', 'details'}

    assert error['type'] == VALIDATION_ERROR

    assert len(error['details']) == 1
    assert len(error['details']['_schema']) == 2
    assert set(error['details']['_schema']) == {
        'Unknown field name nickname.', 'Unknown field name winrate.'
    }

    await PlayerStatistic.collection.delete_many({})
async def test_worker_returns_updated_player_statistics(sanic_server):
    await PlayerStatistic.collection.delete_many({})

    player_id = str(ObjectId())
    create_data = {
        'player_id': player_id,
        'total_games': 10,
        'wins': 5,
        'loses': 5,
        'rating': 2500
    }
    object = PlayerStatistic(**create_data)
    await object.commit()

    players_count = await PlayerStatistic.collection.count_documents({})
    assert players_count == 1

    update_data = deepcopy(create_data)
    update_data.update({
        'total_games': 12,
        'wins': 6,
        'loses': 6,
        'rating': 2500
    })
    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=update_data)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert len(list(content.keys())) == 6
    assert set(content.keys()) == {
        'id', 'player_id', 'total_games', 'wins', 'loses', 'rating'
    }

    assert content['player_id'] == update_data['player_id']
    assert content['total_games'] == update_data['total_games']
    assert content['wins'] == update_data['wins']
    assert content['loses'] == update_data['loses']
    assert content['rating'] == update_data['rating']

    await PlayerStatistic.collection.delete_many({})
示例#21
0
async def test_worker_returns_a_validation_error_for_missing_fields(sanic_server):
    await GameServer.collection.delete_many({})

    objects = await create_game_servers([
        {
            'host': '127.0.0.1',
            'port': 9000,
            'available_slots': 100,
            'credentials': {
                'token': 'super_secret_token'
            },
            'game_mode': 'team-deathmatch'
        }
    ])
    game_server = objects[0]

    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload={
        'required-slots': 10,
        'game-mode': 'team-deathmatch'
    })

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert len(list(content.keys())) == 3
    assert set(content.keys()) == {'host', 'port', 'credentials'}

    filter_func = lambda obj: obj.host == content['host'] and obj.port == content['port']  # NOQA
    extracted_server = list(filter(filter_func, objects))[0]

    assert content['host'] == extracted_server.host
    assert content['port'] == extracted_server.port
    assert content['credentials'] == extracted_server.credentials

    game_server = await GameServer.find_one({"_id": game_server["id"]})
    assert game_server.available_slots == 90

    await GameServer.collection.delete_many({})
示例#22
0
async def test_worker_returns_a_validation_error_for_invalid_host_and_port(
        sanic_server):
    await GameServer.collection.delete_many({})

    create_data = {
        'host': '',
        'port': -1,
        'available-slots': 100,
        'credentials': {
            'token': 'super_secret_token'
        },
        'game-mode': '1v1'
    }

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=create_data)

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 2

    assert 'host' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['host']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['host'][
        0] == "Field cannot be blank."

    assert 'port' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['port']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['port'][
        0] == "Field must have a positive value."

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 0

    await GameServer.collection.delete_many({})
示例#23
0
async def test_worker_returns_a_validation_error_for_invalid_id(sanic_server):
    await GameServer.collection.delete_many({})

    create_data = {
        'id': "INVALID_ID",
        'host': '127.0.0.1',
        'port': 9000,
        'available-slots': 100,
        'credentials': {
            'token': 'super_secret_token'
        },
        'game-mode': '1v1'
    }

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=create_data)

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 1

    assert 'id' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['id']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['id'][0] == "'INVALID_ID' is not a valid " \
                                                                "ObjectId, it must be a 12-byte " \
                                                                "input or a 24-character hex " \
                                                                "string."

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 0

    await GameServer.collection.delete_many({})
示例#24
0
async def test_worker_returns_none_for_an_non_existing_server_type(sanic_server):
    await GameServer.collection.delete_many({})

    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload={
        'required-slots': 10,
        'game-mode': 'battle-royal'
    })

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert content is None

    await GameServer.collection.delete_many({})
示例#25
0
async def test_worker_returns_a_not_found_error(sanic_server):
    await PlayerStatistic.collection.delete_many({})

    retrieve_data = {'player_id': str(ObjectId())}
    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    response = await client.send(payload=retrieve_data)

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == NOT_FOUND_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert isinstance(error[Response.ERROR_DETAILS_FIELD_NAME], str)
    assert error[Response.ERROR_DETAILS_FIELD_NAME] == PLAYER_NOT_FOUND_ERROR

    await PlayerStatistic.collection.delete_many({})
示例#26
0
    async def run(self, *args, loop=None, **kwargs):
        loop = loop or getattr(self.app, 'loop',
                               None) or asyncio.get_event_loop()
        client = RpcAmqpClient(self.app,
                               routing_key=self.REQUEST_QUEUE_NAME,
                               request_exchange=self.REQUEST_EXCHANGE_NAME,
                               response_queue='',
                               response_exchange=self.RESPONSE_EXCHANGE_NAME,
                               loop=loop)

        is_registered = False
        microservice_data = self.get_microservice_data(self.app)
        for _ in range(self.MAX_RETRIES):
            try:
                response = await client.send(
                    payload=microservice_data,
                    consume_timeout=self.RETRY_TIMEOUT)

                if 'error' in response.keys():
                    LOGGER.error("Received validation errors: {}".format(
                        response['error']))
                else:
                    assert 'content' in response.keys()
                    assert response['content'] == 'OK'
                    is_registered = True

                break
            except (AioamqpException, TimeoutError):
                LOGGER.error(
                    "Can't receive a response because the Auth/Auth microservice isn't "
                    "responding or the required queues and the exchanges aren't created. "
                    "Retry after {} second(s).".format(self.RETRY_TIMEOUT))
                await asyncio.sleep(self.RETRY_TIMEOUT, loop=loop)

        await self.free_resources()

        if not is_registered:
            raise ConnectionError(
                'Occurred an error during registering microservice.')
示例#27
0
async def test_worker_returns_one_existing_server_for_one_server_in_list(sanic_server):
    await GameServer.collection.delete_many({})

    create_data = {
        'host': '127.0.0.1',
        'port': 9000,
        'available_slots': 100,
        'credentials': {
            'token': 'super_secret_token'
        },
        'game_mode': '1v1'
    }
    objects = await create_game_servers([create_data, ])

    client = RpcAmqpClient(
        sanic_server.app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload={
        'required-slots': 20,
        'game-mode': "1v1"
    })

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert len(list(content.keys())) == 3
    assert set(content.keys()) == {'host', 'port', 'credentials'}

    assert content['host'] == objects[0].host
    assert content['port'] == objects[0].port
    assert content['credentials'] == objects[0].credentials

    await GameServer.collection.delete_many({})
示例#28
0
async def test_worker_returns_a_validation_error_for_invalid_id_and_slots_type(
        sanic_server):
    await GameServer.collection.delete_many({})

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    data = {'id': 'INVALID_OBJECT_ID', 'freed-slots': 'INVALID_VALUE'}
    response = await client.send(payload=data)

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 2

    assert 'id' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['id']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['id'][0] == "'INVALID_OBJECT_ID' is not a " \
                                                                "valid ObjectId, it must be a " \
                                                                "12-byte input or a " \
                                                                "24-character hex string."

    assert 'freed-slots' in error[Response.ERROR_DETAILS_FIELD_NAME]
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]['freed-slots']) == 1
    assert error[Response.ERROR_DETAILS_FIELD_NAME]['freed-slots'][
        0] == 'Not a valid integer.'

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 0

    await GameServer.collection.delete_many({})
async def test_worker_returns_a_validation_error_for_missing_fields(test_app):
    client = RpcAmqpClient(
        test_app,
        routing_key=REQUEST_QUEUE,
        request_exchange=REQUEST_EXCHANGE,
        response_queue='',
        response_exchange=RESPONSE_EXCHANGE
    )
    response = await client.send(payload={})

    assert Response.ERROR_FIELD_NAME in response.keys()
    error = response[Response.ERROR_FIELD_NAME]

    assert Response.ERROR_TYPE_FIELD_NAME in error.keys()
    assert error[Response.ERROR_TYPE_FIELD_NAME] == VALIDATION_ERROR

    assert Response.ERROR_DETAILS_FIELD_NAME in error.keys()
    assert len(error[Response.ERROR_DETAILS_FIELD_NAME]) == 3

    for field in ['game-mode', 'new-player', 'grouped-players']:
        assert field in error[Response.ERROR_DETAILS_FIELD_NAME]
        assert len(error[Response.ERROR_DETAILS_FIELD_NAME][field]) == 1
        assert error[Response.ERROR_DETAILS_FIELD_NAME][field][0] == 'Missing data for ' \
                                                                     'required field.'
示例#30
0
async def test_worker_returns_an_updated_information_about_slots(sanic_server):
    await GameServer.collection.delete_many({})

    game_server = GameServer(
        **{
            'host': '127.0.0.1',
            'port': 9000,
            'available_slots': 100,
            'credentials': {
                'token': 'super_secret_token'
            },
            'game_mode': '1v1'
        })
    await game_server.commit()

    client = RpcAmqpClient(sanic_server.app,
                           routing_key=REQUEST_QUEUE,
                           request_exchange=REQUEST_EXCHANGE,
                           response_queue='',
                           response_exchange=RESPONSE_EXCHANGE)
    data = {'id': str(game_server.id), 'freed-slots': 10}
    response = await client.send(payload=data)

    assert Response.EVENT_FIELD_NAME in response.keys()
    assert Response.CONTENT_FIELD_NAME in response.keys()
    content = response[Response.CONTENT_FIELD_NAME]

    assert set(content.keys()) == {'id', 'available-slots'}
    assert content['id'] == str(game_server.id)
    assert content[
        'available-slots'] == game_server.available_slots + data['freed-slots']

    servers_count = await GameServer.collection.count_documents({})
    assert servers_count == 1

    await GameServer.collection.delete_many({})