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();
        }
Exemple #2
0
        public async Task When_a_command_is_scheduled_but_the_event_that_triggered_it_was_not_successfully_written_then_the_command_is_not_applied()
        {
            // create a customer account
            var customer = new CustomerAccount(Any.Guid())
                           .Apply(new ChangeEmailAddress(Any.Email()));

            await Save(customer);

            var order = new Order(new CreateOrder(Any.FullName())
            {
                CustomerId = customer.Id
            });

            // act
            // cancel the order but don't save it
            order.Apply(new Cancel());

            // assert
            // verify that the customer did not receive the scheduled NotifyOrderCanceled command
            customer = await Get <CustomerAccount>(customer.Id);

            customer.Events().Last().Should().BeOfType <CustomerAccount.EmailAddressChanged>();

            using (var db = CommandSchedulerDbContext())
            {
                db.ScheduledCommands
                .Where(c => c.AggregateId == customer.Id)
                .Should()
                .ContainSingle(c => c.AppliedTime == null);
            }
        }
        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);
        }
Exemple #4
0
        public async Task Accessing_event_history_from_an_aggregate_instantiated_using_a_snapshot_throws()
        {
            var customerAccount = new CustomerAccount(new CustomerAccountSnapshot
            {
                AggregateId  = Any.Guid(),
                Version      = 10,
                EmailAddress = Any.Email()
            });

            Action getEvents = () => customerAccount.Events();

            getEvents.ShouldThrow <InvalidOperationException>()
            .And
            .Message
            .Should()
            .Contain("Aggregate was sourced from a snapshot, so event history is unavailable.");
        }
        public void Accessing_event_history_from_an_aggregate_instantiated_using_a_snapshot_throws()
        {
            // arrange
            var account = new CustomerAccount()
                          .Apply(new ChangeEmailAddress(Any.Email()));

            account.ConfirmSave();
            var snapshot = account
                           .CreateSnapshot();

            snapshot.Version = 10;
            account          = new CustomerAccount(snapshot);

            // act
            Action getEvents = () => account.Events();

            // assert
            getEvents.ShouldThrow <InvalidOperationException>()
            .And
            .Message
            .Should()
            .Contain("Aggregate was sourced from a snapshot, so event history is unavailable.");
        }
        public async Task When_a_command_is_scheduled_but_the_event_that_triggered_it_was_not_successfully_written_then_the_command_is_not_applied()
        {
            VirtualClock.Start();

            // create a customer account
            var customer = new CustomerAccount(Any.Guid())
                .Apply(new ChangeEmailAddress(Any.Email()));
            await accountRepository.Save(customer);

            var order = new Order(new CreateOrder(Any.FullName())
            {
                CustomerId = customer.Id
            });

            // act
            // cancel the order but don't save it
            order.Apply(new Cancel());

            // assert
            // verify that the customer did not receive the scheduled NotifyOrderCanceled command
            customer = await accountRepository.GetLatest(customer.Id);
            customer.Events().Last().Should().BeOfType<CustomerAccount.EmailAddressChanged>();

            using (var db = new CommandSchedulerDbContext())
            {
                db.ScheduledCommands
                  .Where(c => c.AggregateId == customer.Id)
                  .Should()
                  .ContainSingle(c => c.AppliedTime == null &&
                                      c.DueTime == null);
            }
        }
        public async Task A_scheduled_command_can_schedule_other_commands()
        {
            // ARRANGE
            var email = Any.Email();
            Console.WriteLine(new { clockName, email });
            var account = new CustomerAccount()
                .Apply(new ChangeEmailAddress(email))
                .Apply(new SendMarketingEmailOn(Clock.Now().AddDays(1)))
                .Apply(new RequestSpam());
            await accountRepository.Save(account);

            // ACT
            var result = await clockTrigger.AdvanceClock(clockName, TimeSpan.FromDays(10));
            Console.WriteLine(result.ToLogString());
           
            await SchedulerWorkComplete();

            // ASSERT
            account = await accountRepository.GetLatest(account.Id);

            Console.WriteLine(account.Events()
                                     .Select(e => string.Format("{0}: {1}{2}\n",
                                                                e.EventName(),
                                                                e.Timestamp,
                                                                e.IfTypeIs<IScheduledCommand<CustomerAccount>>()
                                                                 .Then(s => " -->  DUE: " + s.DueTime)
                                                                 .ElseDefault()))
                                     .ToLogString());

            account.Events()
                   .OfType<CommandScheduled<CustomerAccount>>()
                   .Count()
                   .Should()
                   .Be(3);
            account.Events()
                   .Last()
                   .Should()
                   .BeOfType<CommandScheduled<CustomerAccount>>();
        }
        public async Task Accessing_event_history_from_an_aggregate_instantiated_using_a_snapshot_throws()
        {
            var customerAccount = new CustomerAccount(new CustomerAccountSnapshot
            {
                AggregateId = Any.Guid(),
                Version = 10,
                EmailAddress = Any.Email()
            });

            Action getEvents = ()=> customerAccount.Events();

            getEvents.ShouldThrow<InvalidOperationException>()
                .And
                .Message
                .Should()
                .Contain("Aggregate was sourced from a snapshot, so event history is unavailable.");
        }