public SqlEventPublisher_features(ITestOutputHelper output)
        {
            this.output = output;

            fixture = new Fixture().Customize(new AutoMoqCustomization());
            fixture.Inject <Func <EventStoreDbContext> >(() => new DataContext());

            serializer = new JsonMessageSerializer();

            messageBus = Mock.Of <IMessageBus>();

            sut = new SqlEventPublisher(
                () => new DataContext(), serializer, messageBus);

            mockDbContext = Mock.Of <EventStoreDbContext>(
                x => x.SaveChangesAsync() == Task.FromResult(default(int)));

            mockDbContext.Aggregates = Mock.Of <DbSet <Aggregate> >();
            Mock.Get(mockDbContext.Aggregates).SetupData();

            mockDbContext.PersistentEvents = Mock.Of <DbSet <PersistentEvent> >();
            Mock.Get(mockDbContext.PersistentEvents).SetupData();

            mockDbContext.PendingEvents = Mock.Of <DbSet <PendingEvent> >();
            Mock.Get(mockDbContext.PendingEvents).SetupData();

            mockDbContext.UniqueIndexedProperties = Mock.Of <DbSet <UniqueIndexedProperty> >();
            Mock.Get(mockDbContext.UniqueIndexedProperties).SetupData();
        }
        public async Task PublishPendingEvents_commits_once(
            FakeUserCreated created,
            FakeUsernameChanged usernameChanged)
        {
            // Arrange
            var sourceId = Guid.NewGuid();

            var events = new DomainEvent[] { created, usernameChanged };

            RaiseEvents(sourceId, events);

            Mock.Get(mockDbContext.PendingEvents)
            .SetupData(events
                       .Select(e => new Envelope(e))
                       .Select(e => PendingEvent.FromEnvelope(e, serializer))
                       .ToList());

            var sut = new SqlEventPublisher(
                () => mockDbContext, serializer, messageBus);

            // Act
            await sut.PublishPendingEvents(sourceId, CancellationToken.None);

            // Assert
            Mock.Get(mockDbContext).Verify(
                x => x.SaveChangesAsync(CancellationToken.None),
                Times.Once());
        }
示例#3
0
        public void TestInitialize()
        {
            _fixture = new Fixture().Customize(new AutoMoqCustomization());
            _fixture.Inject <Func <EventStoreDbContext> >(CreateDbContext);

            _serializer = new JsonMessageSerializer();

            _messageBus = Mock.Of <IMessageBus>();

            _sut = new SqlEventPublisher(CreateDbContext, _serializer, _messageBus);
        }
示例#4
0
        public async Task FlushPendingEvents_absorbs_exception_caused_by_that_some_pending_event_already_deleted_since_loaded()
        {
            // Arrange
            var         completionSource = new TaskCompletionSource <bool>();
            IMessageBus messageBus       = new AwaitingMessageBus(completionSource.Task);
            var         fixture          = new Fixture();
            FakeUser    user             = fixture.Create <FakeUser>();

            user.ChangeUsername(fixture.Create(nameof(user.Username)));
            var eventStore = new SqlEventStore(CreateDbContext, _serializer);
            await eventStore.SaveEvents <FakeUser>(user.FlushPendingEvents());

            var sut = new SqlEventPublisher(CreateDbContext, _serializer, messageBus);

            // Act
            Func <Task> action = async() =>
            {
                Task flushTask = sut.FlushPendingEvents(user.Id, CancellationToken.None);

                using (EventStoreDbContext db = CreateDbContext())
                {
                    List <PendingEvent> pendingEvents = await db
                                                        .PendingEvents
                                                        .Where(e => e.AggregateId == user.Id)
                                                        .OrderBy(e => e.Version)
                                                        .Take(1)
                                                        .ToListAsync();

                    db.PendingEvents.RemoveRange(pendingEvents);
                    await db.SaveChangesAsync();
                }

                completionSource.SetResult(true);
                await flushTask;
            };

            // Assert
            action.ShouldNotThrow();
            using (EventStoreDbContext db = CreateDbContext())
            {
                (await db.PendingEvents.AnyAsync(e => e.AggregateId == user.Id))
                .Should().BeFalse("all pending events should be deleted");
            }
        }
示例#5
0
        public async Task FlushPendingEvents_does_not_invoke_Send_if_pending_event_not_found()
        {
            // Arrange
            var         sourceId   = Guid.NewGuid();
            IMessageBus messageBus = Mock.Of <IMessageBus>();
            var         sut        = new SqlEventPublisher(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer(),
                messageBus);

            // Act
            await sut.FlushPendingEvents <FakeUser>(sourceId, default);

            // Assert
            Mock.Get(messageBus).Verify(
                x =>
                x.Send(It.IsAny <IEnumerable <Envelope> >(), default),
                Times.Never());
        }
示例#6
0
        public async Task FlushPendingEvents_sends_events_correctly()
        {
            // Arrange
            var created         = new FakeUserCreated();
            var usernameChanged = new FakeUsernameChanged();
            var sourceId        = Guid.NewGuid();

            var events = new DomainEvent[] { created, usernameChanged };

            events.Raise(sourceId);

            var envelopes = new List <Envelope>();

            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                var serializer = new JsonMessageSerializer();
                foreach (DomainEvent e in events)
                {
                    var envelope = new Envelope(
                        messageId: Guid.NewGuid(),
                        correlationId: Guid.NewGuid(),
                        contributor: Guid.NewGuid().ToString(),
                        message: e);
                    envelopes.Add(envelope);
                    db.PendingEvents.Add(PendingEvent.FromEnvelope <FakeUser>(envelope, serializer));
                }

                await db.SaveChangesAsync();
            }

            var messageBus = new MessageBus();

            var sut = new SqlEventPublisher(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer(),
                messageBus);

            // Act
            await sut.FlushPendingEvents <FakeUser>(sourceId, CancellationToken.None);

            // Assert
            messageBus.Sent.ShouldAllBeEquivalentTo(envelopes, opts => opts.RespectingRuntimeTypes());
        }
示例#7
0
        public async Task FlushPendingEvents_deletes_pending_events()
        {
            // Arrange
            var sourceId = Guid.NewGuid();

            var created         = new FakeUserCreated();
            var usernameChanged = new FakeUsernameChanged();
            var events          = new DomainEvent[] { created, usernameChanged };

            events.Raise(sourceId);

            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                var serializer = new JsonMessageSerializer();
                foreach (DomainEvent e in events)
                {
                    var envelope = new Envelope(e);
                    db.PendingEvents.Add(PendingEvent.FromEnvelope <FakeUser>(envelope, serializer));
                }

                await db.SaveChangesAsync();
            }

            var sut = new SqlEventPublisher(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer(),
                Mock.Of <IMessageBus>());

            // Act
            await sut.FlushPendingEvents <FakeUser>(sourceId);

            // Assert
            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                bool actual = await db
                              .PendingEvents
                              .Where(e => e.AggregateId == sourceId)
                              .AnyAsync();

                actual.Should().BeFalse();
            }
        }