Esempio n. 1
0
        public async Task Project_CancelMessageWithCorrectSequenceNumber_ShouldCancelHandlerAndNotThrowSequenceNumberException()
        {
            await _sequenceNumberRepository.Store(new Dictionary <string, int> {
                { "A", 10 }
            });

            var messageEnvelope = new FakeMessageEnvelope(10, new RegisteredMessageA());
            var isCancelled     = false;

            _projectionMocks[0].SetupGet(x => x.Key).Returns("A");
            _projectionMocks[0]
            .Setup(x => x.Handle(It.IsAny <Func <object> >(), messageEnvelope, It.IsAny <CancellationToken>()))
            .Returns <object, FakeMessageEnvelope, CancellationToken>(async(_, __, token) =>
            {
                await Task.Delay(20).ConfigureAwait(false);
                isCancelled = token.IsCancellationRequested;
                return(false);
            });

            var projections             = new HashSet <IProjection <string, FakeMessageEnvelope> >(_projectionMocks.Take(1).Select(x => x.Object));
            var projector               = new Projector <string, FakeMessageEnvelope, TestNextSequenceNumberRepository>(projections, _factoryMock.Object);
            var cancellationTokenSource = new CancellationTokenSource(5);
            await projector.Project(messageEnvelope, cancellationTokenSource.Token).ConfigureAwait(false);

            Assert.True(isCancelled);
        }
Esempio n. 2
0
        public async Task Project_WithProjectionThatResolvesConnection_ShouldCreateResolveDisposeLifetimeScopeInCorrectOrder()
        {
            await _sequenceNumberRepository.Store(new Dictionary <string, int> {
                { "A", 5 }
            });

            var messageEnvelope = new FakeMessageEnvelope(5, new RegisteredMessageA());
            var connectionType  = typeof(ConnectionA);

            _projectionMocks[0].SetupGet(x => x.Key).Returns("A");
            _projectionMocks[0].SetupGet(x => x.ConnectionType).Returns(connectionType);
            _projectionMocks[0]
            .Setup(x => x.Handle(It.IsAny <Func <object> >(), messageEnvelope, CancellationToken.None))
            .Callback <Func <object>, FakeMessageEnvelope, CancellationToken>((connectionResolver, _, __) =>
            {
                Assert.That(connectionResolver(), Is.Not.Null);
            })
            .Returns(() => Task.FromResult(true));

            var projections = new HashSet <IProjection <string, FakeMessageEnvelope> >(_projectionMocks.Take(1).Select(x => x.Object));
            var projector   = new Projector <string, FakeMessageEnvelope, TestNextSequenceNumberRepository>(projections, _factoryMock.Object);

            // Get the sequence number first so this scope creation/disposal does not influence our test
            await projector.GetNextSequenceNumber();

            var executionOrder = 0;

            _factoryMock.Reset();
            _factoryMock
            .Setup(x => x.BeginLifetimeScope())
            .Callback(() => Assert.That(executionOrder++, Is.EqualTo(0)))
            .Returns(() =>
            {
                var scopeMock = new Mock <IDependencyLifetimeScope>();

                scopeMock
                .Setup(x => x.Resolve(typeof(TestNextSequenceNumberRepository)))
                .Returns(_sequenceNumberRepository);

                scopeMock
                .Setup(x => x.Resolve(connectionType))
                .Callback(() => Assert.That(executionOrder++, Is.EqualTo(1)))
                .Returns(() => new FakeConnection());

                scopeMock
                .Setup(x => x.Dispose())
                .Callback(() => Assert.That(executionOrder++, Is.EqualTo(2)));
                return(scopeMock.Object);
            });

            // ReSharper disable once MethodSupportsCancellation
            await projector.Project(messageEnvelope);

            Assert.That(executionOrder, Is.EqualTo(3));
        }
Esempio n. 3
0
        public async Task Handle_MessageWithoutRegisteredHandler_ShouldReturnFalse()
        {
            var projectionMock = new Mock <TestProjection>(null)
            {
                CallBase = true
            };
            var unregisteredMessageEnvelope = new FakeMessageEnvelope(1, new UnregisteredMessage());

            IProjection <string, FakeMessageEnvelope> projection = projectionMock.Object;

            Assert.That(await projection.Handle(_connectionFactory, unregisteredMessageEnvelope, CancellationToken.None), Is.False);
        }
Esempio n. 4
0
        public async Task Project_MessageWithWrongSequenceNumber_ShouldThrowException()
        {
            await _sequenceNumberRepository.Store(new Dictionary <string, int> {
                { "A", 5 }, { "B", 6 }, { "C", 3 }
            });

            _projectionMocks[0].SetupGet(x => x.Key).Returns("A");
            _projectionMocks[1].SetupGet(x => x.Key).Returns("B");
            _projectionMocks[2].SetupGet(x => x.Key).Returns("C");

            var messageEnvelope = new FakeMessageEnvelope(2, new RegisteredMessageA());
            var projections     = new HashSet <IProjection <string, FakeMessageEnvelope> >(_projectionMocks.Select(x => x.Object));
            var projector       = new Projector <string, FakeMessageEnvelope, TestNextSequenceNumberRepository>(projections, _factoryMock.Object);
            var ex = Assert.ThrowsAsync <ArgumentOutOfRangeException>(() => projector.Project(messageEnvelope));

            Assert.That(ex.ParamName, Is.EqualTo("SequenceNumber"));
        }
