// 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 dictionary = new Dictionary() { { "stringParameterWithDefaultValue", 42 } }; // Act object value = ActionDescriptor.ExtractParameterOrDefaultFromDictionary(ParameterExtractionController.StringParameterWithDefaultValue, dictionary); // Assert Assert.Equal("hello", value); } [Fact] public void ExtractParameterOrDefaultFromDictionary_ReturnsDefaultTypeValueIfNoMatchAndNoDefaultParameterValue() { // Arrange Dictionary dictionary = new Dictionary(); // Act object value = ActionDescriptor.ExtractParameterOrDefaultFromDictionary(ParameterExtractionController.IntParameter, dictionary); // Assert Assert.Equal(0, value); } [Fact] public void ExtractParameterOrDefaultFromDictionary_ReturnsDictionaryValueIfTypeMatch() { // Arrange Dictionary dictionary = new Dictionary() { { "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 mockDescriptor = new Mock() { 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() { CallBase = true }; mockDescriptor.Setup(d => d.GetCustomAttributes(typeof(FilterAttribute), true)).Returns(new object[] { new Mock().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 selectors = ad.GetSelectors(); // Assert Assert.IsType(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().Object; var descriptor1 = new Mock { CallBase = true }; descriptor1.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor); descriptor1.SetupGet(d => d.ActionName).Returns("Action1"); var descriptor2 = new Mock { 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().Object; var descriptor1 = new Mock { CallBase = true }; descriptor1.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor); descriptor1.SetupGet(d => d.ActionName).Returns("Action1"); var descriptor2 = new Mock { 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(); controllerDescriptor1.SetupGet(cd => cd.UniqueId).Returns("1"); var descriptor1 = new Mock { CallBase = true }; descriptor1.SetupGet(d => d.ControllerDescriptor).Returns(controllerDescriptor1.Object); descriptor1.SetupGet(d => d.ActionName).Returns("Action1"); var controllerDescriptor2 = new Mock(); controllerDescriptor2.SetupGet(cd => cd.UniqueId).Returns("2"); var descriptor2 = new Mock { 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().Object; public override string ActionName { get { return "ActionName"; } } public override ControllerDescriptor ControllerDescriptor { get { return controllerDescriptor; } } public override object Execute(ControllerContext controllerContext, IDictionary parameters) { throw new NotImplementedException(); } public override ParameterDescriptor[] GetParameters() { throw new NotImplementedException(); } } class DerivedDescriptor : BaseDescriptor { } private static ActionDescriptor GetActionDescriptor() { Mock mockDescriptor = new Mock() { 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) { } } } }