Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,216 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AcceptVerbsAttributeTest
{
private const string _invalidEnumFormatString = @"The enum '{0}' did not produce the correct array.
Expected: {1}
Actual: {2}";
[Fact]
public void ConstructorThrowsIfVerbsIsEmpty()
{
// Act & Assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new AcceptVerbsAttribute(new string[0]); }, "verbs");
}
[Fact]
public void ConstructorThrowsIfVerbsIsNull()
{
// Act & Assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new AcceptVerbsAttribute((string[])null); }, "verbs");
}
[Fact]
public void EnumToArray()
{
// Arrange
IDictionary<string, HttpVerbs> enumValues = EnumToDictionary<HttpVerbs>();
var allCombinations = EnumerableToCombinations(enumValues);
// Act & assert
foreach (var combination in allCombinations)
{
// generate all the names + values in this combination
List<string> aggrNames = new List<string>();
HttpVerbs aggrValues = (HttpVerbs)0;
foreach (var entry in combination)
{
aggrNames.Add(entry.Key);
aggrValues |= entry.Value;
}
// get the resulting array
string[] array = AcceptVerbsAttribute.EnumToArray(aggrValues);
var aggrNamesOrdered = aggrNames.OrderBy(name => name, StringComparer.OrdinalIgnoreCase);
var arrayOrdered = array.OrderBy(name => name, StringComparer.OrdinalIgnoreCase);
bool match = aggrNamesOrdered.SequenceEqual(arrayOrdered, StringComparer.OrdinalIgnoreCase);
if (!match)
{
string message = String.Format(_invalidEnumFormatString, aggrValues,
aggrNames.Aggregate((a, b) => a + ", " + b),
array.Aggregate((a, b) => a + ", " + b));
Assert.True(false, message);
}
}
}
[Fact]
public void IsValidForRequestReturnsFalseIfHttpVerbIsNotInVerbsCollection()
{
// Arrange
AcceptVerbsAttribute attr = new AcceptVerbsAttribute("get", "post");
ControllerContext context = GetControllerContextWithHttpVerb("HEAD");
// Act
bool result = attr.IsValidForRequest(context, null);
// Assert
Assert.False(result);
}
[Fact]
public void IsValidForRequestReturnsTrueIfHttpVerbIsInVerbsCollection()
{
// Arrange
AcceptVerbsAttribute attr = new AcceptVerbsAttribute("get", "post");
ControllerContext context = GetControllerContextWithHttpVerb("POST");
// Act
bool result = attr.IsValidForRequest(context, null);
// Assert
Assert.True(result);
}
[Fact]
public void IsValidForRequestReturnsTrueIfHttpVerbIsOverridden()
{
// Arrange
AcceptVerbsAttribute attr = new AcceptVerbsAttribute("put");
ControllerContext context = GetControllerContextWithHttpVerb("POST", "PUT", null, null);
// Act
bool result = attr.IsValidForRequest(context, null);
// Assert
Assert.True(result);
}
[Fact]
public void IsValidForRequestThrowsIfControllerContextIsNull()
{
// Arrange
AcceptVerbsAttribute attr = new AcceptVerbsAttribute("get", "post");
// Act & Assert
Assert.ThrowsArgumentNull(
delegate { attr.IsValidForRequest(null, null); }, "controllerContext");
}
[Fact]
public void VerbsPropertyFromEnumConstructor()
{
// Arrange
AcceptVerbsAttribute attr = new AcceptVerbsAttribute(HttpVerbs.Get | HttpVerbs.Post);
// Act
ReadOnlyCollection<string> collection = attr.Verbs as ReadOnlyCollection<string>;
// Assert
Assert.NotNull(collection);
Assert.Equal(2, collection.Count);
Assert.Equal("GET", collection[0]);
Assert.Equal("POST", collection[1]);
}
[Fact]
public void VerbsPropertyFromStringArrayConstructor()
{
// Arrange
AcceptVerbsAttribute attr = new AcceptVerbsAttribute("get", "post");
// Act
ReadOnlyCollection<string> collection = attr.Verbs as ReadOnlyCollection<string>;
// Assert
Assert.NotNull(collection);
Assert.Equal(2, collection.Count);
Assert.Equal("get", collection[0]);
Assert.Equal("post", collection[1]);
}
internal static ControllerContext GetControllerContextWithHttpVerb(string httpRequestVerb)
{
return GetControllerContextWithHttpVerb(httpRequestVerb, null, null, null);
}
internal static ControllerContext GetControllerContextWithHttpVerb(string httpRequestVerb, string httpHeaderVerb, string httpFormVerb, string httpQueryStringVerb)
{
Mock<ControllerContext> mockControllerContext = new Mock<ControllerContext>();
mockControllerContext.Setup(c => c.HttpContext.Request.HttpMethod).Returns(httpRequestVerb);
NameValueCollection headers = new NameValueCollection();
if (!String.IsNullOrEmpty(httpHeaderVerb))
{
headers.Add(HttpRequestExtensions.XHttpMethodOverrideKey, httpHeaderVerb);
}
mockControllerContext.Setup(c => c.HttpContext.Request.Headers).Returns(headers);
NameValueCollection form = new NameValueCollection();
if (!String.IsNullOrEmpty(httpFormVerb))
{
form.Add(HttpRequestExtensions.XHttpMethodOverrideKey, httpFormVerb);
}
mockControllerContext.Setup(c => c.HttpContext.Request.Form).Returns(form);
NameValueCollection queryString = new NameValueCollection();
if (!String.IsNullOrEmpty(httpQueryStringVerb))
{
queryString.Add(HttpRequestExtensions.XHttpMethodOverrideKey, httpQueryStringVerb);
}
mockControllerContext.Setup(c => c.HttpContext.Request.QueryString).Returns(queryString);
return mockControllerContext.Object;
}
private static IDictionary<string, TEnum> EnumToDictionary<TEnum>()
{
// Arrange
var values = Enum.GetValues(typeof(TEnum)).Cast<TEnum>();
return values.ToDictionary(value => Enum.GetName(typeof(TEnum), value), value => value);
}
private static IEnumerable<ICollection<T>> EnumerableToCombinations<T>(IEnumerable<T> elements)
{
List<T> allElements = elements.ToList();
int maxCount = 1 << allElements.Count;
for (int idxCombination = 0; idxCombination < maxCount; idxCombination++)
{
List<T> thisCollection = new List<T>();
for (int idxBit = 0; idxBit < 32; idxBit++)
{
bool bitActive = (((uint)idxCombination >> idxBit) & 1) != 0;
if (bitActive)
{
thisCollection.Add(allElements[idxBit]);
}
}
yield return thisCollection;
}
}
}
}

View File

