예제 #1
0
        public async Task ViewComponentResult_NoContentTypeSet_PreservesResponseContentType(
            string responseContentType,
            string expectedContentType)
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName = "Full.Name.Text",
                ShortName = "Text",
                TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var actionContext = CreateActionContext(descriptor);

            actionContext.HttpContext.Response.ContentType = expectedContentType;

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments = new { name = "World!" },
                ViewComponentName = "Text",
                TempData = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            Assert.Equal(expectedContentType, actionContext.HttpContext.Response.ContentType);
        }
예제 #2
0
        public async Task ExecuteAsync_ViewComponentResult_AllowsNullViewDataAndTempData()
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName = "Full.Name.Text",
                ShortName = "Text",
                TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var actionContext = CreateActionContext(descriptor);

            var viewComponentResult = new ViewComponentResult
            {
                Arguments = new { name = "World!" },
                ViewData = null,
                TempData = null,
                ViewComponentName = "Text"
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);
            // No assert, just confirm it didn't throw
        }
예제 #3
0
        public async Task ExecuteResultAsync_SetsStatusCode()
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName = "Full.Name.Text",
                ShortName = "Text",
                TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var actionContext = CreateActionContext(descriptor);

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments = new { name = "World!" },
                ViewComponentType = typeof(TextViewComponent),
                StatusCode = 404,
                TempData = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            Assert.Equal(404, actionContext.HttpContext.Response.StatusCode);
        }
예제 #4
0
        public async Task ViewComponentResult_SetsContentTypeHeader_OverrideResponseContentType()
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName = "Full.Name.Text",
                ShortName = "Text",
                TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var actionContext = CreateActionContext(descriptor);

            var expectedContentType = "text/html; charset=utf-8";
            actionContext.HttpContext.Response.ContentType = "application/x-will-be-overridden";

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments = new { name = "World!" },
                ViewComponentName = "Text",
                ContentType = new MediaTypeHeaderValue("text/html") { Encoding = Encoding.UTF8 }.ToString(),
                TempData = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            Assert.Equal(expectedContentType, actionContext.HttpContext.Response.ContentType);
        }
예제 #5
0
        public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByType()
        {
            // Arrange
            var expected = $"A view component named '{typeof(TextViewComponent).FullName}' could not be found. " +
                           "A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated " +
                           "with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. " +
                           "A view component must not be decorated with 'NonViewComponentAttribute'.";

            var actionContext = CreateActionContext();
            var services      = CreateServices(diagnosticListener: null, context: actionContext.HttpContext);

            services.AddSingleton <IViewComponentSelector>();


            var viewComponentResult = new ViewComponentResult
            {
                ViewComponentType = typeof(TextViewComponent),
                TempData          = _tempDataDictionary,
            };

            // Act and Assert
            var exception = await Assert.ThrowsAsync <InvalidOperationException>(
                () => viewComponentResult.ExecuteResultAsync(actionContext));

            Assert.Equal(expected, exception.Message);
        }
예제 #6
0
        public async Task ExecuteResultAsync_ExecutesViewComponent_ByFullName()
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName = "Full.Name.Text",
                ShortName = "Text",
                TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var actionContext = CreateActionContext(descriptor);

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments = new { name = "World!" },
                ViewComponentName = "Full.Name.Text",
                TempData = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            var body = ReadBody(actionContext.HttpContext.Response);
            Assert.Equal("Hello, World!", body);
        }
예제 #7
0
        public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByName()
        {
            // Arrange
            var expected = "A view component named 'Text' could not be found.";

            var actionContext = CreateActionContext();

            var viewComponentResult = new ViewComponentResult
            {
                ViewComponentName = "Text",
                TempData = _tempDataDictionary,
            };

            // Act and Assert
            var exception = await Assert.ThrowsAsync<InvalidOperationException>(
                () => viewComponentResult.ExecuteResultAsync(actionContext));
            Assert.Equal(expected, exception.Message);
        }
예제 #8
0
        public async Task ExecuteResultAsync_Throws_IfNameOrTypeIsNotSet()
        {
            // Arrange
            var expected =
                "Either the 'ViewComponentName' or 'ViewComponentType' " +
                "property must be set in order to invoke a view component.";

            var actionContext = CreateActionContext();

            var viewComponentResult = new ViewComponentResult
            {
                TempData = _tempDataDictionary,
            };

            // Act and Assert
            var exception = await Assert.ThrowsAsync<InvalidOperationException>(
                () => viewComponentResult.ExecuteResultAsync(actionContext));
            Assert.Equal(expected, exception.Message);
        }
예제 #9
0
        public async Task ViewComponentResult_SetsContentTypeHeader(
            string contentType,
            string expectedContentType)
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName   = "Full.Name.Text",
                ShortName  = "Text",
                TypeInfo   = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var actionContext = CreateActionContext(descriptor);

            var contentTypeBeforeViewResultExecution = contentType?.ToString();

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments         = new { name = "World!" },
                ViewComponentName = "Text",
                ContentType       = contentType,
                TempData          = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            var resultContentType = actionContext.HttpContext.Response.ContentType;

            MediaTypeAssert.Equal(expectedContentType, resultContentType);

            // Check if the original instance provided by the user has not changed.
            // Since we do not have access to the new instance created within the view executor,
            // check if at least the content is the same.
            var contentTypeAfterViewResultExecution = contentType?.ToString();

            MediaTypeAssert.Equal(contentTypeBeforeViewResultExecution, contentTypeAfterViewResultExecution);
        }
