public void BuildResultsByGameTest()
        {
            Database.SetInitializer<SelectumContext>(null);

            int currentGameFilterId = 1;
            int userId = 1;
            string viewBagMessageToUser = string.Empty;

            // expected
            string expectedMessageToUser = "******";
            var expected = new ResultsByGame();
            expected.Results = new List<ResultByGame>();
            expected.Totals = new List<int>();
            expected.Users = new List<User>();
            expected.Results.Add(new ResultByGame());

            ResultsByGameController controller = new ResultsByGameController();
            ResultsByGame actual = controller.BuildResultsByGame(currentGameFilterId, userId, ref viewBagMessageToUser);

            actual.Results = new List<ResultByGame>();
            actual.Results.Add(new ResultByGame());
            actual.Users = new List<User>();

            Assert.AreEqual(expectedMessageToUser, viewBagMessageToUser);

            UnitTestingHelper.AssertPublicPropertiesEqual(expected, actual);
        }
        public void GameFilter()
        {
            //AreaRegistration.RegisterAllAreas();

            //WebApiConfig.Register(GlobalConfiguration.Configuration);
            //FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            //RouteConfig.RegisterRoutes(RouteTable.Routes);
            //BundleConfig.RegisterBundles(BundleTable.Bundles);
            //AuthConfig.RegisterAuth();
            //Database.SetInitializer<SelectumContext>(new SelectumInitializer());
            Database.SetInitializer<SelectumContext>(null);

            int id = 0;

            // expecteds
            string messageToUser = "******";
            var resultsViewModel = new ResultsByGame();
            resultsViewModel.Results.Add(new ResultByGame());

            ResultsByGameController controller = new ResultsByGameController();
            ViewResult result = controller.GameFilter(id) as ViewResult;

            Assert.AreEqual(messageToUser, result.ViewBag.MessageToUser);

            IgnoreProperties ignoreProps = new IgnoreProperties();
            ignoreProps.Add(new PropertyComparisonExclusion(typeof(List<string>), "Capacity"));
            UnitTestingHelper.AssertPublicPropertiesEqual(resultsViewModel, result.Model, ignoreProps);
        }
        public ResultsByGame BuildResultsByGame(int currentGameFilterId, int userId, ref string viewBagMessageToUser)
        {
            var resultsViewModel = new ResultsByGame();
            var resultsByGame = new List<ResultByGame>();

            // get this users game selections for this game filter
            var thisUsersGameSelections = db.UserGameSelections
                                            .Where(_ => _.UserId == userId && _.GameSpread.Game.GameFilterId == currentGameFilterId)
                                            .ToList();

            // check to make sure he has saved/submitted his user selections
            if (thisUsersGameSelections == null || thisUsersGameSelections.Count == 0)
            {
                viewBagMessageToUser = "******";
            }
            else
            {
                //check to make sure all the games are saved
                bool gamesSaved = true;

                foreach (var userGameSelection in thisUsersGameSelections)
                {
                    // if anyone saved is false, then it will be false
                    gamesSaved = gamesSaved || userGameSelection.Saved;
                }

                if (!gamesSaved)
                {
                    viewBagMessageToUser = "******";
                }
                else
                {
                    var users = db.Users.OrderBy(u => u.UserId).ToList();

                    // add the users to the view model (this will be column headers on page)
                    resultsViewModel.Users = users;

                    // order game results by game then user
                    var userGameResults = db.UserGameResults
                                            .Include(ugr => ugr.UserGameSelection)
                                            .Include(ugr => ugr.UserGameSelection.GameSpread)
                                            .Include(ugr => ugr.UserGameSelection.GameSpread.Game)
                                            .Where(ugr => ugr.UserGameSelection.GameSpread.Game.GameFilterId == currentGameFilterId)
                                            .OrderBy(ugr => ugr.UserGameSelection.GameSpread.GameId)
                                            .ThenBy(ugr => ugr.UserGameSelection.UserId)
                                            .ToList();

                    // order game results by game then user
                    var userGameSelections = db.UserGameSelections
                                            .Include(ugr => ugr.GameSpread)
                                            .Include(ugr => ugr.GameSpread.Game)
                                            .Where(ugr => ugr.GameSpread.Game.GameFilterId == currentGameFilterId)
                                            .OrderBy(ugr => ugr.GameSpread.GameId)
                                            .ThenBy(ugr => ugr.UserId)
                                            .ToList();

                    var gameResults = db.GameResults
                        .Include(gr => gr.GameSpread)
                        .Include(gr => gr.GameSpread.Game)
                        .Include(gr => gr.GameSpread.FavoriteTeam)
                        .Include(gr => gr.GameSpread.UnderdogTeam)
                        .Where(gr => gr.GameSpread.Game.GameFilterId == currentGameFilterId)
                        .OrderBy(gr => gr.GameSpread.GameId)
                        .ToList();

                    // loop through each game, adding the user game results for that game sorted by userid
                    foreach (var gameResult in gameResults)
                    {
                        // make sure it is ordered by userId
                        var userGameResultsTemp = userGameResults
                                                    .Where(ugr => ugr.UserGameSelection.GameSpread.GameId == gameResult.GameSpread.GameId)
                                                    .OrderBy(ugr => ugr.UserGameSelection.UserId)
                                                    .ToList();

                        /*  TODO insert missing users data
                        for (int i = 0; i <users.Count; i++)
                        {
                            // if the user game results do not exist, insert dummy one
                            if (userGameResultsTemp[i] == null)
                            {
                                //doesn't exist, so insert one
                                userGameResultsTemp.Insert(i, new UserGameResult(){
                            }
                        }
                        */

                        var userGameSelectionsTemp = userGameSelections
                                                        .Where(ugr => ugr.GameSpread.GameId == gameResult.GameSpread.GameId)
                                                        .OrderBy(ugr => ugr.UserId)
                                                        .ToList();

                        resultsByGame.Add(new ResultByGame(gameResult, userGameResultsTemp, userGameSelectionsTemp));
                    }

                    if (resultsByGame.Count > 0)
                    {
                        // make sure each game has each user in the same order
                        // get the user/game order from the first item
                        var userGameResultsFromFirst = resultsByGame[0].UserGameResults;
                        var userGameSelectionsFromFirst = resultsByGame[0].UserGameSelections;

                        // now check all the subsequent userGameResults
                        for (int i = 1; i < resultsByGame.Count; i++)
                        {
                            var userGameResultsNext = resultsByGame[i].UserGameResults;
                            var userGameSelectionsNext = resultsByGame[i].UserGameSelections;

                            if (userGameResultsFromFirst.Count != userGameResultsNext.Count)
                            {
                                throw new ArgumentException(
                                                string.Format(
                                                "The number of users does not match GameId:{0} and GameId:{1} for UserGameResults",
                                                resultsByGame[0].GameResult.GameSpread.GameId,
                                                resultsByGame[i].GameResult.GameSpread.GameId));
                            }

                            if (userGameSelectionsFromFirst.Count != userGameSelectionsNext.Count)
                            {
                                throw new ArgumentException(
                                                string.Format(
                                                "The number of users does not match GameId:{0} and GameId:{1} for UserGameSelections",
                                                resultsByGame[0].GameResult.GameSpread.GameId,
                                                resultsByGame[i].GameResult.GameSpread.GameId));
                            }

                            // now that we know the lengths are equal, make sure each item is in the same
                            // userid order as the first userGameResult
                            for (int x = 0; x < userGameResultsNext.Count; x++)
                            {
                                if (userGameResultsFromFirst[x].UserGameSelection.UserId !=
                                    userGameResultsNext[x].UserGameSelection.UserId)
                                {
                                    throw new ArgumentException(
                                                    string.Format(
                                                    "The users (UserId:{2}, UserId:{3}) in position:{4} do not match for GameId:{0} and GameId:{1} for UserGameResults",
                                                    resultsByGame[0].GameResult.GameSpread.GameId,
                                                    resultsByGame[i].GameResult.GameSpread.GameId,
                                                    userGameResultsFromFirst[x].UserGameSelection.UserId,
                                                    userGameResultsNext[x].UserGameSelection.UserId,
                                                    x));
                                }
                            }

                            for (int x = 0; x < userGameSelectionsNext.Count; x++)
                            {
                                if (userGameSelectionsFromFirst[x].UserId !=
                                    userGameSelectionsNext[x].UserId)
                                {
                                    throw new ArgumentException(
                                                    string.Format(
                                                    "The users (UserId:{2}, UserId:{3}) in position:{4} do not match for GameId:{0} and GameId:{1} for UserGameSelection",
                                                    resultsByGame[0].GameResult.GameSpread.GameId,
                                                    resultsByGame[i].GameResult.GameSpread.GameId,
                                                    userGameSelectionsFromFirst[x].UserId,
                                                    userGameSelectionsNext[x].UserId,
                                                    x));
                                }
                            }
                        }

                        List<int> totals = new List<int>();
                        // lastly calculate a total row
                        foreach (var user in users)
                        {
                            int total = 0;
                            foreach (var result in resultsByGame)
                            {
                                total += result.UserGameResults
                                                    .Where(ur => ur.UserGameSelection.UserId == user.UserId)
                                                    .Sum(ur => ur.BetPoints);
                            }

                            totals.Add(total);
                        }

                        viewBagMessageToUser = string.Format("Until all users have submitted their data, your data might be shifted over to the left (under the wrong user's name)");

                        resultsViewModel.Results = resultsByGame;
                        resultsViewModel.Totals = totals;
                    }
                    else
                    {
                        // there were no game results found for this filter
                        //throw new ArgumentException(string.Format("Missing game results for given GameFilterId:{0}", currentGameFilterId));

                        viewBagMessageToUser = string.Format("Missing game results for given GameFilterId:{0}", currentGameFilterId);
                    }
                }
            }

            return resultsViewModel;
        }