Esempio n. 5
0
        public void Handle_TwoDifferentMessages_ShouldCallCorrectHandlerWithCorrectArguments()
        {
            var           connectionMock    = new Mock <FakeConnection>();
            Func <object> connectionFactory = () => connectionMock.Object;
            var           token             = new CancellationToken();
            var           messageA          = new RegisteredMessageA();
            var           messageB          = new RegisteredMessageB();
            var           messageEnvelopeA  = new FakeMessageEnvelope(1, messageA);
            var           messageEnvelopeB  = new FakeMessageEnvelope(2, messageB);

            IProjection <string, FakeMessageEnvelope> projection = new TestProjection("A");

            projection.Handle(connectionFactory, messageEnvelopeA, token);
            projection.Handle(connectionFactory, messageEnvelopeB, token);

            connectionMock.Verify(x => x.UpdateA(messageEnvelopeA, messageA), Times.Once);
            connectionMock.Verify(x => x.UpdateB(messageEnvelopeB, messageB, token), Times.Once);
        }
Esempio n. 6
0
        public async Task UseAutofac_ProjectMessage_ShouldResolveConnection()
        {
            var sequence        = 1;
            var messageEnvelope = new FakeMessageEnvelope(sequence, new FakeMessage());

            var projectionMock = new Mock <IProjection <string, FakeMessageEnvelope> >();

            projectionMock.SetupGet(x => x.Key).Returns("SomeKey");
            projectionMock.SetupGet(x => x.ConnectionType).Returns(typeof(FakeConnection));
            projectionMock
            .Setup(x => x.Handle(It.IsAny <Func <object> >(), messageEnvelope, It.IsAny <CancellationToken>()))
            .Callback <Func <object>, FakeMessageEnvelope, CancellationToken>(
                (resolver, _, __) =>
            {
                var connection = resolver();
                Assert.That(connection, Is.Not.Null);
                Assert.That(connection.GetType(), Is.EqualTo(typeof(FakeConnection)));
            })
            .Returns(() => Task.FromResult(true));

            var services = new ContainerBuilder();

            services.RegisterType <FakeConnection>().AsSelf().InstancePerLifetimeScope();
            services.RegisterType <FakeNextSequenceNumberRepository>().AsSelf().InstancePerLifetimeScope();
            services.RegisterInstance(projectionMock.Object).AsImplementedInterfaces().SingleInstance();
            services.Register(ctx => new ProjectorBuilder <string, FakeMessageEnvelope>()
                              .RegisterProjectionsFromAutofac(ctx)
                              .UseAutofacDependencyLifetimeScopeFactory(ctx)
                              .Build <FakeNextSequenceNumberRepository>())
            .AsSelf()
            .SingleInstance();

            var container = services.Build();

            var projector = container.Resolve <Projector <string, FakeMessageEnvelope, FakeNextSequenceNumberRepository> >();
            // ReSharper disable once MethodSupportsCancellation
            await projector.Project(messageEnvelope);

            projectionMock.Verify(x => x.Handle(
                                      It.IsAny <Func <object> >(),
                                      It.IsAny <FakeMessageEnvelope>(),
                                      It.IsAny <CancellationToken>()), Times.Once);
        }
Esempio n. 7
0
        public async Task Project_MessageWithCorrectSequenceNumber_ShouldIncrementSequenceNumber()
        {
            await _sequenceNumberRepository.Store(new Dictionary <string, int> {
                { "A", 5 }, { "B", 6 }, { "C", 3 }
            });

            _projectionMocks[0].SetupGet(x => x.Key).Returns("A");
            _projectionMocks[1].SetupGet(x => x.Key).Returns("B");
            _projectionMocks[2].SetupGet(x => x.Key).Returns("C");

            var messageEnvelope = new FakeMessageEnvelope(3, new RegisteredMessageA());
            var projections     = new HashSet <IProjection <string, FakeMessageEnvelope> >(_projectionMocks.Select(x => x.Object));
            var projector       = new Projector <string, FakeMessageEnvelope, TestNextSequenceNumberRepository>(projections, _factoryMock.Object);

            Assert.That(await projector.GetNextSequenceNumber(), Is.EqualTo(3));
            await projector.Project(messageEnvelope);

            Assert.That(await projector.GetNextSequenceNumber(), Is.EqualTo(4));
        }
Esempio n. 8
0
        public async Task Project_SecondProjectionThrowsException_ProjectShouldThrowExceptionAfterStoringCorrectSequenceNumbers()
        {
            await _sequenceNumberRepository.Store(new Dictionary <string, int> {
                { "A", 50 }, { "B", 50 }, { "C", 50 }
            });

            _projectionMocks[0].SetupGet(x => x.Key).Returns("A");
            _projectionMocks[1].SetupGet(x => x.Key).Returns("B");
            _projectionMocks[2].SetupGet(x => x.Key).Returns("C");

            var messageEnvelope = new FakeMessageEnvelope(50, new RegisteredMessageA());

            _projectionMocks[1].Setup(x => x.Handle(It.IsAny <Func <object> >(), messageEnvelope, CancellationToken.None))
            .Callback(() => { throw new DivideByZeroException(); });

            var projections = new HashSet <IProjection <string, FakeMessageEnvelope> >(_projectionMocks.Select(x => x.Object));
            var projector   = new Projector <string, FakeMessageEnvelope, TestNextSequenceNumberRepository>(projections, _factoryMock.Object);

            Assert.ThrowsAsync <DivideByZeroException>(() => projector.Project(messageEnvelope));

            Assert.That(_sequenceNumberRepository["A"], Is.EqualTo(51));
            Assert.That(_sequenceNumberRepository["B"], Is.EqualTo(50));
            Assert.That(_sequenceNumberRepository["C"], Is.EqualTo(50));
        }