public async Task ShouldCallConnectHook(
            [Frozen] Mock <IConnectHook> connectHook,
            ConnectInitializer sut)
        {
            await sut.ConnectAsync(_validConnection, Cts.Token);

            connectHook.Verify(x => x.HandleAsync(_connectMessage, Cts.Token));
        }
        public async Task ShouldSendDisconnectedMessage_WhenFirstMessageIsNotConnect(
            IConnection connection,
            ConnectInitializer sut)
        {
            await Assert.ThrowsAsync <InvalidOperationException>(
                async() => await sut.ConnectAsync(connection, Cts.Token));

            Mock.Get(connection).Verify(x => x.SendAsync(It.IsAny <Disconnected>(), Cts.Token));
        }
        public async Task ShouldThrow_WhenFirstMessageIsNotConnect(
            IConnection connection,
            ConnectInitializer sut)
        {
            Mock.Get(connection).Setup(x => x.ReceiveAsync(Cts.Token))
            .ReturnsAsync(Create <TestMessage>());

            await Assert.ThrowsAsync <InvalidOperationException>(
                async() => await sut.ConnectAsync(connection, Cts.Token));
        }
        public async Task ShouldSetUpdateDetector(
            [Frozen] IUpdateDetector updateDetector,
            ConnectInitializer sut)
        {
            var client = await sut.ConnectAsync(_validConnection, Cts.Token);

            Assert.Equal(updateDetector, GetPrivateField(client, "_updateDetector"));

            client.Group = "new";
            Mock.Get(updateDetector).Verify(x => x.MarkForUpdate("new"));
        }
        public async Task ShouldThrow_WhenConnectHookThrows(
            Exception exception,
            [Frozen] Mock <IConnectHook> connectHook,
            ConnectInitializer sut)
        {
            connectHook.Setup(x => x.HandleAsync(_connectMessage, Cts.Token))
            .ThrowsAsync(exception);

            var thrown = await Assert.ThrowsAsync <Exception>(
                async() => await sut.ConnectAsync(_validConnection, Cts.Token));

            Assert.Equal(exception, thrown);
        }
        public async Task ShouldCallManyConnectHooksInOrder(
            [Frozen] IEnumerable <IConnectHook> connectHooks,
            ConnectInitializer sut)
        {
            var hooks = connectHooks.ToList();
            var count = 0;

            Mock.Get(hooks[0]).Setup(x => x.HandleAsync(It.IsAny <Connect>(), Cts.Token))
            .Callback(() =>
            {
                if (count == 0)
                {
                    count++;
                }
            });

            Mock.Get(hooks[1]).Setup(x => x.HandleAsync(It.IsAny <Connect>(), Cts.Token))
            .Callback(() =>
            {
                if (count == 1)
                {
                    count++;
                }
            });

            Mock.Get(hooks[2]).Setup(x => x.HandleAsync(It.IsAny <Connect>(), Cts.Token))
            .Callback(() =>
            {
                if (count == 2)
                {
                    count++;
                }
            });

            await sut.ConnectAsync(_validConnection, Cts.Token);

            foreach (var connectHook in connectHooks)
            {
                Mock.Get(connectHook).Verify(x => x.HandleAsync(_connectMessage, Cts.Token));
            }

            Assert.Equal(3, count);
        }
        public async Task ShouldSetConnection(ConnectInitializer sut)
        {
            var client = await sut.ConnectAsync(_validConnection, Cts.Token);

            Assert.Equal(_validConnection, client.Connection);
        }
        public async Task ShouldSetGroup(ConnectInitializer sut)
        {
            var client = await sut.ConnectAsync(_validConnection, Cts.Token);

            Assert.Equal(_connectMessage.Group, client.Group);
        }