public void ModelStateDictionary_ReturnGenericErrorMessage_WhenModelStateNotSet() { // Arrange var expected = "The supplied value is invalid for Length."; var dictionary = new ModelStateDictionary(); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act dictionary.TryAddModelError("key", new FormatException(), metadata); // Assert var error = Assert.Single(dictionary["key"].Errors); Assert.Equal(expected, error.ErrorMessage); }
public void ModelStateDictionary_NoErrorMessage_ForNonFormatException() { // Arrange var dictionary = new ModelStateDictionary(); dictionary.SetModelValue("key", new string[] { "some value" }, "some value"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act dictionary.TryAddModelError("key", new InvalidOperationException(), metadata); // Assert var error = Assert.Single(dictionary["key"].Errors); Assert.Empty(error.ErrorMessage); }
public void ModelStateDictionary_ReturnSpecificErrorMessage_WhenModelStateSet() { // Arrange var expected = "The value 'some value' is not valid for Length."; var dictionary = new ModelStateDictionary(); dictionary.SetModelValue("key", new string[] { "some value" }, "some value"); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act dictionary.TryAddModelError("key", new FormatException(), metadata); // Assert var error = Assert.Single(dictionary["key"].Errors); Assert.Equal(expected, error.ErrorMessage); }
public void TryAddModelError_WithErrorString_ReturnsFalse_AndAddsMaxModelErrorMessage() { // Arrange var expected = "The maximum number of allowed model errors has been reached."; var dictionary = new ModelStateDictionary { MaxAllowedErrors = 3 }; var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act and Assert Assert.False(dictionary.HasReachedMaxErrors); var result = dictionary.TryAddModelError("key1", "error1"); Assert.True(result); Assert.False(dictionary.HasReachedMaxErrors); result = dictionary.TryAddModelError("key2", new Exception(), metadata); Assert.True(result); Assert.False(dictionary.HasReachedMaxErrors); // Still room for TooManyModelErrorsException. result = dictionary.TryAddModelError("key3", "error3"); Assert.False(result); Assert.True(dictionary.HasReachedMaxErrors); result = dictionary.TryAddModelError("key4", "error4"); // no-op Assert.False(result); Assert.True(dictionary.HasReachedMaxErrors); Assert.Equal(3, dictionary.ErrorCount); Assert.Equal(3, dictionary.Count); var error = Assert.Single(dictionary[string.Empty].Errors); Assert.IsType <TooManyModelErrorsException>(error.Exception); Assert.Equal(expected, error.Exception.Message); // TooManyModelErrorsException added instead of key3 error. Assert.DoesNotContain("key3", dictionary.Keys); // Last addition did nothing. Assert.DoesNotContain("key4", dictionary.Keys); }
public void AddModelErrorUsesExistingModelStateIfPresent() { // Arrange var dictionary = new ModelStateDictionary(); dictionary.AddModelError("some key", "some error"); var exception = new Exception(); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act dictionary.AddModelError("some key", exception, metadata); // Assert Assert.Equal(2, dictionary.ErrorCount); var kvp = Assert.Single(dictionary); Assert.Equal("some key", kvp.Key); Assert.Equal(2, kvp.Value.Errors.Count); Assert.Equal("some error", kvp.Value.Errors[0].ErrorMessage); Assert.Same(exception, kvp.Value.Errors[1].Exception); }
public void ModelStateConstructorWithDetail_AddsCorrectDictionaryItems() { // Arrange ModelStateDictionary modelState = new ModelStateDictionary(); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); modelState.AddModelError("[0].Name", "error1"); modelState.AddModelError("[0].Name", "error2"); modelState.AddModelError("[0].Address", "error"); modelState.AddModelError("[2].Name", new Exception("OH NO"), metadata); // Act HttpError error = new HttpError(modelState, true); // Assert HttpError modelStateError = error["ModelState"] as HttpError; Assert.Contains(new KeyValuePair<string, object>("Message", "The request is invalid."), error); Assert.Contains("error1", modelStateError["[0].Name"] as IEnumerable<string>); Assert.Contains("error2", modelStateError["[0].Name"] as IEnumerable<string>); Assert.Contains("error", modelStateError["[0].Address"] as IEnumerable<string>); Assert.True(modelStateError.ContainsKey("[2].Name")); Assert.Contains("OH NO", modelStateError["[2].Name"] as IEnumerable<string>); }
public void ModelStateDictionary_TracksAddedErrorsOverCopyConstructor() { // Arrange var expected = "The maximum number of allowed model errors has been reached."; var dictionary = new ModelStateDictionary { MaxAllowedErrors = 3 }; var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act dictionary.AddModelError("key1", "error1"); dictionary.TryAddModelError("key3", new Exception(), metadata); var copy = new ModelStateDictionary(dictionary); copy.AddModelError("key2", "error2"); // Assert Assert.Equal(3, copy.Count); var error = Assert.Single(copy[string.Empty].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); Assert.Equal(expected, error.Exception.Message); }
public void TryAddModelError_WithException_ReturnsFalse_AndAddsMaxModelErrorMessage() { // Arrange var expected = "The maximum number of allowed model errors has been reached."; var dictionary = new ModelStateDictionary { MaxAllowedErrors = 3 }; var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act and Assert var result = dictionary.TryAddModelError("key1", "error1"); Assert.True(result); result = dictionary.TryAddModelError("key2", new Exception(), metadata); Assert.True(result); result = dictionary.TryAddModelError("key3", new Exception(), metadata); Assert.False(result); Assert.Equal(3, dictionary.Count); var error = Assert.Single(dictionary[string.Empty].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); Assert.Equal(expected, error.Exception.Message); }
public void AddModelError_WithException_AddsTooManyModelError_WhenMaxErrorIsReached() { // Arrange var expected = "The maximum number of allowed model errors has been reached."; var dictionary = new ModelStateDictionary { MaxAllowedErrors = 4 }; var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); dictionary.AddModelError("key1", new Exception(), metadata); dictionary.AddModelError("key2", "error2"); dictionary.AddModelError("key3", "error3"); dictionary.AddModelError("key3", new Exception(), metadata); // Act and Assert Assert.True(dictionary.HasReachedMaxErrors); Assert.Equal(4, dictionary.ErrorCount); Assert.Equal(4, dictionary.Count); var error = Assert.Single(dictionary[string.Empty].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); Assert.Equal(expected, error.Exception.Message); // Second key3 model error resulted in TooManyModelErrorsException instead. error = Assert.Single(dictionary["key3"].Errors); Assert.Null(error.Exception); Assert.Equal("error3", error.ErrorMessage); }
public void Validate_SkipsRemainingValidationIfModelStateIsInvalid() { // Because a property validator fails, the model validator shouldn't run // Arrange var expected = new[] { "In OnValidating()", "In IValidatableObject.Validate()", "In OnValidated()" }; var log = new List<string>(); var model = new LoggingValidatableObject(log); var modelMetadata = GetModelMetadata(model); var provider = new EmptyModelMetadataProvider(); var childMetadata = provider.GetMetadataForProperty(() => model, model.GetType(), "InvalidStringProperty"); var node = new ModelValidationNode(modelMetadata, "theKey"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.InvalidStringProperty")); node.Validating += (sender, e) => log.Add("In OnValidating()"); node.Validated += (sender, e) => log.Add("In OnValidated()"); var context = CreateContext(modelMetadata); // Act node.Validate(context); // Assert Assert.Equal(expected, log); Assert.Equal("Sample error message", context.ModelState["theKey.InvalidStringProperty"].Errors[0].ErrorMessage); }
// Adds one or more errors for all properties in OrderedModel. But adds errors out of order. private void AddOrderedErrors(ModelStateDictionary modelState) { var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(OrderedModel), nameof(OrderedModel.Property3)); modelState.AddModelError("Property3", "This is an error for Property3."); modelState.AddModelError("Property3", new InvalidCastException("An ignored Exception."), metadata); modelState.AddModelError("Property2", "This is an error for Property2."); modelState.AddModelError("Property2", "This is another error for Property2."); modelState.AddModelError("OrderedProperty3", "This is an error for OrderedProperty3."); modelState.AddModelError("OrderedProperty2", "This is an error for OrderedProperty2."); modelState.AddModelError("OrderedProperty2", "This is another error for OrderedProperty2."); modelState.AddModelError("LastProperty", "This is an error for LastProperty."); modelState.AddModelError("Property1", "This is an error for Property1."); modelState.AddModelError("Property1", "This is another error for Property1."); modelState.AddModelError("OrderedProperty1", "This is an error for OrderedProperty1."); modelState.AddModelError("OrderedProperty2", "This is yet-another error for OrderedProperty2."); }
// Adds errors for various parts of the model, including the root. private void AddMultipleErrors(ModelStateDictionary modelState) { modelState.AddModelError("Property3.Property2", "This is an error for Property3.Property2."); modelState.AddModelError("Property3.OrderedProperty3", "This is an error for Property3.OrderedProperty3."); modelState.AddModelError("Property3.OrderedProperty2", "This is an error for Property3.OrderedProperty2."); var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(ValidationModel), nameof(ValidationModel.Property3)); modelState.AddModelError("Property3", "This is an error for Property3."); modelState.AddModelError("Property3", new InvalidCastException("Exception will be ignored."), metadata); metadata = provider.GetMetadataForProperty(typeof(ValidationModel), nameof(ValidationModel.Property2)); modelState.AddModelError("Property2", "This is an error for Property2."); modelState.AddModelError("Property2", "This is another error for Property2."); modelState.AddModelError("Property2", new OverflowException("Produces invalid value message"), metadata); metadata = provider.GetMetadataForType(typeof(ValidationModel)); modelState.AddModelError(string.Empty, "This is an error for the model root."); modelState.AddModelError(string.Empty, "This is another error for the model root."); modelState.AddModelError(string.Empty, new InvalidOperationException("Another ignored Exception."), metadata); }
public void AddModelError_WithErrorString_AddsTooManyModelErrors_WhenMaxErrorsIsReached() { // Arrange var expected = "The maximum number of allowed model errors has been reached."; var dictionary = new ModelStateDictionary { MaxAllowedErrors = 5 }; var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); dictionary.AddModelError("key1", "error1"); dictionary.AddModelError("key2", new Exception(), metadata); dictionary.AddModelError("key3", new Exception(), metadata); dictionary.AddModelError("key4", "error4"); dictionary.AddModelError("key5", "error5"); // Act and Assert Assert.True(dictionary.HasReachedMaxErrors); Assert.Equal(5, dictionary.ErrorCount); var error = Assert.Single(dictionary[string.Empty].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); Assert.Equal(expected, error.Exception.Message); // TooManyModelErrorsException added instead of key5 error. Assert.DoesNotContain("key5", dictionary.Keys); }
public void TryAddModelError_WithErrorString_ReturnsFalse_AndAddsMaxModelErrorMessage() { // Arrange var expected = "The maximum number of allowed model errors has been reached."; var dictionary = new ModelStateDictionary { MaxAllowedErrors = 3 }; var provider = new EmptyModelMetadataProvider(); var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length)); // Act and Assert Assert.False(dictionary.HasReachedMaxErrors); var result = dictionary.TryAddModelError("key1", "error1"); Assert.True(result); Assert.False(dictionary.HasReachedMaxErrors); result = dictionary.TryAddModelError("key2", new Exception(), metadata); Assert.True(result); Assert.False(dictionary.HasReachedMaxErrors); // Still room for TooManyModelErrorsException. result = dictionary.TryAddModelError("key3", "error3"); Assert.False(result); Assert.True(dictionary.HasReachedMaxErrors); result = dictionary.TryAddModelError("key4", "error4"); // no-op Assert.False(result); Assert.True(dictionary.HasReachedMaxErrors); Assert.Equal(3, dictionary.ErrorCount); Assert.Equal(3, dictionary.Count); var error = Assert.Single(dictionary[string.Empty].Errors); Assert.IsType<TooManyModelErrorsException>(error.Exception); Assert.Equal(expected, error.Exception.Message); // TooManyModelErrorsException added instead of key3 error. Assert.DoesNotContain("key3", dictionary.Keys); // Last addition did nothing. Assert.DoesNotContain("key4", dictionary.Keys); }
public void Validate_Ordering() { // Proper order of invocation: // 1. OnValidating() // 2. Child validators // 3. This validator // 4. OnValidated() // Arrange var expected = new[] { "In OnValidating()", "In LoggingValidatonAttribute.IsValid()", "In IValidatableObject.Validate()", "In OnValidated()" }; var log = new List<string>(); var model = new LoggingValidatableObject(log); var modelMetadata = GetModelMetadata(model); var provider = new EmptyModelMetadataProvider(); var childMetadata = provider.GetMetadataForProperty(() => model, model.GetType(), "ValidStringProperty"); var node = new ModelValidationNode(modelMetadata, "theKey"); node.Validating += (sender, e) => log.Add("In OnValidating()"); node.Validated += (sender, e) => log.Add("In OnValidated()"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.ValidStringProperty")); var context = CreateContext(modelMetadata); // Act node.Validate(context); // Assert Assert.Equal(expected, log); }