예제 #1
0
        public async Task ScheduleRequiresMultipleEmbeds()
        {
            const int teamsCount   = 50;
            const int readersCount = teamsCount / 2;

            MessageStore             messageStore  = new MessageStore();
            ICommandContext          context       = this.CreateCommandContext(messageStore, guildId: DefaultGuildId);
            GlobalTournamentsManager globalManager = new GlobalTournamentsManager();
            TournamentsManager       manager       = globalManager.GetOrAdd(DefaultGuildId, id => new TournamentsManager());

            HashSet <Team> teams = new HashSet <Team>(
                Enumerable.Range(1, teamsCount).Select(id => new Team()
            {
                Name = $"#Team{id}"
            }));
            HashSet <Reader> readers = new HashSet <Reader>(
                Enumerable.Range(1, readersCount).Select(id => new Reader()
            {
                Id = (ulong)id, Name = $"#Reader{id}"
            }));

            RoundRobinScheduleFactory factory = new RoundRobinScheduleFactory(1, 0);
            Schedule schedule = factory.Generate(teams, readers);

            ITournamentState state = new TournamentState(DefaultGuildId, "T");

            state.Schedule = schedule;
            manager.AddOrUpdateTournament(state.Name, state, (name, oldState) => oldState);
            Assert.IsTrue(
                manager.TrySetCurrentTournament(state.Name, out string errorMessage),
                $"Failed to set the tournament: '{errorMessage}'");
            globalManager.GetOrAdd(DefaultGuildId, id => manager);

            BotCommandHandler commandHandler = new BotCommandHandler(context, globalManager);

            await commandHandler.GetScheduleAsync();

            Assert.IsTrue(
                messageStore.ChannelEmbeds.Count > 1,
                $"Expected more than 1 embed, got {messageStore.ChannelEmbeds.Count}");

            string allEmbeds = string.Join('\n', messageStore.ChannelEmbeds);

            for (int round = 0; round < schedule.Rounds.Count; round++)
            {
                Assert.IsTrue(
                    allEmbeds.Contains(BotStrings.RoundNumber(round + 1)),
                    $"Round {round + 1} not found in the embeds. Embeds: '{allEmbeds}'");
                foreach (Game game in schedule.Rounds[round].Games)
                {
                    string expectedGame = BotStrings.ScheduleLine(
                        game.Reader.Name, game.Teams.Select(team => team.Name).ToArray());
                    Assert.IsTrue(
                        allEmbeds.Contains(expectedGame),
                        $"Game '{expectedGame}' not foudn in embed. Embed: '{allEmbeds}'");
                }
            }
        }
예제 #2
0
        public override Task <PreconditionResult> CheckPermissionsAsync(
            ICommandContext context, CommandInfo command, IServiceProvider serviceProvider)
        {
            Verify.IsNotNull(context, nameof(context));

            GlobalTournamentsManager globalManager = serviceProvider.GetService <GlobalTournamentsManager>();
            TournamentsManager       manager       = globalManager.GetOrAdd(context.Guild.Id, CreateTournamentsManager);

            // TD is only allowed to run commands when they are a director of the current tournament.
            Result <bool> result = manager.TryReadActionOnCurrentTournament(currentTournament =>
                                                                            currentTournament.GuildId == context.Guild.Id && CanActAsTournamentDirector(context, currentTournament)
                                                                            );

            if (result.Success && result.Value)
            {
                return(Task.FromResult(PreconditionResult.FromSuccess()));
            }
            else if (command.Name == SetupCommandName && context.Message.Content.Length > SetupCommand.Length)
            {
                // TODO: We should investigate if there's a better place to make this check, because the attribute
                // now knows about "setup"
                string tournamentName = context.Message.Content.Substring(SetupCommand.Length).Trim();
                if (IsAdminUser(context) ||
                    (manager.TryGetTournament(tournamentName, out ITournamentState tournament) &&
                     CanActAsTournamentDirector(context, tournament)))
                {
                    return(Task.FromResult(PreconditionResult.FromSuccess()));
                }
            }

            return(Task.FromResult(PreconditionResult.FromError("User did not have tournament director privileges.")));
        }
예제 #3
0
        public async Task AddTwoTournamentDirectors()
        {
            const ulong              firstUserId   = 123;
            const ulong              secondUserId  = 1234;
            MessageStore             messageStore  = new MessageStore();
            ICommandContext          context       = this.CreateCommandContext(messageStore);
            GlobalTournamentsManager globalManager = new GlobalTournamentsManager();

            AddTournamentDirectorDirectly(globalManager, firstUserId);

            BotCommandHandler commandHandler = new BotCommandHandler(context, globalManager);

            IGuildUser guildUser = this.CreateGuildUser(secondUserId);
            await commandHandler.AddTournamentDirectorAsync(guildUser, DefaultTournamentName);

            string expectedMessage = BotStrings.AddTournamentDirectorSuccessful(
                DefaultTournamentName, DefaultGuildName);

            messageStore.VerifyChannelMessages(expectedMessage);

            TournamentsManager manager = globalManager.GetOrAdd(DefaultGuildId, id => new TournamentsManager());

            Assert.IsTrue(
                manager.TryGetTournament(DefaultTournamentName, out ITournamentState state),
                "Could not find tournament.");
            Assert.IsTrue(state.IsDirector(firstUserId), "First director was not added.");
            Assert.IsTrue(state.IsDirector(secondUserId), "Second director was not added.");
        }
