public async Task StopEverything_AfterSecondStart()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            try
            {
                await receiver.Start(stream);
            }
            catch (Exception) { }
            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await WaitForMessage(receivedMessage);

            Assert.Null(receivedMessage);
        }
        public async Task ThrowException_WhenStartingReceiverTwice()
        {
            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            await Assert.ThrowsAsync <AdminPortException>(async() => await receiver.Start(stream));

            Assert.Equal(WorkState.Errored, receiver.State);
        }
        public async Task BeAbletToDealWithDataThatIsNotSendAsWholeAtOneMoment()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            for (int i = 0; i < packet.Size; ++i)
            {
                stream.Write(packet.Buffer, i, 1);
                await Task.Delay(2);
            }


            stream.Position = 0;
            await WaitForMessage(receivedMessage);

            VerifyMessage(receivedMessage);
        }
        public async Task NotBeingAbleToReceiveCorrectPacket_AfterWrongPacket()
        {
            Packet packet = CreateWrongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;
            long savedPos = stream.Position;
            await Task.Delay(1000);

            packet = CreatePongMessage();
            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = savedPos;

            await WaitForMessage(receivedMessage);

            Assert.Null(receivedMessage);
        }
        public async Task ChangeStatusToWorking_AfterStart()
        {
            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            Assert.Equal(WorkState.Working, receiver.State);
        }
        public async Task NotErrorOut_WhenMessageReceivedThrowsException()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);
            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            receiver.MessageReceived += (_, msg) => throw new Exception("Peek a boo!");
            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await Task.Delay(TimeSpan.FromSeconds(1));

            Assert.Equal(WorkState.Working, receiver.State);
        }
        public async Task ReadPacketProperlyAndSendMessageAboutIt()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await WaitForMessage(receivedMessage);

            VerifyMessage(receivedMessage);
        }
        public async Task ErrorOut_AfterSendingWrongPacket()
        {
            Packet packet = CreateWrongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await Task.Delay(TimeSpan.FromSeconds(1));

            Assert.Equal(WorkState.Errored, receiver.State);
        }
        public async Task BeAbleToDealWithLongWaitingTimeForPacket()
        {
            Packet packet = CreatePongMessage();

            using MemoryStream stream = new MemoryStream(2000);

            var receiver = new AdminPortTcpClientReceiver(packetService);
            await receiver.Start(stream);

            IAdminMessage receivedMessage = null;

            receiver.MessageReceived += (_, msg) => receivedMessage = msg;

            await Task.Delay(TimeSpan.FromSeconds(10));

            stream.Write(packet.Buffer, 0, packet.Size);
            stream.Position = 0;

            await WaitForMessage(receivedMessage);

            VerifyMessage(receivedMessage);
        }