Пример #1
0
        public void given_command_publisher_exception_handled_SaveProcessManagerAndPublishCommands_does_not_throw()
        {
            // Arrange
            var processManager = new FooProcessManager();
            CancellationToken cancellationToken = CancellationToken.None;
            Exception         exception         = new InvalidOperationException();
            ICommandPublisher commandPublisher  = Mock.Of <ICommandPublisher>();

            Mock.Get(commandPublisher)
            .Setup(x => x.FlushCommands(processManager.Id, cancellationToken))
            .ThrowsAsync(exception);

            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                commandPublisher,
                new DelegatingCommandPublisherExceptionHandler(
                    context =>
                    context.Handled =
                        context.ProcessManagerType == typeof(FooProcessManager) &&
                        context.ProcessManagerId == processManager.Id &&
                        context.Exception == exception));

            // Act
            Func <Task> action = () =>
                                 sut.SaveProcessManagerAndPublishCommands(processManager, cancellationToken: cancellationToken);

            // Assert
            action.ShouldNotThrow();
        }
Пример #2
0
        public void SaveProcessManagerAndPublishCommands_absorbs_command_publisher_exception_handler_exception()
        {
            // Arrange
            var processManager = new FooProcessManager();
            CancellationToken cancellationToken = CancellationToken.None;
            ICommandPublisher commandPublisher  = Mock.Of <ICommandPublisher>();

            Mock.Get(commandPublisher)
            .Setup(x => x.FlushCommands(processManager.Id, cancellationToken))
            .ThrowsAsync(new InvalidOperationException());

            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                commandPublisher,
                new DelegatingCommandPublisherExceptionHandler(
                    context =>
            {
                context.Handled = true;
                throw new InvalidOperationException();
            }));

            // Act
            Func <Task> action = () =>
                                 sut.SaveProcessManagerAndPublishCommands(processManager, cancellationToken: cancellationToken);

            // Assert
            action.ShouldNotThrow();
        }
Пример #3
0
        public async Task SaveProcessManagerAndPublishCommands_inserts_new_process_manager()
        {
            // Arrange
            var processManager = new FooProcessManager {
                AggregateId = Guid.NewGuid()
            };
            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                Mock.Of <ICommandPublisher>());

            using (sut)
            {
                // Act
                await sut.SaveProcessManagerAndPublishCommands(processManager);
            }

            // Assert
            using (var db = new FooProcessManagerDbContext())
            {
                FooProcessManager actual = await
                                           db.FooProcessManagers.SingleOrDefaultAsync(x => x.Id == processManager.Id);

                actual.Should().NotBeNull();
                actual.AggregateId.Should().Be(processManager.AggregateId);
            }
        }
Пример #4
0
        public void given_command_publisher_fails_SaveProcessManagerAndPublishCommands_invokes_exception_handler()
        {
            // Arrange
            var processManager = new FooProcessManager();
            CancellationToken cancellationToken = CancellationToken.None;
            Exception         exception         = new InvalidOperationException();
            ICommandPublisher commandPublisher  = Mock.Of <ICommandPublisher>();

            Mock.Get(commandPublisher)
            .Setup(x => x.FlushCommands(processManager.Id, cancellationToken))
            .ThrowsAsync(exception);

            ICommandPublisherExceptionHandler commandPublisherExceptionHandler = Mock.Of <ICommandPublisherExceptionHandler>();

            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                commandPublisher,
                commandPublisherExceptionHandler);

            // Act
            Func <Task> action = () =>
                                 sut.SaveProcessManagerAndPublishCommands(processManager, cancellationToken: cancellationToken);

            // Assert
            action.ShouldThrow <InvalidOperationException>().Which.Should().BeSameAs(exception);
            Mock.Get(commandPublisherExceptionHandler).Verify(
                x =>
                x.Handle(It.Is <CommandPublisherExceptionContext>(
                             p =>
                             p.ProcessManagerType == typeof(FooProcessManager) &&
                             p.ProcessManagerId == processManager.Id &&
                             p.Exception == exception)),
                Times.Once());
        }