@@ -0,0 +1,282 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ActionDescriptorTest
{
[Fact]
public void ExtractParameterOrDefaultFromDictionary_ReturnsDefaultParameterValueIfMismatch()
{
// Arrange
Dictionary<string, object> dictionary = new Dictionary<string, object>()
{
{ "stringParameterWithDefaultValue", 42 }
};
// Act
object value = ActionDescriptor.ExtractParameterOrDefaultFromDictionary(ParameterExtractionController.StringParameterWithDefaultValue, dictionary);
// Assert
Assert.Equal("hello", value);
}
[Fact]
public void ExtractParameterOrDefaultFromDictionary_ReturnsDefaultTypeValueIfNoMatchAndNoDefaultParameterValue()
{
// Arrange
Dictionary<string, object> dictionary = new Dictionary<string, object>();
// Act
object value = ActionDescriptor.ExtractParameterOrDefaultFromDictionary(ParameterExtractionController.IntParameter, dictionary);
// Assert
Assert.Equal(0, value);
}
[Fact]
public void ExtractParameterOrDefaultFromDictionary_ReturnsDictionaryValueIfTypeMatch()
{
// Arrange
Dictionary<string, object> dictionary = new Dictionary<string, object>()
{
{ "stringParameterNoDefaultValue", "someValue" }
};
// Act
object value = ActionDescriptor.ExtractParameterOrDefaultFromDictionary(ParameterExtractionController.StringParameterNoDefaultValue, dictionary);
// Assert
Assert.Equal("someValue", value);
}
[Fact]
public void GetCustomAttributesReturnsEmptyArrayOfAttributeType()
{
// Arrange
ActionDescriptor ad = GetActionDescriptor();
// Act
ObsoleteAttribute[] attrs = (ObsoleteAttribute[])ad.GetCustomAttributes(typeof(ObsoleteAttribute), true);
// Assert
Assert.Empty(attrs);
}
[Fact]
public void GetCustomAttributesThrowsIfAttributeTypeIsNull()
{
// Arrange
ActionDescriptor ad = GetActionDescriptor();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { ad.GetCustomAttributes(null /* attributeType */, true); }, "attributeType");
}
[Fact]
public void GetCustomAttributesWithoutAttributeTypeCallsGetCustomAttributesWithAttributeType()
{
// Arrange
object[] expected = new object[0];
Mock<ActionDescriptor> mockDescriptor = new Mock<ActionDescriptor>() { CallBase = true };
mockDescriptor.Setup(d => d.GetCustomAttributes(typeof(object), true)).Returns(expected);
ActionDescriptor ad = mockDescriptor.Object;
// Act
object[] returned = ad.GetCustomAttributes(true /* inherit */);
// Assert
Assert.Same(expected, returned);
}
[Fact]
public void GetFilterAttributes_CallsGetCustomAttributes()
{
// Arrange
var mockDescriptor = new Mock<ActionDescriptor>() { CallBase = true };
mockDescriptor.Setup(d => d.GetCustomAttributes(typeof(FilterAttribute), true)).Returns(new object[] { new Mock<FilterAttribute>().Object }).Verifiable();
// Act
var result = mockDescriptor.Object.GetFilterAttributes(true).ToList();
// Assert
mockDescriptor.Verify();
Assert.Single(result);
}
[Fact]
public void GetSelectorsReturnsEmptyCollection()
{
// Arrange
ActionDescriptor ad = GetActionDescriptor();
// Act
ICollection<ActionSelector> selectors = ad.GetSelectors();
// Assert
Assert.IsType<ActionSelector[]>(selectors);
Assert.Empty(selectors);
}
[Fact]
public void IsDefinedReturnsFalse()
{
// Arrange
ActionDescriptor ad = GetActionDescriptor();
// Act
bool isDefined = ad.IsDefined(typeof(object), true);
// Assert
Assert.False(isDefined);
}
[Fact]
public void IsDefinedThrowsIfAttributeTypeIsNull()
{
// Arrange
ActionDescriptor ad = GetActionDescriptor();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { ad.IsDefined(null /* attributeType */, true); }, "attributeType");
}
[Fact]
public void UniqueId_SameTypeControllerDescriptorAndActionName_SameID()
{
// Arrange
var controllerDescriptor = new Mock<ControllerDescriptor>().Object;
var descriptor1 = new Mock<ActionDescriptor> { CallBase = true };
descriptor1.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor);
descriptor1.SetupGet(d => d.ActionName).Returns("Action1");
var descriptor2 = new Mock<ActionDescriptor> { CallBase = true };
descriptor2.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor);
descriptor2.SetupGet(d => d.ActionName).Returns("Action1");
// Act
var id1 = descriptor1.Object.UniqueId;
var id2 = descriptor2.Object.UniqueId;
// Assert
Assert.Equal(id1, id2);
}
[Fact]
public void UniqueId_VariesWithActionName()
{
// Arrange
var controllerDescriptor = new Mock<ControllerDescriptor>().Object;
var descriptor1 = new Mock<ActionDescriptor> { CallBase = true };
descriptor1.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor);
descriptor1.SetupGet(d => d.ActionName).Returns("Action1");
var descriptor2 = new Mock<ActionDescriptor> { CallBase = true };
descriptor2.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor);
descriptor2.SetupGet(d => d.ActionName).Returns("Action2");
// Act
var id1 = descriptor1.Object.UniqueId;
var id2 = descriptor2.Object.UniqueId;
// Assert
Assert.NotEqual(id1, id2);
}
[Fact]
public void UniqueId_VariesWithControllerDescriptorsUniqueId()
{
// Arrange
var controllerDescriptor1 = new Mock<ControllerDescriptor>();
controllerDescriptor1.SetupGet(cd => cd.UniqueId).Returns("1");
var descriptor1 = new Mock<ActionDescriptor> { CallBase = true };
descriptor1.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor1.Object);
descriptor1.SetupGet(d => d.ActionName).Returns("Action1");
var controllerDescriptor2 = new Mock<ControllerDescriptor>();
controllerDescriptor2.SetupGet(cd => cd.UniqueId).Returns("2");
var descriptor2 = new Mock<ActionDescriptor> { CallBase = true };
descriptor2.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor2.Object);
descriptor2.SetupGet(d => d.ActionName).Returns("Action1");
// Act
var id1 = descriptor1.Object.UniqueId;
var id2 = descriptor2.Object.UniqueId;
// Assert
Assert.NotEqual(id1, id2);
}
[Fact]
public void UniqueId_VariesWithActionDescriptorType()
{
// Arrange
var descriptor1 = new BaseDescriptor();
var descriptor2 = new DerivedDescriptor();
// Act
var id1 = descriptor1.UniqueId;
var id2 = descriptor2.UniqueId;
// Assert
Assert.NotEqual(id1, id2);
}
class BaseDescriptor : ActionDescriptor
{
static ControllerDescriptor controllerDescriptor = new Mock<ControllerDescriptor>().Object;
public override string ActionName
{
get { return "ActionName"; }
}
public override ControllerDescriptor ControllerDescriptor
{
get { return controllerDescriptor; }
}
public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters)
{
throw new NotImplementedException();
}
public override ParameterDescriptor[] GetParameters()
{
throw new NotImplementedException();
}
}
class DerivedDescriptor : BaseDescriptor
{
}
private static ActionDescriptor GetActionDescriptor()
{
Mock<ActionDescriptor> mockDescriptor = new Mock<ActionDescriptor>() { CallBase = true };
return mockDescriptor.Object;
}
private class ParameterExtractionController : Controller
{
public static readonly ParameterInfo IntParameter = typeof(ParameterExtractionController).GetMethod("SomeMethod").GetParameters()[0];
public static readonly ParameterInfo StringParameterNoDefaultValue = typeof(ParameterExtractionController).GetMethod("SomeMethod").GetParameters()[1];
public static readonly ParameterInfo StringParameterWithDefaultValue = typeof(ParameterExtractionController).GetMethod("SomeMethod").GetParameters()[2];
public void SomeMethod(int intParameter, string stringParameterNoDefaultValue, [DefaultValue("hello")] string stringParameterWithDefaultValue)
{
}
}
}
}

View File

@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.TestUtil;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ActionExecutedContextTest
{
[Fact]
public void ConstructorThrowsIfActionDescriptorIsNull()
{
// Arrange
ControllerContext controllerContext = new Mock<ControllerContext>().Object;
ActionDescriptor actionDescriptor = null;
bool canceled = true;
Exception exception = null;
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ActionExecutedContext(controllerContext, actionDescriptor, canceled, exception); }, "actionDescriptor");
}
[Fact]
public void PropertiesAreSetByConstructor()
{
// Arrange
ControllerContext controllerContext = new Mock<ControllerContext>().Object;
ActionDescriptor actionDescriptor = new Mock<ActionDescriptor>().Object;
bool canceled = true;
Exception exception = new Exception();
// Act
ActionExecutedContext actionExecutedContext = new ActionExecutedContext(controllerContext, actionDescriptor, canceled, exception);
// Assert
Assert.Equal(actionDescriptor, actionExecutedContext.ActionDescriptor);
Assert.Equal(canceled, actionExecutedContext.Canceled);
Assert.Equal(exception, actionExecutedContext.Exception);
}
[Fact]
public void ResultProperty()
{
// Arrange
ActionExecutedContext actionExecutedContext = new Mock<ActionExecutedContext>().Object;
// Act & assert
MemberHelper.TestPropertyWithDefaultInstance(actionExecutedContext, "Result", new ViewResult(), EmptyResult.Instance);
}
}
}

View File

@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ActionExecutingContextTest
{
[Fact]
public void ConstructorThrowsIfActionDescriptorIsNull()
{
// Arrange
ControllerContext controllerContext = new Mock<ControllerContext>().Object;
ActionDescriptor actionDescriptor = null;
Dictionary<string, object> actionParameters = new Dictionary<string, object>();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ActionExecutingContext(controllerContext, actionDescriptor, actionParameters); }, "actionDescriptor");
}
[Fact]
public void ConstructorThrowsIfActionParametersIsNull()
{
// Arrange
ControllerContext controllerContext = new Mock<ControllerContext>().Object;
ActionDescriptor actionDescriptor = new Mock<ActionDescriptor>().Object;
Dictionary<string, object> actionParameters = null;
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new ActionExecutingContext(controllerContext, actionDescriptor, actionParameters); }, "actionParameters");
}
[Fact]
public void PropertiesAreSetByConstructor()
{
// Arrange
ControllerContext controllerContext = new Mock<ControllerContext>().Object;
ActionDescriptor actionDescriptor = new Mock<ActionDescriptor>().Object;
Dictionary<string, object> actionParameters = new Dictionary<string, object>();
// Act
ActionExecutingContext actionExecutingContext = new ActionExecutingContext(controllerContext, actionDescriptor, actionParameters);
// Assert
Assert.Equal(actionDescriptor, actionExecutingContext.ActionDescriptor);
Assert.Equal(actionParameters, actionExecutingContext.ActionParameters);
}
}
}

View File

@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ActionFilterAttributeTest
{
[Fact]
public void DefaultOrderIsNegativeOne()
{
// Act
var attr = new EmptyActionFilterAttribute();
// Assert
Assert.Equal(-1, attr.Order);
}
[Fact]
public void OrderIsSetCorrectly()
{
// Act
var attr = new EmptyActionFilterAttribute() { Order = 98052 };
// Assert
Assert.Equal(98052, attr.Order);
}
[Fact]
public void SpecifyingInvalidOrderThrows()
{
// Act & Assert
Assert.ThrowsArgumentOutOfRange(
delegate { new EmptyActionFilterAttribute() { Order = -2 }; },
"value",
"Order must be greater than or equal to -1.");
}
private class EmptyActionFilterAttribute : ActionFilterAttribute
{
}
}
}

