public void events_raised_whilst_consuming_events_should_be_recorded()
        {
            var waitForConsumption = new ManualResetEventSlim(false);
            Transaction consumerTransaction = null;

            var eventStore = Substitute.For<EventStore>();

            //Because consumers run in background threads, we need to block until complete before we assert.
            eventStore.When(_ => _.LogConsumption(Arg.Any<RaisedEvent>(), Arg.Any<ConsumptionLog>())).Do(info =>
                                                                                                             {
                                                                                                                 consumerTransaction =
                                                                                                                     Transaction.Current;
                                                                                                                 waitForConsumption.Set();
                                                                                                             });

            var domain = new TestableDomain(null, null, eventStore);

            var key = "test";

            domain.Consume(
                new RaisedEvent(
                    new DogRegistered(key, null),
                    DateTimeOffset.UtcNow));

            waitForConsumption.Wait();

            var aggregateInfo = domain.AggregateTracker[typeof (Dog), key];

            ((string) aggregateInfo.Instance.AsDynamic().earbrand).ShouldEqual(key);
            aggregateInfo.Lifestate.ShouldEqual(AggregateLifestate.Live);

            var recorded = domain.TransactionTracker[consumerTransaction].RecordedEvents;
            recorded.Count().ShouldEqual(1);
            recorded.First().Event.ShouldBeType<DogIsNotVaccinated>();
        }
        public void events_raised_whilst_restoring_do_not_propogate()
        {
            using (var ts = new TransactionScope())
            {
                var domain = new TestableDomain(null, null, null);

                var aggregateKey = "test";

                var ai = domain.AggregateTracker[typeof (Dog), aggregateKey];
                new TestableAggregateFactory().Buildup(
                    ai,
                    new Event[]
                        {
                            new DogRegistered(aggregateKey, null)
                        });

                domain.TransactionTracker[Transaction.Current].RecordedEvents.ShouldBeEmpty();
            }
        }
        public void it_should_construct_the_aggregate_using_the_first_event()
        {
            using (var ts = new TransactionScope())
            {
                var domain = new TestableDomain(null, null, null);

                var aggregateKey = "test";

                var ai = domain.AggregateTracker[typeof (Dog), aggregateKey];
                new TestableAggregateFactory().Buildup(
                    ai,
                    new Event[]
                        {
                            new DogRegistered(aggregateKey, null)
                        });

                ai.Instance.ShouldNotBeNull();
                ((string) ai.Instance.AsDynamic().earbrand).ShouldEqual(aggregateKey);
            }
        }
        public void it_should_buildup_the_aggregate_using_the_recorded_events()
        {
            using (var ts = new TransactionScope())
            {
                var domain = new TestableDomain(null, null, null);

                var aggregateKey = "test";
                var givenName = "Wolfie";
                var assignedDate = new DateTime(2013, 05, 16);

                var ai = domain.AggregateTracker[typeof (Dog), aggregateKey];
                new TestableAggregateFactory().Buildup(
                    ai,
                    new Event[]
                        {
                            new DogRegistered(aggregateKey, null),
                            new DogNamed(aggregateKey, givenName, assignedDate)
                        });

                ((string) ai.Instance.AsDynamic().name).ShouldEqual(givenName);
            }
        }
        public void events_raised_whilst_consuming_events_should_be_emitted()
        {
            var waitForConsumption = new ManualResetEventSlim(false);

            var eventEmitter = Substitute.For<EventEmitter>();
            var eventStore = Substitute.For<EventStore>();

            //Because consumers run in background threads, we need to block until complete before we assert.
            eventStore.When(_ => _.LogConsumption(Arg.Any<RaisedEvent>(), Arg.Any<ConsumptionLog>())).Do(
                info => { waitForConsumption.Set(); });

            var domain = new TestableDomain(eventEmitter, null, eventStore);

            var key = "test";

            domain.Consume(
                new RaisedEvent(
                    new DogRegistered(key, null),
                    DateTimeOffset.UtcNow));

            waitForConsumption.Wait();

            eventEmitter.Received().Emit(Arg.Is<RaisedEvent>(_ => ((DogIsNotVaccinated) _.Event).Earbrand == key));
        }
        public void the_aggregate_content_should_report_live_for_the_instance_after_restore()
        {
            using (var ts = new TransactionScope())
            {
                var domain = new TestableDomain(null, null, null);

                var aggregateKey = "test";
                var givenName = "Wolfie";
                var assignedDate = new DateTime(2013, 05, 16);

                var ai = domain.AggregateTracker[typeof (Dog), aggregateKey];
                new TestableAggregateFactory().Buildup(
                    ai,
                    new Event[]
                        {
                            new DogRegistered(aggregateKey, null),
                            new DogNamed(aggregateKey, givenName, assignedDate)
                        });

                ai.Lifestate.ShouldEqual(AggregateLifestate.Live);
                ((string) ai.Instance.AsDynamic().earbrand).ShouldEqual(aggregateKey);
                ((string) ai.Instance.AsDynamic().name).ShouldEqual(givenName);
                ((DateTime) ai.Instance.AsDynamic().nameAssignedDate).ShouldEqual(assignedDate);
            }
        }
        public void events_raised_whilst_handling_commands_should_be_emitted()
        {
            var eventEmitter = Substitute.For<EventEmitter>();
            var eventStore = Substitute.For<EventStore>();
            var key = "test";

            using (var ts = new TransactionScope())
            {
                var domain = new TestableDomain(eventEmitter, null, eventStore);

                var expected = new RegisterDog(key, null, null);

                domain.Apply(expected);

                ts.Complete();
            }

            eventEmitter.Received().Emit(Arg.Is<RaisedEvent>(_ => ((DogRegistered) _.Event).Earbrand == key));
        }
        public void events_raised_whilst_handling_commands_should_be_recorded()
        {
            var eventStore = Substitute.For<EventStore>();

            using ( new TransactionScope())
            {
                var domain = new TestableDomain(null, null, eventStore);

                var key = "test";

                domain.Apply(new RegisterDog(key, null, null));

                var aggregateInfo = domain.AggregateTracker[typeof (Dog), key];
                aggregateInfo.Lifestate.ShouldEqual(AggregateLifestate.Untracked);

                var recorded = domain.TransactionTracker[Transaction.Current].RecordedEvents;
                recorded.Count().ShouldEqual(1);
                recorded.First().Event.ShouldBeType<DogRegistered>();
            }
        }