/// <summary> /// Validates the specified IBAN for correctness. /// </summary> /// <param name="iban">The IBAN value.</param> /// <returns>a validation result, indicating if the IBAN is valid or not</returns> public ValidationResult Validate(string?iban) { string?normalizedIban = Iban.NormalizeOrNull(iban); var context = new ValidationRuleContext(normalizedIban ?? string.Empty); var validationResult = new ValidationResult { AttemptedValue = normalizedIban }; foreach (IIbanValidationRule rule in _rules) { try { validationResult.Error = rule.Validate(context) as ErrorResult; } #pragma warning disable CA1031 // Do not catch general exception types - justification: custom rules can throw unexpected exceptions. We handle it with ExceptionResult. catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { validationResult.Error = new ExceptionResult(ex); } if (!validationResult.IsValid) { break; } } validationResult.Country = context.Country; return(validationResult); }
public void Given_multiple_check_digit_validators_matching_the_country_when_validating_it_should_validate_using_any(bool matchesFirst) { var checkDigitValidatorStubs = new Dictionary <string, IEnumerable <NationalCheckDigitsValidator> > { { "ZZ", new[] { _checkDigitsValidatorMock.Object, _checkDigitsValidatorMock.Object } } }; _checkDigitsValidatorMock .SetupSequence(m => m.Validate(It.IsAny <string>())) .Returns(matchesFirst) .Returns(true); var sut = new HasValidNationalCheckDigitsRule(checkDigitValidatorStubs); var context = new ValidationRuleContext("ZZ0123456", new IbanCountry("ZZ") { Bban = new BbanStructure( new TestPattern(new[] { new PatternToken(AsciiCategory.Digit, 7) }), 2) }); // Act sut.Validate(context); // Assert _checkDigitsValidatorMock.Verify(m => m.Validate(It.IsAny <string>()), Times.Exactly(matchesFirst ? 1 : 2)); }
public void Given_that_no_validator_matches_iban_country_when_validating_it_should_pass() { var context = new ValidationRuleContext("XX000000", new IbanCountry("XX")); // Act ValidationRuleResult actual = _sut.Validate(context); // Assert actual.Should().BeSameAs(ValidationRuleResult.Success); _checkDigitsValidatorMock.Verify(m => m.Validate(It.IsAny <string>()), Times.Never); }
public void Given_that_bban_structure_length_is_zero_when_validating_it_should_fail() { var context = new ValidationRuleContext("ZZ000000", new IbanCountry("ZZ") { Bban = new BbanStructure(new TestPattern(Enumerable.Empty <PatternToken>())) }); // Act ValidationRuleResult actual = _sut.Validate(context); // Assert actual.Should().BeOfType <InvalidNationalCheckDigitsResult>(); _checkDigitsValidatorMock.Verify(m => m.Validate(It.IsAny <string>()), Times.Never); }
public void When_validating_it_should_extract_bban_from_iban(int position, int length, string expectedExtractedBban) { var context = new ValidationRuleContext("ZZ0123456", new IbanCountry("ZZ") { Bban = new BbanStructure( new TestPattern(new[] { new PatternToken(AsciiCategory.Digit, length) }), position) }); // Act _sut.Validate(context); // Assert _checkDigitsValidatorMock.Verify(m => m.Validate(expectedExtractedBban), Times.Once); }
public void Given_that_bban_expected_length_is_greater_than_available_when_validating_it_should_fail(int position, int length) { var context = new ValidationRuleContext("ZZ000000", new IbanCountry("ZZ") { Bban = new BbanStructure( new TestPattern(new[] { new PatternToken(AsciiCategory.Digit, length) }), position) }); // Act ValidationRuleResult actual = _sut.Validate(context); // Assert actual.Should().BeOfType <InvalidNationalCheckDigitsResult>(); _checkDigitsValidatorMock.Verify(m => m.Validate(It.IsAny <string>()), Times.Never); }
/// <inheritdoc /> public ValidationRuleResult Validate(ValidationRuleContext context) { if (!_nationalCheckDigitsValidators.TryGetValue(context.Country !.TwoLetterISORegionName, out IEnumerable <NationalCheckDigitsValidator>?checkDigitsValidators)) { // No national check digits validators found. return(ValidationRuleResult.Success); } BbanStructure bbanStructure = context.Country.Bban; if (bbanStructure.Position + bbanStructure.Length > context.Value.Length || bbanStructure.Length == 0) { // BBAN positional data unavailable, or not matching input. return(new InvalidNationalCheckDigitsResult()); } string bban = context.Value.Substring(bbanStructure.Position, bbanStructure.Length); return(checkDigitsValidators.Any(validator => validator.Validate(bban)) ? ValidationRuleResult.Success : new InvalidNationalCheckDigitsResult()); }
public void Given_multiple_check_digit_validators_when_validating_it_should_only_use_those_that_have_matching_country() { var matchingCheckDigitValidatorMock = new Mock <NationalCheckDigitsValidator>(Mock.Of <ICheckDigitsCalculator>(), new[] { "WW" }); var checkDigitValidatorStubs = new Dictionary <string, IEnumerable <NationalCheckDigitsValidator> > { { "ZZ", new[] { _checkDigitsValidatorMock.Object } }, { "WW", new[] { matchingCheckDigitValidatorMock.Object } } }; _checkDigitsValidatorMock .Setup(m => m.Validate(It.IsAny <string>())) .Returns(true) .Verifiable(); matchingCheckDigitValidatorMock .Setup(m => m.Validate(It.IsAny <string>())) .Returns(true) .Verifiable(); var sut = new HasValidNationalCheckDigitsRule(checkDigitValidatorStubs); var context = new ValidationRuleContext("WW0123456", new IbanCountry("WW") { Bban = new BbanStructure( new TestPattern(new[] { new PatternToken(AsciiCategory.Digit, 7) }), 2) }); // Act ValidationRuleResult actual = sut.Validate(context); // Assert actual.Should().BeSameAs(ValidationRuleResult.Success); matchingCheckDigitValidatorMock.Verify(); _checkDigitsValidatorMock.Verify(m => m.Validate(It.IsAny <string>()), Times.Never); }
public ValidationRuleResult Validate(ValidationRuleContext context) { return(ValidationRuleResult.Success); }
public ValidationRuleResult Validate(ValidationRuleContext context) { throw new NotImplementedException(); }