예제 #10
0
        public async Task ExecuteResultAsync_WithCustomViewComponentHelper()
        {
            // Arrange
            var expected   = "Hello from custom helper";
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName   = "Full.Name.Text",
                ShortName  = "Text",
                TypeInfo   = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };
            var result = Task.FromResult <IHtmlContent>(new HtmlContentBuilder().AppendHtml(expected));

            var helper = Mock.Of <IViewComponentHelper>(h => h.InvokeAsync(It.IsAny <Type>(), It.IsAny <object>()) == result);

            var httpContext = new DefaultHttpContext();
            var services    = CreateServices(diagnosticListener: null, httpContext, new[] { descriptor });

            services.AddSingleton <IViewComponentHelper>(helper);

            httpContext.RequestServices = services.BuildServiceProvider();
            httpContext.Response.Body   = new MemoryStream();

            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments         = new { name = "World!" },
                ViewComponentType = typeof(TextViewComponent),
                TempData          = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            var body = ReadBody(actionContext.HttpContext.Response);

            Assert.Equal(expected, body);
        }
예제 #11
0
        public async Task ExecuteResultAsync_Throws_IfServicesNotRegistered()
        {
            // Arrange
            var actionContext = new ActionContext(new DefaultHttpContext()
            {
                RequestServices = Mock.Of <IServiceProvider>(),
            }, new RouteData(), new ActionDescriptor());
            var expected =
                $"Unable to find the required services. Please add all the required services by calling " +
                $"'IServiceCollection.AddControllersWithViews()' inside the call to 'ConfigureServices(...)' " +
                $"in the application startup code.";

            var viewResult = new ViewComponentResult();

            // Act
            var ex = await Assert.ThrowsAsync <InvalidOperationException>(() => viewResult.ExecuteResultAsync(actionContext));

            // Assert
            Assert.Equal(expected, ex.Message);
        }
예제 #12
0
        public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByType()
        {
            // Arrange
            var expected = $"A view component named '{typeof(TextViewComponent).FullName}' could not be found.";

            var actionContext = CreateActionContext();
            var services = CreateServices(diagnosticListener: null, context: actionContext.HttpContext);
            services.AddSingleton<IViewComponentSelector>();


            var viewComponentResult = new ViewComponentResult
            {
                ViewComponentType = typeof(TextViewComponent),
                TempData = _tempDataDictionary,
            };

            // Act and Assert
            var exception = await Assert.ThrowsAsync<InvalidOperationException>(
                () => viewComponentResult.ExecuteResultAsync(actionContext));
            Assert.Equal(expected, exception.Message);
        }
예제 #13
0
        public async Task ExecuteResultAsync_ExecutesViewComponent_AndWritesDiagnosticSource()
        {
            // Arrange
            var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
            var descriptor = new ViewComponentDescriptor()
            {
                FullName   = "Full.Name.Text",
                ShortName  = "Text",
                TypeInfo   = typeof(TextViewComponent).GetTypeInfo(),
                MethodInfo = methodInfo,
                Parameters = methodInfo.GetParameters(),
            };

            var adapter = new TestDiagnosticListener();

            var actionContext = CreateActionContext(adapter, descriptor);

            var viewComponentResult = new ViewComponentResult()
            {
                Arguments         = new { name = "World!" },
                ViewComponentName = "Text",
                TempData          = _tempDataDictionary,
            };

            // Act
            await viewComponentResult.ExecuteResultAsync(actionContext);

            // Assert
            var body = ReadBody(actionContext.HttpContext.Response);

            Assert.Equal("Hello, World!", body);

            Assert.NotNull(adapter.BeforeViewComponent?.ActionDescriptor);
            Assert.NotNull(adapter.BeforeViewComponent?.ViewComponentContext);
            Assert.NotNull(adapter.BeforeViewComponent?.ViewComponent);
            Assert.NotNull(adapter.AfterViewComponent?.ActionDescriptor);
            Assert.NotNull(adapter.AfterViewComponent?.ViewComponentContext);
            Assert.NotNull(adapter.AfterViewComponent?.ViewComponentResult);
            Assert.NotNull(adapter.AfterViewComponent?.ViewComponent);
        }
예제 #14
0
        public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByName()
        {
            // Arrange
            var expected = "A view component named 'Text' could not be found. A view component must be " +
                           "a public non-abstract class, not contain any generic parameters, and either be decorated " +
                           "with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. " +
                           "A view component must not be decorated with 'NonViewComponentAttribute'.";

            var actionContext = CreateActionContext();

            var viewComponentResult = new ViewComponentResult
            {
                ViewComponentName = "Text",
                TempData          = _tempDataDictionary,
            };

            // Act and Assert
            var exception = await Assert.ThrowsAsync <InvalidOperationException>(
                () => viewComponentResult.ExecuteResultAsync(actionContext));

            Assert.Equal(expected, exception.Message);
        }