public void CanStartGame()
        {
            var stream  = Mock.Of <IServerStreamWriter <GameRequest> >();
            var logger  = Mock.Of <ILogger <BattleHostConnection> >();
            var factory = Mock.Of <IGameFactory>();

            var bhc = new BattleHostConnection(factory, logger);

            Assert.False(bhc.CanStartGame);
            bhc.Connect(stream);
            Assert.True(bhc.CanStartGame);
        }
        public void Connect()
        {
            var stream  = Mock.Of <IServerStreamWriter <GameRequest> >();
            var logger  = Mock.Of <ILogger <BattleHostConnection> >();
            var factory = Mock.Of <IGameFactory>();

            var bhc = new BattleHostConnection(factory, logger);

            Assert.Equal(BattleHostConnectionState.Disconnected, bhc.State);
            bhc.Connect(stream);
            Assert.Equal(BattleHostConnectionState.Connected, bhc.State);
        }
        public void StartGame()
        {
            var stream  = Mock.Of <IServerStreamWriter <GameRequest> >();
            var logger  = Mock.Of <ILogger <BattleHostConnection> >();
            var factory = new Mock <IGameFactory>();

            factory.Setup(f => f.Create(It.IsAny <int>(), It.IsAny <int>())).Returns(CreateGame());

            var bhc = new BattleHostConnection(factory.Object, logger);

            bhc.Connect(stream);
            bhc.StartGame(47, 11);
            factory.Verify(f => f.Create(It.IsAny <int>(), It.IsAny <int>()), Times.Once());
            Assert.Equal(BattleHostConnectionState.GameRunning, bhc.State);
        }
        public async Task Shoot()
        {
            // This test verifies the entire shooting protocol from the
            // BattleHostConnection's view.

            var logger = Mock.Of <ILogger <BattleHostConnection> >();

            var         stream      = new Mock <IServerStreamWriter <GameRequest> >();
            GameRequest?gameRequest = null;

            stream.Setup(s => s.WriteAsync(It.IsAny <GameRequest>()))
            .Callback <GameRequest>(gr => gameRequest = gr)
            .Returns(Task.FromResult(0));

            var factory = new Mock <IGameFactory>();

            factory.Setup(f => f.Create(It.IsAny <int>(), It.IsAny <int>())).Returns(CreateGame());

            // Create connection and start game
            var bhc = new BattleHostConnection(factory.Object, logger);

            bhc.Connect(stream.Object);
            bhc.StartGame(47, 11);
            Assert.NotNull(bhc.Game);

            // Simulate shooting of player 1
            var shootTask = bhc.Shoot(1);

            Assert.False(shootTask.IsCompleted);
            Assert.NotNull(gameRequest);
            Assert.Equal(GameRequest.PayloadOneofCase.ShotRequest, gameRequest !.PayloadCase);
            Assert.NotNull(gameRequest.ShotRequest);
            Assert.Empty(gameRequest.ShotRequest.LastShot);
            Assert.Equal(SquareContent.Unknown, bhc.Game !.ShootingBoards[0][new BoardIndex(0, 0)]);

            // Simulate incoming shot result
            await bhc.Handle(ProtocolTranslator.EncodeShotResponse(new(Guid.Empty, new BoardIndex(0, 0))));

            Assert.False(shootTask.IsCompleted);
            Assert.Equal(SquareContent.Water, bhc.Game !.ShootingBoards[0][new BoardIndex(0, 0)]);

            // Simulate incoming shot ack
            await bhc.Handle(ProtocolTranslator.EncodeShotResultAck());

            Assert.True(shootTask.IsCompleted);
        }