View File

@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
using Xunit;
namespace System.Web.Mvc.Test
{
public class ActionMethodDispatcherCacheTest
{
[Fact]
public void GetDispatcher()
{
// Arrange
MethodInfo methodInfo = typeof(object).GetMethod("ToString");
ActionMethodDispatcherCache cache = new ActionMethodDispatcherCache();
// Act
ActionMethodDispatcher dispatcher1 = cache.GetDispatcher(methodInfo);
ActionMethodDispatcher dispatcher2 = cache.GetDispatcher(methodInfo);
// Assert
Assert.Same(methodInfo, dispatcher1.MethodInfo);
Assert.Same(dispatcher1, dispatcher2);
}
}
}

View File

@@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Reflection;
using Xunit;
namespace System.Web.Mvc.Test
{
public class ActionMethodDispatcherTest
{
[Fact]
public void ExecuteWithNormalActionMethod()
{
// Arrange
DispatcherController controller = new DispatcherController();
object[] parameters = new object[] { 5, "some string", new DateTime(2001, 1, 1) };
MethodInfo methodInfo = typeof(DispatcherController).GetMethod("NormalAction");
ActionMethodDispatcher dispatcher = new ActionMethodDispatcher(methodInfo);
// Act
object returnValue = dispatcher.Execute(controller, parameters);
// Assert
var stringResult = Assert.IsType<string>(returnValue);
Assert.Equal("Hello from NormalAction!", stringResult);
Assert.Equal(5, controller._i);
Assert.Equal("some string", controller._s);
Assert.Equal(new DateTime(2001, 1, 1), controller._dt);
}
[Fact]
public void ExecuteWithParameterlessActionMethod()
{
// Arrange
DispatcherController controller = new DispatcherController();
object[] parameters = new object[0];
MethodInfo methodInfo = typeof(DispatcherController).GetMethod("ParameterlessAction");
ActionMethodDispatcher dispatcher = new ActionMethodDispatcher(methodInfo);
// Act
object returnValue = dispatcher.Execute(controller, parameters);
// Assert
var intResult = Assert.IsType<int>(returnValue);
Assert.Equal(53, intResult);
}
[Fact]
public void ExecuteWithStaticActionMethod()
{
// Arrange
DispatcherController controller = new DispatcherController();
object[] parameters = new object[0];
MethodInfo methodInfo = typeof(DispatcherController).GetMethod("StaticAction");
ActionMethodDispatcher dispatcher = new ActionMethodDispatcher(methodInfo);
// Act
object returnValue = dispatcher.Execute(controller, parameters);
// Assert
var intResult = Assert.IsType<int>(returnValue);
Assert.Equal(89, intResult);
}
[Fact]
public void ExecuteWithVoidActionMethod()
{
// Arrange
DispatcherController controller = new DispatcherController();
object[] parameters = new object[] { 5, "some string", new DateTime(2001, 1, 1) };
MethodInfo methodInfo = typeof(DispatcherController).GetMethod("VoidAction");
ActionMethodDispatcher dispatcher = new ActionMethodDispatcher(methodInfo);
// Act
object returnValue = dispatcher.Execute(controller, parameters);
// Assert
Assert.Null(returnValue);
Assert.Equal(5, controller._i);
Assert.Equal("some string", controller._s);
Assert.Equal(new DateTime(2001, 1, 1), controller._dt);
}
[Fact]
public void MethodInfoProperty()
{
// Arrange
MethodInfo original = typeof(object).GetMethod("ToString");
ActionMethodDispatcher dispatcher = new ActionMethodDispatcher(original);
// Act
MethodInfo returned = dispatcher.MethodInfo;
// Assert
Assert.Same(original, returned);
}
private class DispatcherController : Controller
{
public int _i;
public string _s;
public DateTime _dt;
public object NormalAction(int i, string s, DateTime dt)
{
VoidAction(i, s, dt);
return "Hello from NormalAction!";
}
public int ParameterlessAction()
{
return 53;
}
public void VoidAction(int i, string s, DateTime dt)
{
_i = i;
_s = s;
_dt = dt;
}
public static int StaticAction()
{
return 89;
}
}
}
}

View File

@@ -0,0 +1,214 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ActionMethodSelectorTest
{
[Fact]
public void AliasedMethodsProperty()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
// Act
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Assert
Assert.Equal(2, selector.AliasedMethods.Length);
List<MethodInfo> sortedAliasedMethods = selector.AliasedMethods.OrderBy(methodInfo => methodInfo.Name).ToList();
Assert.Equal("Bar", sortedAliasedMethods[0].Name);
Assert.Equal("FooRenamed", sortedAliasedMethods[1].Name);
}
[Fact]
public void ControllerTypeProperty()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Act & Assert
Assert.Same(controllerType, selector.ControllerType);
}
[Fact]
public void FindActionMethodReturnsMatchingMethodIfOneMethodMatches()
{
// Arrange
Type controllerType = typeof(SelectionAttributeController);
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Act
MethodInfo matchedMethod = selector.FindActionMethod(null, "OneMatch");
// Assert
Assert.Equal("OneMatch", matchedMethod.Name);
Assert.Equal(typeof(string), matchedMethod.GetParameters()[0].ParameterType);
}
[Fact]
public void FindActionMethodReturnsMethodWithActionSelectionAttributeIfMultipleMethodsMatchRequest()
{
// DevDiv Bugs 212062: If multiple action methods match a request, we should match only the methods with an
// [ActionMethod] attribute since we assume those methods are more specific.
// Arrange
Type controllerType = typeof(SelectionAttributeController);
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Act
MethodInfo matchedMethod = selector.FindActionMethod(null, "ShouldMatchMethodWithSelectionAttribute");
// Assert
Assert.Equal("MethodHasSelectionAttribute1", matchedMethod.Name);
}
[Fact]
public void FindActionMethodReturnsNullIfNoMethodMatches()
{
// Arrange
Type controllerType = typeof(SelectionAttributeController);
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Act
MethodInfo matchedMethod = selector.FindActionMethod(null, "ZeroMatch");
// Assert
Assert.Null(matchedMethod);
}
[Fact]
public void FindActionMethodThrowsIfMultipleMethodsMatch()
{
// Arrange
Type controllerType = typeof(SelectionAttributeController);
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Act & veriy
Assert.Throws<AmbiguousMatchException>(
delegate { selector.FindActionMethod(null, "TwoMatch"); },
@"The current request for action 'TwoMatch' on controller type 'SelectionAttributeController' is ambiguous between the following action methods:
Void TwoMatch2() on type System.Web.Mvc.Test.ActionMethodSelectorTest+SelectionAttributeController
Void TwoMatch() on type System.Web.Mvc.Test.ActionMethodSelectorTest+SelectionAttributeController");
}
[Fact]
public void NonAliasedMethodsProperty()
{
// Arrange
Type controllerType = typeof(MethodLocatorController);
// Act
ActionMethodSelector selector = new ActionMethodSelector(controllerType);
// Assert
Assert.Single(selector.NonAliasedMethods);
List<MethodInfo> sortedMethods = selector.NonAliasedMethods["foo"].OrderBy(methodInfo => methodInfo.GetParameters().Length).ToList();
Assert.Equal("Foo", sortedMethods[0].Name);
Assert.Empty(sortedMethods[0].GetParameters());
Assert.Equal("Foo", sortedMethods[1].Name);
Assert.Equal(typeof(string), sortedMethods[1].GetParameters()[0].ParameterType);
}
private class MethodLocatorController : Controller
{
public void Foo()
{
}
public void Foo(string s)
{
}
[ActionName("Foo")]
public void FooRenamed()
{
}
[ActionName("Bar")]
public void Bar()
{
}
[ActionName("PrivateVoid")]
private void PrivateVoid()
{
}
protected void ProtectedVoidAction()
{
}
public static void StaticMethod()
{
}
// ensure that methods inheriting from Controller or a base class are not matched
[ActionName("Blah")]
protected override void ExecuteCore()
{
throw new NotImplementedException();
}
public string StringProperty { get; set; }
#pragma warning disable 0067
public event EventHandler<EventArgs> SomeEvent;
#pragma warning restore 0067
}
private class SelectionAttributeController : Controller
{
[Match(false)]
public void OneMatch()
{
}
public void OneMatch(string s)
{
}
public void TwoMatch()
{
}
[ActionName("TwoMatch")]
public void TwoMatch2()
{
}
[Match(true), ActionName("ShouldMatchMethodWithSelectionAttribute")]
public void MethodHasSelectionAttribute1()
{
}
[ActionName("ShouldMatchMethodWithSelectionAttribute")]
public void MethodDoesNotHaveSelectionAttribute1()
{
}
private class MatchAttribute : ActionMethodSelectorAttribute
{
private bool _match;
public MatchAttribute(bool match)
{
_match = match;
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
return _match;
}
}
}
}
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ActionNameAttributeTest
{
[Fact]
public void ConstructorThrowsIfNameIsEmpty()
{
// Act & Assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new ActionNameAttribute(String.Empty); }, "name");
}
[Fact]
public void ConstructorThrowsIfNameIsNull()
{
// Act & Assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new ActionNameAttribute(null); }, "name");
}
[Fact]
public void IsValidForRequestReturnsFalseIfGivenNameDoesNotMatch()
{
// Arrange
ActionNameAttribute attr = new ActionNameAttribute("Bar");
// Act
bool returned = attr.IsValidName(null, "foo", null);
// Assert
Assert.False(returned);
}
[Fact]
public void IsValidForRequestReturnsTrueIfGivenNameMatches()
{
// Arrange
ActionNameAttribute attr = new ActionNameAttribute("Bar");
// Act
bool returned = attr.IsValidName(null, "bar", null);
// Assert
Assert.True(returned);
}
[Fact]
public void NameProperty()
{
// Arrange
ActionNameAttribute attr = new ActionNameAttribute("someName");
// Act & Assert
Assert.Equal("someName", attr.Name);
}
}
}

