Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validátor PSČ a čísel pojišťovny #133

Merged
merged 3 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions registry/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Helper utilities and decorators."""
from flask import flash
from wtforms.validators import ValidationError

from registry.donor.models import Medals

Expand All @@ -18,3 +19,41 @@ def template_globals():
"""
all_medals = Medals.query.all()
return dict(all_medals=all_medals)


class NumericValidator:
"""
A WTForms validator for validating strings that consist only of digits and are
exactly of a specified length.
"""

def __init__(self, length, msg_numeric=None, msg_length=None):
"""
:param int length: The exact length the field must have
:param str msg_numeric: An error message for when the field contains forbidden
characters
:param str msg_length: An error message for when the field doesn't have
the specified length
"""
self.length = length

if msg_numeric is None:
msg_numeric = "Pole musí obsahovat pouze číslice"
if msg_length is None:
plural = "znaků"
if length == 1:
plural = "znak"
elif length <= 4:
plural = "znaky"

msg_length = f"Pole musí mít právě {length} {plural}"

self.msg_numeric = msg_numeric
self.msg_length = msg_length

def __call__(self, form, field):
if field.data:
if not field.data.isdigit():
raise ValidationError(self.msg_numeric)
if len(field.data) != self.length:
raise ValidationError(self.msg_length)
8 changes: 8 additions & 0 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
from flask_wtf import FlaskForm
from wtforms import StringField


def login(user, testapp):
res = testapp.post(
"/", params={"email": user.email, "password": user.test_password}
).follow()
assert "Přihlášení proběhlo úspěšně" in res


class FakeForm(FlaskForm):
field = StringField()
68 changes: 67 additions & 1 deletion tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import pytest
from flask import url_for
from sqlalchemy.exc import IntegrityError
from wtforms.validators import ValidationError

from registry.donor.models import (
AwardedMedals,
Expand All @@ -19,9 +20,10 @@
Record,
)
from registry.list.models import DonationCenter, Medals
from registry.utils import NumericValidator

from .fixtures import sample_of_rc
from .helpers import login
from .helpers import FakeForm, login


class TestPublicInterface:
Expand Down Expand Up @@ -633,3 +635,67 @@ def test_download_batch_compare_file(self, user, testapp):
batch_file = res.click(description="Stáhnout soubor s dávkou")
file_to_compare = Path("tests/data/batch7_downloaded.txt").read_text()
assert batch_file.text == file_to_compare


class TestNumericValidator:
def test_length_validation(self):
validator = NumericValidator(5)
form = FakeForm()

form.field.data = "12345"
validator(form, form.field)

form.field.data = "11111111111"
with pytest.raises(ValidationError, match="^Pole musí mít právě 5 znaků$"):
validator(form, form.field)

form.field.data = "0"
with pytest.raises(ValidationError, match="^Pole musí mít právě 5 znaků$"):
validator(form, form.field)

def test_numeric_validation(self):
validator = NumericValidator(5)
form = FakeForm()

form.field.data = "12345"
validator(form, form.field)

form.field.data = "1234a"
with pytest.raises(
ValidationError, match="^Pole musí obsahovat pouze číslice$"
):
validator(form, form.field)

form.field.data = "0x123"
with pytest.raises(
ValidationError, match="^Pole musí obsahovat pouze číslice$"
):
validator(form, form.field)

def test_messages(self):
validator = NumericValidator(5, msg_numeric="numeric", msg_length="length")
form = FakeForm()

form.field.data = "abcde"
with pytest.raises(ValidationError, match="^numeric$"):
validator(form, form.field)

form.field.data = "1"
with pytest.raises(ValidationError, match="^length$"):
validator(form, form.field)

def test_plural(self):
form = FakeForm()
form.field.data = "11111111111"

validator = NumericValidator(5)
with pytest.raises(ValidationError, match="^Pole musí mít právě 5 znaků$"):
validator(form, form.field)

validator = NumericValidator(3)
with pytest.raises(ValidationError, match="^Pole musí mít právě 3 znaky$"):
validator(form, form.field)

validator = NumericValidator(1)
with pytest.raises(ValidationError, match="^Pole musí mít právě 1 znak$"):
validator(form, form.field)