Пример #5
0
        public void Dispose_disposes_db_context()
        {
            IDisposable disposable = Mock.Of <IDisposable>();
            var         sut        = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext {
                DisposableResource = disposable
            },
                new JsonMessageSerializer(),
                Mock.Of <ICommandPublisher>());

            sut.Dispose();

            Mock.Get(disposable).Verify(x => x.Dispose(), Times.Once());
        }
Пример #6
0
        public async Task SaveProcessManagerAndPublishCommands_commits_once()
        {
            // Arrange
            var context = new FooProcessManagerDbContext();
            var sut     = new SqlProcessManagerDataContext <FooProcessManager>(
                context,
                new JsonMessageSerializer(),
                Mock.Of <ICommandPublisher>());
            var processManager = new FooProcessManager();

            // Act
            await sut.SaveProcessManagerAndPublishCommands(processManager);

            // Assert
            context.CommitCount.Should().Be(1);
        }
Пример #7
0
        public async Task SaveProcessManagerAndPublishCommands_inserts_pending_scheduled_commands_sequentially()
        {
            // Arrange
            var fixture = new Fixture();
            IEnumerable <(FooCommand command, DateTimeOffset scheduledTime)> scheduledCommands = fixture.CreateMany <(FooCommand, DateTimeOffset)>();
            var processManager = new FooProcessManager(
                from e in scheduledCommands
                select new ScheduledCommand(e.command, e.scheduledTime));
            var    operationId   = Guid.NewGuid();
            var    correlationId = Guid.NewGuid();
            string contributor   = fixture.Create <string>();
            var    serializer    = new JsonMessageSerializer();

            // Act
            using (var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                       new FooProcessManagerDbContext(),
                       serializer,
                       Mock.Of <ICommandPublisher>()))
            {
                await sut.SaveProcessManagerAndPublishCommands(processManager, operationId, correlationId, contributor);
            }

            // Assert
            using (var db = new FooProcessManagerDbContext())
            {
                IQueryable <PendingScheduledCommand> query =
                    from c in db.PendingScheduledCommands
                    where c.ProcessManagerId == processManager.Id
                    orderby c.Id
                    select c;

                var pendingScheduledCommands = query.ToList();
                pendingScheduledCommands.Should().HaveCount(scheduledCommands.Count());
                foreach (((FooCommand command, DateTimeOffset scheduledTime)expected, PendingScheduledCommand actual)t in
                         scheduledCommands.Zip(pendingScheduledCommands, (expected, actual) => (expected, actual)))
                {
                    t.actual.ProcessManagerType.Should().Be(typeof(FooProcessManager).FullName);
                    t.actual.ProcessManagerId.Should().Be(processManager.Id);
                    t.actual.MessageId.Should().NotBeEmpty();
                    t.actual.OperationId.Should().Be(operationId);
                    t.actual.CorrelationId.Should().Be(correlationId);
                    t.actual.Contributor.Should().Be(contributor);
                    serializer.Deserialize(t.actual.CommandJson).ShouldBeEquivalentTo(t.expected.command, opts => opts.RespectingRuntimeTypes());
                    t.actual.ScheduledTime.Should().Be(t.expected.scheduledTime);
                }
            }
        }
Пример #8
0
        public async Task SaveProcessManagerAndPublishCommands_publishes_commands()
        {
            // Arrange
            var fixture = new Fixture();
            FooProcessManager processManager = fixture.Create <FooProcessManager>();
            ICommandPublisher publisher      = Mock.Of <ICommandPublisher>();
            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                publisher);

            // Act
            await sut.SaveProcessManagerAndPublishCommands(processManager);

            // Assert
            Mock.Get(publisher).Verify(x => x.FlushCommands(processManager.Id, CancellationToken.None), Times.Once());
        }
