示例#1
0
    def test_resumes_players(self):
        s = persistent.State("arbitrary-tourney-id")
        p = data.Player(123, "challonge_id", 1)
        s.add_players([p])

        # pretend we crashed, this is the "reloaded" one.
        new_s = persistent.State("arbitrary-tourney-id")

        self.assertEqual(1, len(new_s.players))
        self.assertEqual(p, new_s.players[0])
示例#2
0
    def test_add_players_to_bracket(self):
        p1_name, p2_name = "Alice", "Bob"
        p1_challonge_id, p2_challonge_id = "1001", "1002"  # Challonge IDs
        p1_discord_id, p2_discord_id = 1, 2  # Discord IDs

        # Fake challonge call, will succeed
        mock_challonge = unittest.mock.MagicMock(spec=challonge.Client)
        mock_challonge.add_players = unittest.mock.MagicMock(
            return_value={
                p1_name: p1_challonge_id,
                p2_name: p2_challonge_id,
            })

        state = persistent.State("arbitraryID12")
        bracket = Bracket(mock_challonge, state)

        # Create the players.
        bracket.create_players({
            p1_discord_id: p1_name,
            p2_discord_id: p2_name,
        })

        self.assertEqual(2, len(bracket.players))
        self.assertEqual(p1_discord_id, bracket.players[0].discord_id)
        self.assertEqual(p1_challonge_id, bracket.players[0].challonge_id)
        self.assertEqual(p2_discord_id, bracket.players[1].discord_id)
        self.assertEqual(p2_challonge_id, bracket.players[1].challonge_id)
示例#3
0
    def test_resumes_called_matches(self):
        tourney_id = "some-tourney-id"
        tourney_link = "challonge.com/arbitrary-link"
        match_id = "some-match-id"

        # State with 1 match called.
        m = data.new_match(data.new_player(0, "arbitrary-id1"),
                           data.new_player(1, "arbitrary-id2"), match_id)
        m.call_time = datetime.now()
        s = persistent.State(tourney_id, tourney_link)
        s.set_matches([m])

        # pretend we crashed

        new_s = persistent.State(tourney_id)  # Same tourney ID as before.
        self.assertEqual(1, len(new_s.known_matches))
        self.assertIsNotNone(new_s.known_matches[0].call_time)
        self.assertEqual(tourney_link, new_s.bracket_link)
示例#4
0
    def test_pings_uncalled_players_exactly_once(self):
        p1_name, p2_name = "Alice", "Bob"  # Discord names.
        p1_discord_id, p2_discord_id = 1, 2  # Discord IDs.
        p1_challonge_id, p2_challonge_id = "1001", "1002"  # Challonge IDs.

        # Set "challonge" up to add Alice and Bob.
        mock_challonge = unittest.mock.MagicMock(spec=challonge.Client)
        mock_challonge.add_players = unittest.mock.MagicMock(
            return_value={
                p1_name: p1_challonge_id,
                p2_name: p2_challonge_id,
            })

        # Set "challonge" up to have 1 in progress match.
        match = challonge.Match("arbitrary_match_id", p1_challonge_id,
                                p2_challonge_id)
        mock_challonge.list_matches = unittest.mock.MagicMock(
            return_value=[match])

        # Not mocked, we're testing real logic here.
        state = persistent.State("arbitraryID12")
        bracket = Bracket(mock_challonge, state)

        # Mock out external dependencies.
        mock_discord_client = unittest.mock.MagicMock(
            spec=discord.ext.commands.Bot)
        output_channel = unittest.mock.MagicMock(spec=discord.TextChannel)
        output_channel.send.return_value.id = 1234

        # Add players to the bracket.
        bracket.create_players({
            p1_discord_id: p1_name,
            p2_discord_id: p2_name,
        })

        bot = main.Tournament(mock_discord_client, bracket, 4206969,
                              output_channel)
        _wait_for(bot.check_matches())

        # Players should have been pinged, as there is 1 in-progress match that hasn't been called.
        output_channel.send.assert_called_once()
        self.assertIn(f"<@!{p1_discord_id}>",
                      output_channel.send.call_args[0][0])
        self.assertIn(f"<@!{p2_discord_id}>",
                      output_channel.send.call_args[0][0])

        # Check again. Because we already pinged the players once, they should not have been called again.
        output_channel.send.reset_mock()
        _wait_for(bot.check_matches())
        output_channel.send.assert_not_called()
