public async Task SaveEvents_inserts_UniqueIndexedProperty_with_value_of_latest_indexed_event() { // Arrange var userId = Guid.NewGuid(); var created = new FakeUserCreated(); var usernameChanged = new FakeUsernameChanged(); var events = new DomainEvent[] { created, usernameChanged }; events.Raise(userId); var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); // Act await sut.SaveEvents <FakeUser>(events); // Assert using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { UniqueIndexedProperty actual = await db .UniqueIndexedProperties .Where( p => p.AggregateId == userId && p.PropertyName == nameof(FakeUserCreated.Username)) .SingleOrDefaultAsync(); actual.PropertyValue.Should().Be(usernameChanged.Username); actual.Version.Should().Be(usernameChanged.Version); } }
public async Task SaveEvents_updates_Aggregate_correctly_for_existing_aggregate_id( FakeUsernameChanged usernameChanged) { // Arrange using (var db = new DataContext()) { var aggregate = new Aggregate { AggregateId = userId, AggregateType = typeof(FakeUser).FullName, Version = 1 }; db.Aggregates.Add(aggregate); await db.SaveChangesAsync(); } var events = new DomainEvent[] { usernameChanged }; RaiseEvents(userId, 1, usernameChanged); // Act await sut.SaveEvents <FakeUser>(events); // Assert using (var db = new DataContext()) { Aggregate actual = await db .Aggregates .Where(a => a.AggregateId == userId) .SingleOrDefaultAsync(); actual.Version.Should().Be(usernameChanged.Version); } }
public async Task PublishPendingEvents_deletes_pending_events( FakeUserCreated created, FakeUsernameChanged usernameChanged) { // Arrange var sourceId = Guid.NewGuid(); var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(sourceId, events); using (var db = new DataContext()) { foreach (DomainEvent e in events) { var envelope = new Envelope(e); db.PendingEvents.Add(PendingEvent.FromEnvelope(envelope, serializer)); } await db.SaveChangesAsync(); } // Act await sut.PublishPendingEvents(sourceId, CancellationToken.None); // Assert using (var db = new DataContext()) { bool actual = await db .PendingEvents .Where(e => e.AggregateId == sourceId) .AnyAsync(); actual.Should().BeFalse(); } }
public void SaveEvents_fails_if_events_not_have_same_source_id() { // Arrange var userId = Guid.NewGuid(); var created = new FakeUserCreated { SourceId = userId, Version = 1, RaisedAt = DateTime.UtcNow, }; var usernameChanged = new FakeUsernameChanged { SourceId = Guid.NewGuid(), Version = 2, RaisedAt = DateTime.UtcNow, }; var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); // Act Func <Task> action = () => sut.SaveEvents <FakeUser>(new DomainEvent[] { created, usernameChanged }); // Assert action.ShouldThrow <ArgumentException>().Where(x => x.ParamName == "events"); }
public async Task SaveEvents_fails_if_version_of_first_event_not_follows_aggregate( FakeUsernameChanged usernameChanged) { // Arrange using (var db = new DataContext()) { var aggregate = new Aggregate { AggregateId = userId, AggregateType = typeof(FakeUser).FullName, Version = 1 }; db.Aggregates.Add(aggregate); await db.SaveChangesAsync(); } var events = new DomainEvent[] { usernameChanged }; RaiseEvents(userId, 2, usernameChanged); // Act Func <Task> action = () => sut.SaveEvents <FakeUser>(events); // Assert action.ShouldThrow <ArgumentException>() .Where(x => x.ParamName == "events"); }
public async Task SaveEvents_fails_if_version_of_first_event_not_follows_aggregate() { // Arrange var userId = Guid.NewGuid(); using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { var aggregate = new Aggregate { AggregateId = userId, AggregateType = typeof(FakeUser).FullName, Version = 1, }; db.Aggregates.Add(aggregate); await db.SaveChangesAsync(); } var usernameChanged = new FakeUsernameChanged(); usernameChanged.Raise(userId, 2); var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); // Act Func <Task> action = () => sut.SaveEvents <FakeUser>(new[] { usernameChanged }); // Assert action.ShouldThrow <ArgumentException>().Where(x => x.ParamName == "events"); }
public async Task SaveEvents_sets_message_properties_correctly( FakeUserCreated created, FakeUsernameChanged usernameChanged, Guid correlationId) { // Arrange var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(userId, events); // Act await sut.SaveEvents <FakeUser>(events, correlationId); // Asseert using (var db = new DataContext()) { IEnumerable <object> expected = db .PendingEvents .Where(e => e.AggregateId == userId) .OrderBy(e => e.Version) .AsEnumerable() .Select(e => new { e.MessageId, e.CorrelationId }) .ToList(); IEnumerable <object> actual = db .PersistentEvents .Where(e => e.AggregateId == userId) .OrderBy(e => e.Version) .AsEnumerable() .Select(e => new { e.MessageId, e.CorrelationId }) .ToList(); actual.ShouldAllBeEquivalentTo(expected); } }
public async Task SaveEvents_removes_existing_UniqueIndexedProperty_if_property_value_is_null( FakeUserCreated created, FakeUsernameChanged usernameChanged) { // Arrange RaiseEvents(userId, created); await sut.SaveEvents <FakeUser>(new[] { created }); usernameChanged.Username = null; RaiseEvents(userId, 1, usernameChanged); // Act await sut.SaveEvents <FakeUser>(new[] { usernameChanged }); // Assert using (var db = new DataContext()) { UniqueIndexedProperty actual = await db .UniqueIndexedProperties .Where( p => p.AggregateType == typeof(FakeUser).FullName && p.PropertyName == nameof(FakeUserCreated.Username) && p.PropertyValue == created.Username) .SingleOrDefaultAsync(); actual.Should().BeNull(); } }
public async Task SaveEvents_updates_existing_UniqueIndexedProperty_correctly( FakeUserCreated created, FakeUsernameChanged usernameChanged) { // Arrange RaiseEvents(userId, created); await sut.SaveEvents <FakeUser>(new[] { created }); RaiseEvents(userId, 1, usernameChanged); // Act await sut.SaveEvents <FakeUser>(new[] { usernameChanged }); // Assert using (var db = new DataContext()) { UniqueIndexedProperty actual = await db .UniqueIndexedProperties .Where( p => p.AggregateId == userId && p.PropertyName == nameof(FakeUserCreated.Username)) .SingleOrDefaultAsync(); actual.Should().NotBeNull(); actual.PropertyValue.Should().Be(usernameChanged.Username); actual.Version.Should().Be(usernameChanged.Version); } }
public async Task SaveEvents_throws_DuplicateCorrelationException_if_correlation_duplicate() { // Arrange var userId = Guid.NewGuid(); var created = new FakeUserCreated(); var usernameChanged = new FakeUsernameChanged(); new DomainEvent[] { created, usernameChanged }.Raise(userId); var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); var correlationId = Guid.NewGuid(); await sut.SaveEvents <FakeUser>(new[] { created }, correlationId : correlationId); // Act Func <Task> action = () => sut.SaveEvents <FakeUser>(new[] { usernameChanged }, correlationId: correlationId); // Assert action.ShouldThrow <DuplicateCorrelationException>().Where( x => x.SourceType == typeof(FakeUser) && x.SourceId == userId && x.CorrelationId == correlationId && x.InnerException is DbUpdateException); }
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 async Task SaveEvents_saves_pending_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); string operationId = Guid.NewGuid().ToString(); var correlationId = Guid.NewGuid(); string contributor = Guid.NewGuid().ToString(); // Act await sut.SaveEvents <FakeUser>(events, operationId, correlationId, contributor); // Asseert using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { var pendingEvents = db .PendingEvents .Where(e => e.AggregateId == userId) .OrderBy(e => e.Version) .ToList(); foreach (var t in pendingEvents.Zip(events, (pending, source) => new { Pending = pending, Source = source })) { var actual = new { t.Pending.Version, t.Pending.CorrelationId, t.Pending.Contributor, Message = serializer.Deserialize(t.Pending.EventJson), }; actual.ShouldBeEquivalentTo(new { t.Source.Version, OperationId = operationId, CorrelationId = correlationId, Contributor = contributor, Message = t.Source, }, opts => opts.RespectingRuntimeTypes()); } } }
public async Task FlushPendingEvents_sends_events_correctly() { // Arrange FakeUserCreated created = _fixture.Create <FakeUserCreated>(); FakeUsernameChanged usernameChanged = _fixture.Create <FakeUsernameChanged>(); var sourceId = Guid.NewGuid(); string operationId = _fixture.Create <string>(); var correlationId = Guid.NewGuid(); string contributor = _fixture.Create <string>(); var domainEvents = new DomainEvent[] { created, usernameChanged }; RaiseEvents(sourceId, domainEvents); var envelopes = new List <Envelope>(); using (var db = new DataContext()) { foreach (DomainEvent domainEvent in domainEvents) { var envelope = new Envelope(Guid.NewGuid(), domainEvent, operationId, correlationId, contributor); envelopes.Add(envelope); db.PendingEvents.Add(PendingEvent.FromEnvelope(envelope, _serializer)); } await db.SaveChangesAsync(); } List <Envelope> batch = null; Mock.Get(_messageBus) .Setup( x => x.Send( It.IsAny <IEnumerable <Envelope> >(), It.IsAny <CancellationToken>())) .Callback <IEnumerable <Envelope>, CancellationToken>((b, t) => batch = b.ToList()) .Returns(Task.FromResult(true)); // Act await _sut.FlushPendingEvents(sourceId, CancellationToken.None); // Assert Mock.Get(_messageBus).Verify( x => x.Send( It.IsAny <IEnumerable <Envelope> >(), CancellationToken.None), Times.Once()); batch.ShouldAllBeEquivalentTo(envelopes, 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); } }
public async Task SaveEvents_commits_once( FakeUserCreated created, FakeUsernameChanged usernameChanged) { var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(userId, events); var sut = new SqlEventStore( () => mockDbContext, new JsonMessageSerializer()); await sut.SaveEvents <FakeUser>(events); Mock.Get(mockDbContext).Verify( x => x.SaveChangesAsync(CancellationToken.None), Times.Once()); }
public async Task LoadEvents_restores_all_events_correctly( FakeUserCreated created, FakeUsernameChanged usernameChanged) { // Arrange var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(userId, events); await sut.SaveEvents <FakeUser>(events); // Act IEnumerable <IDomainEvent> actual = await sut.LoadEvents <FakeUser>(userId); // Assert actual.ShouldAllBeEquivalentTo(events); }
public async Task PublishPendingEvents_sends_events( FakeUserCreated created, FakeUsernameChanged usernameChanged) { // Arrange var sourceId = Guid.NewGuid(); var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(sourceId, events); var envelopes = new List <Envelope>(); using (var db = new DataContext()) { foreach (DomainEvent e in events) { var envelope = new Envelope(e); envelopes.Add(envelope); db.PendingEvents.Add(PendingEvent.FromEnvelope(envelope, serializer)); } await db.SaveChangesAsync(); } 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(sourceId, CancellationToken.None); // Assert Mock.Get(messageBus).Verify( x => x.SendBatch( It.IsAny <IEnumerable <Envelope> >(), CancellationToken.None), Times.Once()); batch.ShouldAllBeEquivalentTo(envelopes, opts => opts.RespectingRuntimeTypes()); }
public async Task SaveEvents_saves_pending_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()) { var pendingEvents = db .PendingEvents .Where(e => e.AggregateId == _userId) .OrderBy(e => e.Version) .ToList(); foreach (var t in pendingEvents.Zip(events, (pending, source) => new { Pending = pending, Source = source })) { var actual = new { t.Pending.Version, t.Pending.OperationId, t.Pending.CorrelationId, t.Pending.Contributor, Message = _serializer.Deserialize(t.Pending.EventJson), }; actual.ShouldBeEquivalentTo(new { t.Source.Version, OperationId = operationId, CorrelationId = correlationId, Contributor = contributor, Message = t.Source, }, opts => opts.RespectingRuntimeTypes()); } } }
public async Task SaveEvents_throws_DuplicateCorrelationException_if_correlation_duplicate( FakeUserCreated created, FakeUsernameChanged usernameChanged, Guid correlationId) { RaiseEvents(userId, created, usernameChanged); await sut.SaveEvents <FakeUser>(new[] { created }, correlationId); Func <Task> action = () => sut.SaveEvents <FakeUser>(new[] { usernameChanged }, correlationId); action.ShouldThrow <DuplicateCorrelationException>().Where( x => x.SourceType == typeof(FakeUser) && x.SourceId == userId && x.CorrelationId == correlationId && x.InnerException is DbUpdateException); }
public async Task LoadEvents_restores_events_after_specified_version_correctly() { // Arrange FakeUserCreated created = _fixture.Create <FakeUserCreated>(); FakeUsernameChanged usernameChanged = _fixture.Create <FakeUsernameChanged>(); var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(_userId, events); await _sut.SaveEvents <FakeUser>(events); // Act IEnumerable <IDomainEvent> actual = await _sut.LoadEvents <FakeUser>(_userId, 1); // Assert actual.ShouldAllBeEquivalentTo(events.Skip(1)); }
public async Task SaveEvents_throws_DuplicateCorrelationException_if_correlation_duplicate() { FakeUserCreated created = _fixture.Create <FakeUserCreated>(); FakeUsernameChanged usernameChanged = _fixture.Create <FakeUsernameChanged>(); RaiseEvents(_userId, created, usernameChanged); var correlationId = Guid.NewGuid(); await _sut.SaveEvents <FakeUser>(new[] { created }, correlationId : correlationId); Func <Task> action = () => _sut.SaveEvents <FakeUser>(new[] { usernameChanged }, correlationId: correlationId); action.ShouldThrow <DuplicateCorrelationException>().Where( x => x.SourceType == typeof(FakeUser) && x.SourceId == _userId && x.CorrelationId == correlationId && x.InnerException is DbUpdateException); }
public async Task SaveEvents_sets_message_properties_correctly() { // Arrange var userId = Guid.NewGuid(); var created = new FakeUserCreated(); var usernameChanged = new FakeUsernameChanged(); var events = new DomainEvent[] { created, usernameChanged }; events.Raise(userId); var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); // Act await sut.SaveEvents <FakeUser>( events, correlationId : Guid.NewGuid(), contributor : Guid.NewGuid().ToString()); // Asseert using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { IEnumerable <object> expected = db .PendingEvents .Where(e => e.AggregateId == userId) .OrderBy(e => e.Version) .AsEnumerable() .Select(e => new { e.MessageId, e.CorrelationId, e.Contributor }) .ToList(); IEnumerable <object> actual = db .PersistentEvents .Where(e => e.AggregateId == userId) .OrderBy(e => e.Version) .AsEnumerable() .Select(e => new { e.MessageId, e.CorrelationId, e.Contributor }) .ToList(); actual.ShouldAllBeEquivalentTo(expected); } }
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()); }
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(); } }
public async Task SaveEvents_saves_pending_events_correctly( FakeUserCreated created, FakeUsernameChanged usernameChanged, Guid correlationId) { // Arrange var events = new DomainEvent[] { created, usernameChanged }; RaiseEvents(userId, events); // Act await sut.SaveEvents <FakeUser>(events, correlationId); // Asseert using (var db = new DataContext()) { List <PendingEvent> pendingEvents = db .PendingEvents .Where(e => e.AggregateId == userId) .OrderBy(e => e.Version) .ToList(); foreach (var t in pendingEvents.Zip(events, (pending, source) => new { Pending = pending, Source = source })) { var actual = new { t.Pending.Version, t.Pending.CorrelationId, Message = serializer.Deserialize(t.Pending.EventJson) }; actual.ShouldBeEquivalentTo(new { t.Source.Version, CorrelationId = correlationId, Message = t.Source }, opts => opts.RespectingRuntimeTypes()); } } }
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 SaveEvents_updates_Aggregate_correctly_for_existing_aggregate_id() { // Arrange var userId = Guid.NewGuid(); using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { var aggregate = new Aggregate { AggregateId = userId, AggregateType = typeof(FakeUser).FullName, Version = 1, }; db.Aggregates.Add(aggregate); await db.SaveChangesAsync(); } var usernameChanged = new FakeUsernameChanged(); usernameChanged.Raise(userId, 1); var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); // Act await sut.SaveEvents <FakeUser>(new[] { usernameChanged }); // Assert using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { Aggregate actual = await db .Aggregates .Where(a => a.AggregateId == userId) .SingleOrDefaultAsync(); actual.Version.Should().Be(usernameChanged.Version); } }
public void SaveEvents_fails_if_events_not_have_same_source_id( FakeUserCreated created, FakeUsernameChanged usernameChanged) { // Arrange created.SourceId = userId; created.Version = 1; created.RaisedAt = DateTimeOffset.Now; usernameChanged.SourceId = Guid.NewGuid(); usernameChanged.Version = 2; usernameChanged.RaisedAt = DateTimeOffset.Now; var events = new DomainEvent[] { created, usernameChanged }; // Act Func <Task> action = () => sut.SaveEvents <FakeUser>(events); // Assert action.ShouldThrow <ArgumentException>() .Where(x => x.ParamName == "events"); }
public async Task SaveEvents_removes_existing_UniqueIndexedProperty_if_property_value_is_null() { // Arrange var userId = Guid.NewGuid(); var sut = new SqlEventStore( () => new FakeEventStoreDbContext(_dbContextOptions), new JsonMessageSerializer()); var created = new FakeUserCreated(); created.Raise(userId); await sut.SaveEvents <FakeUser>(new[] { created }); var usernameChanged = new FakeUsernameChanged { Username = null }; usernameChanged.Raise(userId, 1); // Act await sut.SaveEvents <FakeUser>(new[] { usernameChanged }); // Assert using (var db = new FakeEventStoreDbContext(_dbContextOptions)) { UniqueIndexedProperty actual = await db .UniqueIndexedProperties .Where( p => p.AggregateType == typeof(FakeUser).FullName && p.PropertyName == nameof(FakeUserCreated.Username) && p.PropertyValue == created.Username) .SingleOrDefaultAsync(); actual.Should().BeNull(); } }