public void TestLogin()
        {
            // Create udp client to mock registry
            UdpClient mockClient = new UdpClient(0);
            int mockClientPort = ((IPEndPoint)mockClient.Client.LocalEndPoint).Port;
            PublicEndPoint mockClientEP = new PublicEndPoint()
            {
                Host = "127.0.0.1",
                Port = mockClientPort
            };

            // Create fake player
            TestablePlayer player = new TestablePlayer()
            {
                RegistryEndPoint = mockClientEP,
                IdentityInfo = new IdentityInfo()
                {
                    FirstName = "Test",
                    LastName = "Player",
                    ANumber = "A01234983",
                    Alias = "TP"
                },
                ProcessLabel = "Test TP"
            };

            // Run player
            Thread loginThread = new Thread(new ThreadStart(player.Start));
            loginThread.Start();

            // Get message from registry client
            IPEndPoint senderEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] bytes = mockClient.Receive(ref senderEP);
            Assert.IsNotNull(bytes);
            Assert.AreNotEqual(0, bytes.Length);

            // Assert on LoginRequest
            Message msg = Message.Decode(bytes);
            Assert.IsNotNull(msg);
            Assert.IsTrue(msg is LoginRequest);
            LoginRequest request = msg as LoginRequest;
            Assert.AreEqual(player.IdentityInfo.Alias, request.Identity.Alias);
            Assert.AreEqual(player.IdentityInfo.ANumber, request.Identity.ANumber);
            Assert.AreEqual(player.IdentityInfo.FirstName, request.Identity.FirstName);
            Assert.AreEqual(player.IdentityInfo.LastName, request.Identity.LastName);
            Assert.AreEqual(player.ProcessLabel, request.ProcessLabel);
            Assert.AreEqual(ProcessInfo.ProcessType.Player,request.ProcessType);

            // Send LoginReply from registry to player
            LoginReply reply = new LoginReply()
            {
                ProcessInfo = new ProcessInfo()
                {
                    ProcessId = 5,
                    Type = ProcessInfo.ProcessType.Player,
                    EndPoint = new PublicEndPoint()
                    {
                        HostAndPort = senderEP.ToString()
                    },
                    Label = "Test Player",
                    Status = ProcessInfo.StatusCode.Initializing
                },
                Success = true
            };
            bytes = reply.Encode();
            mockClient.Send(bytes, bytes.Length, senderEP);

            // Assert on LoginReply, player state
            Thread.Sleep(2000);
            player.Stop();
            loginThread.Join();
            Assert.AreEqual(player.ProcessInfo.ProcessId, reply.ProcessInfo.ProcessId);
            Assert.AreEqual(player.ProcessInfo.Type, reply.ProcessInfo.Type);
            Assert.AreEqual(player.ProcessInfo.EndPoint.HostAndPort, reply.ProcessInfo.EndPoint.HostAndPort);
            Assert.AreEqual(player.ProcessInfo.Label, reply.ProcessInfo.Label);
            Assert.AreEqual(player.ProcessInfo.Status, reply.ProcessInfo.Status);
            Assert.IsTrue(player.CurrentState is GetGamesState);
        }
        public void TestJoinGame()
        {
            // Create udp client to mock registry
            UdpClient mockClient = new UdpClient(0);
            int mockClientPort = ((IPEndPoint)mockClient.Client.LocalEndPoint).Port;
            PublicEndPoint mockClientEP = new PublicEndPoint()
            {
                Host = "127.0.0.1",
                Port = mockClientPort
            };

            // Create fake player
            TestablePlayer player = new TestablePlayer()
            {
                RegistryEndPoint = mockClientEP,
                ProcessInfo = new ProcessInfo()
                {
                    ProcessId = 5,
                    Type = ProcessInfo.ProcessType.Player,
                    EndPoint = mockClientEP,
                    Label = "Test Player",
                    Status = ProcessInfo.StatusCode.Initializing
                }
            };
            player.GamesList = new GameInfo[]
            {
                new GameInfo()
                {
                    GameId = 7,
                    Label = "Test Game",
                    Status = GameInfo.StatusCode.Available,
                    GameManager = new ProcessInfo()
                    {
                        EndPoint = mockClientEP
                    }
                }
            };
            player.CurrentState = new JoinGameState(player);

            // Run player
            Thread playerThread = new Thread(new ThreadStart(player.Start));
            playerThread.Start();

            // Get message registry client
            IPEndPoint senderEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] bytes = mockClient.Receive(ref senderEP);

            // Assert on GameListRequest
            Message msg = Message.Decode(bytes);
            Assert.IsNotNull(msg);
            Assert.IsTrue(msg is JoinGameRequest);
            JoinGameRequest request = msg as JoinGameRequest;
            Assert.AreEqual(request.GameId, player.GamesList[0].GameId);
            Assert.AreEqual(request.Player.ProcessId, player.ProcessInfo.ProcessId);
            Assert.AreEqual(request.Player.Type, player.ProcessInfo.Type);
            Assert.AreEqual(request.Player.Label, player.ProcessInfo.Label);

            // Send GameListReply from registry to player
            JoinGameReply reply = new JoinGameReply()
            {
                GameId = request.GameId,
                InitialLifePoints = 20,
                Success = true
            };
            bytes = reply.Encode();
            mockClient.Send(bytes, bytes.Length, senderEP);

            // Assert on GameListReply, player state
            Thread.Sleep(2000);
            player.Stop();
            playerThread.Join();
            Assert.AreEqual(player.LifePoints, reply.InitialLifePoints);
            Assert.IsTrue(player.CurrentState is NullState);
            Assert.AreEqual(player.ProcessInfo.Status, ProcessInfo.StatusCode.JoinedGame);
        }
        public void TestGetGames()
        {
            // Create udp client to mock registry
            UdpClient mockClient = new UdpClient(0);
            int mockClientPort = ((IPEndPoint)mockClient.Client.LocalEndPoint).Port;
            PublicEndPoint mockClientEP = new PublicEndPoint()
            {
                Host = "127.0.0.1",
                Port = mockClientPort
            };

            // Create fake player
            TestablePlayer player = new TestablePlayer()
            {
                RegistryEndPoint = mockClientEP
            };
            player.CurrentState = new GetGamesState(player);

            // Run player
            Thread playerThread = new Thread(new ThreadStart(player.Start));
            playerThread.Start();

            // Get message registry client
            IPEndPoint senderEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] bytes = mockClient.Receive(ref senderEP);

            // Assert on GameListRequest
            Message msg = Message.Decode(bytes);
            Assert.IsNotNull(msg);
            Assert.IsTrue(msg is GameListRequest);
            GameListRequest request = msg as GameListRequest;
            Assert.AreEqual(request.StatusFilter, (int)GameInfo.StatusCode.Available);

            // Send GameListReply from registry to player
            GameListReply reply = new GameListReply()
            {
                GameInfo = new GameInfo[] {
                    new GameInfo() {
                        GameId = 7,
                        Label = "Test Game",
                        Status = GameInfo.StatusCode.Available,
                        GameManager = new ProcessInfo()
                        {
                            EndPoint = new PublicEndPoint()
                            {
                                HostAndPort = senderEP.ToString()
                            }
                        }
                    }
                },
                Success = true
            };
            bytes = reply.Encode();
            mockClient.Send(bytes, bytes.Length, senderEP);

            // Assert on GameListReply, player state
            Thread.Sleep(2000);
            player.Stop();
            playerThread.Join();
            Assert.AreEqual(player.GamesList.Length, 1);
            GameInfo playerInfo = player.GamesList[0];
            GameInfo replyInfo = reply.GameInfo[0];
            Assert.AreEqual(playerInfo.GameId, replyInfo.GameId);
            Assert.AreEqual(playerInfo.Label, replyInfo.Label);
            Assert.AreEqual(playerInfo.Status, replyInfo.Status);
            Assert.AreEqual(playerInfo.GameManager.EndPoint.HostAndPort, replyInfo.GameManager.EndPoint.HostAndPort);
            Assert.IsTrue(player.CurrentState is JoinGameState);
        }