View File

@@ -0,0 +1,75 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AdditionalMetadataAttributeTest
{
[Fact]
public void GuardClauses()
{
// Act & assert
Assert.ThrowsArgumentNull(
() => new AdditionalMetadataAttribute(null, new object()),
"name");
AdditionalMetadataAttribute attr = new AdditionalMetadataAttribute("key", null);
Assert.ThrowsArgumentNull(
() => attr.OnMetadataCreated(null),
"metadata");
}
[Fact]
public void OnMetaDataCreatedSetsAdditionalValue()
{
// Arrange
string name = "name";
object value = new object();
ModelMetadata modelMetadata = new ModelMetadata(new Mock<ModelMetadataProvider>().Object, null, null, typeof(object), null);
AdditionalMetadataAttribute attr = new AdditionalMetadataAttribute(name, value);
// Act
attr.OnMetadataCreated(modelMetadata);
// Assert
Assert.Equal(modelMetadata.AdditionalValues[name], value);
Assert.Equal(attr.Name, name);
Assert.Equal(attr.Value, value);
}
[Fact]
public void MultipleAttributesCanSetValuesOnMetadata()
{
// Arrange
string name1 = "name1";
string name2 = "name2";
object value1 = new object();
object value2 = new object();
object value3 = new object();
ModelMetadata modelMetadata = new ModelMetadata(new Mock<ModelMetadataProvider>().Object, null, null, typeof(object), null);
AdditionalMetadataAttribute attr1 = new AdditionalMetadataAttribute(name1, value1);
AdditionalMetadataAttribute attr2 = new AdditionalMetadataAttribute(name2, value2);
AdditionalMetadataAttribute attr3 = new AdditionalMetadataAttribute(name1, value3);
// Act
attr1.OnMetadataCreated(modelMetadata);
attr2.OnMetadataCreated(modelMetadata);
attr3.OnMetadataCreated(modelMetadata);
// Assert
Assert.Equal(2, modelMetadata.AdditionalValues.Count);
Assert.Equal(modelMetadata.AdditionalValues[name1], value3);
Assert.Equal(modelMetadata.AdditionalValues[name2], value2);
Assert.NotEqual(attr1.TypeId, attr2.TypeId);
Assert.NotEqual(attr2.TypeId, attr3.TypeId);
Assert.NotEqual(attr3.TypeId, attr1.TypeId);
}
}
}

View File

@@ -0,0 +1,238 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Routing;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AjaxHelperTest
{
[Fact]
public void ConstructorWithNullViewContextThrows()
{
// Assert
Assert.ThrowsArgumentNull(
delegate { AjaxHelper ajaxHelper = new AjaxHelper(null, new Mock<IViewDataContainer>().Object); },
"viewContext");
}
[Fact]
public void ConstructorWithNullViewDataContainerThrows()
{
// Assert
Assert.ThrowsArgumentNull(
delegate { AjaxHelper ajaxHelper = new AjaxHelper(new Mock<ViewContext>().Object, null); },
"viewDataContainer");
}
[Fact]
public void ConstructorSetsProperties1()
{
// Arrange
ViewContext viewContext = new Mock<ViewContext>().Object;
IViewDataContainer vdc = new Mock<IViewDataContainer>().Object;
// Act
AjaxHelper ajaxHelper = new AjaxHelper(viewContext, vdc);
// Assert
Assert.Equal(viewContext, ajaxHelper.ViewContext);
Assert.Equal(vdc, ajaxHelper.ViewDataContainer);
Assert.Equal(RouteTable.Routes, ajaxHelper.RouteCollection);
}
[Fact]
public void ConstructorSetsProperties2()
{
// Arrange
ViewContext viewContext = new Mock<ViewContext>().Object;
IViewDataContainer vdc = new Mock<IViewDataContainer>().Object;
RouteCollection rc = new RouteCollection();
// Act
AjaxHelper ajaxHelper = new AjaxHelper(viewContext, vdc, rc);
// Assert
Assert.Equal(viewContext, ajaxHelper.ViewContext);
Assert.Equal(vdc, ajaxHelper.ViewDataContainer);
Assert.Equal(rc, ajaxHelper.RouteCollection);
}
[Fact]
public void GenericHelperConstructorSetsProperties1()
{
// Arrange
ViewContext viewContext = new Mock<ViewContext>().Object;
ViewDataDictionary<Controller> vdd = new ViewDataDictionary<Controller>(new Mock<Controller>().Object);
Mock<IViewDataContainer> vdc = new Mock<IViewDataContainer>();
vdc.Setup(v => v.ViewData).Returns(vdd);
// Act
AjaxHelper<Controller> ajaxHelper = new AjaxHelper<Controller>(viewContext, vdc.Object);
// Assert
Assert.Equal(viewContext, ajaxHelper.ViewContext);
Assert.Equal(vdc.Object, ajaxHelper.ViewDataContainer);
Assert.Equal(RouteTable.Routes, ajaxHelper.RouteCollection);
Assert.Equal(vdd.Model, ajaxHelper.ViewData.Model);
}
[Fact]
public void GenericHelperConstructorSetsProperties2()
{
// Arrange
ViewContext viewContext = new Mock<ViewContext>().Object;
ViewDataDictionary<Controller> vdd = new ViewDataDictionary<Controller>(new Mock<Controller>().Object);
Mock<IViewDataContainer> vdc = new Mock<IViewDataContainer>();
vdc.Setup(v => v.ViewData).Returns(vdd);
RouteCollection rc = new RouteCollection();
// Act
AjaxHelper<Controller> ajaxHelper = new AjaxHelper<Controller>(viewContext, vdc.Object, rc);
// Assert
Assert.Equal(viewContext, ajaxHelper.ViewContext);
Assert.Equal(vdc.Object, ajaxHelper.ViewDataContainer);
Assert.Equal(rc, ajaxHelper.RouteCollection);
Assert.Equal(vdd.Model, ajaxHelper.ViewData.Model);
}
[Fact]
public void GlobalizationScriptPathPropertyDefault()
{
try
{
// Act
AjaxHelper.GlobalizationScriptPath = null;
// Assert
Assert.Equal("~/Scripts/Globalization", AjaxHelper.GlobalizationScriptPath);
}
finally
{
AjaxHelper.GlobalizationScriptPath = null;
}
}
[Fact]
public void GlobalizationScriptPathPropertySet()
{
try
{
// Act
AjaxHelper.GlobalizationScriptPath = "/Foo/Bar";
// Assert
Assert.Equal("/Foo/Bar", AjaxHelper.GlobalizationScriptPath);
}
finally
{
AjaxHelper.GlobalizationScriptPath = null;
}
}
[Fact]
public void JavaScriptStringEncodeReturnsEmptyStringIfMessageIsEmpty()
{
// Arrange
AjaxHelper ajaxHelper = GetAjaxHelper();
// Act
string encoded = ajaxHelper.JavaScriptStringEncode(String.Empty);
// Assert
Assert.Equal(String.Empty, encoded);
}
[Fact]
public void JavaScriptStringEncodeReturnsEncodedMessage()
{
// Arrange
string message = "I said, \"Hello, world!\"\nHow are you?";
AjaxHelper ajaxHelper = GetAjaxHelper();
// Act
string encoded = ajaxHelper.JavaScriptStringEncode(message);
// Assert
Assert.Equal(@"I said, \""Hello, world!\""\nHow are you?", encoded);
}
[Fact]
public void JavaScriptStringEncodeReturnsNullIfMessageIsNull()
{
// Arrange
AjaxHelper ajaxHelper = GetAjaxHelper();
// Act
string encoded = ajaxHelper.JavaScriptStringEncode(null /* message */);
// Assert
Assert.Null(encoded);
}
[Fact]
public void ViewBagProperty_ReflectsViewData()
{
// Arrange
ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
// Act
AjaxHelper ajaxHelper = new AjaxHelper(new Mock<ViewContext>().Object, viewDataContainer.Object);
// Assert
Assert.Equal(1, ajaxHelper.ViewBag.A);
}
[Fact]
public void ViewBagProperty_ReflectsNewViewDataContainerInstance()
{
// Arrange
ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
ViewDataDictionary otherViewDataDictionary = new ViewDataDictionary() { { "A", 2 } };
Mock<IViewDataContainer> otherViewDataContainer = new Mock<IViewDataContainer>();
otherViewDataContainer.Setup(container => container.ViewData).Returns(otherViewDataDictionary);
AjaxHelper ajaxHelper = new AjaxHelper(new Mock<ViewContext>().Object, viewDataContainer.Object, new RouteCollection());
// Act
ajaxHelper.ViewDataContainer = otherViewDataContainer.Object;
// Assert
Assert.Equal(2, ajaxHelper.ViewBag.A);
}
[Fact]
public void ViewBag_PropagatesChangesToViewData()
{
// Arrange
ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
AjaxHelper ajaxHelper = new AjaxHelper(new Mock<ViewContext>().Object, viewDataContainer.Object, new RouteCollection());
// Act
ajaxHelper.ViewBag.A = "foo";
ajaxHelper.ViewBag.B = 2;
// Assert
Assert.Equal("foo", ajaxHelper.ViewData["A"]);
Assert.Equal(2, ajaxHelper.ViewData["B"]);
}
private static AjaxHelper GetAjaxHelper()
{
ViewContext viewContext = new Mock<ViewContext>().Object;
IViewDataContainer viewDataContainer = new Mock<IViewDataContainer>().Object;
return new AjaxHelper(viewContext, viewDataContainer);
}
}
}

