public async Task PublishPendingEvents_does_not_fails_even_if_all_events_persisted()
        {
            // Arrange
            var userId = Guid.NewGuid();

            var userCreated     = fixture.Create <FakeUserCreated>();
            var usernameChanged = fixture.Create <FakeUsernameChanged>();
            var domainEvents    = new DomainEvent[] { userCreated, usernameChanged };

            RaiseEvents(userId, domainEvents);

            var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e)));

            var batchOperation = new TableBatchOperation();

            envelopes
            .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            batchOperation.Clear();
            envelopes
            .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            // Act
            Func <Task> action = () => sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None);

            // Assert
            action.ShouldNotThrow();
        }
        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());
        }
        public void Generic_object_serialization_with_anonymous_of_anonymous_types_does_not_throws()
        {
            var changeset = new DomainEvent[]
            {
                new SampleEvent("ciao"),
                new SampleEvent("foo")
            };
            ClassWithAnonymousType classWithAnonymousType = new ClassWithAnonymousType()
            {
                DomainEvents = new[] { "foo", "bar" },
                ExtraData    = new
                {
                    Events = changeset.Select(evt => new
                    {
                        evt.GetType().Name,
                        Data = evt
                    }).ToArray(),
                }
            };
            var serialized        = JsonConvert.SerializeObject(classWithAnonymousType, GetSettingsForTest());
            var defaultSerialized = JsonConvert.SerializeObject(classWithAnonymousType, GetDefaultSettingsWithFullSerialization());

            Console.WriteLine(serialized);
            Console.WriteLine(defaultSerialized);

            ClassWithAnonymousType test = JsonConvert.DeserializeObject <ClassWithAnonymousType>(defaultSerialized, GetDefaultSettingsWithFullSerialization());

            Assert.DoesNotThrow(() => JsonConvert.DeserializeObject <ClassWithAnonymousType>(serialized, GetSettingsForTest()));
        }
        public void Saga_state_should_contain_all_messages()
        {
            var messagesSent = new DomainEvent[] { _startMessage, _coffeMadeEvent, _reStartEvent };

            CollectionAssert.AreEquivalent(messagesSent.Select(m => m.SourceId),
                                           _sagaDataAggregate.ReceivedMessages.Cast <DomainEvent>().Select(m => m.SourceId));
        }
        public async Task PublishAllEvents_sends_pending_events()
        {
            // Arrange
            var domainEvents = new List <DomainEvent>();

            List <Guid> users = fixture.CreateMany <Guid>().ToList();

            foreach (Guid userId in users)
            {
                var userCreated     = fixture.Create <FakeUserCreated>();
                var usernameChanged = fixture.Create <FakeUsernameChanged>();
                var events          = new DomainEvent[] { userCreated, usernameChanged };
                RaiseEvents(userId, events);

                var envelopes = new List <Envelope>(events.Select(e => new Envelope(e)));

                var batchOperation = new TableBatchOperation();
                envelopes
                .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer))
                .ForEach(batchOperation.Insert);
                await s_eventTable.ExecuteBatchAsync(batchOperation);

                batchOperation.Clear();
                envelopes
                .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer))
                .ForEach(batchOperation.Insert);
                await s_eventTable.ExecuteBatchAsync(batchOperation);

                domainEvents.AddRange(events);
            }

            var messages = new List <IDomainEvent>();

            Mock.Get(messageBus)
            .Setup(
                x =>
                x.SendBatch(
                    It.IsAny <IEnumerable <Envelope> >(),
                    It.IsAny <CancellationToken>()))
            .Callback <IEnumerable <Envelope>, CancellationToken>(
                (batch, cancellationToken) =>
                messages.AddRange(batch
                                  .Select(b => b.Message)
                                  .OfType <IDomainEvent>()
                                  .Where(m => users.Contains(m.SourceId))))
            .Returns(Task.FromResult(true));

            // Act
            await sut.PublishAllEvents(CancellationToken.None);

            // Assert
            messages.Should().OnlyContain(e => e is IDomainEvent);
            messages.ShouldAllBeEquivalentTo(domainEvents);
        }
        public async Task PublishPendingEvents_does_not_delete_pending_events_if_fails_to_send()
        {
            // Arrange
            var userId = Guid.NewGuid();

            var userCreated     = fixture.Create <FakeUserCreated>();
            var usernameChanged = fixture.Create <FakeUsernameChanged>();
            var domainEvents    = new DomainEvent[] { userCreated, usernameChanged };

            RaiseEvents(userId, domainEvents);

            var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e)));

            var batchOperation = new TableBatchOperation();
            var pendingEvents  = new List <PendingEventTableEntity>(
                envelopes.Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer)));

            pendingEvents.ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            batchOperation.Clear();
            envelopes
            .Take(1)
            .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            Mock.Get(messageBus)
            .Setup(
                x =>
                x.SendBatch(
                    It.IsAny <IEnumerable <Envelope> >(),
                    It.IsAny <CancellationToken>()))
            .Throws(new InvalidOperationException());

            // Act
            try
            {
                await sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None);
            }
            catch (InvalidOperationException)
            {
            }

            // Assert
            string partitionKey         = PendingEventTableEntity.GetPartitionKey(typeof(FakeUser), userId);
            var    query                = new TableQuery <PendingEventTableEntity>().Where($"PartitionKey eq '{partitionKey}'");
            IEnumerable <object> actual = s_eventTable.ExecuteQuery(query).Select(e => e.RowKey);

            actual.ShouldAllBeEquivalentTo(pendingEvents.Select(e => e.RowKey));
        }
        public async Task PublishPendingEventss_sends_only_persisted_pending_events()
        {
            // Arrange
            var userId = Guid.NewGuid();

            var userCreated     = fixture.Create <FakeUserCreated>();
            var usernameChanged = fixture.Create <FakeUsernameChanged>();
            var domainEvents    = new DomainEvent[] { userCreated, usernameChanged };

            RaiseEvents(userId, domainEvents);

            var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e)));

            var batchOperation = new TableBatchOperation();

            envelopes
            .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            batchOperation.Clear();
            envelopes
            .Take(1)
            .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            List <Envelope> batch = null;

            Mock.Get(messageBus)
            .Setup(
                x =>
                x.SendBatch(
                    It.IsAny <IEnumerable <Envelope> >(),
                    It.IsAny <CancellationToken>()))
            .Callback <IEnumerable <Envelope>, CancellationToken>((b, t) => batch = b.ToList())
            .Returns(Task.FromResult(true));

            // Act
            await sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None);

            // Assert
            Mock.Get(messageBus).Verify(
                x =>
                x.SendBatch(
                    It.IsAny <IEnumerable <Envelope> >(),
                    CancellationToken.None),
                Times.Once());
            batch.ShouldAllBeEquivalentTo(envelopes.Take(1), opts => opts.RespectingRuntimeTypes());
        }
        public async Task SaveEvents_saves_events_correctly()
        {
            // Arrange
            var userId = Guid.NewGuid();

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

            events.Raise(userId);

            var serializer = new JsonMessageSerializer();

            var sut = new SqlEventStore(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                serializer);

            // Act
            await sut.SaveEvents <FakeUser>(events);

            // Asseert
            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                IEnumerable <object> actual = db
                                              .PersistentEvents
                                              .Where(e => e.AggregateId == userId)
                                              .OrderBy(e => e.Version)
                                              .AsEnumerable()
                                              .Select(e => new
                {
                    e.AggregateType,
                    e.Version,
                    e.EventType,
                    Payload = serializer.Deserialize(e.EventJson),
                })
                                              .ToList();

                actual.Should().HaveCount(events.Length);

                IEnumerable <object> expected = events.Select(e => new
                {
                    AggregateType = typeof(FakeUser).FullName,
                    e.Version,
                    EventType = e.GetType().FullName,
                    Payload   = e,
                });

                actual.ShouldAllBeEquivalentTo(expected);
            }
        }
        public async Task SaveEvents_saves_events_correctly()
        {
            // Arrange
            FakeUserCreated     created         = _fixture.Create <FakeUserCreated>();
            FakeUsernameChanged usernameChanged = _fixture.Create <FakeUsernameChanged>();
            var events = new DomainEvent[] { created, usernameChanged };

            RaiseEvents(_userId, events);
            string operationId   = _fixture.Create <string>();
            var    correlationId = Guid.NewGuid();
            string contributor   = _fixture.Create <string>();

            // Act
            await _sut.SaveEvents <FakeUser>(events, operationId, correlationId, contributor);

            // Asseert
            using (var db = new DataContext())
            {
                IEnumerable <object> actual = db
                                              .PersistentEvents
                                              .Where(e => e.AggregateId == _userId)
                                              .OrderBy(e => e.Version)
                                              .AsEnumerable()
                                              .Select(e => new
                {
                    e.Version,
                    e.EventType,
                    e.OperationId,
                    e.CorrelationId,
                    e.Contributor,
                    Payload = _serializer.Deserialize(e.EventJson),
                })
                                              .ToList();

                actual.Should().HaveCount(events.Length);

                IEnumerable <object> expected = events.Select(e => new
                {
                    e.Version,
                    EventType     = e.GetType().FullName,
                    OperationId   = operationId,
                    CorrelationId = correlationId,
                    Contributor   = contributor,
                    Payload       = e,
                });

                actual.ShouldAllBeEquivalentTo(expected);
            }
        }