Пример #9
0
        public async Task FindProcessManager_returns_null_if_process_manager_that_satisfies_predicate_not_found()
        {
            // Arrange
            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                Mock.Of <ICommandPublisher>());

            using (sut)
            {
                Expression <Func <FooProcessManager, bool> > predicate = x => x.Id == Guid.NewGuid();

                // Act
                FooProcessManager actual = await sut.FindProcessManager(predicate, CancellationToken.None);

                // Assert
                actual.Should().BeNull();
            }
        }
Пример #10
0
        public async Task FindProcessManager_returns_process_manager_that_satisfies_predicate()
        {
            // Arrange
            var processManagers = Enumerable
                                  .Repeat <Func <FooProcessManager> >(() => new FooProcessManager {
                AggregateId = Guid.NewGuid()
            }, 10)
                                  .Select(f => f.Invoke())
                                  .ToList();

            FooProcessManager expected = processManagers.First();

            using (var db = new FooProcessManagerDbContext())
            {
                var random = new Random();
                foreach (FooProcessManager processManager in from p in processManagers
                         orderby random.Next()
                         select p)
                {
                    db.FooProcessManagers.Add(processManager);
                }

                await db.SaveChangesAsync();
            }

            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                Mock.Of <ICommandPublisher>());

            using (sut)
            {
                Expression <Func <FooProcessManager, bool> > predicate = x => x.AggregateId == expected.AggregateId;

                // Act
                FooProcessManager actual = await sut.FindProcessManager(predicate, CancellationToken.None);

                // Assert
                actual.Should().NotBeNull();
                actual.Id.Should().Be(expected.Id);
            }
        }
Пример #11
0
        public void given_fails_to_commit_SaveProcessManagerAndPublishCommands_does_not_publish_commands()
        {
            // Arrange
            var fixture = new Fixture();
            ICommandPublisher publisher      = Mock.Of <ICommandPublisher>();
            FooProcessManager processManager = fixture.Create <FooProcessManager>();

            processManager.SetValidationError("invalid process manager state");
            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                publisher);

            // Act
            Func <Task> action = () => sut.SaveProcessManagerAndPublishCommands(processManager);

            // Assert
            action.ShouldThrow <DbEntityValidationException>();
            Mock.Get(publisher).Verify(x => x.FlushCommands(processManager.Id, CancellationToken.None), Times.Never());
        }
Пример #12
0
        public async Task FindProcessManager_flushes_pending_commands()
        {
            // Arrange
            ICommandPublisher publisher = Mock.Of <ICommandPublisher>();
            var processManager          = new FooProcessManager();
            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                publisher);

            using (var db = new FooProcessManagerDbContext())
            {
                db.FooProcessManagers.Add(processManager);
                await db.SaveChangesAsync();
            }

            // Act
            await sut.FindProcessManager(p => p.Id == processManager.Id, CancellationToken.None);

            // Assert
            Mock.Get(publisher).Verify(x => x.FlushCommands(processManager.Id, CancellationToken.None), Times.Once());
        }
Пример #13
0
        public async Task SaveProcessManagerAndPublishCommands_updates_existing_process_manager()
        {
            // Arrange
            var fixture = new Fixture();
            FooProcessManager processManager = fixture.Create <FooProcessManager>();

            using (var db = new FooProcessManagerDbContext())
            {
                db.FooProcessManagers.Add(processManager);
                await db.SaveChangesAsync();
            }

            string statusValue = fixture.Create <string>();

            var sut = new SqlProcessManagerDataContext <FooProcessManager>(
                new FooProcessManagerDbContext(),
                new JsonMessageSerializer(),
                Mock.Of <ICommandPublisher>());

            using (sut)
            {
                processManager = await sut.FindProcessManager(x => x.Id == processManager.Id);

                processManager.StatusValue = statusValue;

                // Act
                await sut.SaveProcessManagerAndPublishCommands(processManager);
            }

            // Assert
            using (var db = new FooProcessManagerDbContext())
            {
                FooProcessManager actual = await
                                           db.FooProcessManagers.SingleOrDefaultAsync(x => x.Id == processManager.Id);

                actual.StatusValue.Should().Be(statusValue);
            }
        }