public async Task ProperEndingShotShipDestroyedGameEndTest()
        {
            object expected = new GameStateResponse(1234)
            {
                GameStatus = GameStatuses.SHOOTING, NextPlayer = 1, Player2Ships = prepareTwoShipsWithOneMissingDamage()
            };
            var mockCache = MockMemoryCacheServiceWithGetAndSet.GetMemoryCache(expected);

            var mockConfig = new Moq.Mock <IOptions <BattleshipConfiguration> >();

            mockConfig.Setup(config => config.Value).Returns(() => prepareConfig());
            var mockEngine = new Moq.Mock <GameEngine>(mockConfig.Object);
            var controller = new BattleShipController(mockCache, mockConfig.Object, mockEngine.Object, null);


            ShotRequest request = new ShotRequest()
            {
                GameId = 1234, PlayerId = 1, Coordinate = new Coordinate(2, 2)
            };

            var result     = controller.Shot(request);
            var viewResult = Assert.IsType <ActionResult <GameStateResponse> >(result);

            Assert.Equal(result.Value.NextPlayer, 0);                                       //no more moves
            Assert.Equal(result.Value.GameStatus, GameStatuses.FINISHED);                   //Game finished
            Assert.Equal(result.Value.WinnerPlayer, 1);                                     //winner
            Assert.Equal(result.Value.Message, "Game finished, player 1 has won the game"); //message
        }
        public async Task MissedShotTest()
        {
            object expected = new GameStateResponse(1234)
            {
                GameStatus = GameStatuses.SHOOTING, NextPlayer = 1, Player2Ships = prepareTwoShipsWithOneDamage()
            };
            var mockCache = MockMemoryCacheServiceWithGetAndSet.GetMemoryCache(expected);

            var mockConfig = new Moq.Mock <IOptions <BattleshipConfiguration> >();

            mockConfig.Setup(config => config.Value).Returns(() => prepareConfig());
            var mockEngine = new Moq.Mock <GameEngine>(mockConfig.Object);
            var controller = new BattleShipController(mockCache, mockConfig.Object, mockEngine.Object, null);


            ShotRequest request = new ShotRequest()
            {
                GameId = 1234, PlayerId = 1, Coordinate = new Coordinate(5, 5)
            };

            var result     = controller.Shot(request);
            var viewResult = Assert.IsType <ActionResult <GameStateResponse> >(result);

            Assert.Equal(result.Value.NextPlayer, 2);                     //swapped players
            Assert.Equal(result.Value.GameStatus, GameStatuses.SHOOTING); //game still going
            Assert.Equal(result.Value.Message, "Missed!");                //message
        }
        public async Task IncorrectCoordinatesShotTest()
        {
            object expected = new GameStateResponse(1234)
            {
                GameStatus = GameStatuses.SHOOTING, NextPlayer = 1
            };
            var mockCache = MockMemoryCacheService.GetMemoryCache(expected);

            var mockConfig = new Moq.Mock <IOptions <BattleshipConfiguration> >();

            mockConfig.Setup(config => config.Value).Returns(() => prepareConfig());
            var mockEngine = new Moq.Mock <GameEngine>(mockConfig.Object);
            var controller = new BattleShipController(mockCache, mockConfig.Object, mockEngine.Object, null);

            List <Coordinate> incorrectCoordinates = new List <Coordinate> {
                new Coordinate(-1, 1),
                new Coordinate(1, -2),
                new Coordinate(0, 1),
                new Coordinate(1, 0),
                new Coordinate(15, 5),
                new Coordinate(5, 15),
                new Coordinate(15, 15)
            };

            foreach (Coordinate c in  incorrectCoordinates)
            {
                ShotRequest request = new ShotRequest()
                {
                    GameId = 1234, PlayerId = 1, Coordinate = c
                };

                var ex = Assert.Throws <InvalidCoordinatesException>(() => controller.Shot(request));
                Assert.Equal("Invalid coordinates supplied, possible values: columns 1-10, rows 1-10", ex.Message);
            }
        }
        public async Task PlacingGameShotTest()
        {
            object expected  = new GameStateResponse(1234); //status = placing
            var    mockCache = MockMemoryCacheService.GetMemoryCache(expected);

            var mockConfig = new Moq.Mock <IOptions <BattleshipConfiguration> >();
            var mockEngine = new Moq.Mock <GameEngine>(mockConfig.Object);
            var controller = new BattleShipController(mockCache, mockConfig.Object, mockEngine.Object, null);

            ShotRequest request = new ShotRequest()
            {
                GameId = 1234, PlayerId = 1, Coordinate = new Coordinate(1, 1)
            };

            var ex = Assert.Throws <InvalidGameStatusShootingException>(() => controller.Shot(request));

            Assert.Equal("Game is not in the Shooting mode, current mode: PLACING", ex.Message);
        }
        public async Task InvalidGameShotTest()
        {
            object expected  = null; //game not found
            var    mockCache = MockMemoryCacheService.GetMemoryCache(expected);

            var mockConfig = new Moq.Mock <IOptions <BattleshipConfiguration> >();
            var mockEngine = new Moq.Mock <GameEngine>(mockConfig.Object);
            var controller = new BattleShipController(mockCache, mockConfig.Object, mockEngine.Object, null);

            ShotRequest request = new ShotRequest()
            {
                GameId = 1234, PlayerId = 1, Coordinate = new Coordinate(1, 1)
            };

            var ex = Assert.Throws <InvalidGameIdException>(() => controller.Shot(request));

            Assert.Equal("Invalid game Id 1234, no valid game with the given id exists.", ex.Message);
        }
        public async Task IncorrectPlayerGameShotTest()
        {
            object expected = new GameStateResponse(1234)
            {
                GameStatus = GameStatuses.SHOOTING, NextPlayer = 1
            };
            var mockCache = MockMemoryCacheService.GetMemoryCache(expected);

            var mockConfig = new Moq.Mock <IOptions <BattleshipConfiguration> >();
            var mockEngine = new Moq.Mock <GameEngine>(mockConfig.Object);
            var controller = new BattleShipController(mockCache, mockConfig.Object, mockEngine.Object, null);

            ShotRequest request = new ShotRequest()
            {
                GameId = 1234, PlayerId = 2, Coordinate = new Coordinate(1, 1)
            };

            var ex = Assert.Throws <InvalidTurnPlayerException>(() => controller.Shot(request));

            Assert.Equal("Not your turn! Wait for player 1 to shot next", ex.Message);
        }