示例#5
0
def create(api_token: str,
           name: str,
           admin_id: int,
           tournament_type=challonge.TourneyType.DOUBLE_ELIM,
           is_unlisted=True):
    """
    Creates a new tournament in Challonge owned by the user with the given API key.

    name can only contain letters, numbers, and underscores.
    Returns a new Tournament object corresponding to the created tournament.
    """
    challonge_client = challonge.Client(api_token)

    tourney_id, url = challonge_client.create_tournament(
        name, tournament_type, is_unlisted)
    state = persistent.State(tourney_id, url)
    state.set_admin(admin_id)

    return Bracket(challonge_client, state)
示例#6
0
    def test_dq_both_players(self):
        """
        Scenario in which neither player checks into their match.

        Asserts:
        1. Both players are warned.
        2. A score is set after the DQ interval.
        3. No further messages are sent after that.
        """
        warn_timer_in_secs = 1
        dq_timer_in_secs = 2
        emoji = "😀"

        # 2 Players, Alice and Bob.
        p1_name, p2_name = "Alice", "Bob"  # Discord names.
        p1_discord_id, p2_discord_id = 1, 2  # Discord IDs.
        p1_challonge_id, p2_challonge_id = "1001", "1002"  # Challonge IDs.
        tourney_id = "tourneyID12"

        # Set "challonge" up to add Alice and Bob.
        mock_challonge = unittest.mock.MagicMock(spec=challonge.Client)
        mock_challonge.add_players = unittest.mock.MagicMock(
            return_value={
                p1_name: p1_challonge_id,
                p2_name: p2_challonge_id,
            })

        # Set "challonge" up to have 1 in progress match (Alice vs Bob).
        match_id = "arbitrary_match_id"
        match = challonge.Match(match_id, p1_challonge_id, p2_challonge_id)
        mock_challonge.list_matches = unittest.mock.MagicMock(
            return_value=[match])

        # Not mocked, we're testing real logic here.
        state = persistent.State(tourney_id)
        bracket = Bracket(mock_challonge, state)

        # Mock out external dependencies.
        mock_discord_client = unittest.mock.MagicMock(
            spec=discord.ext.commands.Bot)
        output_channel = unittest.mock.MagicMock(spec=discord.TextChannel)

        # Add players to the bracket.
        bracket.create_players({
            p1_discord_id: p1_name,
            p2_discord_id: p2_name,
        })

        bot = main.Tournament(
            mock_discord_client,
            bracket,
            4206969,
            output_channel,
            options=main.Options(
                warn_timer_in_minutes=warn_timer_in_secs / 60,
                dq_timer_in_minutes=dq_timer_in_secs / 60,
                check_in_emoji=discord.PartialEmoji(name=emoji)))

        # Call the match. Set the ID to be returned from the sent message, so we can reference it later.
        match_call_message = unittest.mock.MagicMock(spec=discord.Message)
        match_call_message.id = 6942096
        output_channel.send.return_value = match_call_message
        _wait_for(bot.check_matches())
        output_channel.send.assert_called_once()
        self.assertIn(f"<@!{p1_discord_id}>",
                      output_channel.send.call_args[0][0])
        self.assertIn(f"<@!{p2_discord_id}>",
                      output_channel.send.call_args[0][0])

        # Neither player checks in.
        match_call_message.reactions = [_reaction(emoji)]
        util.get_user_ids = lambda _: _future({})
        output_channel.fetch_message.return_value = match_call_message

        # 1. Both players should be warned.
        output_channel.send.reset_mock()
        time.sleep(warn_timer_in_secs)
        _wait_for(bot.check_matches())
        output_channel.fetch_message.assert_called_with(match_call_message.id)
        self.assertGreaterEqual(output_channel.send.call_count, 2)
        self.assertIn(f"<@!{p1_discord_id}>",
                      output_channel.send.call_args_list[0][0][0])
        self.assertIn(f"<@!{p2_discord_id}>",
                      output_channel.send.call_args_list[1][0][0])

        # Nobody should have been DQ'd yet.
        mock_challonge.set_score.assert_not_called()

        # Wait until DQ deadline, nobody checks in still.
        time.sleep(dq_timer_in_secs - warn_timer_in_secs + 1)
        output_channel.send.reset_mock()
        _wait_for(bot.check_matches())

        # 2. Make sure a score was set for the match so it doesn't hold up the bracket.
        output_channel.send.assert_called_once()
        mock_challonge.set_score.assert_called()

        # Let's assume that set_score failed, and so the match is still
        # returned by challonge.list_matches.
        # 3. Make sure we don't message the players again.
        output_channel.send.reset_mock()
        _wait_for(bot.check_matches())
        output_channel.send.assert_not_called()
示例#7
0
def resume(api_token: str, tournament_id: str):
    client = challonge.Client(api_token)
    return Bracket(client, persistent.State(tournament_id))