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();
        }
Exemple #4
0
        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();
            }
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        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);
        }