View File

@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Moq;
using Xunit;
namespace System.Web.Mvc.Test
{
public class AjaxHelper_1Test
{
[Fact]
public void ViewBagAndViewDataStayInSync()
{
// Arrange
Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
// Act
AjaxHelper<object> ajaxHelper = new AjaxHelper<object>(new Mock<ViewContext>().Object, viewDataContainer.Object);
ajaxHelper.ViewData["B"] = 2;
ajaxHelper.ViewBag.C = 3;
// Assert
// Original ViewData should not be modified by redfined ViewData and ViewBag
AjaxHelper nonGenericAjaxHelper = ajaxHelper;
Assert.Single(nonGenericAjaxHelper.ViewData.Keys);
Assert.Equal(1, nonGenericAjaxHelper.ViewData["A"]);
Assert.Equal(1, nonGenericAjaxHelper.ViewBag.A);
// Redefined ViewData and ViewBag should be in sync
Assert.Equal(3, ajaxHelper.ViewData.Keys.Count);
Assert.Equal(1, ajaxHelper.ViewData["A"]);
Assert.Equal(2, ajaxHelper.ViewData["B"]);
Assert.Equal(3, ajaxHelper.ViewData["C"]);
Assert.Equal(1, ajaxHelper.ViewBag.A);
Assert.Equal(2, ajaxHelper.ViewBag.B);
Assert.Equal(3, ajaxHelper.ViewBag.C);
}
}
}

View File

@@ -0,0 +1,72 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Specialized;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AjaxRequestExtensionsTest
{
[Fact]
public void IsAjaxRequestWithNullRequestThrows()
{
// Act & Assert
Assert.ThrowsArgumentNull(
delegate { AjaxRequestExtensions.IsAjaxRequest(null); }, "request");
}
[Fact]
public void IsAjaxRequestWithKeyIsTrue()
{
// Arrange
Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>();
mockRequest.Setup(r => r["X-Requested-With"]).Returns("XMLHttpRequest").Verifiable();
HttpRequestBase request = mockRequest.Object;
// Act
bool retVal = AjaxRequestExtensions.IsAjaxRequest(request);
// Assert
Assert.True(retVal);
mockRequest.Verify();
}
[Fact]
public void IsAjaxRequestWithoutKeyOrHeaderIsFalse()
{
// Arrange
Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>();
NameValueCollection headerCollection = new NameValueCollection();
mockRequest.Setup(r => r.Headers).Returns(headerCollection).Verifiable();
mockRequest.Setup(r => r["X-Requested-With"]).Returns((string)null).Verifiable();
HttpRequestBase request = mockRequest.Object;
// Act
bool retVal = AjaxRequestExtensions.IsAjaxRequest(request);
// Assert
Assert.False(retVal);
mockRequest.Verify();
}
[Fact]
public void IsAjaxRequestReturnsTrueIfHeaderSet()
{
// Arrange
Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>();
NameValueCollection headerCollection = new NameValueCollection();
headerCollection["X-Requested-With"] = "XMLHttpRequest";
mockRequest.Setup(r => r.Headers).Returns(headerCollection).Verifiable();
HttpRequestBase request = mockRequest.Object;
// Act
bool retVal = AjaxRequestExtensions.IsAjaxRequest(request);
// Assert
Assert.True(retVal);
mockRequest.Verify();
}
}
}

View File

@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AllowHtmlAttributeTest
{
[Fact]
public void OnMetadataCreated_ThrowsIfMetadataIsNull()
{
// Arrange
AllowHtmlAttribute attr = new AllowHtmlAttribute();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { attr.OnMetadataCreated(null); }, "metadata");
}
[Fact]
public void OnMetadataCreated()
{
// Arrange
ModelMetadata modelMetadata = new ModelMetadata(new Mock<ModelMetadataProvider>().Object, null, null, typeof(object), "SomeProperty");
AllowHtmlAttribute attr = new AllowHtmlAttribute();
// Act
bool originalValue = modelMetadata.RequestValidationEnabled;
attr.OnMetadataCreated(modelMetadata);
bool newValue = modelMetadata.RequestValidationEnabled;
// Assert
Assert.True(originalValue);
Assert.False(newValue);
}
}
}

View File

