public async Task GetLatest_can_return_an_aggregate_built_from_a_snapshot_projection() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var snapshot = new CustomerAccountSnapshot { AggregateId = Any.Guid(), Version = 123, AggregateTypeName = AggregateType <CustomerAccount> .EventStreamName, EmailAddress = Any.Email(), NoSpam = true, UserName = Any.FullName(), ETags = new[] { Any.Word(), Any.Word() } }; await snapshotRepository.SaveSnapshot(snapshot); // act var account = await CreateRepository <CustomerAccount>().GetLatest(snapshot.AggregateId); // assert account.Id.Should().Be(snapshot.AggregateId); account.Version.Should().Be(snapshot.Version); account.EmailAddress.Should().Be(snapshot.EmailAddress); account.UserName.Should().Be(snapshot.UserName); account.NoSpam.Should().Be(snapshot.NoSpam); foreach (var etag in snapshot.ETags) { account.HasETag(etag).Should().BeTrue("etags are expected to be loaded from the snapshot"); } }
public async Task GetLatest_can_return_an_aggregate_built_from_a_snapshot_projection() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var etags = new[] { Any.Word(), Any.Word() }; var bloomFilter = new BloomFilter(); etags.ForEach(bloomFilter.Add); var snapshot = new CustomerAccountSnapshot { AggregateId = Any.Guid(), Version = 123, AggregateTypeName = AggregateType <CustomerAccount> .EventStreamName, EmailAddress = Any.Email(), NoSpam = true, UserName = Any.FullName(), ETags = bloomFilter }; await snapshotRepository.SaveSnapshot(snapshot); // act var account = await CreateRepository <CustomerAccount>().GetLatest(snapshot.AggregateId); // assert account.Id.Should().Be(snapshot.AggregateId); account.Version.Should().Be(snapshot.Version); account.EmailAddress.Should().Be(snapshot.EmailAddress); account.UserName.Should().Be(snapshot.UserName); account.NoSpam.Should().Be(snapshot.NoSpam); }
public async Task Null_or_empty_or_whitespace_ETags_are_not_saved_in_the_snapshot() { var account = new CustomerAccount() .Apply(new RequestSpam { ETag = "" }) .Apply(new RequestSpam { ETag = " " }) .Apply(new RequestSpam { ETag = null }); var repository = new InMemorySnapshotRepository(); await repository.SaveSnapshot(account); var snapshot = await repository.GetSnapshot(account.Id); snapshot.ETags .Should() .BeEmpty(); }
public async Task Snapshotting_can_be_bypassed() { var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var account = new CustomerAccount() .Apply(new ChangeEmailAddress(Any.Email())) .Apply(new RequestSpam()) .Apply(new SendMarketingEmail()) .Apply(new SendOrderConfirmationEmail(Any.AlphanumericString(8, 8))); var eventSourcedRepository = CreateRepository <CustomerAccount>(); await eventSourcedRepository.Save(account); await snapshotRepository.SaveSnapshot(account); // act account = await eventSourcedRepository.GetLatest(account.Id); // assert account.Events().Count() .Should() .Be(4); }
public async Task When_new_events_are_added_to_an_aggregate_sourced_from_a_stale_snapshot_the_version_increments_correctly() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var snapshot = new CustomerAccountSnapshot { AggregateId = Any.Guid(), Version = 122, AggregateTypeName = AggregateType <CustomerAccount> .EventStreamName, EmailAddress = Any.Email(), NoSpam = true, UserName = Any.FullName(), ETags = new[] { Any.Word(), Any.Word() } }; await snapshotRepository.SaveSnapshot(snapshot); await SaveEventsDirectly(new CustomerAccount.RequestedSpam { AggregateId = snapshot.AggregateId, SequenceNumber = snapshot.Version + 1 }.ToStoredEvent()); // act var account = await CreateRepository <CustomerAccount>().GetLatest(snapshot.AggregateId); account.Apply(new RequestSpam()); // assert account.Version.Should().Be(124); }
public async Task When_a_snapshot_is_not_up_to_date_then_GetLatest_retrieves_later_events_and_applies_them() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var snapshot = new CustomerAccountSnapshot { AggregateId = Any.Guid(), Version = 123, AggregateTypeName = AggregateType <CustomerAccount> .EventStreamName, EmailAddress = Any.Email(), NoSpam = true, UserName = Any.FullName(), ETags = new[] { Any.Word(), Any.Word() } }; await snapshotRepository.SaveSnapshot(snapshot); await SaveEventsDirectly(new CustomerAccount.RequestedSpam { AggregateId = snapshot.AggregateId, SequenceNumber = 124 }.ToStoredEvent()); // act var account = await CreateRepository <CustomerAccount>().GetLatest(snapshot.AggregateId); // assert account.Version.Should().Be(124); account.NoSpam.Should().Be(false); }
public async Task GetLatest_can_return_an_aggregate_built_from_a_snapshot() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var original = new CustomerAccount() .Apply(new ChangeEmailAddress(Any.Email())) .Apply(new RequestNoSpam()); var repository = CreateRepository <CustomerAccount>(); await repository.Save(original); await snapshotRepository.SaveSnapshot(original); // act var fromSnapshot = await repository.GetLatest(original.Id); // assert fromSnapshot.Id.Should().Be(original.Id); fromSnapshot.Version.Should().Be(fromSnapshot.Version); fromSnapshot.EmailAddress.Should().Be(fromSnapshot.EmailAddress); fromSnapshot.UserName.Should().Be(fromSnapshot.UserName); fromSnapshot.NoSpam.Should().Be(fromSnapshot.NoSpam); }
public async Task When_a_snapshot_is_not_up_to_date_then_GetLatest_retrieves_later_events_and_applies_them() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var customerAccount = new CustomerAccount() .Apply(new ChangeEmailAddress(Any.Email())); var repository = CreateRepository <CustomerAccount>(); await repository.Save(customerAccount); var snapshot = customerAccount.CreateSnapshot(); Console.WriteLine(snapshot.Body); await snapshotRepository.SaveSnapshot(snapshot); await SaveEventsDirectly(new CustomerAccount.RequestedSpam { AggregateId = snapshot.AggregateId, SequenceNumber = 124 }.ToInMemoryStoredEvent()); // act var account = await repository.GetLatest(snapshot.AggregateId); // assert account.Version.Should().Be(124); account.NoSpam.Should().Be(false); }
public async Task When_new_events_are_added_to_an_aggregate_sourced_from_a_stale_snapshot_the_version_increments_correctly() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var account = new CustomerAccount() .Apply(new ChangeEmailAddress(Any.Email())) .Apply(new RequestSpam()); var originalVersion = account.Version; var repository = CreateRepository <CustomerAccount>(); await repository.Save(account); await snapshotRepository.SaveSnapshot(account); await SaveEventsDirectly(new CustomerAccount.RequestedSpam { AggregateId = account.Id, SequenceNumber = originalVersion + 1 }.ToInMemoryStoredEvent()); // act account = await repository.GetLatest(account.Id); // assert account.Version.Should().Be(originalVersion + 1); }
public void SaveSnapshot_throws_an_informative_exception_when_no_snapshot_creator_is_found() { var repository = new InMemorySnapshotRepository(); Action save = () => repository.SaveSnapshot(new Order(new CreateOrder(Any.FullName()))).Wait(); save.ShouldThrow <DomainConfigurationException>(); }
public void SaveSnapshot_throws_an_informative_exception_when_no_snapshot_creator_is_found() { var repository = new InMemorySnapshotRepository(); Action save = () => repository.SaveSnapshot(new Order(new CreateOrder(Any.FullName()))).Wait(); save.ShouldThrow<DomainConfigurationException>(); }
public async Task ETags_are_saved_in_the_snapshot() { var etag = Any.Guid().ToString(); var account = new CustomerAccount().Apply(new RequestSpam { ETag = etag }); account.ConfirmSave(); var repository = new InMemorySnapshotRepository(); await repository.SaveSnapshot(account); var snapshot = await repository.GetSnapshot(account.Id); snapshot.ETags .Should() .Contain(etag); }
public async Task Repeated_ETags_are_not_repeated_in_the_snapshot() { var account = new CustomerAccount() .Apply(new RequestSpam { ETag = "a" }) .Apply(new RequestSpam { ETag = "a" }); account.ConfirmSave(); var repository = new InMemorySnapshotRepository(); await repository.SaveSnapshot(account); var snapshot = await repository.GetSnapshot(account.Id); snapshot.ETags .Should() .ContainSingle(etag => etag == "a"); }
public async Task When_new_events_are_added_to_an_aggregate_sourced_from_a_fully_current_snapshot_the_version_increments_correctly() { // arrange var snapshotRepository = new InMemorySnapshotRepository(); Configuration.Current.UseDependency <ISnapshotRepository>(_ => snapshotRepository); var customerAccount = new CustomerAccount() .Apply(new ChangeEmailAddress(Any.Email())); var repository = CreateRepository <CustomerAccount>(); await repository.Save(customerAccount); var snapshottedVersion = customerAccount.Version; await snapshotRepository.SaveSnapshot(customerAccount); // act var account = await repository.GetLatest(customerAccount.Id); account.Apply(new RequestSpam()); // assert account.Version.Should().Be(snapshottedVersion + 1); }