// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.PipelineCore; using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; using Moq; using Xunit; namespace Microsoft.AspNet.Mvc { public class ViewViewComponentResultTest { [Fact] public void Execute_RendersPartialViews() { // Arrange var view = new Mock(); view.Setup(v => v.RenderAsync(It.IsAny())) .Returns(Task.FromResult(result: true)) .Verifiable(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.Found("some-view", view.Object)) .Verifiable(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewEngine = viewEngine.Object, ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view.Object, viewData); // Act result.Execute(viewComponentContext); // Assert viewEngine.Verify(); view.Verify(); } [Fact] public void Execute_ResolvesView_WithDefaultAsViewName() { // Arrange var view = new Mock(MockBehavior.Strict); view.Setup(v => v.RenderAsync(It.IsAny())) .Returns(Task.FromResult(result: true)) .Verifiable(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.Found("Default", view.Object)) .Verifiable(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewEngine = viewEngine.Object, ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view.Object, viewData); // Act result.Execute(viewComponentContext); // Assert viewEngine.Verify(); view.Verify(); } [Fact] public void Execute_ThrowsIfPartialViewCannotBeFound() { // Arrange var expected = string.Join(Environment.NewLine, "The view 'Components/Object/some-view' was not found. The following locations were searched:", "location1", "location2."); var view = Mock.Of(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.NotFound("Components/Object/some-view", new[] { "location1", "location2" })) .Verifiable(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewEngine = viewEngine.Object, ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view, viewData); // Act and Assert var ex = Assert.Throws(() => result.Execute(viewComponentContext)); Assert.Equal(expected, ex.Message); } [Fact] public void Execute_DoesNotWrapThrownExceptionsInAggregateExceptions() { // Arrange var expected = new IndexOutOfRangeException(); var view = new Mock(); view.Setup(v => v.RenderAsync(It.IsAny())) .Throws(expected) .Verifiable(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.Found("some-view", view.Object)) .Verifiable(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewEngine = viewEngine.Object, ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view.Object, viewData); // Act var actual = Record.Exception(() => result.Execute(viewComponentContext)); // Assert Assert.Same(expected, actual); view.Verify(); } [Fact] public async Task ExecuteAsync_RendersPartialViews() { // Arrange var view = Mock.Of(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.Found("some-view", view)) .Verifiable(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewEngine = viewEngine.Object, ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view, viewData); // Act await result.ExecuteAsync(viewComponentContext); // Assert viewEngine.Verify(); } [Fact] public async Task ExecuteAsync_ResolvesViewEngineFromServiceProvider_IfNoViewEngineIsExplicitlyProvided() { // Arrange var view = Mock.Of(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.Found("some-view", view)) .Verifiable(); var serviceProvider = new Mock(); serviceProvider.Setup(p => p.GetService(typeof(ICompositeViewEngine))) .Returns(viewEngine.Object); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view, viewData); viewComponentContext.ViewContext.HttpContext.RequestServices = serviceProvider.Object; // Act await result.ExecuteAsync(viewComponentContext); // Assert viewEngine.Verify(); serviceProvider.Verify(); } [Fact] public async Task ExecuteAsync_ThrowsIfPartialViewCannotBeFound() { // Arrange var expected = string.Join(Environment.NewLine, "The view 'Components/Object/some-view' was not found. The following locations were searched:", "view-location1", "view-location2."); var view = Mock.Of(); var viewEngine = new Mock(MockBehavior.Strict); viewEngine.Setup(e => e.FindPartialView(It.IsAny(), It.IsAny())) .Returns(ViewEngineResult.NotFound( "Components/Object/some-view", new[] { "view-location1", "view-location2" })) .Verifiable(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewEngine = viewEngine.Object, ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view, viewData); // Act and Assert var ex = await Assert.ThrowsAsync( () => result.ExecuteAsync(viewComponentContext)); Assert.Equal(expected, ex.Message); } [Fact] public async Task ExecuteAsync_Throws_IfNoViewEngineCanBeResolved() { // Arrange var expected = "TODO: No service for type 'Microsoft.AspNet.Mvc.Rendering.ICompositeViewEngine'" + " has been registered."; var view = Mock.Of(); var serviceProvider = new ServiceCollection().BuildServiceProvider(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var result = new ViewViewComponentResult { ViewName = "some-view", ViewData = viewData }; var viewComponentContext = GetViewComponentContext(view, viewData); viewComponentContext.ViewContext.HttpContext.RequestServices = serviceProvider; // Act and Assert var ex = await Assert.ThrowsAsync( () => result.ExecuteAsync(viewComponentContext)); Assert.Equal(expected, ex.Message); } private static ViewComponentContext GetViewComponentContext(IView view, ViewDataDictionary viewData) { var actionContext = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor()); var viewContext = new ViewContext(actionContext, view, viewData, TextWriter.Null); var viewComponentContext = new ViewComponentContext(typeof(object).GetTypeInfo(), viewContext, TextWriter.Null); return viewComponentContext; } } }