@@ -0,0 +1,99 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Routing;
using Xunit;
namespace System.Web.Mvc.Test
{
public class AreaHelpersTest
{
[Fact]
public void GetAreaNameFromAreaRouteCollectionRoute()
{
// Arrange
RouteCollection routes = new RouteCollection();
AreaRegistrationContext context = new AreaRegistrationContext("area_name", routes);
Route route = context.MapRoute(null, "the_url");
// Act
string areaName = AreaHelpers.GetAreaName(route);
// Assert
Assert.Equal("area_name", areaName);
}
[Fact]
public void GetAreaNameFromIAreaAssociatedItem()
{
// Arrange
CustomRouteWithArea route = new CustomRouteWithArea();
// Act
string areaName = AreaHelpers.GetAreaName(route);
// Assert
Assert.Equal("area_name", areaName);
}
[Fact]
public void GetAreaNameFromRouteData()
{
// Arrange
RouteData routeData = new RouteData();
routeData.DataTokens["area"] = "area_name";
// Act
string areaName = AreaHelpers.GetAreaName(routeData);
// Assert
Assert.Equal("area_name", areaName);
}
[Fact]
public void GetAreaNameFromRouteDataFallsBackToRoute()
{
// Arrange
RouteCollection routes = new RouteCollection();
AreaRegistrationContext context = new AreaRegistrationContext("area_name", routes);
Route route = context.MapRoute(null, "the_url");
RouteData routeData = new RouteData(route, new MvcRouteHandler());
// Act
string areaName = AreaHelpers.GetAreaName(routeData);
// Assert
Assert.Equal("area_name", areaName);
}
[Fact]
public void GetAreaNameReturnsNullIfRouteNotAreaAware()
{
// Arrange
Route route = new Route("the_url", new MvcRouteHandler());
// Act
string areaName = AreaHelpers.GetAreaName(route);
// Assert
Assert.Null(areaName);
}
private class CustomRouteWithArea : RouteBase, IRouteWithArea
{
public string Area
{
get { return "area_name"; }
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
throw new NotImplementedException();
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -0,0 +1,140 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Routing;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AreaRegistrationContextTest
{
[Fact]
public void ConstructorSetsProperties()
{
// Arrange
string areaName = "the_area";
RouteCollection routes = new RouteCollection();
// Act
AreaRegistrationContext context = new AreaRegistrationContext(areaName, routes);
// Assert
Assert.Equal(areaName, context.AreaName);
Assert.Same(routes, context.Routes);
}
[Fact]
public void ConstructorThrowsIfAreaNameIsEmpty()
{
// Act & assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new AreaRegistrationContext("", new RouteCollection()); }, "areaName");
}
[Fact]
public void ConstructorThrowsIfAreaNameIsNull()
{
// Act & assert
Assert.ThrowsArgumentNullOrEmpty(
delegate { new AreaRegistrationContext(null, new RouteCollection()); }, "areaName");
}
[Fact]
public void ConstructorThrowsIfRoutesIsNull()
{
// Act & assert
Assert.ThrowsArgumentNull(
delegate { new AreaRegistrationContext("the_area", null); }, "routes");
}
[Fact]
public void MapRouteWithEmptyStringNamespaces()
{
// Arrange
string[] implicitNamespaces = new string[] { "implicit_1", "implicit_2" };
string[] explicitNamespaces = new string[0];
RouteCollection routes = new RouteCollection();
AreaRegistrationContext context = new AreaRegistrationContext("the_area", routes);
ReplaceCollectionContents(context.Namespaces, implicitNamespaces);
// Act
Route route = context.MapRoute("the_name", "the_url", explicitNamespaces);
// Assert
Assert.Equal(route, routes["the_name"]);
Assert.Equal("the_area", route.DataTokens["area"]);
Assert.Equal(true, route.DataTokens["UseNamespaceFallback"]);
Assert.Null(route.DataTokens["namespaces"]);
}
[Fact]
public void MapRouteWithExplicitNamespaces()
{
// Arrange
string[] implicitNamespaces = new string[] { "implicit_1", "implicit_2" };
string[] explicitNamespaces = new string[] { "explicit_1", "explicit_2" };
RouteCollection routes = new RouteCollection();
AreaRegistrationContext context = new AreaRegistrationContext("the_area", routes);
ReplaceCollectionContents(context.Namespaces, implicitNamespaces);
// Act
Route route = context.MapRoute("the_name", "the_url", explicitNamespaces);
// Assert
Assert.Equal(route, routes["the_name"]);
Assert.Equal("the_area", route.DataTokens["area"]);
Assert.Equal(false, route.DataTokens["UseNamespaceFallback"]);
Assert.Equal(explicitNamespaces, (string[])route.DataTokens["namespaces"]);
}
[Fact]
public void MapRouteWithImplicitNamespaces()
{
// Arrange
string[] implicitNamespaces = new string[] { "implicit_1", "implicit_2" };
string[] explicitNamespaces = new string[] { "explicit_1", "explicit_2" };
RouteCollection routes = new RouteCollection();
AreaRegistrationContext context = new AreaRegistrationContext("the_area", routes);
ReplaceCollectionContents(context.Namespaces, implicitNamespaces);
// Act
Route route = context.MapRoute("the_name", "the_url");
// Assert
Assert.Equal(route, routes["the_name"]);
Assert.Equal("the_area", route.DataTokens["area"]);
Assert.Equal(false, route.DataTokens["UseNamespaceFallback"]);
Assert.Equal(implicitNamespaces, (string[])route.DataTokens["namespaces"]);
}
[Fact]
public void MapRouteWithoutNamespaces()
{
// Arrange
RouteCollection routes = new RouteCollection();
AreaRegistrationContext context = new AreaRegistrationContext("the_area", routes);
// Act
Route route = context.MapRoute("the_name", "the_url");
// Assert
Assert.Equal(route, routes["the_name"]);
Assert.Equal("the_area", route.DataTokens["area"]);
Assert.Null(route.DataTokens["namespaces"]);
Assert.Equal(true, route.DataTokens["UseNamespaceFallback"]);
}
private static void ReplaceCollectionContents(ICollection<string> collectionToReplace, IEnumerable<string> newContents)
{
collectionToReplace.Clear();
foreach (string item in newContents)
{
collectionToReplace.Add(item);
}
}
}
}

View File

@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Routing;
using Xunit;
namespace System.Web.Mvc.Test
{
public class AreaRegistrationTest
{
[Fact]
public void CreateContextAndRegister()
{
// Arrange
string[] expectedNamespaces = new string[] { "System.Web.Mvc.Test.*" };
RouteCollection routes = new RouteCollection();
MyAreaRegistration registration = new MyAreaRegistration();
// Act
registration.CreateContextAndRegister(routes, "some state");
// Assert
Assert.Equal(expectedNamespaces, registration.Namespaces);
Assert.Equal("some state", registration.State);
}
[Fact]
public void RegisterAllAreas()
{
// Arrange
string[] expectedLoadedAreas = new string[] { "AreaRegistrationTest_AreaRegistration" };
AnnotatedRouteCollection routes = new AnnotatedRouteCollection();
MockBuildManager buildManager = new MockBuildManager(new Assembly[] { typeof(AreaRegistrationTest).Assembly });
// Act
AreaRegistration.RegisterAllAreas(routes, buildManager, null);
// Assert
Assert.Equal(expectedLoadedAreas, routes._areasLoaded.ToArray());
}
private class MyAreaRegistration : AreaRegistration
{
public string[] Namespaces;
public object State;
public override string AreaName
{
get { return "my_area"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
Namespaces = context.Namespaces.ToArray();
State = context.State;
}
}
}
[CLSCompliant(false)]
public class AnnotatedRouteCollection : RouteCollection
{
public List<string> _areasLoaded = new List<string>();
}
public abstract class AreaRegistrationTest_AbstractAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "the_area"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
((AnnotatedRouteCollection)context.Routes)._areasLoaded.Add("AreaRegistrationTest_AbstractAreaRegistration");
}
}
public class AreaRegistrationTest_AreaRegistration : AreaRegistrationTest_AbstractAreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
((AnnotatedRouteCollection)context.Routes)._areasLoaded.Add("AreaRegistrationTest_AreaRegistration");
}
}
public class AreaRegistrationTest_NoConstructorAreaRegistration : AreaRegistrationTest_AreaRegistration
{
private AreaRegistrationTest_NoConstructorAreaRegistration()
{
}
public override void RegisterArea(AreaRegistrationContext context)
{
((AnnotatedRouteCollection)context.Routes)._areasLoaded.Add("AreaRegistrationTest_NoConstructorAreaRegistration");
}
}
}

View File

