def test_add_user(self): # assert that the user ID is equivalent across both calls. self.assertEqual( FirestoreDB.add_user(json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, name='user/foo', tiktok='tiktok/bar', phone_number='+10000000000'), FirestoreDB.add_user(json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, name='user/bar', tiktok='tiktok/bar', phone_number='+10000000000') )
def test_generate_tribes_count_initialization( self, algorithm_type, number_of_joined_players, game_options, expected_game_count_tribes, expected_game_count_teams, expected_game_count_players, expected_tribe_count_teams, expected_tribe_count_players, expected_team_count_players): # create a game game_id = FirestoreDB.add_game( json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, hashtag='hashtag/foo') _gamedb._game_id = game_id # generate mock players with an id attribute and add the players to the game players = list() for i in range(0, number_of_joined_players): name = 'name/foo' tiktok = 'tiktok/bar' phone_number = f'+1000000000{i}' player = _gamedb.player(name=name, tiktok=tiktok, phone_number=phone_number) FirestoreDB.add_user( json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, name=name, tiktok=tiktok, phone_number=phone_number) players.append(player) # read counts for game, all tribes, all teams and verify that they are correct game_info_dict = algorithm_type.generate_tribes( game_id=game_id, players=players, game_options=game_options, gamedb=_gamedb) game = _gamedb.game_from_id(game_id) self.assertEqual(game.count_tribes, expected_game_count_tribes) self.assertEqual(game.count_teams, expected_game_count_teams) self.assertEqual(game.count_players, expected_game_count_players) for tribe in game_info_dict['tribes']: tribe_ref = _gamedb.tribe_from_id(tribe.id) self.assertEqual(tribe_ref.count_teams, expected_tribe_count_teams) self.assertEqual(tribe_ref.count_players, expected_tribe_count_players) for team in game_info_dict['teams']: self.assertEqual( _gamedb.team_from_id(team.id).count_players, expected_team_count_players)
def test_integration(self): test_id = str(uuid.uuid4()) # Inject a game ID (test uuid) into the gamedb. use a globally unique country code to ensure # that only this game gets scheduled. game_id = FirestoreDB.add_game( json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, hashtag=_TEST_GAME_HASHTAG, country_code=f'US-{test_id}') gamedb = FirestoreDB( json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, game_id=game_id) log_message(f'Running integration test for game {game_id}') # create an integration test subsystem log stream that specifically captures # game inputs and outputs at the SMS boundary. test_log_stream = GameIntegrationTestLogStream(game_id=game_id, test_id=test_id) # add test challenges for challenge in _TEST_CHALLENGES: gamedb.add_challenge(challenge=challenge) # if non-existent, create users associated with players. NOTE: critical for FE code # to create users when players sign up. for player_info in [*_EMULATED_PLAYERS, *_REAL_PLAYERS]: FirestoreDB.add_user( json_config_path=_TEST_FIRESTORE_INSTANCE_JSON_PATH, name=player_info[0], tiktok=player_info[1], phone_number=player_info[2]) # Inject players into gamedb. set the phone number of the players to a known, or emulated device. emulated_players = [] for player_info in _EMULATED_PLAYERS: player = gamedb.player(name=player_info[0], tiktok=player_info[1], phone_number=player_info[2]) emulated_players.append( EmulatedPlayer(id=player.id, name=player.name, tiktok=player.tiktok, phone_number=player.phone_number, test_stream=test_log_stream, gamedb=gamedb)) for player_info in _REAL_PLAYERS: player = gamedb.player(name=player_info[0], tiktok=player_info[1], phone_number=player_info[2]) # mock the scheduling method in MM service so that we can force schedule # after initialization. save_check_start_time_fn = MatchmakerService._check_start_time check_start_time_fn = mock.MagicMock() check_start_time_fn.return_value = False MatchmakerService._check_start_time = check_start_time_fn # create device emulator for Twilio SMS events. patch this # into the game engine class for the test. notification_emulator = FakeTwilioSMSNotifier( json_config_path=_TEST_TWILIO_SMS_CONFIG_PATH, game_id=game_id, emulated_devices=emulated_players) build_notifier_fn = mock.MagicMock() build_notifier_fn.return_value = notification_emulator Engine._get_sms_notifier = build_notifier_fn # Instantiate a local matchmaker service. make sure all services have the right configs, # e.g. twilio should be using the prod service phone number so that it can actually send messages. # set the clock mode on (2) to async so that game events happen immediately during testing. service = MatchmakerService( matchmaker=MatchMakerRoundRobin(), region=f'US-{test_id}', gamedb=gamedb, game_options=GameOptions( game_clock_mode=GameClockMode.ASYNC, game_wait_sleep_interval_sec=_TEST_SLEEP_INTERVAL, multi_tribe_min_tribe_size=2, engine_worker_thread_count=5, tribe_council_time_sec=_TEST_SLEEP_INTERVAL)) # mock the MM Twilio client service._get_sms_notifier = mock.MagicMock( return_value=notification_emulator) try: service.start_matchmaker_daemon(sleep_seconds=1) # force schedule the game in MM (1). check_start_time_fn.return_value = True MatchmakerService._check_start_time = check_start_time_fn while gamedb.game_from_id(game_id).count_players > 1: time.sleep(_TEST_SLEEP_INTERVAL) finally: MatchmakerService._check_start_time = save_check_start_time_fn service.set_stop() test_dict = test_log_stream.to_dict() if _SAVE_TEST_LOGS: persisted_test_logs = test_log_stream.persist() log_message(persisted_test_logs) with open(f'game_logs/stream.{test_id}.json', 'w+') as f: f.write(persisted_test_logs) active_players = list() for player in gamedb.stream_players( active_player_predicate_value=True): active_players.append(player) winner = active_players[0] found_winner_message = False for output in test_dict['outputs']: if 'You are the last survivor and WINNER' in output[ 'message'] and output['name'] == winner.name: found_winner_message = True self.assertTrue(found_winner_message)