Example #10
0
        public async Task SaveEvents_saves_events_correctly(
            FakeUserCreated created,
            FakeUsernameChanged usernameChanged)
        {
            // Arrange
            var events = new DomainEvent[] { created, usernameChanged };

            RaiseEvents(userId, events);

            // Act
            await sut.SaveEvents <FakeUser>(events);

            // Asseert
            using (var db = new DataContext())
            {
                IEnumerable <object> actual = db
                                              .PersistentEvents
                                              .Where(e => e.AggregateId == userId)
                                              .OrderBy(e => e.Version)
                                              .AsEnumerable()
                                              .Select(e => new
                {
                    e.Version,
                    e.EventType,
                    Payload = serializer.Deserialize(e.EventJson)
                })
                                              .ToList();

                actual.Should().HaveCount(events.Length);

                IEnumerable <object> expected = events.Select(e => new
                {
                    Version   = e.Version,
                    EventType = e.GetType().FullName,
                    Payload   = e
                });

                actual.ShouldAllBeEquivalentTo(expected);
            }
        }
        public async Task PublishPendingEvents_deletes_all_pending_events()
        {
            // Arrange
            var userId = Guid.NewGuid();

            var userCreated     = fixture.Create <FakeUserCreated>();
            var usernameChanged = fixture.Create <FakeUsernameChanged>();
            var domainEvents    = new DomainEvent[] { userCreated, usernameChanged };

            RaiseEvents(userId, domainEvents);

            var envelopes = new List <Envelope>(domainEvents.Select(e => new Envelope(e)));

            var batchOperation = new TableBatchOperation();

            envelopes
            .Select(e => PendingEventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            batchOperation.Clear();
            envelopes
            .Take(1)
            .Select(e => EventTableEntity.FromEnvelope <FakeUser>(e, serializer))
            .ForEach(batchOperation.Insert);
            await s_eventTable.ExecuteBatchAsync(batchOperation);

            // Act
            await sut.PublishPendingEvents <FakeUser>(userId, CancellationToken.None);

            // Assert
            string partitionKey = PendingEventTableEntity.GetPartitionKey(typeof(FakeUser), userId);
            var    query        = new TableQuery <PendingEventTableEntity>().Where($"PartitionKey eq '{partitionKey}'");
            List <PendingEventTableEntity> actual = s_eventTable.ExecuteQuery(query).ToList();

            actual.Should().BeEmpty();
        }