@@ -0,0 +1,348 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AssociatedMetadataProviderTest
{
// FilterAttributes
[Fact]
public void ReadOnlyAttributeIsFilteredOffWhenContainerTypeIsViewPage()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act
provider.GetMetadataForProperty(() => null, typeof(ViewPage<PropertyModel>), "Model");
// Assert
CreateMetadataParams parms = provider.CreateMetadataLog.Single();
Assert.False(parms.Attributes.Any(a => a is ReadOnlyAttribute));
}
[Fact]
public void ReadOnlyAttributeIsFilteredOffWhenContainerTypeIsViewUserControl()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act
provider.GetMetadataForProperty(() => null, typeof(ViewUserControl<PropertyModel>), "Model");
// Assert
CreateMetadataParams parms = provider.CreateMetadataLog.Single();
Assert.False(parms.Attributes.Any(a => a is ReadOnlyAttribute));
}
[Fact]
public void ReadOnlyAttributeIsPreservedForReadOnlyModelProperties()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act
provider.GetMetadataForProperty(() => null, typeof(ModelWithReadOnlyProperty), "ReadOnlyProperty");
// Assert
CreateMetadataParams parms = provider.CreateMetadataLog.Single();
Assert.True(parms.Attributes.Any(a => a is ReadOnlyAttribute));
}
// GetMetadataForProperties
[Fact]
public void GetMetadataForPropertiesNullContainerTypeThrows()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act & Assert
Assert.ThrowsArgumentNull(
() => provider.GetMetadataForProperties(new Object(), null),
"containerType");
}
[Fact]
public void GetMetadataForPropertiesCreatesMetadataForAllPropertiesOnModelWithPropertyValues()
{
// Arrange
PropertyModel model = new PropertyModel { LocalAttributes = 42, MetadataAttributes = "hello", MixedAttributes = 21.12 };
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act
provider.GetMetadataForProperties(model, typeof(PropertyModel)).ToList(); // Call ToList() to force the lazy evaluation to evaluate
// Assert
CreateMetadataParams local =
provider.CreateMetadataLog.Single(m => m.ContainerType == typeof(PropertyModel) &&
m.PropertyName == "LocalAttributes");
Assert.Equal(typeof(int), local.ModelType);
Assert.Equal(42, local.Model);
Assert.True(local.Attributes.Any(a => a is RequiredAttribute));
CreateMetadataParams metadata =
provider.CreateMetadataLog.Single(m => m.ContainerType == typeof(PropertyModel) &&
m.PropertyName == "MetadataAttributes");
Assert.Equal(typeof(string), metadata.ModelType);
Assert.Equal("hello", metadata.Model);
Assert.True(metadata.Attributes.Any(a => a is RangeAttribute));
CreateMetadataParams mixed =
provider.CreateMetadataLog.Single(m => m.ContainerType == typeof(PropertyModel) &&
m.PropertyName == "MixedAttributes");
Assert.Equal(typeof(double), mixed.ModelType);
Assert.Equal(21.12, mixed.Model);
Assert.True(mixed.Attributes.Any(a => a is RequiredAttribute));
Assert.True(mixed.Attributes.Any(a => a is RangeAttribute));
}
[Fact]
public void GetMetadataForPropertyWithNullContainerReturnsMetadataWithNullValuesForProperties()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act
provider.GetMetadataForProperties(null, typeof(PropertyModel)).ToList(); // Call ToList() to force the lazy evaluation to evaluate
// Assert
Assert.True(provider.CreateMetadataLog.Any());
foreach (var parms in provider.CreateMetadataLog)
{
Assert.Null(parms.Model);
}
}
// GetMetadataForProperty
[Fact]
public void GetMetadataForPropertyNullContainerTypeThrows()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act & Assert
Assert.ThrowsArgumentNull(
() => provider.GetMetadataForProperty(null /* model */, null /* containerType */, "propertyName"),
"containerType");
}
[Fact]
public void GetMetadataForPropertyNullOrEmptyPropertyNameThrows()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act & Assert
Assert.ThrowsArgumentNullOrEmpty(
() => provider.GetMetadataForProperty(null /* model */, typeof(object), null /* propertyName */),
"propertyName");
Assert.ThrowsArgumentNullOrEmpty(
() => provider.GetMetadataForProperty(null, typeof(object), String.Empty),
"propertyName");
}
[Fact]
public void GetMetadataForPropertyInvalidPropertyNameThrows()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act & Assert
Assert.Throws<ArgumentException>(
() => provider.GetMetadataForProperty(null, typeof(object), "BadPropertyName"),
"The property System.Object.BadPropertyName could not be found.");
}
[Fact]
public void GetMetadataForPropertyWithLocalAttributes()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
ModelMetadata metadata = new ModelMetadata(provider, typeof(PropertyModel), null, typeof(int), "LocalAttributes");
provider.CreateMetadataReturnValue = metadata;
// Act
ModelMetadata result = provider.GetMetadataForProperty(null, typeof(PropertyModel), "LocalAttributes");
// Assert
Assert.Same(metadata, result);
Assert.True(provider.CreateMetadataLog.Single().Attributes.Any(a => a is RequiredAttribute));
}
[Fact]
public void GetMetadataForPropertyWithMetadataAttributes()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
ModelMetadata metadata = new ModelMetadata(provider, typeof(PropertyModel), null, typeof(string), "MetadataAttributes");
provider.CreateMetadataReturnValue = metadata;
// Act
ModelMetadata result = provider.GetMetadataForProperty(null, typeof(PropertyModel), "MetadataAttributes");
// Assert
Assert.Same(metadata, result);
CreateMetadataParams parms = provider.CreateMetadataLog.Single(p => p.PropertyName == "MetadataAttributes");
Assert.True(parms.Attributes.Any(a => a is RangeAttribute));
}
[Fact]
public void GetMetadataForPropertyWithMixedAttributes()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
ModelMetadata metadata = new ModelMetadata(provider, typeof(PropertyModel), null, typeof(double), "MixedAttributes");
provider.CreateMetadataReturnValue = metadata;
// Act
ModelMetadata result = provider.GetMetadataForProperty(null, typeof(PropertyModel), "MixedAttributes");
// Assert
Assert.Same(metadata, result);
CreateMetadataParams parms = provider.CreateMetadataLog.Single(p => p.PropertyName == "MixedAttributes");
Assert.True(parms.Attributes.Any(a => a is RequiredAttribute));
Assert.True(parms.Attributes.Any(a => a is RangeAttribute));
}
// GetMetadataForType
[Fact]
public void GetMetadataForTypeNullModelTypeThrows()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
// Act & Assert
Assert.ThrowsArgumentNull(
() => provider.GetMetadataForType(() => new Object(), null),
"modelType");
}
[Fact]
public void GetMetadataForTypeIncludesAttributesOnType()
{
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
ModelMetadata metadata = new ModelMetadata(provider, null, null, typeof(TypeModel), null);
provider.CreateMetadataReturnValue = metadata;
// Act
ModelMetadata result = provider.GetMetadataForType(null, typeof(TypeModel));
// Assert
Assert.Same(metadata, result);
CreateMetadataParams parms = provider.CreateMetadataLog.Single(p => p.ModelType == typeof(TypeModel));
Assert.True(parms.Attributes.Any(a => a is ReadOnlyAttribute));
}
[AdditionalMetadata("ClassName", "ClassValue")]
class ClassWithAdditionalMetadata
{
[AdditionalMetadata("PropertyName", "PropertyValue")]
public int MyProperty { get; set; }
}
[Fact]
public void MetadataAwareAttributeCanModifyTypeMetadata()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
provider.CreateMetadataReturnValue = new ModelMetadata(provider, null, null, typeof(ClassWithAdditionalMetadata), null);
// Act
ModelMetadata metadata = provider.GetMetadataForType(null, typeof(ClassWithAdditionalMetadata));
// Assert
var kvp = metadata.AdditionalValues.Single();
Assert.Equal("ClassName", kvp.Key);
Assert.Equal("ClassValue", kvp.Value);
}
[Fact]
public void MetadataAwareAttributeCanModifyPropertyMetadata()
{
// Arrange
TestableAssociatedMetadataProvider provider = new TestableAssociatedMetadataProvider();
provider.CreateMetadataReturnValue = new ModelMetadata(provider, typeof(ClassWithAdditionalMetadata), null, typeof(int), "MyProperty");
// Act
ModelMetadata metadata = provider.GetMetadataForProperty(null, typeof(ClassWithAdditionalMetadata), "MyProperty");
// Assert
var kvp = metadata.AdditionalValues.Single();
Assert.Equal("PropertyName", kvp.Key);
Assert.Equal("PropertyValue", kvp.Value);
}
// Helpers
[MetadataType(typeof(Metadata))]
private class PropertyModel
{
[Required]
public int LocalAttributes { get; set; }
public string MetadataAttributes { get; set; }
[Required]
public double MixedAttributes { get; set; }
private class Metadata
{
[Range(10, 100)]
public object MetadataAttributes { get; set; }
[Range(10, 100)]
public object MixedAttributes { get; set; }
}
}
private class ModelWithReadOnlyProperty
{
public int ReadOnlyProperty { get; private set; }
}
[ReadOnly(true)]
private class TypeModel
{
}
class TestableAssociatedMetadataProvider : AssociatedMetadataProvider
{
public List<CreateMetadataParams> CreateMetadataLog = new List<CreateMetadataParams>();
public ModelMetadata CreateMetadataReturnValue = null;
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType,
string propertyName)
{
CreateMetadataLog.Add(new CreateMetadataParams
{
Attributes = attributes,
ContainerType = containerType,
Model = modelAccessor == null ? null : modelAccessor(),
ModelType = modelType,
PropertyName = propertyName
});
return CreateMetadataReturnValue;
}
}
class CreateMetadataParams
{
public IEnumerable<Attribute> Attributes { get; set; }
public Type ContainerType { get; set; }
public object Model { get; set; }
public Type ModelType { get; set; }
public string PropertyName { get; set; }
}
}
}

View File

@@ -0,0 +1,126 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AssociatedValidatorProviderTest
{
[Fact]
public void GetValidatorsGuardClauses()
{
// Arrange
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(object));
Mock<AssociatedValidatorProvider> provider = new Mock<AssociatedValidatorProvider> { CallBase = true };
// Act & Assert
Assert.ThrowsArgumentNull(
() => provider.Object.GetValidators(null, new ControllerContext()),
"metadata");
Assert.ThrowsArgumentNull(
() => provider.Object.GetValidators(metadata, null),
"context");
}
[Fact]
public void GetValidatorsForPropertyWithLocalAttributes()
{
// Arrange
IEnumerable<Attribute> callbackAttributes = null;
ControllerContext context = new ControllerContext();
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForProperty(null, typeof(PropertyModel), "LocalAttributes");
Mock<TestableAssociatedValidatorProvider> provider = new Mock<TestableAssociatedValidatorProvider> { CallBase = true };
provider.Setup(p => p.AbstractGetValidators(metadata, context, It.IsAny<IEnumerable<Attribute>>()))
.Callback<ModelMetadata, ControllerContext, IEnumerable<Attribute>>((m, c, attributes) => callbackAttributes = attributes)
.Returns(() => null)
.Verifiable();
// Act
provider.Object.GetValidators(metadata, context);
// Assert
provider.Verify();
Assert.True(callbackAttributes.Any(a => a is RequiredAttribute));
}
[Fact]
public void GetValidatorsForPropertyWithMetadataAttributes()
{
// Arrange
IEnumerable<Attribute> callbackAttributes = null;
ControllerContext context = new ControllerContext();
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForProperty(null, typeof(PropertyModel), "MetadataAttributes");
Mock<TestableAssociatedValidatorProvider> provider = new Mock<TestableAssociatedValidatorProvider> { CallBase = true };
provider.Setup(p => p.AbstractGetValidators(metadata, context, It.IsAny<IEnumerable<Attribute>>()))
.Callback<ModelMetadata, ControllerContext, IEnumerable<Attribute>>((m, c, attributes) => callbackAttributes = attributes)
.Returns(() => null)
.Verifiable();
// Act
provider.Object.GetValidators(metadata, context);
// Assert
provider.Verify();
Assert.True(callbackAttributes.Any(a => a is RangeAttribute));
}
[Fact]
public void GetValidatorsForPropertyWithMixedAttributes()
{
// Arrange
IEnumerable<Attribute> callbackAttributes = null;
ControllerContext context = new ControllerContext();
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForProperty(null, typeof(PropertyModel), "MixedAttributes");
Mock<TestableAssociatedValidatorProvider> provider = new Mock<TestableAssociatedValidatorProvider> { CallBase = true };
provider.Setup(p => p.AbstractGetValidators(metadata, context, It.IsAny<IEnumerable<Attribute>>()))
.Callback<ModelMetadata, ControllerContext, IEnumerable<Attribute>>((m, c, attributes) => callbackAttributes = attributes)
.Returns(() => null)
.Verifiable();
// Act
provider.Object.GetValidators(metadata, context);
// Assert
provider.Verify();
Assert.True(callbackAttributes.Any(a => a is RangeAttribute));
Assert.True(callbackAttributes.Any(a => a is RequiredAttribute));
}
[MetadataType(typeof(Metadata))]
private class PropertyModel
{
[Required]
public int LocalAttributes { get; set; }
public string MetadataAttributes { get; set; }
[Required]
public double MixedAttributes { get; set; }
private class Metadata
{
[Range(10, 100)]
public object MetadataAttributes { get; set; }
[Range(10, 100)]
public object MixedAttributes { get; set; }
}
}
public abstract class TestableAssociatedValidatorProvider : AssociatedValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
return AbstractGetValidators(metadata, context, attributes);
}
// Hoist access
public abstract IEnumerable<ModelValidator> AbstractGetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes);
}
}
}

