a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
327 lines
11 KiB
C#
327 lines
11 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Web.Mvc;
|
|
using Xunit;
|
|
using Assert = Microsoft.TestCommon.AssertEx;
|
|
|
|
namespace Microsoft.Web.Mvc.ModelBinding.Test
|
|
{
|
|
public class ModelBinderUtilTest
|
|
{
|
|
[Fact]
|
|
public void CastOrDefault_CorrectType_ReturnsInput()
|
|
{
|
|
// Act
|
|
int retVal = ModelBinderUtil.CastOrDefault<int>(42);
|
|
|
|
// Assert
|
|
Assert.Equal(42, retVal);
|
|
}
|
|
|
|
[Fact]
|
|
public void CastOrDefault_IncorrectType_ReturnsDefaultTModel()
|
|
{
|
|
// Act
|
|
DateTime retVal = ModelBinderUtil.CastOrDefault<DateTime>(42);
|
|
|
|
// Assert
|
|
Assert.Equal(default(DateTime), retVal);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateIndexModelName_EmptyParentName()
|
|
{
|
|
// Act
|
|
string fullChildName = ModelBinderUtil.CreateIndexModelName("", 42);
|
|
|
|
// Assert
|
|
Assert.Equal("[42]", fullChildName);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateIndexModelName_IntIndex()
|
|
{
|
|
// Act
|
|
string fullChildName = ModelBinderUtil.CreateIndexModelName("parentName", 42);
|
|
|
|
// Assert
|
|
Assert.Equal("parentName[42]", fullChildName);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateIndexModelName_StringIndex()
|
|
{
|
|
// Act
|
|
string fullChildName = ModelBinderUtil.CreateIndexModelName("parentName", "index");
|
|
|
|
// Assert
|
|
Assert.Equal("parentName[index]", fullChildName);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreatePropertyModelName()
|
|
{
|
|
// Act
|
|
string fullChildName = ModelBinderUtil.CreatePropertyModelName("parentName", "childName");
|
|
|
|
// Assert
|
|
Assert.Equal("parentName.childName", fullChildName);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreatePropertyModelName_EmptyParentName()
|
|
{
|
|
// Act
|
|
string fullChildName = ModelBinderUtil.CreatePropertyModelName("", "childName");
|
|
|
|
// Assert
|
|
Assert.Equal("childName", fullChildName);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetPossibleBinderInstance_Match_ReturnsBinder()
|
|
{
|
|
// Act
|
|
IExtensibleModelBinder binder = ModelBinderUtil.GetPossibleBinderInstance(typeof(List<int>), typeof(List<>), typeof(SampleGenericBinder<>));
|
|
|
|
// Assert
|
|
Assert.IsType<SampleGenericBinder<int>>(binder);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetPossibleBinderInstance_NoMatch_ReturnsNull()
|
|
{
|
|
// Act
|
|
IExtensibleModelBinder binder = ModelBinderUtil.GetPossibleBinderInstance(typeof(ArraySegment<int>), typeof(List<>), typeof(SampleGenericBinder<>));
|
|
|
|
// Assert
|
|
Assert.Null(binder);
|
|
}
|
|
|
|
[Fact]
|
|
public void RawValueToObjectArray_RawValueIsEnumerable_ReturnsInputAsArray()
|
|
{
|
|
// Assert
|
|
List<int> original = new List<int> { 1, 2, 3, 4 };
|
|
|
|
// Act
|
|
object[] retVal = ModelBinderUtil.RawValueToObjectArray(original);
|
|
|
|
// Assert
|
|
Assert.Equal(new object[] { 1, 2, 3, 4 }, retVal);
|
|
}
|
|
|
|
[Fact]
|
|
public void RawValueToObjectArray_RawValueIsObject_WrapsObjectInSingleElementArray()
|
|
{
|
|
// Act
|
|
object[] retVal = ModelBinderUtil.RawValueToObjectArray(42);
|
|
|
|
// Assert
|
|
Assert.Equal(new object[] { 42 }, retVal);
|
|
}
|
|
|
|
[Fact]
|
|
public void RawValueToObjectArray_RawValueIsObjectArray_ReturnsInputInstance()
|
|
{
|
|
// Assert
|
|
object[] original = new object[2];
|
|
|
|
// Act
|
|
object[] retVal = ModelBinderUtil.RawValueToObjectArray(original);
|
|
|
|
// Assert
|
|
Assert.Same(original, retVal);
|
|
}
|
|
|
|
[Fact]
|
|
public void RawValueToObjectArray_RawValueIsString_WrapsStringInSingleElementArray()
|
|
{
|
|
// Act
|
|
object[] retVal = ModelBinderUtil.RawValueToObjectArray("hello");
|
|
|
|
// Assert
|
|
Assert.Equal(new object[] { "hello" }, retVal);
|
|
}
|
|
|
|
[Fact]
|
|
public void ReplaceEmptyStringWithNull_ConvertEmptyStringToNullDisabled_ModelIsEmptyString_LeavesModelAlone()
|
|
{
|
|
// Arrange
|
|
ModelMetadata modelMetadata = GetMetadata(typeof(string));
|
|
modelMetadata.ConvertEmptyStringToNull = false;
|
|
|
|
// Act
|
|
object model = "";
|
|
ModelBinderUtil.ReplaceEmptyStringWithNull(modelMetadata, ref model);
|
|
|
|
// Assert
|
|
Assert.Equal("", model);
|
|
}
|
|
|
|
[Fact]
|
|
public void ReplaceEmptyStringWithNull_ConvertEmptyStringToNullEnabled_ModelIsEmptyString_ReplacesModelWithNull()
|
|
{
|
|
// Arrange
|
|
ModelMetadata modelMetadata = GetMetadata(typeof(string));
|
|
modelMetadata.ConvertEmptyStringToNull = true;
|
|
|
|
// Act
|
|
object model = "";
|
|
ModelBinderUtil.ReplaceEmptyStringWithNull(modelMetadata, ref model);
|
|
|
|
// Assert
|
|
Assert.Null(model);
|
|
}
|
|
|
|
[Fact]
|
|
public void ReplaceEmptyStringWithNull_ConvertEmptyStringToNullEnabled_ModelIsWhitespaceString_ReplacesModelWithNull()
|
|
{
|
|
// Arrange
|
|
ModelMetadata modelMetadata = GetMetadata(typeof(string));
|
|
modelMetadata.ConvertEmptyStringToNull = true;
|
|
|
|
// Act
|
|
object model = " "; // whitespace
|
|
ModelBinderUtil.ReplaceEmptyStringWithNull(modelMetadata, ref model);
|
|
|
|
// Assert
|
|
Assert.Null(model);
|
|
}
|
|
|
|
[Fact]
|
|
public void ReplaceEmptyStringWithNull_ConvertEmptyStringToNullDisabled_ModelIsNotEmptyString_LeavesModelAlone()
|
|
{
|
|
// Arrange
|
|
ModelMetadata modelMetadata = GetMetadata(typeof(string));
|
|
modelMetadata.ConvertEmptyStringToNull = true;
|
|
|
|
// Act
|
|
object model = 42;
|
|
ModelBinderUtil.ReplaceEmptyStringWithNull(modelMetadata, ref model);
|
|
|
|
// Assert
|
|
Assert.Equal(42, model);
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContext_SuccessWithNonNullModel()
|
|
{
|
|
// Arrange
|
|
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
|
|
{
|
|
ModelMetadata = GetMetadata(typeof(string))
|
|
};
|
|
bindingContext.ModelMetadata.Model = "hello!";
|
|
|
|
// Act
|
|
ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(string), false);
|
|
|
|
// Assert
|
|
// Nothing to do - if we got this far without throwing, the test succeeded
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContext_SuccessWithNullModel()
|
|
{
|
|
// Arrange
|
|
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
|
|
{
|
|
ModelMetadata = GetMetadata(typeof(string))
|
|
};
|
|
|
|
// Act
|
|
ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(string), true);
|
|
|
|
// Assert
|
|
// Nothing to do - if we got this far without throwing, the test succeeded
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContextThrowsIfBindingContextIsNull()
|
|
{
|
|
// Act & assert
|
|
Assert.ThrowsArgumentNull(
|
|
delegate { ModelBinderUtil.ValidateBindingContext(null, typeof(string), true); }, "bindingContext");
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContextThrowsIfModelInstanceIsWrongType()
|
|
{
|
|
// Arrange
|
|
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
|
|
{
|
|
ModelMetadata = GetMetadata(typeof(string))
|
|
};
|
|
bindingContext.ModelMetadata.Model = 42;
|
|
|
|
// Act & assert
|
|
Assert.Throws<ArgumentException>(
|
|
delegate { ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(string), true); },
|
|
@"The binding context has a Model of type 'System.Int32', but this binder can only operate on models of type 'System.String'.
|
|
Parameter name: bindingContext");
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContextThrowsIfModelIsNullButCannotBe()
|
|
{
|
|
// Arrange
|
|
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
|
|
{
|
|
ModelMetadata = GetMetadata(typeof(string))
|
|
};
|
|
|
|
// Act & assert
|
|
Assert.Throws<ArgumentException>(
|
|
delegate { ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(string), false); },
|
|
@"The binding context has a null Model, but this binder requires a non-null model of type 'System.String'.
|
|
Parameter name: bindingContext");
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContextThrowsIfModelMetadataIsNull()
|
|
{
|
|
// Arrange
|
|
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext();
|
|
|
|
// Act & assert
|
|
Assert.Throws<ArgumentException>(
|
|
delegate { ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(string), true); },
|
|
@"The binding context cannot have a null ModelMetadata.
|
|
Parameter name: bindingContext");
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateBindingContextThrowsIfModelTypeIsWrong()
|
|
{
|
|
// Arrange
|
|
ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
|
|
{
|
|
ModelMetadata = GetMetadata(typeof(object))
|
|
};
|
|
|
|
// Act & assert
|
|
Assert.Throws<ArgumentException>(
|
|
delegate { ModelBinderUtil.ValidateBindingContext(bindingContext, typeof(string), true); },
|
|
@"The binding context has a ModelType of 'System.Object', but this binder can only operate on models of type 'System.String'.
|
|
Parameter name: bindingContext");
|
|
}
|
|
|
|
private static ModelMetadata GetMetadata(Type modelType)
|
|
{
|
|
EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider();
|
|
return provider.GetMetadataForType(null, modelType);
|
|
}
|
|
|
|
private class SampleGenericBinder<T> : IExtensibleModelBinder
|
|
{
|
|
public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
}
|