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})
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)
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.'
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({})
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)
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({})
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.'
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({})
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({})
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({})
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({})
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({})
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({})
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.')
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({})
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.'
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({})