View File

@@ -0,0 +1,265 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc.Async;
using System.Web.Mvc.Async.Test;
using System.Web.Routing;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class AsyncControllerTest
{
[Fact]
public void ActionInvokerProperty()
{
// Arrange
EmptyController controller = new EmptyController();
// Act
IActionInvoker invoker = controller.ActionInvoker;
// Assert
Assert.IsType<AsyncControllerActionInvoker>(invoker);
}
[Fact]
public void AsyncManagerProperty()
{
// Arrange
EmptyController controller = new EmptyController();
// Act
AsyncManager asyncManager = controller.AsyncManager;
// Assert
Assert.NotNull(asyncManager);
}
[Fact]
public void Execute_ThrowsIfCalledMoreThanOnce()
{
// Arrange
IAsyncController controller = new EmptyController();
RequestContext requestContext = GetRequestContext("SomeAction");
// Act & assert
controller.BeginExecute(requestContext, null, null);
Assert.Throws<InvalidOperationException>(
delegate { controller.BeginExecute(requestContext, null, null); },
@"A single instance of controller 'System.Web.Mvc.Test.AsyncControllerTest+EmptyController' cannot be used to handle multiple requests. If a custom controller factory is in use, make sure that it creates a new instance of the controller for each request.");
}
[Fact]
public void Execute_ThrowsIfRequestContextIsNull()
{
// Arrange
IAsyncController controller = new EmptyController();
// Act & assert
Assert.ThrowsArgumentNull(
delegate { controller.BeginExecute(null, null, null); }, "requestContext");
}
[Fact]
public void ExecuteCore_Asynchronous_ActionFound()
{
// Arrange
MockAsyncResult innerAsyncResult = new MockAsyncResult();
Mock<IAsyncActionInvoker> mockActionInvoker = new Mock<IAsyncActionInvoker>();
mockActionInvoker.Setup(o => o.BeginInvokeAction(It.IsAny<ControllerContext>(), "SomeAction", It.IsAny<AsyncCallback>(), It.IsAny<object>())).Returns(innerAsyncResult);
mockActionInvoker.Setup(o => o.EndInvokeAction(innerAsyncResult)).Returns(true);
RequestContext requestContext = GetRequestContext("SomeAction");
EmptyController controller = new EmptyController()
{
ActionInvoker = mockActionInvoker.Object
};
// Act & assert
IAsyncResult outerAsyncResult = ((IAsyncController)controller).BeginExecute(requestContext, null, null);
Assert.False(controller.TempDataSaved);
((IAsyncController)controller).EndExecute(outerAsyncResult);
Assert.True(controller.TempDataSaved);
Assert.False(controller.HandleUnknownActionCalled);
}
[Fact]
public void ExecuteCore_Asynchronous_ActionNotFound()
{
// Arrange
MockAsyncResult innerAsyncResult = new MockAsyncResult();
Mock<IAsyncActionInvoker> mockActionInvoker = new Mock<IAsyncActionInvoker>();
mockActionInvoker.Setup(o => o.BeginInvokeAction(It.IsAny<ControllerContext>(), "SomeAction", It.IsAny<AsyncCallback>(), It.IsAny<object>())).Returns(innerAsyncResult);
mockActionInvoker.Setup(o => o.EndInvokeAction(innerAsyncResult)).Returns(false);
RequestContext requestContext = GetRequestContext("SomeAction");
EmptyController controller = new EmptyController()
{
ActionInvoker = mockActionInvoker.Object
};
// Act & assert
IAsyncResult outerAsyncResult = ((IAsyncController)controller).BeginExecute(requestContext, null, null);
Assert.False(controller.TempDataSaved);
((IAsyncController)controller).EndExecute(outerAsyncResult);
Assert.True(controller.TempDataSaved);
Assert.True(controller.HandleUnknownActionCalled);
}
[Fact]
public void ExecuteCore_Synchronous_ActionFound()
{
// Arrange
MockAsyncResult innerAsyncResult = new MockAsyncResult();
Mock<IActionInvoker> mockActionInvoker = new Mock<IActionInvoker>();
mockActionInvoker.Setup(o => o.InvokeAction(It.IsAny<ControllerContext>(), "SomeAction")).Returns(true);
RequestContext requestContext = GetRequestContext("SomeAction");
EmptyController controller = new EmptyController()
{
ActionInvoker = mockActionInvoker.Object
};
// Act & assert
IAsyncResult outerAsyncResult = ((IAsyncController)controller).BeginExecute(requestContext, null, null);
Assert.False(controller.TempDataSaved);
((IAsyncController)controller).EndExecute(outerAsyncResult);
Assert.True(controller.TempDataSaved);
Assert.False(controller.HandleUnknownActionCalled);
}
[Fact]
public void ExecuteCore_Synchronous_ActionNotFound()
{
// Arrange
MockAsyncResult innerAsyncResult = new MockAsyncResult();
Mock<IActionInvoker> mockActionInvoker = new Mock<IActionInvoker>();
mockActionInvoker.Setup(o => o.InvokeAction(It.IsAny<ControllerContext>(), "SomeAction")).Returns(false);
RequestContext requestContext = GetRequestContext("SomeAction");
EmptyController controller = new EmptyController()
{
ActionInvoker = mockActionInvoker.Object
};
// Act & assert
IAsyncResult outerAsyncResult = ((IAsyncController)controller).BeginExecute(requestContext, null, null);
Assert.False(controller.TempDataSaved);
((IAsyncController)controller).EndExecute(outerAsyncResult);
Assert.True(controller.TempDataSaved);
Assert.True(controller.HandleUnknownActionCalled);
}
[Fact]
public void ExecuteCore_SavesTempDataOnException()
{
// Arrange
Mock<IAsyncActionInvoker> mockActionInvoker = new Mock<IAsyncActionInvoker>();
mockActionInvoker
.Setup(o => o.BeginInvokeAction(It.IsAny<ControllerContext>(), "SomeAction", It.IsAny<AsyncCallback>(), It.IsAny<object>()))
.Throws(new Exception("Some exception text."));
RequestContext requestContext = GetRequestContext("SomeAction");
EmptyController controller = new EmptyController()
{
ActionInvoker = mockActionInvoker.Object
};
// Act & assert
Assert.Throws<Exception>(
delegate { ((IAsyncController)controller).BeginExecute(requestContext, null, null); },
@"Some exception text.");
Assert.True(controller.TempDataSaved);
}
[Fact]
public void CreateActionInvokerCallsIntoResolverInstance()
{
// Controller uses an IDependencyResolver to create an IActionInvoker.
var controller = new EmptyController();
Mock<IDependencyResolver> resolverMock = new Mock<IDependencyResolver>();
Mock<IAsyncActionInvoker> actionInvokerMock = new Mock<IAsyncActionInvoker>();
resolverMock.Setup(r => r.GetService(typeof(IAsyncActionInvoker))).Returns(actionInvokerMock.Object);
controller.Resolver = resolverMock.Object;
var ai = controller.CreateActionInvoker();
resolverMock.Verify(r => r.GetService(typeof(IAsyncActionInvoker)), Times.Once());
Assert.Same(actionInvokerMock.Object, ai);
}
[Fact]
public void CreateActionInvokerCallsIntoResolverInstanceAndCreatesANewOneIfNecessary()
{
// If IDependencyResolver is set, but empty, falls back and still creates.
var controller = new EmptyController();
Mock<IDependencyResolver> resolverMock = new Mock<IDependencyResolver>();
resolverMock.Setup(r => r.GetService(typeof(IAsyncActionInvoker))).Returns(null);
resolverMock.Setup(r => r.GetService(typeof(IActionInvoker))).Returns(null);
controller.Resolver = resolverMock.Object;
var ai = controller.CreateActionInvoker();
resolverMock.Verify(r => r.GetService(typeof(IAsyncActionInvoker)), Times.Once());
resolverMock.Verify(r => r.GetService(typeof(IActionInvoker)), Times.Once());
Assert.NotNull(ai);
}
private static RequestContext GetRequestContext(string actionName)
{
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
RouteData routeData = new RouteData();
routeData.Values["action"] = actionName;
return new RequestContext(mockHttpContext.Object, routeData);
}
private class EmptyController : AsyncController
{
public bool TempDataSaved;
public bool HandleUnknownActionCalled;
protected override ITempDataProvider CreateTempDataProvider()
{
return new DummyTempDataProvider();
}
protected override void HandleUnknownAction(string actionName)
{
HandleUnknownActionCalled = true;
}
// Test can expose protected method as public.
public new IActionInvoker CreateActionInvoker()
{
return base.CreateActionInvoker();
}
private class DummyTempDataProvider : ITempDataProvider
{
public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
{
return new TempDataDictionary();
}
public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
{
((EmptyController)controllerContext.Controller).TempDataSaved = true;
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More