public async Task MiddlewareBuilder_WithoutDefaults_ShouldExecute()
        {
            var callRecord = new List <string>();

            void Before(string id) => callRecord.Add($"Before_{id}");
            void After(string id) => callRecord.Add($"After_{id}");

            var outer = new TrackingMiddleware("outer", Before, After);
            var inner = new TrackingMiddleware("inner", Before, After);

            var handler = new InspectableHandler <SimpleMessage>();

            var middlewareBuilder = new HandlerMiddlewareBuilder(_resolver, _resolver)
                                    .Configure(hmb =>
                                               hmb.Use(outer)
                                               .Use(inner)
                                               .UseHandler(ctx => handler));

            var handlerMiddleware = middlewareBuilder.Build();

            var context = TestHandleContexts.From <SimpleMessage>();

            await handlerMiddleware.RunAsync(context, null, CancellationToken.None);

            callRecord.ShouldBe(new[] { "Before_outer", "Before_inner", "After_inner", "After_outer" });
            handler.ReceivedMessages.ShouldHaveSingleItem();
        }
        public async Task ThreeMiddlewares_ShouldExecuteInCorrectOrder()
        {
            var callRecord = new List <string>();

            void Before(string id) => callRecord.Add($"Before_{id}");
            void After(string id) => callRecord.Add($"After_{id}");

            var outer  = new TrackingMiddleware("outer", Before, After);
            var middle = new TrackingMiddleware("middle", Before, After);
            var inner  = new TrackingMiddleware("inner", Before, After);

            var middleware = new HandlerMiddlewareBuilder(_resolver, _resolver)
                             .Configure(pipe =>
            {
                pipe.Use(outer);
                pipe.Use(middle);
                pipe.Use(inner);
            }).Build();

            var context = new HandleMessageContext(new SimpleMessage(),
                                                   typeof(SimpleMessage),
                                                   "a-fake-queue");

            await middleware.RunAsync(context,
                                      ct =>
            {
                callRecord.Add("HandledMessage");
                return(Task.FromResult(true));
            },
                                      CancellationToken.None);

            var record = string.Join(Environment.NewLine, callRecord);

            record.ShouldMatchApproved(c => c.SubFolder("Approvals"));
        }
        public async Task Then_The_Middlewares_Are_Called()
        {
            var handler = new InspectableHandler <SimpleMessage>();

            var callRecord = new List <string>();

            void Before(string id) => callRecord.Add($"Before_{id}");
            void After(string id) => callRecord.Add($"After_{id}");

            var outerMiddleware  = new TrackingMiddleware("outer", Before, After);
            var middleMiddleware = new TrackingMiddleware("middle", Before, After);
            var innerMiddleware  = new TrackingMiddleware("inner", Before, After);

            var services = GivenJustSaying()
                           .AddSingleton(outerMiddleware)
                           .AddSingleton <IHandlerAsync <SimpleMessage> >(handler)
                           .ConfigureJustSaying(builder =>
                                                builder.WithLoopbackTopic <SimpleMessage>(UniqueName,
                                                                                          topic => topic.WithReadConfiguration(rc =>
                                                                                                                               rc.WithMiddlewareConfiguration(
                                                                                                                                   pipe =>
            {
                pipe.Use <TrackingMiddleware>();               // from DI
                pipe.Use(() => middleMiddleware);              // provide a Func<MiddlewareBase<HandleMessageContext, bool>
                pipe.Use(innerMiddleware);                     // Existing instance
            }))));

            await WhenAsync(services,
                            async (publisher, listener, serviceProvider, cancellationToken) =>
            {
                await listener.StartAsync(cancellationToken);
                await publisher.StartAsync(cancellationToken);

                // Act
                await publisher.PublishAsync(new SimpleMessage(), cancellationToken);

                await Patiently.AssertThatAsync(OutputHelper,
                                                () => handler.ReceivedMessages.Any());
            });

            string.Join(Environment.NewLine, callRecord)
            .ShouldMatchApproved(c => c.SubFolder("Approvals"));
        }