diff --git a/.gitignore b/.gitignore index e1db484..1b891c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .venv/ +venv .pytest_cache/ build/ dist/ @@ -15,4 +16,4 @@ appsettings.json .ruff_cache .tool-versions .tox -coverage.xml +coverage.xml \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 18c7e20..3f0f41d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -15,7 +15,16 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR - Adicionar validação de Objetos [#31](https://github.com/fazedordecodigo/PyFlunt/issues/31) - Adicionar validação de Regex [#32](https://github.com/fazedordecodigo/PyFlunt/issues/32) - Adicionar validação de URL [#33](https://github.com/fazedordecodigo/PyFlunt/issues/33) -- Adicionar Result Pattner [#61](https://github.com/fazedordecodigo/PyFlunt/issues/61) +- Adicionar Result Pattern [#61](https://github.com/fazedordecodigo/PyFlunt/issues/61) +- Refatorar FluntRegexPatterns [#129](https://github.com/fazedordecodigo/PyFlux/issues/129) + +## [2.3.1] - 2024-12-16 +### Adicionado +- Refatoração para `get_pattern` em `CreditCardValidationContract` e `EmailValidationContract`. + +### Corrigido +- Garantindo que os padrões regex retornem dados válidos para validações. +- Refatorar FluntRegexPatterns [#129](https://github.com/fazedordecodigo/PyFlux/issues/129) ## [2.3.0] - 2024-03-17 ### Adicionado diff --git a/docs/CHANGELOG_EN.md b/docs/CHANGELOG_EN.md index db7cd60..4099c9d 100644 --- a/docs/CHANGELOG_EN.md +++ b/docs/CHANGELOG_EN.md @@ -16,6 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/pt-BR/ - Add Objects validation [#31](https://github.com/fazedordecodigo/PyFlunt/issues/31) - Add Regex validation [#32](https://github.com/fazedordecodigo/PyFlunt/issues/32) - Add URL validation [#33](https://github.com/fazedordecodigo/PyFlunt/issues/33) +- Refactor `FluntRegexPatterns` [#129](https://github.com/fazedordecodigo/PyFlunt/issues/129) + +## [2.3.1] - 2024-12-16 +### Added +- Refactor to use `get_pattern` in `CreditCardValidationContract` and `EmailValidationContract`. + +### Fixed +- Ensure regex patterns return valid data for validations. +- Refactor `FluntRegexPatterns` [#129](https://github.com/fazedordecodigo/PyFlunt/issues/129) ## [2.2.0] - 2024-03-13 ### Added diff --git a/flunt/localization/flunt_regex_patterns.py b/flunt/localization/flunt_regex_patterns.py index 500e3fd..a6e699d 100644 --- a/flunt/localization/flunt_regex_patterns.py +++ b/flunt/localization/flunt_regex_patterns.py @@ -1,51 +1,17 @@ """Module Flunt Regex Patterns.""" -REGEX_EMAIL = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" -REGEX_PASSPORT = r"^(?!^0+$)[a-zA-Z0-9]{3,20}$" -REGEX_ONLY_NUMBERS = r"^\d+$" -REGEX_ONLY_LETTERS_AND_NUMBERS = r"[A-Za-z0-9_-]" -REGEX_URL = r"^(http|https):(\/\/www\.|\/\/www\.|\/\/|\/\/)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$|(http|https):(\/\/localhost:\d*|\/\/127\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))(:[0-9]{1,5})?(\/.*)?$" -REGEX_CPF = r"^\d{3}\.?\d{3}\.?\d{3}-?\d{2}$" -REGEX_CNPJ = r"^\d{2}\.?\d{3}\.?\d{3}/?\d{4}-?\d{2}$" +REGEX_PATTERNS = { + "email": r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", + "passport": r"^(?!^0+$)[a-zA-Z0-9]{3,20}$", + "only_numbers": r"^\d+$", + "only_letters_and_numbers": r"[A-Za-z0-9_-]", + "url": r"^(http|https):(\/\/www\.|\/\/www\.|\/\/|\/\/)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$" + r"|(http|https):(\/\/localhost:\d*|\/\/127\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]" + r"|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))(:[0-9]{1,5})?(\/.*)?$", + "cpf": r"^\d{3}\.?\d{3}\.?\d{3}-?\d{2}$", + "cnpj": r"^\d{2}\.?\d{3}\.?\d{3}/?\d{4}-?\d{2}$", +} - -class FluntRegexPatterns: - """ - FluntRegexPatterns. - - This class encapsulates commonly used regular expression patterns. - It provides attributes to access the regular expression patterns - related to CPF, CNPJ, email, URL, only numbers, only letters and numbers, - and passport. - - Attributes - ---------- - - cpf_regex_pattern: str - The regular expression pattern for CPF. - - cnpj_regex_pattern: str - The regular expression pattern for CNPJ. - - email_regex_pattern: str - The regular expression pattern for email. - - url_regex_pattern: str - The regular expression pattern for URL. - - only_number_regex_pattern: str - The regular expression pattern for only numbers. - - only_letters_and_numbers_regex_pattern: str - The regular expression pattern for only letters and numbers. - - passport_regex_pattern: str - The regular expression pattern for passport. - TODO: Alterar de classe para outra estrutura de dados. - - """ - - def __init__(self) -> None: - """Initialize a new instance of the FluntRegexPatterns class.""" - self.cpf_regex_pattern = REGEX_CPF - self.cnpj_regex_pattern = REGEX_CNPJ - self.email_regex_pattern = REGEX_EMAIL - self.url_regex_pattern = REGEX_URL - self.only_number_regex_pattern = REGEX_ONLY_NUMBERS - self.only_letters_and_numbers_regex_pattern = ( - REGEX_ONLY_LETTERS_AND_NUMBERS - ) - self.passport_regex_pattern = REGEX_PASSPORT +def get_pattern(name: str) -> str | None: + """Retrieve a regex pattern by its name.""" + return REGEX_PATTERNS.get(name) \ No newline at end of file diff --git a/flunt/validations/credit_card_validation_contract.py b/flunt/validations/credit_card_validation_contract.py index deed48d..774d42c 100644 --- a/flunt/validations/credit_card_validation_contract.py +++ b/flunt/validations/credit_card_validation_contract.py @@ -5,7 +5,7 @@ from typing_extensions import Self from flunt.constants.messages import IS_NOT_CREDIT_CARD -from flunt.localization.flunt_regex_patterns import FluntRegexPatterns +from flunt.localization.flunt_regex_patterns import get_pattern from flunt.notifications.notifiable import Notifiable @@ -58,8 +58,10 @@ def is_credit_card( ``` """ + only_number_pattern = get_pattern("only_numbers") + if not re.match( - FluntRegexPatterns().only_number_regex_pattern, + only_number_pattern, value, re.IGNORECASE, ): diff --git a/flunt/validations/email_validation_contract.py b/flunt/validations/email_validation_contract.py index 4db1a76..53c3e97 100644 --- a/flunt/validations/email_validation_contract.py +++ b/flunt/validations/email_validation_contract.py @@ -6,7 +6,7 @@ from typing_extensions import Self from flunt.constants.messages import IS_EMAIL, IS_NOT_EMAIL -from flunt.localization.flunt_regex_patterns import FluntRegexPatterns +from flunt.localization.flunt_regex_patterns import get_pattern from flunt.notifications.notifiable import Notifiable @@ -24,8 +24,10 @@ def _valid_email(value) -> Union[re.Match[str], None]: `(Match[str] | None)` """ + email_pattern = get_pattern("email") + return re.match( - FluntRegexPatterns().email_regex_pattern, + email_pattern, value, re.IGNORECASE, ) diff --git a/tests/conftest.py b/tests/conftest.py index 34285bd..e1ffd49 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,6 @@ import pytest -from flunt.localization.flunt_regex_patterns import FluntRegexPatterns +from flunt.localization.flunt_regex_patterns import get_pattern from tests.mocks.entity.sample_entity import SampleEntity @@ -11,6 +11,6 @@ def entity_mock() -> SampleEntity: @pytest.fixture(scope="module") -def regex() -> FluntRegexPatterns: - """Fixture to return a FluntRegexPatterns instance.""" - return FluntRegexPatterns() +def regex() -> get_pattern: + """Fixture to return a get_pattern instance.""" + return get_pattern() diff --git a/tests/localization/test_flunt_regex_patterns.py b/tests/localization/test_flunt_regex_patterns.py index ace216f..fecb791 100644 --- a/tests/localization/test_flunt_regex_patterns.py +++ b/tests/localization/test_flunt_regex_patterns.py @@ -1,11 +1,11 @@ import re - import pytest +from flunt.localization.flunt_regex_patterns import get_pattern + from faker import Faker fake = Faker("pt_BR") - @pytest.mark.parametrize( ("value", "expect"), [ @@ -14,8 +14,9 @@ (fake.name(), False), ], ) -def test_should_identify_a_valid_email_address(regex, value, expect): - result = re.match(regex.email_regex_pattern, value) +def test_should_identify_a_valid_email_address(value, expect): + regex = get_pattern("email") + result = re.match(regex, value) assert isinstance(result, re.Match) is expect @@ -28,8 +29,9 @@ def test_should_identify_a_valid_email_address(regex, value, expect): (fake.cnpj(), False), ], ) -def test_should_identify_a_valid_cpf(regex, value, expect): - result = re.match(regex.cpf_regex_pattern, value) +def test_should_identify_a_valid_cpf(value, expect): + regex = get_pattern("cpf") + result = re.match(regex, value) assert isinstance(result, re.Match) is expect @@ -42,8 +44,9 @@ def test_should_identify_a_valid_cpf(regex, value, expect): (fake.cpf(), False), ], ) -def test_should_identify_a_valid_cnpj(regex, value, expect): - result = re.match(regex.cnpj_regex_pattern, value) +def test_should_identify_a_valid_cnpj(value, expect): + regex = get_pattern("cnpj") + result = re.match(regex, value) assert isinstance(result, re.Match) is expect @@ -55,8 +58,9 @@ def test_should_identify_a_valid_cnpj(regex, value, expect): (fake.name(), False), ], ) -def test_should_identify_a_valid_url(regex, value, expect): - result = re.match(regex.url_regex_pattern, value) +def test_should_identify_a_valid_url(value, expect): + regex = get_pattern("url") + result = re.match(regex, value) assert isinstance(result, re.Match) is expect @@ -69,8 +73,9 @@ def test_should_identify_a_valid_url(regex, value, expect): (fake.ipv4_public(), False), ], ) -def test_should_identify_only_numbers(regex, value, expect): - result = re.match(regex.only_number_regex_pattern, value) +def test_should_identify_only_numbers(value, expect): + regex = get_pattern("only_numbers") + result = re.match(regex, value) assert isinstance(result, re.Match) is expect @@ -83,8 +88,9 @@ def test_should_identify_only_numbers(regex, value, expect): ("", False), ], ) -def test_should_identify_letters_and_numbers(regex, value, expect): - result = re.match(regex.only_letters_and_numbers_regex_pattern, value) +def test_should_identify_letters_and_numbers(value, expect): + regex = get_pattern("only_letters_and_numbers") + result = re.match(regex, value) assert isinstance(result, re.Match) is expect @@ -95,6 +101,7 @@ def test_should_identify_letters_and_numbers(regex, value, expect): (fake.name(), False), ], ) -def test_should_identify_a_valid_passport(regex, value, expect): - result = re.match(regex.passport_regex_pattern, value) - assert isinstance(result, re.Match) is expect +def test_should_identify_a_valid_passport(value, expect): + regex = get_pattern("passport") + result = re.match(regex, value) + assert isinstance(result, re.Match) is expect \ No newline at end of file