-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #198 from fyntex/develop
Release v0.12.3
- Loading branch information
Showing
6 changed files
with
158 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[bumpversion] | ||
current_version = 0.12.2 | ||
current_version = 0.12.3 | ||
commit = True | ||
tag = True | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,4 @@ | |
""" | ||
|
||
|
||
__version__ = '0.12.2' | ||
__version__ = '0.12.3' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
""" | ||
cl_sii "extras" / Django form fields. | ||
""" | ||
try: | ||
import django | ||
except ImportError as exc: # pragma: no cover | ||
raise ImportError("Package 'Django' is required to use this module.") from exc | ||
|
||
from typing import Any, Optional | ||
|
||
import django.core.exceptions | ||
import django.forms | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from cl_sii.rut import Rut | ||
|
||
|
||
class RutField(django.forms.CharField): | ||
|
||
""" | ||
Django form field for RUT. | ||
* Python data type: :class:`cl_sii.rut.Rut` | ||
.. seealso:: | ||
:class:`.dj_model_fields.RutField` | ||
""" | ||
|
||
default_error_messages = { | ||
'invalid': _('Enter a valid RUT.'), | ||
'invalid_dv': _('RUT\'s "digito verificador" is incorrect.'), | ||
} | ||
|
||
def __init__(self, *, validate_dv: bool = False, **kwargs: Any) -> None: | ||
""" | ||
:param validate_dv: Boolean that specifies whether to validate that | ||
the RUT's "digito verificador" is correct. False by default. | ||
""" | ||
|
||
self.validate_dv = validate_dv | ||
super().__init__(strip=True, **kwargs) | ||
|
||
def to_python(self, value: Optional[object]) -> Optional[Rut]: | ||
""" | ||
Validate that the input can be converted to a Python object (:class:`Rut`). | ||
:raises django.core.exceptions.ValidationError: | ||
if the input can't be converted | ||
""" | ||
|
||
if value in self.empty_values: | ||
converted_value = None | ||
elif isinstance(value, Rut): | ||
converted_value = value | ||
else: | ||
try: | ||
converted_value = Rut(value) # type: ignore[arg-type] | ||
except (AttributeError, TypeError, ValueError): | ||
raise django.core.exceptions.ValidationError( | ||
self.error_messages['invalid'], | ||
code='invalid', | ||
) | ||
|
||
if (converted_value is not None and self.validate_dv | ||
and Rut.calc_dv(converted_value.digits) != converted_value.dv): | ||
raise django.core.exceptions.ValidationError( | ||
self.error_messages['invalid_dv'], | ||
code='invalid_dv', | ||
) | ||
|
||
return converted_value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import unittest | ||
|
||
import django.core.exceptions | ||
|
||
from cl_sii.extras.dj_form_fields import Rut, RutField | ||
|
||
|
||
class RutFieldTest(unittest.TestCase): | ||
valid_rut_canonical: str | ||
valid_rut_instance: Rut | ||
valid_rut_verbose_leading_zero_lowercase: str | ||
|
||
@classmethod | ||
def setUpClass(cls) -> None: | ||
cls.invalid_rut_canonical = '60803000K' | ||
cls.valid_rut_canonical = '60803000-K' | ||
cls.valid_rut_instance = Rut(cls.valid_rut_canonical) | ||
cls.valid_rut_canonical_with_invalid_dv = '60803000-0' | ||
cls.valid_rut_canonical_instance_with_invalid_dv = Rut( | ||
cls.valid_rut_canonical_with_invalid_dv | ||
) | ||
cls.valid_rut_verbose_leading_zero_lowercase = '060.803.000-k' | ||
|
||
def test_clean_value_of_invalid_canonical_str(self) -> None: | ||
rut_field = RutField() | ||
with self.assertRaises(django.core.exceptions.ValidationError) as cm: | ||
rut_field.clean(self.invalid_rut_canonical) | ||
self.assertEqual(cm.exception.code, 'invalid') | ||
|
||
def test_clean_value_of_canonical_str(self) -> None: | ||
rut_field = RutField() | ||
cleaned_value = rut_field.clean(self.valid_rut_canonical) | ||
self.assertIsInstance(cleaned_value, Rut) | ||
self.assertEqual(cleaned_value.canonical, self.valid_rut_canonical) | ||
|
||
def test_clean_value_of_non_canonical_str(self) -> None: | ||
rut_field = RutField() | ||
cleaned_value = rut_field.clean(self.valid_rut_verbose_leading_zero_lowercase) | ||
self.assertIsInstance(cleaned_value, Rut) | ||
self.assertEqual(cleaned_value.canonical, self.valid_rut_canonical) | ||
|
||
def test_clean_value_of_Rut(self) -> None: | ||
rut_field = RutField() | ||
cleaned_value = rut_field.clean(self.valid_rut_instance) | ||
self.assertIsInstance(cleaned_value, Rut) | ||
self.assertEqual(cleaned_value.canonical, self.valid_rut_canonical) | ||
|
||
def test_clean_value_of_rut_str_with_invalid_dv_if_validated(self) -> None: | ||
rut_field = RutField(validate_dv=True) | ||
with self.assertRaises(django.core.exceptions.ValidationError) as cm: | ||
rut_field.clean(self.valid_rut_canonical_with_invalid_dv) | ||
self.assertEqual(cm.exception.code, 'invalid_dv') | ||
|
||
def test_clean_value_of_rut_str_with_invalid_dv_if_not_validated(self) -> None: | ||
rut_field = RutField(validate_dv=False) | ||
cleaned_value = rut_field.clean(self.valid_rut_canonical_with_invalid_dv) | ||
self.assertIsInstance(cleaned_value, Rut) | ||
self.assertEqual(cleaned_value.canonical, self.valid_rut_canonical_with_invalid_dv) | ||
|
||
def test_clean_of_empty_value_if_not_required(self) -> None: | ||
rut_field = RutField(required=False) | ||
for value in RutField.empty_values: | ||
cleaned_value = rut_field.clean(value) | ||
self.assertIsNone(cleaned_value) | ||
|
||
def test_clean_of_empty_value_if_required(self) -> None: | ||
rut_field = RutField() | ||
for value in RutField.empty_values: | ||
with self.assertRaises(django.core.exceptions.ValidationError) as cm: | ||
rut_field.clean(value) | ||
self.assertEqual(cm.exception.code, 'required') |