public void when_start_consume_messages_but_not_initialized_it_should_fail()
        {
            var    driver = new BrokerIngressKafkaDriver(MakeDriverConfiguration(), Mock.Of <IConsumerRegistry>());
            Action sut    = () => driver.StartConsumeMessages(new[] { "topic-1", "topic-2" }, CancellationToken.None);

            sut.Should().ThrowExactly <PoezdOperationException>().Where(exception => exception.Message.Contains("initialized"));
        }
        public void when_dispose_it_should_dispose_consumer_registry()
        {
            var consumerRegistryMock = new Mock <IConsumerRegistry>();

            consumerRegistryMock.Setup(registry => registry.Dispose()).Verifiable();
            var driver = new BrokerIngressKafkaDriver(MakeDriverConfiguration(), consumerRegistryMock.Object);

            driver.Dispose();

            consumerRegistryMock.Verify(registry => registry.Dispose(), Times.Once());
        }
        public void when_start_consume_messages_with_invalid_arguments_it_should_fail()
        {
            var driver = new BrokerIngressKafkaDriver(MakeDriverConfiguration(), Mock.Of <IConsumerRegistry>());

            driver.Initialize(
                Mock.Of <IBrokerIngress>(),
                new[] { MakeApi <int, byte[]>(), MakeApi <int, string>() },
                MakeServiceProviderMock().Object);
            Action sut = () => driver.StartConsumeMessages(queueNamePatterns: null, CancellationToken.None);

            sut.Should().ThrowExactly <ArgumentNullException>().Where(exception => exception.ParamName.Equals("queueNamePatterns"));
        }
        public void when_initializing_twice_it_should_fail()
        {
            var driver = new BrokerIngressKafkaDriver(MakeDriverConfiguration(), Mock.Of <IConsumerRegistry>());

            Action sut = () => driver.Initialize(
                Mock.Of <IBrokerIngress>(),
                new[] { MakeApi <int, byte[]>(), MakeApi <int, string>() },
                MakeServiceProviderMock().Object);

            sut.Should().NotThrow();
            sut.Should().ThrowExactly <PoezdOperationException>().Where(exception => exception.Message.Contains("already initialized"));
        }
        public async Task when_start_consume_messages_it_should_consume_messages()
        {
            var consumerRegistryMock = new Mock <IConsumerRegistry>();
            var apiConsumerMock      = new Mock <IApiConsumer <int, byte[]> >();
            var headers = new Headers {
                { "header1", new byte[0] }
            };

            apiConsumerMock
            .Setup(consumer => consumer.Start(It.IsAny <Func <ConsumeResult <int, byte[]>, Task> >(), It.IsAny <CancellationToken>()))
            .Callback(
                (Func <ConsumeResult <int, byte[]>, Task> onMessageReceivedFunc, CancellationToken cancellationToken) =>
            {
                onMessageReceivedFunc(
                    new ConsumeResult <int, byte[]>
                {
                    Topic   = "topic1",
                    Message = new Message <int, byte[]> {
                        Headers = headers, Key = 555, Timestamp = Timestamp.Default, Value = new byte[0]
                    }
                });
            })
            .Returns(() => Task.CompletedTask);
            consumerRegistryMock
            .Setup(registry => registry.Get <int, byte[]>(It.IsAny <IIngressApi>()))
            .Returns(() => apiConsumerMock.Object);

            var sut = new BrokerIngressKafkaDriver(MakeDriverConfiguration(), consumerRegistryMock.Object);

            var consumed    = 0;
            var ingressMock = new Mock <IBrokerIngress>();

            ingressMock
            .Setup(
                ingress => ingress.RouteIngressMessage(
                    It.IsAny <string>(),
                    It.IsAny <DateTimeOffset>(),
                    It.IsAny <int>(),
                    It.IsAny <byte[]>(),
                    It.IsAny <IReadOnlyDictionary <string, string> >()))
            .Callback(() => consumed++);
            sut.Initialize(
                ingressMock.Object,
                new[] { MakeApi <int, byte[]>() },
                MakeServiceProviderMock().Object);

            await sut.StartConsumeMessages(new[] { "topic1" }, CancellationToken.None);

            consumed.Should().Be(expected: 1, "a message should be consumed");
        }
        public void when_initialize_it_should_create_consumers_for_each_api()
        {
            var consumers            = 0;
            var consumerRegistryMock = new Mock <IConsumerRegistry>();

            consumerRegistryMock
            .Setup(registry => registry.Add(It.IsAny <IIngressApi>(), It.IsAny <IApiConsumer <It.IsAnyType, It.IsAnyType> >()))
            .Callback(() => consumers++);
            var configuration = MakeDriverConfiguration();

            var sut = new BrokerIngressKafkaDriver(configuration, consumerRegistryMock.Object);

            sut.Initialize(
                Mock.Of <IBrokerIngress>(),
                new[] { MakeApi <int, byte[]>(), MakeApi <int, string>() },
                MakeServiceProviderMock().Object);

            consumers.Should().Be(expected: 2, "driver was initialized with 2 APIs");
        }
        public void when_initialized_with_service_provider_missing_required_services_it_should_fail()
        {
            var configuration    = MakeDriverConfiguration();
            var consumerRegistry = Mock.Of <IConsumerRegistry>();
            var driver           = new BrokerIngressKafkaDriver(configuration, consumerRegistry);

            var    serviceProviderMock = MakeServiceProviderMock();
            Action sut = () => driver.Initialize(
                Mock.Of <IBrokerIngress>(),
                new[] { MakeApi <int, string>() },
                serviceProviderMock.Object);

            serviceProviderMock.Setup(provider => provider.GetService(typeof(TestConsumerFactory))).Throws <InvalidOperationException>();
            sut.Should().ThrowExactly <InvalidOperationException>();
            serviceProviderMock.Setup(provider => provider.GetService(typeof(TestConsumerFactory))).Returns(new TestConsumerFactory());

            serviceProviderMock.Setup(provider => provider.GetService(typeof(TestHeaderValueCodec))).Throws <InvalidOperationException>();
            sut.Should().ThrowExactly <InvalidOperationException>();
            serviceProviderMock.Setup(provider => provider.GetService(typeof(TestHeaderValueCodec))).Returns(new TestHeaderValueCodec());
        }
        public void when_initialized_with_invalid_arguments_it_should_fail()
        {
            var driver          = new BrokerIngressKafkaDriver(MakeDriverConfiguration(), Mock.Of <IConsumerRegistry>());
            var apis            = new[] { MakeApi <int, string>() };
            var serviceProvider = MakeServiceProviderMock().Object;

            var    brokerIngress = Mock.Of <IBrokerIngress>();
            Action sut           = () => driver.Initialize(
                brokerIngress,
                apis,
                serviceProvider);

            brokerIngress = null;
            sut.Should().ThrowExactly <ArgumentNullException>().Where(exception => exception.ParamName.Equals("brokerIngress"));
            brokerIngress = Mock.Of <IBrokerIngress>();

            apis = null;
            sut.Should().ThrowExactly <ArgumentNullException>().Where(exception => exception.ParamName.Equals("apis"));
            apis = new[] { MakeApi <int, string>() };

            serviceProvider = null;
            sut.Should().ThrowExactly <ArgumentNullException>().Where(exception => exception.ParamName.Equals("serviceProvider"));
        }