/// <summary> /// Banks the account. /// </summary> /// <param name="branchNumber">The combind branch/bank number. I.E. UK sort code</param> /// <returns></returns> public static bool BankAccount(this ValidatableValue<string> inputV, string branchNumber) { var errors = new List<ValidationResult>(); foreach (var l in inputV.Locale) { var validator = new ValidatableValue<string>(inputV.Value, l); if (validatorsWithBranch.ContainsKey(l)) { if (validatorsWithBranch[l](validator, branchNumber)) { //is valid no errors return true; } } else { validator.AddError($"Unable to validate banks for '{l}'"); } errors.AddRange(validator.Errors); } //lets add all the validation errors (if invalid to the source validatable) foreach (var r in errors) { inputV.AddError(r); } return inputV.IsValid; }
public void SetValue_WithTwoRule_AndInvalidValue_NotRaiseIfIsValidNotChanged() { // Arrange var startValue = "1234"; // valid var value = "1"; // invalid rule 1 var value2 = "123456"; // invalid rule 2 var sut = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new StringLengthValidationRule("Length Error", 2, false, true), new StringLengthValidationRule(_ERROR_MESSAGE, 5) }, Value = startValue }; // Act sut.Value = value; using (FluentAssertions.Events.IMonitor <ValidatableValue <string> > monitor = sut.Monitor()) { sut.Value = value2; // Assert monitor.Should().RaisePropertyChangeFor(t => t.Value); monitor.Should().RaisePropertyChangeFor(t => t.Errors); monitor.Should().RaisePropertyChangeFor(t => t.FirstError); monitor.Should().NotRaisePropertyChangeFor(t => t.IsValid); monitor.Should().NotRaisePropertyChangeFor(t => t.IsNotValid); } }
public void IsValidChangedEventRaised_OnIsValidChange() { // Arrange var startValue = "123456"; var sut = new ValidatableValue <string> { Value = startValue, ValidationRules = new IValidationRule <string>[] { new StringLengthValidationRule("Length Error", 2, false, true), new StringLengthValidationRule(_ERROR_MESSAGE, 5) } }; // Act sut.IsValid.Should().BeTrue(); sut.IsNotValid.Should().BeFalse(); using (FluentAssertions.Events.IMonitor <ValidatableValue <string> > monitor = sut.Monitor()) { sut.RaiseValidation(); // Assert monitor.Should().Raise(nameof(ValidatableValue <string> .IsValidChanged)) .WithSender(sut) .WithArgs <IsValidEventArgs>(t => t.IsValid == false); } }
public void SetValue_WithOneRule_AndInvalidValue_RaiseChanges() { // Arrange var startValue = "Not empty"; string value = null; var sut = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new NullValidationRule <string>(_ERROR_MESSAGE) }, Value = startValue }; // Act using (FluentAssertions.Events.IMonitor <ValidatableValue <string> > monitor = sut.Monitor()) { sut.Value = value; // Assert monitor.Should().RaisePropertyChangeFor(t => t.Value); monitor.Should().RaisePropertyChangeFor(t => t.Errors); monitor.Should().RaisePropertyChangeFor(t => t.FirstError); monitor.Should().RaisePropertyChangeFor(t => t.IsValid); monitor.Should().RaisePropertyChangeFor(t => t.IsNotValid); } }
public void Constructor_SetErrorMessage() { // Arrange / Act var compareValue = new ValidatableValue <int> { Value = 100 }; var sut = new SmallerThanValidationRule <int>(ERROR_MESSAGE, compareValue); // Assert sut.ErrorMessage.Should().Be(ERROR_MESSAGE); }
public void SetValue_SetNewValue(string startValue, string newValue) { // Arrange var sut = new ValidatableValue <string> { Value = startValue }; // Act sut.Value = newValue; // Assert sut.Value.Should().Be(newValue); }
private static bool IsLocalPhone(ValidatableValue<string> phoneNumber, string locale, string exitCode) { if (!phoneNumber.IsValueSet || string.IsNullOrWhiteSpace(phoneNumber.Value)) { return false; } Validator validator; if (LocaleMobilePhoneRegexes.TryGetValue(locale, out validator)) { return validator.Validate(phoneNumber.Value, exitCode); } return false; }
public void WithoutRules_IsAlwaysValid(string value) { // Arrange var sut = new ValidatableValue <string>(); // Act sut.Value = value; // Assert sut.IsValid.Should().BeTrue(); sut.IsNotValid.Should().BeFalse(); sut.FirstError.Should().Be(" "); sut.Errors.Should().BeEmpty(); }
[TestCase(101, 100, 100)] // Edge case, equal public void Validate_WithHigher_IsNotValid(int initValue, int newValue, int current) { // Arrange var compareValue = new ValidatableValue <int> { Value = initValue }; var sut = new SmallerThanValidationRule <int>(ERROR_MESSAGE, compareValue); sut.Validate(current).Should().BeTrue(); // Act compareValue.Value = newValue; var result = sut.Validate(current); // Assert result.Should().BeFalse(); }
public void SetValue_WithOneRule_AndValidValue_NoErrors() { // Arrange var value = "Not empty"; var sut = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new NullValidationRule <string>(_ERROR_MESSAGE) }, Value = value }; // Act // Assert sut.IsValid.Should().BeTrue(); sut.IsNotValid.Should().BeFalse(); sut.FirstError.Should().Be(" "); sut.Errors.Should().BeEmpty(); }
public void SetValue_WithDifferentValue_TriggerPropertyChanged() { // Arrange var value1 = Guid.NewGuid().ToString(); var value2 = Guid.NewGuid().ToString(); var sut = new ValidatableValue <string> { Value = value1 }; // Act using (FluentAssertions.Events.IMonitor <ValidatableValue <string> > monitor = sut.Monitor()) { sut.Value = value2; // Assert monitor.Should().RaisePropertyChangeFor(t => t.Value); } }
public void RaiseValidation_ValidateCurrentValue() { // Arrange var startValue = "123456"; var sut = new ValidatableValue <string> { Value = startValue, ValidationRules = new IValidationRule <string>[] { new StringLengthValidationRule("Length Error", 2, false, true), new StringLengthValidationRule(_ERROR_MESSAGE, 5) } }; // Act sut.IsValid.Should().BeTrue(); sut.IsNotValid.Should().BeFalse(); sut.RaiseValidation(); // Assert sut.IsValid.Should().BeFalse(); sut.IsNotValid.Should().BeTrue(); }
public void SetValue_WithOneRule_AndInvalidValue_OneError() { // Arrange var startValue = "Not empty"; string value = null; var sut = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new NullValidationRule <string>(_ERROR_MESSAGE) }, Value = startValue }; // Act sut.Value = value; // Assert sut.IsValid.Should().BeFalse(); sut.IsNotValid.Should().BeTrue(); sut.FirstError.Should().Be(_ERROR_MESSAGE); sut.Errors.Should().HaveCount(1); }
/// <summary> /// Constructor /// </summary> /// <param name="errorMessage"></param> /// <param name="compareValue">Value to compare against</param> /// <param name="equalIsValid">Equal values are valid (default: false)</param> public GreaterThanValidationRule(string errorMessage, ValidatableValue <T> compareValue, bool equalIsValid = false) { _compareValue = compareValue ?? throw new ArgumentNullException(nameof(compareValue)); _equalIsValid = equalIsValid; ErrorMessage = errorMessage; }
/// <summary> /// Validates the bank account to as though its UK based /// </summary> /// <param name="inputV">The input v.</param> /// <param name="branchNumber">The branch number.</param> /// <returns></returns> public static bool UKBankAccount(this ValidatableValue <string> accountValidatable, string branchNumber) { Initilize(); //convertToInt to seed up validator range checks var cleanedBranchNumber = RemoveSpacesAndHyphens(branchNumber); if (cleanedBranchNumber.Length != 6) { accountValidatable.AddError("branchNumber must be exactly 6 digits long"); return(accountValidatable.IsValid); } int integerBracnhNumber = 0; if (!int.TryParse(cleanedBranchNumber, out integerBracnhNumber)) { accountValidatable.AddError("branchNumber is in a invalid format"); } //lets run some account number/sortcodes var cleanedAccountNumber = RemoveSpacesAndHyphens(accountValidatable.Value); if (cleanedAccountNumber.Length < 8) { cleanedAccountNumber = cleanedAccountNumber.PadLeft(8, '0');//padded } if (cleanedAccountNumber.Length == 9) { //Santander (formerly Alliance & Leicester Commercial Bank plc) //we use the fist digit of the account as the last digit of the sortcode cleanedBranchNumber = cleanedBranchNumber.Substring(0, 5) + cleanedAccountNumber[0]; cleanedAccountNumber = cleanedAccountNumber.Substring(1, 8); } //if we have 10 digits then we actually have to perform the check twice becauseer there are 2 different ways to cut up an 8 digit number if (cleanedAccountNumber.Length == 10) { //this could be a 'National Westminster Bank plc' if so use last 8 var validatable = new ValidatableValue <string>(cleanedAccountNumber.Substring(2, 8)); UKBankAccount(validatable, cleanedBranchNumber); if (!validatable.IsValid) { //Co-Operative Bank plc last 8 validatable = new ValidatableValue <string>(cleanedAccountNumber.Substring(0, 8)); UKBankAccount(validatable, cleanedBranchNumber); } foreach (var e in validatable.Errors) { accountValidatable.AddError(e); } return(accountValidatable.IsValid); } var combindAccountRef = cleanedBranchNumber + cleanedAccountNumber; var validator = validators.Where(x => x.CanValidate(integerBracnhNumber, combindAccountRef)); if (!validator.Any()) { //is valid we cant test it return(accountValidatable.IsValid); } var firstTest = validator.First(); if (firstTest.Exception == 5) { //for exception 5 we need to swap out the sortcode and start again if (sortCodeSubstitutions.ContainsKey(cleanedBranchNumber)) { cleanedBranchNumber = sortCodeSubstitutions[cleanedBranchNumber]; integerBracnhNumber = int.Parse(cleanedBranchNumber); combindAccountRef = cleanedBranchNumber + cleanedAccountNumber; validator = validators.Where(x => x.CanValidate(integerBracnhNumber, combindAccountRef)); } } if (firstTest.Calculate(combindAccountRef)) { if (validator.Count() == 1 || new[] { 2, 9, 10, 11, 12, 13, 14 }.Contains(firstTest.Exception)) { return(accountValidatable.IsValid); } else { if (validator.Skip(1).First().Calculate(combindAccountRef)) { return(accountValidatable.IsValid); } } } else { var secondTest = validator.Skip(1).FirstOrDefault(); if (firstTest.Exception == 2) { combindAccountRef = "309634" + cleanedAccountNumber; secondTest = validators.FirstOrDefault(x => x.CanValidate(309634, combindAccountRef)); } if (new[] { 2, 9, 10, 11, 12, 13, 14 }.Contains(firstTest.Exception)) { if (secondTest?.Calculate(combindAccountRef) == true) { return(accountValidatable.IsValid); } } } accountValidatable.AddError("Invalid account details"); return(accountValidatable.IsValid); }
internal bool Validate(ValidatableValue<string> inputVal) { var val = inputVal.Value.ToUpper(); var charCount = val.Count(Char.IsLetterOrDigit); if (charCount != Length) { inputVal.AddError("Invalid length"); return false; } var sb = new StringBuilder(); for (var i = 0; i < val.Length; i++) { var c = val[i]; if (!Char.IsWhiteSpace(c)) { if (Char.IsLetter(c)) { //letter var v = (Char.ToUpper(c) - 'A') + 10; sb.Append(v); } else if (Char.IsDigit(c)) { sb.Append(c); } else { inputVal.AddError("Contains invalid character(s)"); return false; } } } val = sb.ToString(); val = val.Substring(6) + val.Substring(0, 6); var intVal = BigIntegerHelpers.Parse(val); var remainder = System.Numerics.BigInteger.Remainder(intVal, new System.Numerics.BigInteger(97)); if (!remainder.IsOne) { inputVal.AddError("Invalid check digit"); } //lets try and validate the actual account details if (!string.IsNullOrWhiteSpace(LocaleCode)) { val = inputVal.Value.ToUpper().Replace(" ", ""); var m = Pattern.Match(val); string bankCode = null; if (m.Groups["CG_S"] != null) { bankCode = m.Groups["CG_S"].Value;//sort code } var accountNumber = m.Groups["CG_C"].Value;//account number var validator = accountNumber.IsValid(LocaleCode); if (!validator.BankAccount(bankCode)) { foreach (var e in validator.Errors) { inputVal.AddError(e); } } } return inputVal.IsValid; }
/// <summary> /// Validates the bank account to as though its UK based /// </summary> /// <param name="inputV">The input v.</param> /// <param name="branchNumber">The branch number.</param> /// <returns></returns> public static bool UKBankAccount(this ValidatableValue<string> accountValidatable, string branchNumber) { Initilize(); //convertToInt to seed up validator range checks var cleanedBranchNumber = RemoveSpacesAndHyphens(branchNumber); if (cleanedBranchNumber.Length != 6) { accountValidatable.AddError("branchNumber must be exactly 6 digits long"); return accountValidatable.IsValid; } int integerBracnhNumber = 0; if (!int.TryParse(cleanedBranchNumber, out integerBracnhNumber)) { accountValidatable.AddError("branchNumber is in a invalid format"); } //lets run some account number/sortcodes var cleanedAccountNumber = RemoveSpacesAndHyphens(accountValidatable.Value); if (cleanedAccountNumber.Length < 8) { cleanedAccountNumber = cleanedAccountNumber.PadLeft(8, '0');//padded } if (cleanedAccountNumber.Length == 9) { //Santander (formerly Alliance & Leicester Commercial Bank plc) //we use the fist digit of the account as the last digit of the sortcode cleanedBranchNumber = cleanedBranchNumber.Substring(0, 5) + cleanedAccountNumber[0]; cleanedAccountNumber = cleanedAccountNumber.Substring(1, 8); } //if we have 10 digits then we actually have to perform the check twice becauseer there are 2 different ways to cut up an 8 digit number if (cleanedAccountNumber.Length == 10) { //this could be a 'National Westminster Bank plc' if so use last 8 var validatable = new ValidatableValue<string>(cleanedAccountNumber.Substring(2, 8)); UKBankAccount(validatable, cleanedBranchNumber); if (!validatable.IsValid) { //Co-Operative Bank plc last 8 validatable = new ValidatableValue<string>(cleanedAccountNumber.Substring(0, 8)); UKBankAccount(validatable, cleanedBranchNumber); } foreach (var e in validatable.Errors) { accountValidatable.AddError(e); } return accountValidatable.IsValid; } var combindAccountRef = cleanedBranchNumber + cleanedAccountNumber; var validator = validators.Where(x => x.CanValidate(integerBracnhNumber, combindAccountRef)); if (!validator.Any()) { //is valid we cant test it return accountValidatable.IsValid; } var firstTest = validator.First(); if (firstTest.Exception == 5) { //for exception 5 we need to swap out the sortcode and start again if (sortCodeSubstitutions.ContainsKey(cleanedBranchNumber)) { cleanedBranchNumber = sortCodeSubstitutions[cleanedBranchNumber]; integerBracnhNumber = int.Parse(cleanedBranchNumber); combindAccountRef = cleanedBranchNumber + cleanedAccountNumber; validator = validators.Where(x => x.CanValidate(integerBracnhNumber, combindAccountRef)); } } if (firstTest.Calculate(combindAccountRef)) { if (validator.Count() == 1 || new[] { 2, 9, 10, 11, 12, 13, 14 }.Contains(firstTest.Exception)) { return accountValidatable.IsValid; } else { if (validator.Skip(1).First().Calculate(combindAccountRef)) { return accountValidatable.IsValid; } } } else { var secondTest = validator.Skip(1).FirstOrDefault(); if (firstTest.Exception == 2) { combindAccountRef = "309634" + cleanedAccountNumber; secondTest = validators.FirstOrDefault(x => x.CanValidate(309634, combindAccountRef)); } if (new[] { 2, 9, 10, 11, 12, 13, 14 }.Contains(firstTest.Exception)) { if (secondTest?.Calculate(combindAccountRef) == true) { return accountValidatable.IsValid; } } } accountValidatable.AddError("Invalid account details"); return accountValidatable.IsValid; }
public MainViewModel() { // Init validatable values ContainsString = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new ContainsValidationRule <string>("Unknown value", new[] { "test", "example", "fake" }) } }; ContainsString.RaiseValidation(); NotContainsString = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new ContainsValidationRule <string>("Value already exists", new[] { "test", "example", "fake" }, true) } }; NotContainsString.RaiseValidation(); ContainsInteger = new ValidatableValue <int> { ValidationRules = new IValidationRule <int>[] { new ContainsValidationRule <int>("Unknown value", new[] { 5, 12, 25 }) } }; ContainsString.RaiseValidation(); Email = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new EmailValidationRule("Not valid email address", true) } }; Email.RaiseValidation(); EqualsValue = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new EqualValuesValidationRule <string>("Values are not equal", () => Email.Value) } }; EqualsValue.RaiseValidation(); NullValue = new ValidatableValue <ValueHolder> { ValidationRules = new IValidationRule <ValueHolder>[] { new NullValidationRule <ValueHolder>("Value is null") } }; NullValue.RaiseValidation(); PhoneNumber = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new PhoneNumberValidationRule("Not valid phone number") } }; PhoneNumber.RaiseValidation(); IntRange = new ValidatableValue <int> { ValidationRules = new IValidationRule <int>[] { new PrimitiveRangeValidationRule <int>("Value should be between 10 and 50", 10, 50) } }; IntRange.RaiseValidation(); RegexValue = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new RegexValidationRule("Allowed format: dd.MM.yyyy", @"^\d{2}\.\d{2}\.\d{4}$") } }; RegexValue.RaiseValidation(); MixedString = new ValidatableValue <string> { ValidationRules = new IValidationRule <string>[] { new RequiredValidationRule("Required!"), new StringLengthValidationRule("Password should have at least 8 characters!", 8, false), new StringLengthValidationRule("Password should have at maximum 32 characters!", 32) } }; MixedString.RaiseValidation(); // Values Values = new[] { null, new ValueHolder { Id = 1, DislayValue = "Value 1" }, new ValueHolder { Id = 2, DislayValue = "Value 2" }, new ValueHolder { Id = 3, DislayValue = "Value 3" } }; }