예제 #4
0
        protected ITournamentState AddCurrentTournament(
            GlobalTournamentsManager globalManager,
            ulong guildId         = DefaultGuildId,
            string tournamentName = DefaultTournamentName)
        {
            TournamentsManager manager = globalManager.GetOrAdd(guildId, id => new TournamentsManager());
            ITournamentState   state   = new TournamentState(guildId, tournamentName);

            state = manager.AddOrUpdateTournament(tournamentName, state, (name, oldState) => state);
            Assert.IsTrue(
                manager.TrySetCurrentTournament(tournamentName, out string errorMessage),
                "We should be able to set the current tournament.");
            return(state);
        }
예제 #5
0
        // TODO: Add test for ClearAll that checks that all artifacts are cleared.

        private static void AddTournamentDirectorDirectly(GlobalTournamentsManager globalManager, ulong userId)
        {
            TournamentsManager manager = globalManager.GetOrAdd(
                DefaultGuildId,
                id => new TournamentsManager()
            {
                GuildId = id
            });
            ITournamentState state = manager.AddOrUpdateTournament(
                DefaultTournamentName,
                new TournamentState(DefaultGuildId, DefaultTournamentName),
                (name, oldState) => oldState);

            Assert.IsTrue(state.TryAddDirector(userId), "First TD added should occur.");
        }
예제 #6
0
        public async Task RemoveNonexistentTournamentDirector()
        {
            const ulong              otherId        = DefaultUserId + 1;
            MessageStore             messageStore   = new MessageStore();
            ICommandContext          context        = this.CreateCommandContext(messageStore);
            GlobalTournamentsManager globalManager  = new GlobalTournamentsManager();
            BotCommandHandler        commandHandler = new BotCommandHandler(context, globalManager);

            AddTournamentDirectorDirectly(globalManager, DefaultUserId);

            IGuildUser guildUser = this.CreateGuildUser(otherId);
            await commandHandler.RemoveTournamentDirectorAsync(guildUser, DefaultTournamentName);

            string expectedMessage = BotStrings.UserNotTournamentDirector(DefaultTournamentName, DefaultGuildName);

            messageStore.VerifyChannelMessages(expectedMessage);

            TournamentsManager manager = globalManager.GetOrAdd(DefaultGuildId, id => new TournamentsManager());

            Assert.IsTrue(
                manager.TryGetTournament(DefaultTournamentName, out ITournamentState state), "Could not find tournament.");
            Assert.IsFalse(state.IsDirector(otherId), "Director should not have been added.");
        }
예제 #7
0
        public async Task AddSameTournamentDirectors()
        {
            MessageStore             messageStore  = new MessageStore();
            ICommandContext          context       = this.CreateCommandContext(messageStore);
            GlobalTournamentsManager globalManager = new GlobalTournamentsManager();

            AddTournamentDirectorDirectly(globalManager, DefaultUserId);

            BotCommandHandler commandHandler = new BotCommandHandler(context, globalManager);

            IGuildUser guildUser = this.CreateGuildUser(DefaultUserId);
            await commandHandler.AddTournamentDirectorAsync(guildUser, DefaultTournamentName);

            string expectedMessage = BotStrings.UserAlreadyTournamentDirector(DefaultTournamentName, DefaultGuildName);

            messageStore.VerifyChannelMessages(expectedMessage);

            TournamentsManager manager = globalManager.GetOrAdd(DefaultGuildId, id => new TournamentsManager());

            Assert.IsTrue(
                manager.TryGetTournament(DefaultTournamentName, out ITournamentState state),
                "Could not find tournament.");
            Assert.IsTrue(state.IsDirector(DefaultUserId), "User should still be a director.");
        }
예제 #8
0
        public async Task SimplestSchedule()
        {
            const string readerName     = "#Reader";
            const string firstTeamName  = "#TeamA";
            const string secondTeamName = "#TeamB";

            MessageStore             messageStore  = new MessageStore();
            ICommandContext          context       = this.CreateCommandContext(messageStore, guildId: DefaultGuildId);
            GlobalTournamentsManager globalManager = new GlobalTournamentsManager();
            TournamentsManager       manager       = globalManager.GetOrAdd(DefaultGuildId, id => new TournamentsManager());

            HashSet <Team> teams = new HashSet <Team>()
            {
                new Team()
                {
                    Name = firstTeamName
                },
                new Team()
                {
                    Name = secondTeamName
                }
            };
            HashSet <Reader> readers = new HashSet <Reader>()
            {
                new Reader()
                {
                    Id   = 0,
                    Name = readerName
                }
            };
            RoundRobinScheduleFactory factory = new RoundRobinScheduleFactory(2, 0);
            Schedule schedule = factory.Generate(teams, readers);

            ITournamentState state = new TournamentState(DefaultGuildId, "T");

            state.Schedule = schedule;
            manager.AddOrUpdateTournament(state.Name, state, (name, oldState) => oldState);
            Assert.IsTrue(
                manager.TrySetCurrentTournament(state.Name, out string errorMessage),
                $"Failed to set the tournament: '{errorMessage}'");
            globalManager.GetOrAdd(DefaultGuildId, id => manager);

            BotCommandHandler commandHandler = new BotCommandHandler(context, globalManager);

            await commandHandler.GetScheduleAsync();

            Assert.AreEqual(1, messageStore.ChannelEmbeds.Count, "Unexpected number of embeds");

            string embed = messageStore.ChannelEmbeds[0];

            for (int round = 0; round < schedule.Rounds.Count; round++)
            {
                Assert.IsTrue(
                    embed.Contains(BotStrings.RoundNumber(round + 1)),
                    $"Round {round + 1} not found in embed. Embed: '{embed}'");
                string expectedGame = BotStrings.ScheduleLine(
                    readerName, schedule.Rounds[round].Games[0].Teams.Select(team => team.Name).ToArray());
                Assert.IsTrue(
                    embed.Contains(expectedGame),
                    $"Game '{expectedGame}' not foudn in embed. Embed: '{embed}'");
            }
        }