/Test/SystemWebMvcTest/Mvc/Test/ControllerActionInvokerTest.cs
C# | 2456 lines | 1785 code | 407 blank | 264 comment | 5 complexity | 4374b283754583dcd0ad6fd4d315596f MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- namespace System.Web.Mvc.Test {
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Threading;
- using System.Web.Mvc;
- using System.Web.Routing;
- using System.Web.TestUtil;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
- using Moq;
-
- [TestClass]
- [CLSCompliant(false)]
- public class ControllerActionInvokerTest {
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchConstructor() {
- // FindActionMethod() shouldn't match special-named methods like type constructors.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod(".ctor");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchEvent() {
- // FindActionMethod() should skip methods that aren't publicly visible.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("add_Event");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchInternalMethod() {
- // FindActionMethod() should skip methods that aren't publicly visible.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("InternalMethod");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchMethodsDefinedOnControllerType() {
- // FindActionMethod() shouldn't match methods originally defined on the Controller type, e.g. Dispose().
-
- // Arrange
- var controller = new BlankController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- var methods = typeof(Controller).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
-
- // Act & Assert
- foreach (var method in methods) {
- bool wasFound = true;
- try {
- MethodInfo mi = helper.PublicFindActionMethod(method.Name);
- wasFound = (mi != null);
- }
- finally {
- Assert.IsFalse(wasFound, "FindActionMethod() should return false for methods defined on the Controller class: " + method);
- }
- }
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchMethodsDefinedOnObjectType() {
- // FindActionMethod() shouldn't match methods originally defined on the Object type, e.g. ToString().
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("ToString");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchNonActionMethod() {
- // FindActionMethod() should respect the [NonAction] attribute.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("NonActionMethod");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchOverriddenNonActionMethod() {
- // FindActionMethod() should trace the method's inheritance chain looking for the [NonAction] attribute.
-
- // Arrange
- var controller = new DerivedFindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("NonActionMethod");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchPrivateMethod() {
- // FindActionMethod() should skip methods that aren't publicly visible.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("PrivateMethod");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchProperty() {
- // FindActionMethod() shouldn't match special-named methods like property getters.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("get_Property");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodDoesNotMatchProtectedMethod() {
- // FindActionMethod() should skip methods that aren't publicly visible.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("ProtectedMethod");
-
- // Assert
- Assert.IsNull(mi);
- }
-
- [TestMethod]
- public void FindActionMethodIsCaseInsensitive() {
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo expected = typeof(FindMethodController).GetMethod("ValidActionMethod");
-
- // Act
- MethodInfo mi1 = helper.PublicFindActionMethod("validactionmethod");
- MethodInfo mi2 = helper.PublicFindActionMethod("VALIDACTIONMETHOD");
-
- // Assert
- Assert.AreEqual(expected, mi1);
- Assert.AreEqual(expected, mi2);
- }
-
- [TestMethod]
- public void FindActionMethodMatchesNewActionMethodsHidingNonActionMethods() {
- // FindActionMethod() should stop looking for [NonAction] in the method's inheritance chain when it sees
- // that a method in a derived class hides the a method in the base class.
-
- // Arrange
- var controller = new DerivedFindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo expected = typeof(DerivedFindMethodController).GetMethod("DerivedIsActionMethod");
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("DerivedIsActionMethod");
-
- // Assert
- Assert.AreEqual(expected, mi);
- }
-
- [TestMethod]
- public void FindActionMethodWithClosedGenerics() {
- // FindActionMethod() should work with generic methods as long as there are no open types.
-
- // Arrange
- var controller = new GenericFindMethodController<int>();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo expected = typeof(GenericFindMethodController<int>).GetMethod("ClosedGenericMethod");
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("ClosedGenericMethod");
-
- // Assert
- Assert.AreEqual(expected, mi);
- }
-
- [TestMethod]
- public void FindActionMethodWithEmptyActionNameThrows() {
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectArgumentExceptionNullOrEmpty(
- delegate {
- helper.PublicFindActionMethod(String.Empty);
- },
- "actionName");
- }
-
- [TestMethod]
- public void FindActionMethodWithNullActionNameThrows() {
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectArgumentExceptionNullOrEmpty(
- delegate {
- helper.PublicFindActionMethod(null /* actionName */);
- },
- "actionName");
- }
-
- [TestMethod]
- public void FindActionMethodWithOpenGenericsThrows() {
- // FindActionMethod() should throw if matching on a generic method with open types.
-
- // Arrange
- var controller = new GenericFindMethodController<int>();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectException<InvalidOperationException>(
- delegate {
- helper.PublicFindActionMethod("OpenGenericMethod");
- },
- "Cannot call action method 'System.Web.Mvc.ActionResult OpenGenericMethod[U](U)' since it is a generic method.");
- }
-
- [TestMethod]
- public void FindActionMethodWithOverloadsThrows() {
- // FindActionMethod() should throw if it encounters an overloaded method.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectException<InvalidOperationException>(
- delegate {
- helper.PublicFindActionMethod("MethodOverloaded");
- },
- @"The current request for action 'MethodOverloaded' on controller type 'FindMethodController' is ambiguous between the following action methods:
- System.Web.Mvc.ActionResult MethodOverloaded() on type System.Web.Mvc.Test.ControllerActionInvokerTest+FindMethodController
- System.Web.Mvc.ActionResult MethodOverloaded(System.String) on type System.Web.Mvc.Test.ControllerActionInvokerTest+FindMethodController");
- }
-
- [TestMethod]
- public void FindActionMethodWithValidMethod() {
- // Test basic functionality of FindActionMethod() by giving it a known good case.
-
- // Arrange
- var controller = new FindMethodController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo expected = typeof(FindMethodController).GetMethod("ValidActionMethod");
-
- // Act
- MethodInfo mi = helper.PublicFindActionMethod("ValidActionMethod");
-
- // Assert
- Assert.AreEqual(expected, mi);
- }
-
- [TestMethod]
- public void GetFiltersForActionMethod() {
- // Arrange
- ControllerBase controller = new GetMemberChainSubderivedController();
- ControllerContext context = GetControllerContext(controller);
- MethodInfo methodInfo = typeof(GetMemberChainSubderivedController).GetMethod("SomeVirtual");
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- var filters = helper.PublicGetFiltersForActionMethod(methodInfo);
-
- // Assert
- Assert.AreEqual(3, filters.AuthorizationFilters.Count, "Wrong number of authorization filters.");
- Assert.AreSame(controller, filters.AuthorizationFilters[0]);
- Assert.AreEqual("BaseClass", ((KeyedFilterAttribute)filters.AuthorizationFilters[1]).Key);
- Assert.AreEqual("BaseMethod", ((KeyedFilterAttribute)filters.AuthorizationFilters[2]).Key);
-
- Assert.AreEqual(6, filters.ActionFilters.Count, "Wrong number of action filters.");
- Assert.AreSame(controller, filters.ActionFilters[0]);
- Assert.AreEqual("BaseClass", ((KeyedFilterAttribute)filters.ActionFilters[1]).Key);
- Assert.AreEqual("BaseMethod", ((KeyedFilterAttribute)filters.ActionFilters[2]).Key);
- Assert.AreEqual("DerivedClass", ((KeyedFilterAttribute)filters.ActionFilters[3]).Key);
- Assert.AreEqual("SubderivedClass", ((KeyedFilterAttribute)filters.ActionFilters[4]).Key);
- Assert.AreEqual("SubderivedMethod", ((KeyedFilterAttribute)filters.ActionFilters[5]).Key);
-
- Assert.AreEqual(6, filters.ResultFilters.Count, "Wrong number of result filters.");
- Assert.AreSame(controller, filters.ResultFilters[0]);
- Assert.AreEqual("BaseClass", ((KeyedFilterAttribute)filters.ResultFilters[1]).Key);
- Assert.AreEqual("BaseMethod", ((KeyedFilterAttribute)filters.ResultFilters[2]).Key);
- Assert.AreEqual("DerivedClass", ((KeyedFilterAttribute)filters.ResultFilters[3]).Key);
- Assert.AreEqual("SubderivedClass", ((KeyedFilterAttribute)filters.ResultFilters[4]).Key);
- Assert.AreEqual("SubderivedMethod", ((KeyedFilterAttribute)filters.ResultFilters[5]).Key);
-
- Assert.AreEqual(1, filters.ExceptionFilters.Count, "Wrong number of exception filters.");
- Assert.AreSame(controller, filters.ExceptionFilters[0]);
- }
-
- [TestMethod]
- public void GetFiltersForActionMethodGetsDerivedClassFiltersForBaseClassMethod() {
- // DevDiv 208062: Action filters specified on derived class won't run if the action method is on a base class
-
- // Arrange
- ControllerBase controller = new GetMemberChainDerivedController();
- ControllerContext context = GetControllerContext(controller);
- MethodInfo methodInfo = typeof(GetMemberChainDerivedController).GetMethod("SomeVirtual");
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- var filters = helper.PublicGetFiltersForActionMethod(methodInfo);
-
- // Assert
- Assert.AreEqual(3, filters.AuthorizationFilters.Count, "Wrong number of authorization filters.");
- Assert.AreSame(controller, filters.AuthorizationFilters[0]);
- Assert.AreEqual("BaseClass", ((KeyedFilterAttribute)filters.AuthorizationFilters[1]).Key);
- Assert.AreEqual("BaseMethod", ((KeyedFilterAttribute)filters.AuthorizationFilters[2]).Key);
-
- Assert.AreEqual(4, filters.ActionFilters.Count, "Wrong number of action filters.");
- Assert.AreSame(controller, filters.ActionFilters[0]);
- Assert.AreEqual("BaseClass", ((KeyedFilterAttribute)filters.ActionFilters[1]).Key);
- Assert.AreEqual("BaseMethod", ((KeyedFilterAttribute)filters.ActionFilters[2]).Key);
- Assert.AreEqual("DerivedClass", ((KeyedFilterAttribute)filters.ActionFilters[3]).Key);
-
- Assert.AreEqual(4, filters.ResultFilters.Count, "Wrong number of result filters.");
- Assert.AreSame(controller, filters.ResultFilters[0]);
- Assert.AreEqual("BaseClass", ((KeyedFilterAttribute)filters.ResultFilters[1]).Key);
- Assert.AreEqual("BaseMethod", ((KeyedFilterAttribute)filters.ResultFilters[2]).Key);
- Assert.AreEqual("DerivedClass", ((KeyedFilterAttribute)filters.ResultFilters[3]).Key);
-
- Assert.AreEqual(1, filters.ExceptionFilters.Count, "Wrong number of exception filters.");
- Assert.AreSame(controller, filters.ExceptionFilters[0]);
- }
-
- [TestMethod]
- public void GetFiltersForActionMethodWithNullMethodInfoThrows() {
- // Arrange
- ControllerBase controller = new GetMemberChainSubderivedController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectArgumentNullException(
- delegate {
- helper.PublicGetFiltersForActionMethod(null /* methodInfo */);
- }, "methodInfo");
- }
-
- [TestMethod]
- public void GetParameterValueAllowsAllSubpropertiesIfBindAttributeNotSpecified() {
- // Arrange
- CustomConverterController controller = new CustomConverterController() { ValueProvider = new Mock<IValueProvider>().Object };
- ControllerContext controllerContext = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithoutBindAttribute = typeof(CustomConverterController).GetMethod("ParameterWithoutBindAttribute").GetParameters()[0];
-
- // Act
- object valueWithoutBindAttribute = helper.PublicGetParameterValue(paramWithoutBindAttribute);
-
- // Assert
- Assert.AreEqual("foo=True&bar=True", valueWithoutBindAttribute);
- }
-
- [TestMethod]
- public void GetParameterValueResolvesConvertersInCorrectOrderOfPrecedence() {
- // Order of precedence:
- // 1. Attributes on the parameter itself
- // 2. Query the global converter provider
-
- // Arrange
- CustomConverterController controller = new CustomConverterController();
- Dictionary<string, object> values = new Dictionary<string, object> { { "foo", "fooValue" } };
- ControllerContext controllerContext = GetControllerContext(controller, values);
- controller.ControllerContext = controllerContext;
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithOneConverter = typeof(CustomConverterController).GetMethod("ParameterHasOneConverter").GetParameters()[0];
- ParameterInfo paramWithNoConverters = typeof(CustomConverterController).GetMethod("ParameterHasNoConverters").GetParameters()[0];
-
- // Act
- object valueWithOneConverter = helper.PublicGetParameterValue(paramWithOneConverter);
- object valueWithNoConverters = helper.PublicGetParameterValue(paramWithNoConverters);
-
- // Assert
- Assert.AreEqual("foo_String", valueWithOneConverter);
- Assert.AreEqual("fooValue", valueWithNoConverters);
- }
-
- [TestMethod]
- public void GetParameterValueRespectsBindAttribute() {
- // Arrange
- CustomConverterController controller = new CustomConverterController() { ValueProvider = new Mock<IValueProvider>().Object };
- ControllerContext controllerContext = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithBindAttribute = typeof(CustomConverterController).GetMethod("ParameterHasBindAttribute").GetParameters()[0];
-
- // Act
- object valueWithBindAttribute = helper.PublicGetParameterValue(paramWithBindAttribute);
-
- // Assert
- Assert.AreEqual("foo=True&bar=False", valueWithBindAttribute);
- }
-
- [TestMethod]
- public void GetParameterValueRespectsBindAttributePrefix() {
- // Arrange
- CustomConverterController controller = new CustomConverterController();
- Dictionary<string, object> values = new Dictionary<string, object> { { "foo", "fooValue" }, { "bar", "barValue" } };
- ControllerContext controllerContext = GetControllerContext(controller, values);
- controller.ControllerContext = controllerContext;
-
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithFieldPrefix = typeof(CustomConverterController).GetMethod("ParameterHasFieldPrefix").GetParameters()[0];
-
- // Act
- object parameterValue = helper.PublicGetParameterValue(paramWithFieldPrefix);
-
- // Assert
- Assert.AreEqual("barValue", parameterValue);
- }
-
- [TestMethod]
- public void GetParameterValueRespectsBindAttributeNullPrefix() {
- // Arrange
- CustomConverterController controller = new CustomConverterController();
- Dictionary<string, object> values = new Dictionary<string, object> { { "foo", "fooValue" }, { "bar", "barValue" } };
- ControllerContext controllerContext = GetControllerContext(controller, values);
- controller.ControllerContext = controllerContext;
-
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithFieldPrefix = typeof(CustomConverterController).GetMethod("ParameterHasNullFieldPrefix").GetParameters()[0];
-
- // Act
- object parameterValue = helper.PublicGetParameterValue(paramWithFieldPrefix);
-
- // Assert
- Assert.AreEqual("fooValue", parameterValue);
- }
-
- [TestMethod]
- public void GetParameterValueRespectsBindAttributeEmptyPrefix() {
- // Arrange
- CustomConverterController controller = new CustomConverterController();
- Dictionary<string, object> values = new Dictionary<string, object> { { "foo", "fooValue" }, { "bar", "barValue" }, { "intprop", "123" }, { "stringprop", "hello" } };
- ControllerContext controllerContext = GetControllerContext(controller, values);
- controller.ControllerContext = controllerContext;
-
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithFieldPrefix = typeof(CustomConverterController).GetMethod("ParameterHasEmptyFieldPrefix").GetParameters()[0];
-
- // Act
- MySimpleModel parameterValue = helper.PublicGetParameterValue(paramWithFieldPrefix) as MySimpleModel;
-
- // Assert
- Assert.IsNotNull(parameterValue);
- Assert.AreEqual<int>(123, parameterValue.IntProp);
- Assert.AreEqual<string>("hello", parameterValue.StringProp);
- }
-
- [TestMethod]
- public void GetParameterValueReturnsNullIfCannotConvertNonRequiredParameter() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- controller.ControllerContext = context;
-
- Dictionary<string, object> dict = new Dictionary<string, object>() {
- { "id", DateTime.Now } // cannot convert DateTime to Nullable<int>
- };
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("TakesNullableInt");
- ParameterInfo[] pis = mi.GetParameters();
-
- // Act
- object oValue = helper.PublicGetParameterValue(pis[0]);
-
- // Assert
- Assert.IsNull(oValue);
- }
-
- [TestMethod]
- public void GetParameterValueReturnsNullIfNullableTypeValueNotFound() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- controller.ControllerContext = context;
-
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("TakesNullableInt");
- ParameterInfo[] pis = mi.GetParameters();
-
- // Act
- object oValue = helper.PublicGetParameterValue(pis[0]);
-
- // Assert
- Assert.IsNull(oValue);
- }
-
- [TestMethod]
- public void GetParameterValueReturnsNullIfReferenceTypeValueNotFound() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- controller.ControllerContext = context;
-
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("Foo");
- ParameterInfo[] pis = mi.GetParameters();
-
- // Act
- object oValue = helper.PublicGetParameterValue(pis[0]);
-
- // Assert
- Assert.IsNull(oValue);
- }
-
- [TestMethod]
- public void GetParameterValuesCallsGetParameterValue() {
- // Arrange
- ControllerBase controller = new ParameterTestingController();
- IDictionary<string, object> dict = new Dictionary<string, object>();
- ControllerContext context = GetControllerContext(controller);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("Foo");
- ParameterInfo[] pis = mi.GetParameters();
-
- Mock<ControllerActionInvokerHelper> mockHelper = new Mock<ControllerActionInvokerHelper>(context);
- mockHelper.CallBase = true;
- mockHelper.Expect(h => h.PublicGetParameterValue(pis[0])).Returns("Myfoo").Verifiable();
- mockHelper.Expect(h => h.PublicGetParameterValue(pis[1])).Returns("Mybar").Verifiable();
- mockHelper.Expect(h => h.PublicGetParameterValue(pis[2])).Returns("Mybaz").Verifiable();
- ControllerActionInvokerHelper helper = mockHelper.Object;
-
- // Act
- IDictionary<string, object> parameters = helper.PublicGetParameterValues(mi);
-
- // Assert
- Assert.AreEqual(3, parameters.Count);
- Assert.AreEqual("Myfoo", parameters["foo"]);
- Assert.AreEqual("Mybar", parameters["bar"]);
- Assert.AreEqual("Mybaz", parameters["baz"]);
- mockHelper.Verify();
- }
-
- [TestMethod]
- public void GetParameterValuesReturnsEmptyArrayForParameterlessMethod() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("Parameterless");
-
- // Act
- IDictionary<string, object> parameters = helper.PublicGetParameterValues(mi);
-
- // Assert
- Assert.AreEqual(0, parameters.Count);
- }
-
- [TestMethod]
- public void GetParameterValuesReturnsValuesForParametersInOrder() {
- // We need to hook into GetParameterValue() to make sure that GetParameterValues() is calling it.
-
- // Arrange
- var controller = new ParameterTestingController();
- Dictionary<string, object> dict = new Dictionary<string, object>() {
- { "foo", "MyFoo" },
- { "bar", "MyBar" },
- { "baz", "MyBaz" }
- };
- ControllerContext context = GetControllerContext(controller, dict);
- controller.ControllerContext = context;
-
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("Foo");
-
- // Act
- IDictionary<string, object> parameters = helper.PublicGetParameterValues(mi);
-
- // Assert
- Assert.AreEqual(3, parameters.Count);
- Assert.AreEqual("MyFoo", parameters["foo"]);
- Assert.AreEqual("MyBar", parameters["bar"]);
- Assert.AreEqual("MyBaz", parameters["baz"]);
- }
-
- [TestMethod]
- public void GetParameterValuesWithNullMethodInfoThrows() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectArgumentNullException(
- delegate {
- helper.PublicGetParameterValues(null /* methodInfo */);
- },
- "methodInfo");
- }
-
- [TestMethod]
- public void GetParameterValuesWithOutParamThrows() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("HasOutParam");
-
- // Act & Assert
- ExceptionHelper.ExpectException<InvalidOperationException>(
- delegate {
- helper.PublicGetParameterValues(mi);
- },
- "Cannot set value for parameter 'foo' in action 'HasOutParam'. Parameters passed by reference are not supported in action methods.");
- }
-
- [TestMethod]
- public void GetParameterValuesWithRefParamThrows() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("HasRefParam");
-
- // Act & Assert
- ExceptionHelper.ExpectException<InvalidOperationException>(
- delegate {
- helper.PublicGetParameterValues(mi);
- },
- "Cannot set value for parameter 'foo' in action 'HasRefParam'. Parameters passed by reference are not supported in action methods.");
- }
-
- // TODO: This test is temporarily disabled now that converters can update ModelState. We should consider reenabling
- // this if invalid inputs to action methods become problematic.
- public void GetParameterValueThrowsIfCannotConvertRequiredParameter() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
- MethodInfo mi = typeof(ParameterTestingController).GetMethod("TakesInt");
- ParameterInfo[] pis = mi.GetParameters();
-
- // Act & Assert
- ExceptionHelper.ExpectInvalidOperationException(
- delegate {
- helper.PublicGetParameterValue(pis[0]);
- },
- "A value is required for parameter 'id' in action 'TakesInt'. The parameter either has no value or its value could"
- + " not be converted. To make a parameter optional its type should either be a reference type or a Nullable type.");
- }
-
- [TestMethod]
- public void GetParameterValueThrowsIfParameterHasMultipleConverters() {
- // Arrange
- CustomConverterController controller = new CustomConverterController();
- ControllerContext controllerContext = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo paramWithTwoConverters = typeof(CustomConverterController).GetMethod("ParameterHasTwoConverters").GetParameters()[0];
-
- // Act & Assert
- ExceptionHelper.ExpectInvalidOperationException(
- delegate {
- helper.PublicGetParameterValue(paramWithTwoConverters);
- },
- "The parameter 'foo' on method 'ParameterHasTwoConverters' contains multiple attributes inheriting from CustomModelBinderAttribute.");
- }
-
- [TestMethod]
- public void GetParameterValueUsesControllerValueProviderAsValueProvider() {
- // Arrange
- Mock<IValueProvider> mockValueProvider = new Mock<IValueProvider>();
- mockValueProvider.Expect(p => p.GetValue("foo")).Returns(new ValueProviderResult("fooValue", "fooValue", null));
-
- CustomConverterController controller = new CustomConverterController() { ValueProvider = mockValueProvider.Object };
- ControllerContext controllerContext = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(controllerContext);
-
- ParameterInfo parameter = typeof(CustomConverterController).GetMethod("ParameterHasNoConverters").GetParameters()[0];
-
- // Act
- object parameterValue = helper.PublicGetParameterValue(parameter);
-
- // Assert
- Assert.AreEqual("fooValue", parameterValue);
- }
-
- [TestMethod]
- public void GetParameterValueWithNullParameterInfoThrows() {
- // Arrange
- var controller = new ParameterTestingController();
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act & Assert
- ExceptionHelper.ExpectArgumentNullException(
- delegate {
- helper.PublicGetParameterValue(null /* parameterInfo */);
- },
- "parameterInfo");
- }
-
- [TestMethod]
- public void InvokeAction() {
- // Arrange
- ControllerBase controller = new Mock<ControllerBase>().Object;
- ControllerContext context = GetControllerContext(controller);
- IDictionary<string, object> paramValues = new Dictionary<string, object>();
- MethodInfo methodInfo = typeof(object).GetMethod("ToString");
- var filterInfo = new FilterInfo();
- ActionResult actionResult = new EmptyResult();
- ActionExecutedContext postContext = new ActionExecutedContext(context, false /* canceled */, null /* exception */) {
- Result = actionResult
- };
- AuthorizationContext authContext = new AuthorizationContext(context);
-
- Mock<ControllerActionInvokerHelper> mockHelper = new Mock<ControllerActionInvokerHelper>();
- mockHelper.CallBase = true;
- mockHelper.Expect(h => h.PublicFindActionMethod("SomeMethod")).Returns(methodInfo).Verifiable();
- mockHelper.Expect(h => h.PublicGetParameterValues(methodInfo)).Returns(paramValues).Verifiable();
- mockHelper.Expect(h => h.PublicGetFiltersForActionMethod(methodInfo)).Returns(filterInfo).Verifiable();
- mockHelper.Expect(h => h.PublicInvokeAuthorizationFilters(methodInfo, filterInfo.AuthorizationFilters)).Returns(authContext).Verifiable();
- mockHelper.Expect(h => h.PublicInvokeActionMethodWithFilters(methodInfo, paramValues, filterInfo.ActionFilters)).Returns(postContext).Verifiable();
- mockHelper.Expect(h => h.PublicInvokeActionResultWithFilters(actionResult, filterInfo.ResultFilters)).Returns((ResultExecutedContext)null).Verifiable();
- ControllerActionInvokerHelper helper = mockHelper.Object;
-
- // Act
- bool retVal = helper.InvokeAction(context, "SomeMethod");
- Assert.IsTrue(retVal, "InvokeAction() should return True on success.");
- Assert.AreSame(context, helper.ControllerContext, "ControllerContext property should have been set by InvokeAction");
- mockHelper.Verify();
- }
-
- [TestMethod]
- public void InvokeActionFiltersOrdersFiltersCorrectly() {
- // Arrange
- List<string> actions = new List<string>();
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- ActionResult actionResult = new EmptyResult();
- ActionFilterImpl filter1 = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- actions.Add("OnActionExecuting1");
- },
- OnActionExecutedImpl = delegate(ActionExecutedContext filterContext) {
- actions.Add("OnActionExecuted1");
- }
- };
- ActionFilterImpl filter2 = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- actions.Add("OnActionExecuting2");
- },
- OnActionExecutedImpl = delegate(ActionExecutedContext filterContext) {
- actions.Add("OnActionExecuted2");
- }
- };
- Func<ActionResult> continuation = delegate {
- actions.Add("Continuation");
- return new EmptyResult();
- };
- ControllerBase controller = new ContinuationController(continuation);
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- helper.PublicInvokeActionMethodWithFilters(ContinuationController.GoMethod, parameters,
- new List<IActionFilter>() { filter1, filter2 });
-
- // Assert
- Assert.AreEqual(5, actions.Count);
- Assert.AreEqual("OnActionExecuting1", actions[0]);
- Assert.AreEqual("OnActionExecuting2", actions[1]);
- Assert.AreEqual("Continuation", actions[2]);
- Assert.AreEqual("OnActionExecuted2", actions[3]);
- Assert.AreEqual("OnActionExecuted1", actions[4]);
- }
-
- [TestMethod]
- public void InvokeActionFiltersPassesArgumentsCorrectly() {
- // Arrange
- bool wasCalled = false;
- MethodInfo mi = ContinuationController.GoMethod;
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- ActionResult actionResult = new EmptyResult();
- ActionFilterImpl filter = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- Assert.AreSame(parameters, filterContext.ActionParameters);
- Assert.IsFalse(wasCalled);
- wasCalled = true;
- filterContext.Result = actionResult;
- }
- };
- Func<ActionResult> continuation = delegate {
- Assert.Fail("Continuation should not be called.");
- return null;
- };
- ControllerBase controller = new ContinuationController(continuation);
- ControllerContext context = GetControllerContext(controller);
- ControllerActionInvokerHelper helper = new ControllerActionInvokerHelper(context);
-
- // Act
- ActionExecutedContext result = helper.PublicInvokeActionMethodWithFilters(mi, parameters,
- new List<IActionFilter>() { filter });
-
- // Assert
- Assert.IsTrue(wasCalled);
- Assert.IsNull(result.Exception);
- Assert.IsFalse(result.ExceptionHandled);
- Assert.AreSame(actionResult, result.Result);
- }
-
- [TestMethod]
- public void InvokeActionFilterWhereContinuationThrowsExceptionAndIsHandled() {
- // Arrange
- List<string> actions = new List<string>();
- MethodInfo mi = typeof(object).GetMethod("ToString");
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- Exception exception = new Exception();
- ActionFilterImpl filter = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- actions.Add("OnActionExecuting");
- },
- OnActionExecutedImpl = delegate(ActionExecutedContext filterContext) {
- actions.Add("OnActionExecuted");
- Assert.AreSame(exception, filterContext.Exception);
- Assert.IsFalse(filterContext.ExceptionHandled);
- filterContext.ExceptionHandled = true;
- }
- };
- Func<ActionExecutedContext> continuation = delegate {
- actions.Add("Continuation");
- throw exception;
- };
-
- // Act
- ActionExecutedContext result = ControllerActionInvoker.InvokeActionMethodFilter(filter, new ActionExecutingContext(ControllerContextTest.GetControllerContext(), parameters), continuation);
-
- // Assert
- Assert.AreEqual(3, actions.Count);
- Assert.AreEqual("OnActionExecuting", actions[0]);
- Assert.AreEqual("Continuation", actions[1]);
- Assert.AreEqual("OnActionExecuted", actions[2]);
- Assert.AreSame(exception, result.Exception);
- Assert.IsTrue(result.ExceptionHandled);
- }
-
- [TestMethod]
- public void InvokeActionFilterWhereContinuationThrowsExceptionAndIsNotHandled() {
- // Arrange
- List<string> actions = new List<string>();
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- ActionFilterImpl filter = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- actions.Add("OnActionExecuting");
- },
- OnActionExecutedImpl = delegate(ActionExecutedContext filterContext) {
- actions.Add("OnActionExecuted");
- }
- };
- Func<ActionExecutedContext> continuation = delegate {
- actions.Add("Continuation");
- throw new Exception("Some exception message.");
- };
-
- // Act & Assert
- ExceptionHelper.ExpectException<Exception>(
- delegate {
- ControllerActionInvoker.InvokeActionMethodFilter(filter, new ActionExecutingContext(ControllerContextTest.GetControllerContext(), parameters), continuation);
- },
- "Some exception message.");
- Assert.AreEqual(3, actions.Count);
- Assert.AreEqual("OnActionExecuting", actions[0]);
- Assert.AreEqual("Continuation", actions[1]);
- Assert.AreEqual("OnActionExecuted", actions[2]);
- }
-
- [TestMethod]
- public void InvokeActionFilterWhereOnActionExecutingCancels() {
- // Arrange
- bool wasCalled = false;
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- ActionExecutedContext postContext = new ActionExecutedContext(ControllerContextTest.GetControllerContext(), false /* canceled */, null /* exception */);
- ActionResult actionResult = new EmptyResult();
- ActionFilterImpl filter = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- Assert.IsFalse(wasCalled);
- wasCalled = true;
- filterContext.Result = actionResult;
- },
- };
- Func<ActionExecutedContext> continuation = delegate {
- Assert.Fail("The continuation should not be called.");
- return null;
- };
-
- // Act
- ActionExecutedContext result = ControllerActionInvoker.InvokeActionMethodFilter(filter, new ActionExecutingContext(ControllerContextTest.GetControllerContext(), parameters), continuation);
-
- // Assert
- Assert.IsTrue(wasCalled);
- Assert.IsNull(result.Exception);
- Assert.IsTrue(result.Canceled);
- Assert.AreSame(actionResult, result.Result);
- }
-
- [TestMethod]
- public void InvokeActionFilterWithNormalControlFlow() {
- // Arrange
- List<string> actions = new List<string>();
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- ActionExecutedContext postContext = new ActionExecutedContext(ControllerContextTest.GetControllerContext(), false /* canceled */, null /* exception */);
- ActionFilterImpl filter = new ActionFilterImpl() {
- OnActionExecutingImpl = delegate(ActionExecutingContext filterContext) {
- Assert.AreSame(parameters, filterContext.ActionParameters);
- Assert.IsNull(filterContext.Result);
- actions.Add("OnActionExecuting");
- },
- OnActionExecutedImpl = delegate(ActionExecutedContext filterContext) {
- Assert.AreEqual(postContext, filterContext);
- actions.Add("OnActionExecuted");
- }
- };
- Func<ActionExecutedContext> continuation = delegate {
- actions.Add("Continuation");
- return postContext;
- };
-
- // Act
- ActionExecutedContext result = ControllerActionInvoker.InvokeActionMethodFilter(filter, new ActionExecutingContext(ControllerContextTest.GetControllerContext(), parameters), continuation);
-
- // Assert
- Assert.AreEqual(3, actions.Count);
- Assert.AreEqual("OnActionExecuting", actions[0]);
- Assert.AreEqual("Continuation", actions[1]);
- Assert.AreEqual("OnActionExecuted", actions[2]);
- Assert.AreSame(result, postContext);
- }
-
- [TestMethod]
- public void InvokeActionInvokesEmptyResultIfAuthorizationFailsAndNoResultSpecified() {
- // Arrange
- ControllerBase controller = new Mock<ControllerBase>().Object;
- ControllerContext context = GetControllerContext(controller);
- IDictionary<string, object> values = new Dictionary<string, object>();
- IDictionary<string, object> paramValues = new Dictionary<string, object>();
- MethodInfo methodInfo = typeof(object).GetMethod("ToString");
- var filterInfo = new FilterInfo();
- ActionResult actionResult = new EmptyResult();
- ActionExecutedContext postContext = new ActionExecutedContext(context, false /* canceled */, null /* exception */) {
- Result = actionResult
- };
- AuthorizationContext authContext = new AuthorizationContext(context) { Cancel = true };
-
- Mock<ControllerActionInvokerHelper> mockHelper = new Mock<ControllerActionInvokerHelper>();
- mockHelper.CallBase = true;
- mockHelper.Expect(h => h.PublicFindActionMethod("SomeMethod")).Returns(methodInfo).Verifiable();
- mockHelper.Expect(h => h.PublicGetParameterValues(methodInfo)).Returns(paramValues).Verifiable()…
Large files files are truncated, but you can click here to view the full file