// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Web.Routing; using System.Web.SessionState; using Moq; using Xunit; using Assert = Microsoft.TestCommon.AssertEx; namespace System.Web.Mvc.Test { public class ControllerBuilderTest { [Fact] public void ControllerBuilderReturnsDefaultControllerBuilderByDefault() { // Arrange ControllerBuilder cb = new ControllerBuilder(); // Act IControllerFactory cf = cb.GetControllerFactory(); // Assert Assert.IsType(cf); } [Fact] public void CreateControllerWithFactoryThatCannotBeCreatedThrows() { // Arrange ControllerBuilder cb = new ControllerBuilder(); cb.SetControllerFactory(typeof(ControllerFactoryThrowsFromConstructor)); // Act Assert.Throws( delegate { RequestContext reqContext = new RequestContext(new Mock().Object, new RouteData()); reqContext.RouteData.Values["controller"] = "foo"; MvcHandlerWithNoVersionHeader handler = new MvcHandlerWithNoVersionHeader(reqContext) { ControllerBuilder = cb }; handler.ProcessRequest(reqContext.HttpContext); }, "An error occurred when trying to create the IControllerFactory 'System.Web.Mvc.Test.ControllerBuilderTest+ControllerFactoryThrowsFromConstructor'. Make sure that the controller factory has a public parameterless constructor."); } [Fact] public void CreateControllerWithFactoryThatReturnsNullThrows() { // Arrange ControllerBuilder cb = new ControllerBuilder(); cb.SetControllerFactory(typeof(ControllerFactoryReturnsNull)); // Act Assert.Throws( delegate { RequestContext reqContext = new RequestContext(new Mock().Object, new RouteData()); reqContext.RouteData.Values["controller"] = "boo"; MvcHandlerWithNoVersionHeader handler = new MvcHandlerWithNoVersionHeader(reqContext) { ControllerBuilder = cb }; handler.ProcessRequest(reqContext.HttpContext); }, "The IControllerFactory 'System.Web.Mvc.Test.ControllerBuilderTest+ControllerFactoryReturnsNull' did not return a controller for the name 'boo'."); } [Fact] public void CreateControllerWithFactoryThatThrowsDoesNothingSpecial() { // Arrange ControllerBuilder cb = new ControllerBuilder(); cb.SetControllerFactory(typeof(ControllerFactoryThrows)); // Act Assert.Throws( delegate { RequestContext reqContext = new RequestContext(new Mock().Object, new RouteData()); reqContext.RouteData.Values["controller"] = "foo"; MvcHandlerWithNoVersionHeader handler = new MvcHandlerWithNoVersionHeader(reqContext) { ControllerBuilder = cb }; handler.ProcessRequest(reqContext.HttpContext); }, "ControllerFactoryThrows"); } [Fact] public void CreateControllerWithFactoryInstanceReturnsInstance() { // Arrange ControllerBuilder cb = new ControllerBuilder(); DefaultControllerFactory factory = new DefaultControllerFactory(); cb.SetControllerFactory(factory); // Act IControllerFactory cf = cb.GetControllerFactory(); // Assert Assert.Same(factory, cf); } [Fact] public void CreateControllerWithFactoryTypeReturnsValidType() { // Arrange ControllerBuilder cb = new ControllerBuilder(); cb.SetControllerFactory(typeof(MockControllerFactory)); // Act IControllerFactory cf = cb.GetControllerFactory(); // Assert Assert.IsType(cf); } [Fact] public void SetControllerFactoryInstanceWithNullThrows() { ControllerBuilder cb = new ControllerBuilder(); Assert.ThrowsArgumentNull( delegate { cb.SetControllerFactory((IControllerFactory)null); }, "controllerFactory"); } [Fact] public void SetControllerFactoryTypeWithNullThrows() { ControllerBuilder cb = new ControllerBuilder(); Assert.ThrowsArgumentNull( delegate { cb.SetControllerFactory((Type)null); }, "controllerFactoryType"); } [Fact] public void SetControllerFactoryTypeWithNonFactoryTypeThrows() { ControllerBuilder cb = new ControllerBuilder(); Assert.Throws( delegate { cb.SetControllerFactory(typeof(int)); }, "The controller factory type 'System.Int32' must implement the IControllerFactory interface.\r\nParameter name: controllerFactoryType"); } [Fact] public void DefaultControllerFactoryIsDefaultControllerFactory() { // Arrange ControllerBuilder builder = new ControllerBuilder(); // Act IControllerFactory returnedControllerFactory = builder.GetControllerFactory(); //Assert Assert.Equal(typeof(DefaultControllerFactory), returnedControllerFactory.GetType()); } [Fact] public void SettingControllerFactoryReturnsSetFactory() { // Arrange ControllerBuilder builder = new ControllerBuilder(); Mock setFactory = new Mock(); // Act builder.SetControllerFactory(setFactory.Object); // Assert Assert.Same(setFactory.Object, builder.GetControllerFactory()); } [Fact] public void ControllerBuilderGetControllerFactoryDelegatesToResolver() { //Arrange Mock factory = new Mock(); Resolver resolver = new Resolver { Current = factory.Object }; ControllerBuilder builder = new ControllerBuilder(resolver); //Act IControllerFactory result = builder.GetControllerFactory(); //Assert Assert.Same(factory.Object, result); } public class ControllerFactoryThrowsFromConstructor : IControllerFactory { public ControllerFactoryThrowsFromConstructor() { throw new Exception("ControllerFactoryThrowsFromConstructor"); } public IController CreateController(RequestContext context, string controllerName) { return null; } public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) { return SessionStateBehavior.Default; } public void ReleaseController(IController controller) { } } public class ControllerFactoryReturnsNull : IControllerFactory { public IController CreateController(RequestContext context, string controllerName) { return null; } public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) { return SessionStateBehavior.Default; } public void ReleaseController(IController controller) { } } public class ControllerFactoryThrows : IControllerFactory { public IController CreateController(RequestContext context, string controllerName) { throw new Exception("ControllerFactoryThrows"); } public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) { return SessionStateBehavior.Default; } public void ReleaseController(IController controller) { } } public class MockControllerFactory : IControllerFactory { public IController CreateController(RequestContext context, string controllerName) { throw new NotImplementedException(); } public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) { return SessionStateBehavior.Default; } public void ReleaseController(IController controller) { } } private sealed class MvcHandlerWithNoVersionHeader : MvcHandler { public MvcHandlerWithNoVersionHeader(RequestContext requestContext) : base(requestContext) { } protected internal override void AddVersionHeader(HttpContextBase httpContext) { // Don't try to set the version header for the unit tests } } } }