public When_multiple_conditions_are_registered_on_a_projection()
            {
                When(() =>
                {
                    action = () =>
                    {
                        var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                        mapBuilder.HandleProjectionModificationsAs((key, context, projector, options) =>
                        {
                            throw new InvalidOperationException("Modification should not be called.");
                        });

                        mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                        {
                            throw new InvalidOperationException("Deletion should not be called.");
                        });

                        mapBuilder.HandleCustomActionsAs((context, projector) =>
                        {
                            throw new InvalidOperationException("Custom action should not be called.");
                        });

                        mapBuilder.Map <ProductAddedToCatalogEvent>()
                        .When(e => e.Category == "Hybrids")
                        .AsUpdateOf(e => e.ProductKey).Using((p, e, ctx) => p.Category = e.Category);

                        mapBuilder.Map <ProductAddedToCatalogEvent>()
                        .When(e => e.Category == "Electrics")
                        .AsDeleteOf(e => e.ProductKey);

                        var map = mapBuilder.Build();
                    };
                });
            }
            public When_an_event_is_mapped_as_a_create_if_does_not_exist()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .AsCreateIfDoesNotExistOf(e => e.ProductKey)
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;
                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleProjectionModificationsAs(async(key, context, projector, options) =>
                    {
                        projection = new ProductCatalogEntry
                        {
                            Id = key,
                        };

                        this.options = options;
                        await projector(projection);
                    });

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        throw new InvalidOperationException("Deletion should not be called.");
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
            public When_a_condition_is_not_met_on_a_projection()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder.HandleProjectionModificationsAs(async(key, context, projector, options) =>
                    {
                        projection = new ProductCatalogEntry
                        {
                            Id = key,
                        };

                        await projector(projection);
                    });

                    mapBuilder
                    .Map <ProductAddedToCatalogEvent>()
                    .When(e => e.Category == "Electric")
                    .AsUpdateOf(e => e.ProductKey)
                    .Using((p, e, ctx) =>
                    {
                        p.Category = e.Category;

                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        throw new InvalidOperationException("Deletion should not be called.");
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductAddedToCatalogEvent
                    {
                        Category   = "Hybrids",
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
            public When_an_event_is_mapped_as_a_custom_action_on_a_projection()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        customActionDecoratorExecuted = true;
                        return(projector());
                    });

                    mapBuilder.HandleProjectionModificationsAs((key, context, projector, options) =>
                    {
                        throw new InvalidOperationException("Modification should not be called.");
                    });

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        throw new InvalidOperationException("Deletion should not be called.");
                    });

                    mapBuilder.Map <ProductDiscontinuedEvent>().As((@event, context) =>
                    {
                        involvedKey = @event.ProductKey;

                        return(Task.FromResult(0));
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }
            public When_an_event_is_mapped_as_a_delete_if_exists()
            {
                Given(() =>
                {
                    var mapBuilder = new EventMapBuilder <ProductCatalogEntry, string, ProjectionContext>();
                    mapBuilder.Map <ProductDiscontinuedEvent>().AsDeleteIfExistsOf(e => e.ProductKey);

                    mapBuilder.HandleProjectionDeletionsAs((key, context, options) =>
                    {
                        projection = new ProductCatalogEntry
                        {
                            Id      = key,
                            Deleted = true
                        };

                        this.options = options;
                        return(Task.FromResult(0));
                    });

                    mapBuilder.HandleProjectionModificationsAs((key, context, projector, options) =>
                    {
                        throw new InvalidOperationException("Modification should not be called.");
                    });

                    mapBuilder.HandleCustomActionsAs((context, projector) =>
                    {
                        throw new InvalidOperationException("Custom action should not be called.");
                    });

                    map = mapBuilder.Build();
                });

                When(async() =>
                {
                    await map.Handle(
                        new ProductDiscontinuedEvent
                    {
                        ProductKey = "c350E"
                    },
                        new ProjectionContext());
                });
            }