Example #1
0
def test_name_changes_state(update_mock, db_session):
    """
    Join two players to a game and confirm that
       a) the second one joining changes the game hash and
       b) the second one changing their name changes the game hash
    """
    g = WurwolvesGame(GAME_ID)
    g.join(USER_ID)

    update_mock.assert_called()
    update_mock.reset_mock()

    game_hash_1 = g.get_game().update_tag

    new_user_id = uuid()
    g.join(new_user_id)

    update_mock.assert_called()
    update_mock.reset_mock()

    game_hash_2 = g.get_game().update_tag

    WurwolvesGame.set_user_name(new_user_id, "Stinky Smelly")

    update_mock.assert_called()
    update_mock.reset_mock()

    game_hash_3 = g.get_game().update_tag

    assert game_hash_1 != game_hash_2
    assert game_hash_1 != game_hash_3
    assert game_hash_2 != game_hash_3
def test_seer_saved_no_fail(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    medic_id = uuid()
    seer_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(medic_id)
    game.join(seer_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    game.seer_night_action(seer_id, wolf_id)
    game.wolf_night_action(wolf_id, seer_id)
    game.medic_night_action(medic_id, seer_id)

    assert game.get_player_model(seer_id).state == PlayerState.ALIVE

    summary = get_summary_of_chat(game, seer_id)

    assert re.search(r"they are a wolf", summary)
Example #3
0
def test_killed_twice(db_session):
    game = WurwolvesGame(GAME_ID)

    # Add four players
    player_ids = [uuid() for _ in range(4)]
    roles = [
        PlayerRole.VILLAGER,
        PlayerRole.VILLAGER,
        PlayerRole.VIGILANTE,
        PlayerRole.WOLF,
    ]
    for p in player_ids:
        game.join(p)

    game.start_game()

    for p, r in zip(player_ids, roles):
        game.set_player_role(game.get_player_id(p), r)

    villager1_id = player_ids[0]
    villager2_id = player_ids[1]
    vigilante_id = player_ids[2]
    wolf_id = player_ids[3]

    # Kill a villager with the vigilante
    game.vigilante_night_action(vigilante_id, villager1_id)
    # ...and the wolf
    game.wolf_night_action(wolf_id, villager1_id)

    # Check that the player retains their role
    db_session.expire_all()
    assert game.get_player_model(
        villager1_id).previous_role != PlayerRole.SPECTATOR
def five_player_game(db_session) -> WurwolvesGame:

    g = WurwolvesGame(GAME_ID)

    # Make players
    user_ids = [uuid() for _ in range(5)]
    roles = [
        PlayerRole.WOLF,
        PlayerRole.MEDIC,
        PlayerRole.SEER,
        PlayerRole.VILLAGER,
        PlayerRole.VILLAGER,
    ]
    names = ["Wolf", "Medic", "Seer", "Villager 1", "Villager 2"]

    for i, id in enumerate(user_ids):
        g.join(id)

    g.start_game()

    # Override the roles
    for id, role, name in zip(user_ids, roles, names):
        u = g.get_player(id)
        u.role = role
        g.set_user_name(id, name)

    g._session.commit()

    roles_map = {name: user_id for name, user_id in zip(names, user_ids)}

    return g, roles_map
Example #5
0
    def factory():
        random_id = str(uuid())
        g = WurwolvesGame(random_id)

        # You need at least three players for start_game() to work
        g.join(USER_ID)
        g.join(uuid())
        g.join(uuid())

        return g
Example #6
0
def demo_game(db_session) -> WurwolvesGame:
    g = WurwolvesGame(GAME_ID)

    # You need at least three players for start_game() to work
    ids = [USER_ID, uuid(), uuid()]
    for i, id in enumerate(ids):
        g.join(id)
        g.set_user_name(id, f"Player {i}")

    return g
Example #7
0
def test_name_player(db_session):
    g = WurwolvesGame(GAME_ID)
    g.join(USER_ID)

    assert len(db_session.query(User).all()) == 1
    u = db_session.query(User).filter(User.id == USER_ID).first()
    assert u.name_is_generated

    g.set_user_name(USER_ID, "Charles")
    db_session.expire_all()

    u = db_session.query(User).filter(User.id == USER_ID).first()
    assert not u.name_is_generated
    assert u.name == "Charles"
def test_masons_announced(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    mason_1_id = uuid()
    mason_2_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(mason_1_id)
    game.join(mason_2_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    mason_1_name = game.get_user_name(mason_1_id)
    mason_2_name = game.get_user_name(mason_2_id)

    assert f"Your fellow masons are {mason_2_name}" in get_summary_of_chat(
        game, mason_1_id)
    assert f"Your fellow masons are {mason_1_name}" in get_summary_of_chat(
        game, mason_2_id)

    assert "Your fellow masons are" not in get_summary_of_chat(game, wolf_id)
    assert "Your fellow masons are" not in get_summary_of_chat(
        game, villager_id)
def test_priest_works(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    priest_id = uuid()
    villager1_id = uuid()
    villager2_id = uuid()

    game.join(wolf_id)
    game.join(priest_id)
    game.join(villager1_id)
    game.join(villager2_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    with pytest.raises(HTTPException):
        game.priest_night_action(priest_id, villager1_id)
    game.wolf_night_action(wolf_id, villager1_id)

    assert game.get_player_model(villager1_id).state == PlayerState.WOLFED

    game._set_stage(GameStage.NIGHT)

    game.priest_night_action(priest_id, villager1_id)
    game.wolf_night_action(wolf_id, villager2_id)

    summary = get_summary_of_chat(game, priest_id)

    assert re.search(r"You remember that .+ was a Villager", summary)
Example #10
0
def test_kick(db_session):
    game = WurwolvesGame(GAME_ID)

    # Add three players
    player_ids = [uuid() for _ in range(3)]
    for p in player_ids:
        game.join(p)

    db_session = game._session

    # Set one to have joined ages ago
    timeout_player_id = player_ids[0]
    timeout_player = game.get_player(timeout_player_id)
    game.set_user_name(timeout_player_id, "timeout player")
    db_session.add(timeout_player)

    timeout_player.last_seen = datetime(1, 1, 1)

    db_session.commit()
    db_session.expire_all()

    # Get the game tag
    tag = game.get_game_model().update_tag

    timeout_player = game.get_player(timeout_player_id)
    db_session.add(timeout_player)

    assert timeout_player.state == PlayerState.SPECTATING

    # Keepalive one of the other players, which should kick the idler
    game.player_keepalive(player_ids[1])

    db_session.expire_all()

    # Check that the idler is gone
    assert not game.get_player(timeout_player_id)
    # And that they're not in the rendered state
    state = game.parse_game_to_state(player_ids[1])
    assert "timeout player" not in state.json()

    # Also check the tag changed
    assert tag != game.get_game_model().update_tag

    tag = game.get_game_model().update_tag

    # Bring the idler back
    game.player_keepalive(timeout_player_id)

    assert game.get_player(timeout_player_id)
    assert tag != game.get_game_model().update_tag
Example #11
0
def test_prostitute_prevents_seer(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    seer_id = uuid()
    prostitute_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(seer_id)
    game.join(prostitute_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    # Seer checks villager but prostitute sleeps with seer.
    # Wolf kills villager, so villager dies
    game.prostitute_night_action(prostitute_id, seer_id)
    game.seer_night_action(seer_id, villager_id)
    game.wolf_night_action(wolf_id, villager_id)

    assert game.get_player_model(villager_id).state == PlayerState.WOLFED

    summary = get_summary_of_chat(game, seer_id)

    assert re.search(r"you couldn't concentrate", summary)
    def func(num_players):
        import random

        random.seed(123)

        g = WurwolvesGame(GAME_ID)

        # You need at least three players for start_game() to work
        g.join(USER_ID)

        for _ in range(num_players - 1):
            g.join(uuid())

        return g
Example #13
0
def test_fool_no_mention_seer(empty_game):
    from unittest.mock import patch
    import backend
    from backend.roles import DistributionSettings

    game = WurwolvesGame("test_game")

    # Make some players in a game
    num_players = 10
    user_ids = [uuid() for _ in range(num_players)]
    [game.join(u) for u in user_ids]

    # Customise the probabilitites to get a fool
    settings = DistributionSettings(role_weights={PlayerRole.FOOL: 1000000})
    game.set_game_config(settings)

    game.start_game()

    # Find the fool (there's almost certainly one)
    fool_player = [p for p in game.get_players() if p.role == PlayerRole.FOOL]
    assert len(fool_player) == 1
    fool_id = fool_player[0].user_id

    game.set_user_name(fool_id, "The one who isn't the seer")
    game._session.commit()

    # Confirm that the fool's state doesn't mention the fool anywhere
    def fool_in_state(fool_state):
        # Unfortunately, it does in one place: the function call. A savvy user could
        # therefore cheat. I should change it so that all player actions call the
        # same function in game. The game would then pass the call on to the
        # appropriate method, depending on the player's role.
        # For now, so this test passes, remove that reference
        fool_state_filtered = fool_state.dict()
        fool_state_filtered["controls_state"]["button_submit_func"] = "removed"
        fool_state = type(fool_state).parse_obj(fool_state_filtered)

        print("Fool state:")
        from pprint import pprint

        pprint(fool_state.dict())

        return "fool" in fool_state.json().lower()

    game._set_stage(GameStage.NIGHT)
    fool_state = game.parse_game_to_state(fool_id)
    assert not fool_in_state(fool_state)

    game._set_stage(GameStage.VOTING)
    fool_state = game.parse_game_to_state(fool_id)
    assert not fool_in_state(fool_state)

    game._set_stage(GameStage.DAY)
    fool_state = game.parse_game_to_state(fool_id)
    assert not fool_in_state(fool_state)

    # Move to the end of the game and confirm that the fool is revealed
    game._set_stage(GameStage.ENDED)
    fool_state = game.parse_game_to_state(fool_id)
    assert fool_in_state(fool_state)
Example #14
0
def test_not_kicked_during_game(db_session):
    game = WurwolvesGame(GAME_ID)

    # Add four players
    player_ids = [uuid() for _ in range(4)]
    roles = [
        PlayerRole.MEDIC,
        PlayerRole.VILLAGER,
        PlayerRole.SPECTATOR,
        PlayerRole.WOLF,
    ]
    for p in player_ids:
        game.join(p)

    db_session = game._session

    game.start_game()

    for p, r in zip(player_ids, roles):
        game.set_player_role(game.get_player_id(p), r)

    timeout_player_id = player_ids[0]
    villager_id = player_ids[1]
    spectator_id = player_ids[2]
    wolf_id = player_ids[3]

    # Kill the medic with the wolf
    game.wolf_night_action(wolf_id, timeout_player_id)
    # Have the idler do something too
    game.medic_night_action(timeout_player_id, wolf_id)

    # Set medic to have joined ages ago
    timeout_player = game.get_player(timeout_player_id)
    db_session.add(timeout_player)
    timeout_player.last_seen = datetime(1, 1, 1)
    db_session.commit()
    db_session.expire_all()

    # Keepalive one of the other players, which should not kick the idler since it's a game
    game.player_keepalive(wolf_id)

    db_session.expire_all()
    assert game.get_player(timeout_player_id)
Example #15
0
def test_prostitute_not_choose_self(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    medic_id = uuid()
    prostitute_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(medic_id)
    game.join(prostitute_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    # Check that the pristitute can't sleep with themselves
    with pytest.raises(HTTPException):
        game.prostitute_night_action(prostitute_id, prostitute_id)
Example #16
0
def test_end_game(api_client, db_session):
    from uuid import uuid4 as uuid

    g = WurwolvesGame(GAME_ID)

    with api_client as s:
        r = s.post(f"/api/{GAME_ID}/join")
        assert r.ok

        for _ in range(4):
            g.join(uuid())

        g.start_game()

        assert g.get_game_model().stage == GameStage.NIGHT

        r = s.post(f"/api/{GAME_ID}/end_game")
        assert r.ok

        assert g.get_game_model().stage == GameStage.ENDED
Example #17
0
def test_start_game(db_session):
    g = WurwolvesGame(GAME_ID)
    g.join(USER_ID)
    g.join(uuid())
    g.join(uuid())

    db_game = get_game(db_session, GAME_ID)

    assert db_game.stage == GameStage.LOBBY

    p: Player
    for p in db_game.players:
        assert p.role == PlayerRole.SPECTATOR
        assert p.state == PlayerState.SPECTATING

    g.start_game()

    db_session.expire_all()

    assert db_game.stage == GameStage.NIGHT

    p: Player
    for p in db_game.players:
        assert p.role != PlayerRole.SPECTATOR
        assert p.state == PlayerState.ALIVE

    new_user_id = uuid()
    g.join(new_user_id)
    db_session.expire_all()

    p = get_player(db_session, GAME_ID, new_user_id)

    assert p.role == PlayerRole.SPECTATOR
Example #18
0
def test_add_player(db_session):
    g = WurwolvesGame(GAME_ID)

    g.join(USER_ID)

    assert len(db_session.query(Game).all()) == 1
    assert len(db_session.query(User).all()) == 1
    db_game = db_session.query(Game).first()
    assert len(
        db_session.query(Player).filter(Player.game == db_game).all()) == 1

    game_hash = g.get_game_model().update_tag

    g.join(uuid())

    assert len(db_session.query(Game).all()) == 1
    assert len(db_session.query(User).all()) == 2
    assert len(
        db_session.query(Player).filter(Player.game == db_game).all()) == 2
    assert game_hash != g.get_game_model().update_tag

    game_hash = g.get_game_model().update_tag

    g.join(USER_ID)

    assert len(db_session.query(Game).all()) == 1
    assert len(db_session.query(User).all()) == 2
    assert len(
        db_session.query(Player).filter(Player.game == db_game).all()) == 2
    assert game_hash == g.get_game_model().update_tag
Example #19
0
def test_prostitute_saves_villager(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    prostitute_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(prostitute_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    # Prostitute sleep with villager, wolf attacks villager.
    # Villager isn't home, so doesn't die
    game.prostitute_night_action(prostitute_id, villager_id)
    game.wolf_night_action(wolf_id, villager_id)

    assert game.get_player_model(villager_id).state == PlayerState.ALIVE
Example #20
0
def test_prostitute_dooms_villager(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    prostitute_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(prostitute_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    # Prostitute sleeps with villager, wolf attacks prostitute.
    # Both die.
    game.prostitute_night_action(prostitute_id, villager_id)
    game.wolf_night_action(wolf_id, prostitute_id)

    assert game.get_player_model(villager_id).state == PlayerState.WOLFED
    assert game.get_player_model(prostitute_id).state == PlayerState.WOLFED
Example #21
0
def test_announced_to_wolves(mock_roles, db_session, role, search):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()

    game.join(wolf_id)
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    summary = get_summary_of_chat(game, wolf_id)

    assert f"There's {search} in the game" in summary
Example #22
0
def test_prostitute_prevents_only_one_wolf_alt(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_1_id = uuid()
    wolf_2_id = uuid()
    prostitute_id = uuid()
    villager_id = uuid()

    game.join(wolf_1_id)
    game.join(wolf_2_id)
    game.join(prostitute_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    # Prostitute sleep with wolf 1, wolves attack villager.
    # First wolf if disabled but second wolf kills
    game.prostitute_night_action(prostitute_id, wolf_1_id)
    game.wolf_night_action(wolf_2_id, villager_id)

    assert game.get_player_model(villager_id).state == PlayerState.WOLFED
Example #23
0
def test_prostitute_prevents_medic(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    medic_id = uuid()
    prostitute_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(medic_id)
    game.join(prostitute_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    # Medic saves villager but prostitute sleeps with medic.
    # Wolf kills villager, so villager dies
    game.prostitute_night_action(prostitute_id, medic_id)
    game.medic_night_action(medic_id, villager_id)
    game.wolf_night_action(wolf_id, villager_id)

    assert game.get_player_model(villager_id).state == PlayerState.WOLFED
Example #24
0
def test_wolves_announced(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    villager_1_id = uuid()

    game.join(wolf_id)
    game.join(villager_1_id)
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())
    game.join(uuid())

    game.start_game()

    assert "There is only one wolf in the game" in get_summary_of_chat(
        game, villager_1_id)
    assert "There is only one wolf in the game" in get_summary_of_chat(
        game, wolf_id)
Example #25
0
def test_miller_works(mock_roles, db_session):
    game = WurwolvesGame("test_game")

    wolf_id = uuid()
    seer_id = uuid()
    miller_id = uuid()
    villager_id = uuid()

    game.join(wolf_id)
    game.join(seer_id)
    game.join(miller_id)
    game.join(villager_id)
    game.join(uuid())
    game.join(uuid())

    game.start_game()
    game.seer_night_action(seer_id, miller_id)
    game.wolf_night_action(wolf_id, villager_id)

    summary = get_summary_of_chat(game, seer_id)

    assert "they are a wolf!" in summary
Example #26
0
def test_kick_with_actions(db_session):
    game = WurwolvesGame(GAME_ID)

    # Add four players
    player_ids = [uuid() for _ in range(4)]
    roles = [
        PlayerRole.MEDIC,
        PlayerRole.VILLAGER,
        PlayerRole.SPECTATOR,
        PlayerRole.WOLF,
    ]
    for p in player_ids:
        game.join(p)

    db_session = game._session

    game.start_game()

    for p, r in zip(player_ids, roles):
        game.set_player_role(game.get_player_id(p), r)

    timeout_player_id = player_ids[0]
    villager_id = player_ids[1]
    spectator_id = player_ids[2]
    wolf_id = player_ids[3]

    # Set one to have joined ages ago
    timeout_player = game.get_player(timeout_player_id)
    db_session.add(timeout_player)

    timeout_player.last_seen = datetime(1, 1, 1)

    db_session.commit()
    db_session.expire_all()

    timeout_player = game.get_player(timeout_player_id)
    db_session.add(timeout_player)

    assert timeout_player.state == PlayerState.ALIVE

    # Keepalive one of the other players, which should not kick the idler since it's a game
    game.player_keepalive(wolf_id)

    db_session.expire_all()
    assert game.get_player(timeout_player_id)

    # Kill the idler with the wolf
    game.wolf_night_action(wolf_id, timeout_player_id)
    # Have the idler do something too
    game.medic_night_action(timeout_player_id, wolf_id)

    db_session.expire_all()

    # Check game ended
    assert game.get_game_model().stage == GameStage.ENDED

    # Keepalive someone else
    game.player_keepalive(wolf_id)

    # Player should not yet be kicked
    db_session.expire_all()
    g = game.get_player(timeout_player_id)
    assert g

    # Put their timeout back into the past
    timeout_player.last_seen = datetime(1, 1, 1)
    db_session.commit()
    db_session.expire_all()

    # Keepalive someone else
    game.player_keepalive(wolf_id)

    # They still should be visible, but marked as inactive now
    db_session.expire_all()
    assert game.get_player(timeout_player_id)
    assert not game.get_player_model(timeout_player_id).active

    # Vote to start a new game
    game.wolf_ended_action(wolf_id)

    # Check a new game started
    db_session.expire_all()
    assert game.get_game_model().stage == GameStage.LOBBY

    # Check the idler was kicked after the next keepalive
    game.player_keepalive(wolf_id)
    assert not game.get_player(timeout_player_id)