public void When_a_command_reserves_a_unique_value_then_a_subsequent_request_by_a_different_owner_fails() { // arrange var username = Any.CamelCaseName(5); // act var account1 = new CustomerAccount(); account1.Apply(new RequestUserName { UserName = username, Principal = new Customer { Name = Any.CamelCaseName() } }); account1.ConfirmSave(); var account2 = new CustomerAccount(); var secondPrincipal = new Customer { Name = Any.CamelCaseName() }; var secondAttempt = account2.Validate(new RequestUserName { UserName = username, Principal = secondPrincipal }); // assert secondAttempt.ShouldBeInvalid($"The user name {username} is taken. Please choose another."); }
public async Task Recursive_scheduling_is_supported_when_scheduled_command_preconditions_are_satisfied_in_process() { var scenarioBuilder = CreateScenarioBuilder(); var scenario = scenarioBuilder.Prepare(); var customer = new CustomerAccount(); customer.Apply(new ChangeEmailAddress(Any.Email())); var scheduler = scenarioBuilder.Configuration.CommandScheduler <Order>(); var orderId = Any.Guid(); await scheduler.Schedule( orderId, new CreateOrder(Any.FullName()) { AggregateId = orderId }, deliveryDependsOn : customer.Events().First()); await Task.Delay(100); var order = scenario.GetLatest <Order>(orderId); order.Should().BeNull(); // act Console.WriteLine("SAVING"); scenario.Save(customer); order = scenario.GetLatest <Order>(orderId); order.Should().NotBeNull(); }
public void When_a_command_reserves_a_unique_value_then_a_subsequent_request_by_the_same_owner_succeeds() { // arrange var username = Any.CamelCaseName(5); // act var account1 = new CustomerAccount(); var principal = new Customer { Name = Any.CamelCaseName() }; account1.Apply(new RequestUserName { UserName = username, Principal = principal }); account1.ConfirmSave(); var account2 = new CustomerAccount(); var secondAttempt = account2.Validate(new RequestUserName { UserName = username, Principal = principal }); // assert secondAttempt.ShouldBeValid(); }
public void Reserving_a_unique_value_can_happen_during_command_validation() { // arrange var name = Any.CamelCaseName(); var firstCall = true; Configuration.Current.ReservationService = new FakeReservationService((value, scope, actor) => { if (firstCall) { firstCall = false; return(true); } return(false); }); // act var account1 = new CustomerAccount(); account1.Apply(new RequestUserName { UserName = name }); account1.ConfirmSave(); var account2 = new CustomerAccount(); var secondAttempt = account2.Validate(new RequestUserName { UserName = name }); // assert secondAttempt.ShouldBeInvalid(string.Format("The user name {0} is taken. Please choose another.", name)); }
public void Reserving_a_unique_value_can_happen_during_command_validation() { // arrange var name = Any.CamelCaseName(); var firstCall = true; Configuration.Current.ReservationService = new FakeReservationService((value, scope, actor) => { if (firstCall) { firstCall = false; return true; } return false; }); // act var account1 = new CustomerAccount(); account1.Apply(new RequestUserName { UserName = name }); account1.ConfirmSave(); var account2 = new CustomerAccount(); var secondAttempt = account2.Validate(new RequestUserName { UserName = name }); // assert secondAttempt.ShouldBeInvalid(string.Format("The user name {0} is taken. Please choose another.", name)); }
public void Projectors_added_after_Prepare_is_called_are_subscribed_to_future_events() { // arrange var onDeliveredCalls = 0; var onEmailAddedCalls = 0; var scenarioBuilder = CreateScenarioBuilder(); var aggregateId = Any.Guid(); var scenario = scenarioBuilder .AddEvents(new Order.Created { AggregateId = aggregateId }) .Prepare(); scenarioBuilder.AddHandler(new Projector { OnDelivered = e => onDeliveredCalls++, OnEmailAdded = e => onEmailAddedCalls++ }); var order = new Order(); order.Apply(new Deliver()); var customer = new CustomerAccount(); customer.Apply(new ChangeEmailAddress(Any.Email())); // act scenario.Save(order); scenario.Save(customer); // assert onDeliveredCalls.Should().Be(1); onEmailAddedCalls.Should().Be(1); }
public void When_the_aggregate_is_saved_then_the_reservation_is_confirmed() { // arrange var username = Any.Email(); var account = new CustomerAccount(); account.Apply(new RequestUserName { UserName = username, Principal = new Customer(username) }); var bus = new FakeEventBus(); bus.Subscribe(new UserNameConfirmer()); var repository = new SqlEventSourcedRepository <CustomerAccount>(bus); // act repository.Save(account); // assert using (var db = new ReservationServiceDbContext()) { db.Set <ReservedValue>() .Single(v => v.Value == username && v.Scope == "UserName") .Expiration .Should() .BeNull(); } }
public async Task An_aggregate_instantiated_from_a_snapshot_adds_new_events_at_the_correct_sequence_number() { var customerAccount = new CustomerAccount(new CustomerAccountSnapshot { AggregateId = Any.Guid(), EmailAddress = Any.Email(), Version = 12 }); customerAccount.Apply(new RequestNoSpam()); customerAccount.Version.Should().Be(13); customerAccount.PendingEvents.Last().SequenceNumber.Should().Be(13); }
public async Task Attempting_to_re_source_an_aggregate_that_was_instantiated_using_a_snapshot_succeeds_if_the_specified_version_is_at_or_after_the_snapshot() { var originalEmail = Any.Email(); var customerAccount = new CustomerAccount(new CustomerAccountSnapshot { AggregateId = Any.Guid(), Version = 10, EmailAddress = originalEmail }); customerAccount.Apply(new ChangeEmailAddress(Any.Email())); var accountAtv10 = customerAccount.AsOfVersion(10); accountAtv10.Version.Should().Be(10); accountAtv10.EmailAddress.Should().Be(originalEmail); }
public void An_aggregate_instantiated_from_a_snapshot_adds_new_events_at_the_correct_sequence_number() { // arrange var account = new CustomerAccount() .Apply(new ChangeEmailAddress(Any.Email())); account.ConfirmSave(); var snapshot = account.CreateSnapshot(); snapshot.Version = 12; // act var accountFromSnapshot = new CustomerAccount(snapshot); accountFromSnapshot.Apply(new RequestNoSpam()); // assert accountFromSnapshot.Version.Should().Be(13); accountFromSnapshot.PendingEvents.Last().SequenceNumber.Should().Be(13); }
public async Task When_the_aggregate_is_saved_then_the_reservation_is_confirmed() { // arrange var username = Any.Email(); var account = new CustomerAccount(); account.Apply(new RequestUserName { UserName = username, Principal = new Customer(username) }); Configuration.Current.EventBus.Subscribe(new UserNameConfirmer()); var repository = Configuration.Current.Repository <CustomerAccount>(); // act await repository.Save(account); // assert var reservation = await GetReservedValue(username, "UserName"); reservation.Expiration.Should().NotHaveValue(); }
public void Attempting_to_re_source_an_aggregate_that_was_instantiated_using_a_snapshot_succeeds_if_the_specified_version_is_at_or_after_the_snapshot() { // arrange var originalEmail = Any.Email(); var account = new CustomerAccount() .Apply(new ChangeEmailAddress(originalEmail)); account.ConfirmSave(); var snapshot = account.CreateSnapshot(); snapshot.Version = 10; account = new CustomerAccount(snapshot); account.Apply(new ChangeEmailAddress(Any.Email())); // act var accountAtVersion10 = account.AsOfVersion(10); // arrange accountAtVersion10.Version.Should().Be(10); accountAtVersion10.EmailAddress.Should().Be(originalEmail); }
public async Task When_a_scheduled_command_fails_and_the_clock_is_advanced_again_then_it_can_be_retried() { // ARRANGE var account = new CustomerAccount() .Apply(new ChangeEmailAddress { NewEmailAddress = Any.Email() }); account .Apply(new SendMarketingEmailOn(Clock.Now().AddDays(5))) .Apply(new RequestNoSpam()); await accountRepository.Save(account); // ACT await clockTrigger.AdvanceClock(clockName, TimeSpan.FromDays(6)); account.CommunicationsSent.Count().Should().Be(0); // requesting spam will unblock the original scheduled command if it is re-attempted account = await accountRepository.GetLatest(account.Id); account.Apply(new RequestSpam()); await accountRepository.Save(account); await clockTrigger.AdvanceClock(clockName, TimeSpan.FromMinutes(1)); // ASSERT account = await accountRepository.GetLatest(account.Id); account.CommunicationsSent.Count().Should().Be(1); }
public async Task Attempting_to_re_source_an_aggregate_that_was_instantiated_using_a_snapshot_succeeds_if_the_specified_version_is_at_or_after_the_snapshot() { var originalEmail = Any.Email(); var customerAccount = new CustomerAccount(new CustomerAccountSnapshot { AggregateId = Any.Guid(), Version = 10, EmailAddress = originalEmail }); customerAccount.Apply(new ChangeEmailAddress(Any.Email())); var accountAtv10 = customerAccount.AsOfVersion(10); accountAtv10.Version.Should().Be(10); accountAtv10.EmailAddress.Should().Be(originalEmail); }
public async Task An_aggregate_instantiated_from_a_snapshot_adds_new_events_at_the_correct_sequence_number() { var customerAccount = new CustomerAccount(new CustomerAccountSnapshot { AggregateId = Any.Guid(), EmailAddress = Any.Email(), Version = 12 }); customerAccount.Apply(new RequestNoSpam()); customerAccount.Version.Should().Be(13); customerAccount.PendingEvents.Last().SequenceNumber.Should().Be(13); }