public async Task RouteAsync_FailOnNoAction_LogsCorrectValues()
        {
            // Arrange
            var sink = new TestSink();
            var loggerFactory = new TestLoggerFactory(sink, enabled: true);

            var mockActionSelector = new Mock<IActionSelector>();
            mockActionSelector
                .Setup(a => a.Select(It.IsAny<RouteContext>()))
                .Returns<ActionDescriptor>(null);

            var context = CreateRouteContext(
                actionSelector: mockActionSelector.Object,
                loggerFactory: loggerFactory);

            var handler = new MvcRouteHandler();
            var expectedMessage = "No actions matched the current request";

            // Act
            await handler.RouteAsync(context);

            // Assert
            Assert.Empty(sink.Scopes);
            Assert.Single(sink.Writes);
            Assert.Equal(expectedMessage, sink.Writes[0].State?.ToString());
        }
        public async Task RouteHandler_Success_LogsCorrectValues()
        {
            // Arrange
            var sink = new TestSink();
            var loggerFactory = new TestLoggerFactory(sink, enabled: true);

            var displayName = "A.B.C";
            var actionDescriptor = new Mock<ActionDescriptor>();
            actionDescriptor
                .SetupGet(ad => ad.DisplayName)
                .Returns(displayName);

            var context = CreateRouteContext(actionDescriptor: actionDescriptor.Object, loggerFactory: loggerFactory);

            var handler = new MvcRouteHandler();
            await handler.RouteAsync(context);

            // Act
            await context.Handler(context.HttpContext);

            // Assert
            Assert.Single(sink.Scopes);
            Assert.Equal(displayName, sink.Scopes[0].Scope?.ToString());

            Assert.Equal(2, sink.Writes.Count);
            Assert.Equal($"Executing action {displayName}", sink.Writes[0].State?.ToString());
            // This message has the execution time embedded, which we don't want to verify.
            Assert.StartsWith($"Executed action {displayName} ", sink.Writes[1].State?.ToString());
        }
        public async Task RouteHandler_RemovesRouteGroupFromRouteValues()
        {
            // Arrange
            var invoker = new Mock<IActionInvoker>();
            invoker
                .Setup(i => i.InvokeAsync())
                .Returns(Task.FromResult(true));

            var invokerFactory = new Mock<IActionInvokerFactory>();
            invokerFactory
                .Setup(f => f.CreateInvoker(It.IsAny<ActionContext>()))
                .Returns<ActionContext>((c) =>
                {
                    return invoker.Object;
                });

            var context = CreateRouteContext(invokerFactory: invokerFactory.Object);
            var handler = new MvcRouteHandler();

            var originalRouteData = context.RouteData;
            originalRouteData.Values.Add(TreeRouter.RouteGroupKey, "/Home/Test");

            // Act
            await handler.RouteAsync(context);

            // Assert
            Assert.Same(originalRouteData, context.RouteData);


            Assert.False(context.RouteData.Values.ContainsKey(TreeRouter.RouteGroupKey));
        }
        public async Task RouteHandler_WritesDiagnostic_ActionInvoked()
        {
            // Arrange
            var listener = new TestDiagnosticListener();

            var context = CreateRouteContext(diagnosticListener: listener);

            var handler = new MvcRouteHandler();
            await handler.RouteAsync(context);

            // Act
            await context.Handler(context.HttpContext);

            // Assert
            Assert.NotNull(listener.AfterAction?.ActionDescriptor);
            Assert.NotNull(listener.AfterAction?.HttpContext);
        }
        public async Task RouteHandler_WritesDiagnostic_ActionSelected()
        {
            // Arrange
            var listener = new TestDiagnosticListener();

            var context = CreateRouteContext(diagnosticListener: listener);
            context.RouteData.Values.Add("tag", "value");

            var handler = new MvcRouteHandler();
            await handler.RouteAsync(context);

            // Act
            await context.Handler(context.HttpContext);

            // Assert
            Assert.NotNull(listener.BeforeAction?.ActionDescriptor);
            Assert.NotNull(listener.BeforeAction?.HttpContext);

            var routeValues = listener.BeforeAction?.RouteData?.Values;
            Assert.NotNull(routeValues);

            Assert.Equal(1, routeValues.Count);
            Assert.Contains(routeValues, kvp => kvp.Key == "tag" && string.Equals(kvp.Value, "value"));
        }