aspnetcore/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTes...

347 lines
13 KiB
C#

// 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.Reflection;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
using Moq;
using Xunit;
namespace Microsoft.AspNet.Mvc.Core
{
public class DefaultControllerFactoryTest
{
[Fact]
public void CreateController_ThrowsIfActionDescriptorIsNotControllerActionDescriptor()
{
// Arrange
var expected = "The action descriptor must be of type 'Microsoft.AspNet.Mvc.ControllerActionDescriptor'." +
Environment.NewLine + "Parameter name: actionContext";
var actionDescriptor = new ActionDescriptor();
var controllerFactory = new DefaultControllerFactory(Mock.Of<IControllerActivator>());
var httpContext = new DefaultHttpContext();
var actionContext = new ActionContext(httpContext,
new RouteData(),
actionDescriptor);
// Act and Assert
var ex = Assert.Throws<ArgumentException>(() =>
controllerFactory.CreateController(actionContext));
Assert.Equal(expected, ex.Message);
Assert.Equal("actionContext", ex.ParamName);
}
[Fact]
public void CreateController_UsesControllerActivatorToInstantiateController()
{
// Arrange
var expected = new MyController();
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(MyController).GetTypeInfo()
};
var httpContext = new DefaultHttpContext();
httpContext.RequestServices = GetServices();
var actionContext = new ActionContext(httpContext,
new RouteData(),
actionDescriptor);
var activator = new Mock<IControllerActivator>();
activator.Setup(a => a.Create(actionContext, typeof(MyController)))
.Returns(expected)
.Verifiable();
var controllerFactory = new DefaultControllerFactory(activator.Object);
// Act
var result = controllerFactory.CreateController(actionContext);
// Assert
var controller = Assert.IsType<MyController>(result);
Assert.Same(expected, controller);
activator.Verify();
}
[Fact]
public void CreateController_SetsPropertiesFromActionContextHierarchy()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
};
var services = GetServices();
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
// Assert
var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
Assert.Same(context, controller.ActionContext);
Assert.Same(httpContext, controller.HttpContext);
}
[Fact]
public void CreateController_SetsViewDataDictionary()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
};
var services = GetServices();
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
// Assert
var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
Assert.NotNull(controller.GetViewData());
}
[Fact]
public void CreateController_SetsBindingContext()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
};
var bindingContext = new ActionBindingContext();
var services = GetServices();
services.GetRequiredService<IScopedInstance<ActionBindingContext>>().Value = bindingContext;
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
// Assert
var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
Assert.Same(bindingContext, controller.BindingContext);
}
[Fact]
public void CreateController_PopulatesServicesFromServiceContainer()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
};
var services = GetServices();
var urlHelper = services.GetRequiredService<IUrlHelper>();
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
// Assert
var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
Assert.Same(urlHelper, controller.Helper);
}
[Fact]
public void CreateController_PopulatesUserServicesFromServiceContainer()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
};
var services = GetServices();
var testService = services.GetService<TestService>();
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
// Assert
var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
Assert.Same(testService, controller.TestService);
}
[Fact]
public void CreateController_IgnoresPropertiesThatAreNotDecoratedWithActivateAttribute()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
};
var services = GetServices();
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act
var result = factory.CreateController(context);
// Assert
var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
Assert.Null(controller.Response);
}
[Fact]
public void CreateController_ThrowsIfPropertyCannotBeActivated()
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = typeof(ControllerThatCannotBeActivated).GetTypeInfo()
};
var services = GetServices();
var httpContext = new DefaultHttpContext
{
RequestServices = services
};
var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
// Act and Assert
var exception = Assert.Throws<InvalidOperationException>(() => factory.CreateController(context));
Assert.Equal("The property 'Service' on controller '" + typeof(ControllerThatCannotBeActivated) +
"' cannot be activated.", exception.Message);
}
[Fact]
public void DefaultControllerFactory_DisposesIDisposableController()
{
// Arrange
var factory = new DefaultControllerFactory(Mock.Of<IControllerActivator>());
var controller = new MyController();
// Act + Assert
Assert.False(controller.Disposed);
factory.ReleaseController(controller);
Assert.True(controller.Disposed);
}
[Fact]
public void DefaultControllerFactory_ReleasesNonIDisposableController()
{
// Arrange
var factory = new DefaultControllerFactory(Mock.Of<IControllerActivator>());
var controller = new object();
// Act + Assert (does not throw)
factory.ReleaseController(controller);
}
private IServiceProvider GetServices()
{
var metadataProvider = new EmptyModelMetadataProvider();
var services = new Mock<IServiceProvider>();
services.Setup(s => s.GetService(typeof(IUrlHelper)))
.Returns(Mock.Of<IUrlHelper>());
services.Setup(s => s.GetService(typeof(IModelMetadataProvider)))
.Returns(metadataProvider);
services.Setup(s => s.GetService(typeof(TestService)))
.Returns(new TestService());
services.Setup(s => s.GetService(typeof(IObjectModelValidator)))
.Returns(new DefaultObjectValidator(Mock.Of<IValidationExcludeFiltersProvider>(), metadataProvider));
services
.Setup(s => s.GetService(typeof(IScopedInstance<ActionBindingContext>)))
.Returns(new MockScopedInstance<ActionBindingContext>());
services.Setup(s => s.GetService(typeof(ITempDataDictionary)))
.Returns(new Mock<ITempDataDictionary>().Object);
return services.Object;
}
private class ControllerWithActivateAndFromServices
{
[Activate]
public ActionContext ActionContext { get; set; }
[Activate]
public ActionBindingContext BindingContext { get; set; }
[Activate]
public HttpContext HttpContext { get; set; }
[Activate]
protected HttpRequest Request { get; set; }
[Activate]
private ViewDataDictionary ViewData { get; set; }
[FromServices]
public IUrlHelper Helper { get; set; }
[FromServices]
public TestService TestService { get; set; }
public HttpResponse Response { get; set; }
public ViewDataDictionary GetViewData()
{
return ViewData;
}
public HttpRequest GetHttpRequest()
{
return Request;
}
}
private class MyController : Controller
{
public bool Disposed { get; set; }
protected override void Dispose(bool disposing)
{
Disposed = true;
}
}
private class ControllerThatCannotBeActivated
{
[Activate]
public TestService Service { get; set; }
}
private class TestService
{
}
}
}