Skip to content

Commit

Permalink
Merge pull request #47 from SergeiMikhailovskii/feature/additional_va…
Browse files Browse the repository at this point in the history
…lidators

Feature/additional validators
  • Loading branch information
LinusMuema authored Oct 20, 2022
2 parents 2b5f828 + 661a580 commit 5412a84
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 0 deletions.
57 changes: 57 additions & 0 deletions form-builder/src/main/java/com/dsc/form_builder/TextFieldState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ open class TextFieldState(
val validations = validators.map {
when (it) {
is Validators.Email -> validateEmail(it.message)
is Validators.Phone -> validatePhone(it.message)
is Validators.WebUrl -> validateWebUrl(it.message)
is Validators.CardNumber -> validateCardNumber(it.message)
is Validators.Required -> validateRequired(it.message)
is Validators.Min -> validateMinChars(it.limit, it.message)
is Validators.Max -> validateMaxChars(it.limit, it.message)
Expand Down Expand Up @@ -89,6 +92,60 @@ open class TextFieldState(
return valid
}


/**
*This function validates a Phone in [value]
*It will return true if the string value is a valid phone number.
*The implementation makes use of the [android.util.Patterns] class to match the phone number.
*@param message the error message passed to [showError] to display if the value is not a valid phone number. By default we use the [PHONE_MESSAGE] constant.
*/
internal fun validatePhone(message: String): Boolean {
val phoneRegex = "(\\+[0-9]+)?(\\([0-9]+\\)[\\- ]*)?([0-9][0-9\\- ]+[0-9])"
val valid = phoneRegex.toRegex().matches(value)
if (!valid) showError(message)
return valid
}

/**
*This function validates a Web Url in [value]
*It will return true if the string value is a valid web url.
*@param message the error message passed to [showError] to display if the value is not a valid web url. By default we use the [WEB_URL_MESSAGE] constant.
*/
internal fun validateWebUrl(message: String): Boolean {
val webUrlRegex =
"(https?://)?(www\\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_+~#?&/=]*)"
val valid = webUrlRegex.toRegex().matches(value)
if (!valid) showError(message)
return valid
}

/**
*This function validates a Card Number in [value]
*It will return true if the string value is a valid card number.
*@param message the error message passed to [showError] to display if the value is not a valid card number. By default we use the [CARD_NUMBER_MESSAGE] constant.
*/
internal fun validateCardNumber(message: String): Boolean {
val cardNumberRegex = "(^3[47][0-9]{13}\$)|" +
"(^(6541|6556)[0-9]{12}\$)|" +
"(^389[0-9]{11}\$)|" +
"(^3(?:0[0-5]|[68][0-9])[0-9]{11}\$)|" +
"(^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})\$\n)|" +
"(^63[7-9][0-9]{13}\$)|" +
"(^(?:2131|1800|35\\d{3})\\d{11}\$)|" +
"(^9[0-9]{15}\$)|" +
"(^(6304|6706|6709|6771)[0-9]{12,15}\$)|" +
"(^(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}\$)|" +
"(^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))\$\n)|" +
"(^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}\$)|" +
"(^(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}\$\n)|" +
"(^(62[0-9]{14,17})\$)|" +
"(^4[0-9]{12}(?:[0-9]{3})?\$)|" +
"(^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})\$)"
val valid = cardNumberRegex.toRegex().matches(value)
if (!valid) showError(message)
return valid
}

/**
* This function validates a required field.
* It will return true if the value is not empty.
Expand Down
21 changes: 21 additions & 0 deletions form-builder/src/main/java/com/dsc/form_builder/Validators.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package com.dsc.form_builder

private const val EMAIL_MESSAGE = "invalid email address"
private const val REQUIRED_MESSAGE = "this field is required"
private const val PHONE_MESSAGE = "invalid phone number"
private const val WEB_URL_MESSAGE = "invalid web url"
private const val CARD_NUMBER_MESSAGE = "invalid card number"

/**
*
Expand Down Expand Up @@ -33,6 +36,24 @@ sealed interface Validators {
*/
class Email(var message: String = EMAIL_MESSAGE) : Validators

/**
* This is a phone validator. It will return true if the string value is a valid phone number. The implementation makes use of the [android.util.Patterns] class to match the phone number.
* @param message the error message to display if the value is not a valid phone number. By default we use the [PHONE_MESSAGE] constant.
*/
class Phone(var message: String = PHONE_MESSAGE) : Validators

/**
* This is a web url validator. It will return true if the string value is a valid web url.
* @param message the error message to display if the value is not a valid web url. By default we use the [WEB_URL_MESSAGE] constant.
*/
class WebUrl(var message: String = WEB_URL_MESSAGE) : Validators

/**
* This is a card number validator. It will return true if the string value is a valid card number.
* @param message the error message to display if the value is not a valid card number. By default we use the [CARD_NUMBER_MESSAGE] constant.
*/
class CardNumber(var message: String = CARD_NUMBER_MESSAGE) : Validators

/**
* This validator is used to check for numeric values. It will return true is the value is numeric and is greater than or equal to the specified limit.
* @param limit the minimum value that the value can hold.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,36 @@ object EmailArgumentsProvider : ArgumentsProvider {
)
}

object PhoneArgumentsProvider : ArgumentsProvider {
override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> = Stream.of(
Arguments.of("test", false),
Arguments.of("88005553535", true),
Arguments.of("+8(800) 555-35-35", true),
Arguments.of("8-800-555-35-35-", false),
)
}

object WebUrlArgumentsProvider : ArgumentsProvider {
override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> = Stream.of(
Arguments.of("test", false),
Arguments.of("htt://www.test.com", false),
Arguments.of("http://test.com", true),
Arguments.of("https://www.test.com", true),
Arguments.of("www.test.", false),
Arguments.of("www.test.com.mx", true),
Arguments.of("https://", false),
Arguments.of("www.test.com", true),
)
}

object CardNumberArgumentsProvider : ArgumentsProvider {
override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> = Stream.of(
Arguments.of("1111111111111111", false),
Arguments.of("1111", false),
Arguments.of("4548111111111111", true)
)
}

object MinCharsArgumentsProvider: ArgumentsProvider {
override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> = Stream.of(
Arguments.of("test", 2, true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,33 @@ internal class TextFieldStateTest {
assert(actual == expected)
}

@ParameterizedTest
@ArgumentsSource(PhoneArgumentsProvider::class)
fun `Validators_Phone works correctly`(phone: String, expected: Boolean) {
classToTest.change(phone)

val actual = classToTest.validatePhone("expected validation: $expected")
assert(actual == expected)
}

@ParameterizedTest
@ArgumentsSource(WebUrlArgumentsProvider::class)
fun `Validators_WebUrl works correctly`(webUrl: String, expected: Boolean) {
classToTest.change(webUrl)

val actual = classToTest.validateWebUrl("expected validation: $expected")
assert(actual == expected)
}

@ParameterizedTest
@ArgumentsSource(CardNumberArgumentsProvider::class)
fun `Validators_CardNumber works correctly`(cardNumber: String, expected: Boolean) {
classToTest.change(cardNumber)

val actual = classToTest.validateCardNumber("expected validation: $expected")
assert(actual == expected)
}

@ParameterizedTest
@ArgumentsSource(MinCharsArgumentsProvider::class)
fun `Validators_MinChars works correctly`(value: String, limit: Int, expected: Boolean) {
Expand Down

0 comments on commit 5412a84

Please sign in to comment.