From ed2e79c30296d62fef5b5f169ea218d55fdfad81 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2020 11:12:53 +0000 Subject: [PATCH 1/2] Port the multi-email validator to email_validator Signed-off-by: Pierre-Yves Chibon --- diff --git a/fedocal/forms.py b/fedocal/forms.py index 631ec66..2725cec 100644 --- a/fedocal/forms.py +++ b/fedocal/forms.py @@ -28,6 +28,7 @@ from datetime import time from fedocal.fedocal_babel import lazy_gettext as _ from fedocal import i18nforms +import email_validator from pytz import common_timezones import wtforms @@ -64,16 +65,16 @@ def validate_multi_email(form, field): """ Raises an exception if the content of the field does not contain one or more email. """ - pattern = re.compile(r'^.+@([^.@][^@]+)$', re.IGNORECASE) data = field.data.replace(' ', ',') for entry in data.split(','): entry = entry.strip() if not entry: continue - match = pattern.match(field.data or '') - if not match: - message = field.gettext(_('Invalid input.')) - raise wtforms.ValidationError(message) + try: + email_validator.validate_email(entry) + except email_validator.EmailNotValidError as e: + # email is not valid, exception message is human-readable + raise wtforms.ValidationError(str(e)) class AddCalendarForm(i18nforms.Form): From 555bde7669277420a91aaeffacd9e73e8003c83d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2020 11:14:55 +0000 Subject: [PATCH 2/2] Drop the flask10_only decorator and fix/adjust the tests Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/__init__.py b/tests/__init__.py index 19955b2..295caec 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -71,19 +71,6 @@ ICS_FILE_NOTOK = os.path.join(os.path.dirname( os.path.abspath(__file__)), 'ical_wrong.txt') -def flask10_only(function): - """ Decorator to skip tests if the flask version is lower than 0.10 """ - @wraps(function) - def decorated_function(*args, **kwargs): - """ Decorated function, actually does the work. """ - import flask - ver = flask.__version__.split('.') - if int(ver[0]) >= 0 and int(ver[1]) >= 10: - return function(*args, **kwargs) - return 'Skipped' - return decorated_function - - @contextmanager def user_set(APP, user): """ Set the provided user as fas_user in the provided application.""" diff --git a/tests/test_flask.py b/tests/test_flask.py index b9abc4d..b0947b1 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -48,7 +48,7 @@ sys.path.insert(0, os.path.join(os.path.dirname( import fedocal import fedocal.fedocallib as fedocallib import fedocal.fedocallib.model as model -from tests import (Modeltests, FakeUser, flask10_only, user_set, TODAY, +from tests import (Modeltests, FakeUser, user_set, TODAY, ICS_FILE, ICS_FILE_NOTOK) @@ -841,16 +841,13 @@ class Flasktests(Modeltests): self.assertFalse( fedocal.is_safe_url('https://fedoraproject.org/')) - @flask10_only def test_auth_login(self): """ Test the auth_login function. """ self.__setup_db() user = FakeUser([], username='pingou') with user_set(fedocal.APP, user): - output = self.app.get('/login/', follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn('Home - Fedocal', output_text) + output = self.app.get('/login/') + self.assertEqual(output.status_code, 302) def test_locations(self): """ Test the locations function. """ @@ -905,7 +902,6 @@ class Flasktests(Modeltests): 'class="errors">No location named foobar could be found', output_text) - @flask10_only def test_add_calendar(self): """ Test the add_calendar function. """ user = None with user_set(fedocal.APP, user): - output = self.app.get('/calendar/add/', follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - # discoveryfailure happens if there is no network - self.assertTrue( - 'OpenID transaction in progress' - in output_text or 'discoveryfailure' in output_text) + output = self.app.get('/calendar/add/') + self.assertEqual(output.status_code, 302) user = FakeUser(['test']) with user_set(fedocal.APP, user): @@ -1057,7 +1047,6 @@ class Flasktests(Modeltests): '="errors">Could not add this calendar to the databasetest_calendar', output_text) - @flask10_only def test_clear_calendar(self): """ Test the clear_calendar function. """ self.__setup_db() @@ -1241,7 +1229,6 @@ class Flasktests(Modeltests): '
  • Calendar cleared
  • ', output_text) - @flask10_only def test_edit_calendar(self): """ Test the edit_calendar function. """ self.__setup_db() @@ -1307,7 +1294,7 @@ class Flasktests(Modeltests): self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertEqual( - output_text.count('This field is required.'), 2) + output_text.count('This field is required.'), 3) self.assertIn( '

    Edit calendar "test_calendar"

    ', output_text) @@ -1339,7 +1326,6 @@ class Flasktests(Modeltests): 'election1', output_text) - @flask10_only def test_auth_logout(self): """ Test the auth_logout function. """ user = FakeUser(fedocal.APP.config['ADMIN_GROUP']) @@ -1362,7 +1348,6 @@ class Flasktests(Modeltests): '
  • You have been logged out
  • ', output_text) - @flask10_only def test_my_meetings(self): """ Test the my_meetings function. """ self.__setup_db() @@ -1397,7 +1382,6 @@ class Flasktests(Modeltests): self.assertIn( ' Test meeting with reminder ', output_text) - @flask10_only def test_add_meeting(self): """ Test the add_meeting function. """ self.__setup_db() @@ -1615,8 +1599,8 @@ class Flasktests(Modeltests): 'meeting_time_stop': time(14, 0), 'meeting_timezone': 'Europe/Paris', 'frequency': '', - 'reminder_from': 'pingou@fp.o', - 'reminder_who': 'pingou@fp.org', + 'reminder_from': 'pingou@fp', + 'remind_who': 'pingou@fp.org', 'remind_when': 'H-12', 'csrf_token': csrf_token, } @@ -1640,7 +1624,7 @@ class Flasktests(Modeltests): 'meeting_timezone': 'Europe/Paris', 'frequency': '', 'reminder_from': 'pingou@fp.o', - 'reminder_who': 'pingou@fp.org, pingou@fp.o', + 'remind_who': 'pingou@fp.org, pingou@fp', 'remind_when': 'H-12', 'csrf_token': csrf_token, } @@ -1652,7 +1636,8 @@ class Flasktests(Modeltests): self.assertIn( '

    New meeting

    ', output_text) self.assertIn( - 'Invalid email address.', output_text) + 'The domain name fp is not valid. It should have a period.', + output_text) # Works - with one email as recipient of the reminder data = { @@ -1663,7 +1648,7 @@ class Flasktests(Modeltests): 'meeting_timezone': 'Europe/Paris', 'frequency': '', 'reminder_from': 'pingou@fp.org', - 'reminder_who': 'pingou@fp.org', + 'remind_who': 'pingou@fp.org', 'remind_when': 'H-12', 'csrf_token': csrf_token, } @@ -1692,7 +1677,7 @@ class Flasktests(Modeltests): 'meeting_timezone': 'Europe/Paris', 'frequency': '', 'reminder_from': 'pingou@fp.org', - 'reminder_who': 'pingou@fp.org,pingou@p.fr', + 'remind_who': 'pingou@fp.org,pingou@p.fr', 'remind_when': 'H-12', 'csrf_token': csrf_token, } @@ -1712,7 +1697,6 @@ class Flasktests(Modeltests): self.assertNotIn( 'href="/meeting/20/?from_date=', output_text) - @flask10_only def test_edit_meeting(self): """ Test the edit_meeting function. """ self.__setup_db() @@ -1801,7 +1785,7 @@ class Flasktests(Modeltests): self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( - 'Not a valid choice', output_text) + 'This field is required.', output_text) self.assertIn( 'Edit meeting - Fedocal', output_text) @@ -1883,6 +1867,8 @@ class Flasktests(Modeltests): meeting_information='Full day meeting 2', calendar_name='test_calendar_disabled', full_day=True) + self.session.add(obj) + self.session.flush() obj.add_manager(self.session, ['toshio']) obj.save(self.session) self.session.commit() @@ -1950,7 +1936,6 @@ class Flasktests(Modeltests): self.assertEqual( output_text.count('*'), 6) - @flask10_only def test_delete_meeting(self): """ Test the delete_meeting function. """ self.__setup_db() @@ -2082,6 +2067,8 @@ class Flasktests(Modeltests): meeting_information='Full day meeting 2', calendar_name='test_calendar_disabled', full_day=True) + self.session.add(obj) + self.session.flush() obj.add_manager(self.session, ['toshio']) obj.save(self.session) self.session.commit() @@ -2289,7 +2276,6 @@ class Flasktests(Modeltests): self.assertIn( '

    This is a test calendar

    ', output_text) - @flask10_only def test_upload_calendar(self): """ Test the upload_calendar function. """ self.__setup_db() @@ -2371,7 +2357,6 @@ class Flasktests(Modeltests): 'extension "txt" which is not an allowed ' 'format', output_text) - @flask10_only def test_markdown_preview(self): """ Test the markdown_preview function. """ user = FakeUser(['gitr2spec'], username='kevin') diff --git a/tests/test_flask_extras.py b/tests/test_flask_extras.py index 0ed8aad..d9f47c4 100644 --- a/tests/test_flask_extras.py +++ b/tests/test_flask_extras.py @@ -45,7 +45,7 @@ sys.path.insert(0, os.path.join(os.path.dirname( import fedocal import fedocal.fedocallib as fedocallib import fedocal.fedocallib.model as model -from tests import (Modeltests, FakeUser, flask10_only, user_set, TODAY) +from tests import (Modeltests, FakeUser, user_set, TODAY) # pylint: disable=E1103 @@ -75,7 +75,6 @@ class ExtrasFlasktests(Modeltests): fedocal.SESSION = self.session self.app = fedocal.APP.test_client() - @flask10_only def test_start_date_edit_meeting_form(self): """ Test the content of the start_date in the edit meeting form. """ @@ -93,6 +92,8 @@ class ExtrasFlasktests(Modeltests): calendar_name='test_calendar', recursion_frequency=14, recursion_ends=TODAY + timedelta(days=90)) + self.session.add(obj) + self.session.flush() obj.add_manager(self.session, 'pingou,') obj.save(self.session) self.session.commit() @@ -110,7 +111,7 @@ class ExtrasFlasktests(Modeltests): # If no date is specified, it returns the next occurence self.assertIn( - '' % (next_date), output_text ) @@ -123,9 +124,8 @@ class ExtrasFlasktests(Modeltests): output2_text = output2.get_data(as_text=True) self.assertIn( - '' % (TODAY + timedelta(days=28)), - output2_text + '' % (TODAY + timedelta(days=28)), output2_text ) # If an exact date in the future is specified, return that date @@ -136,7 +136,7 @@ class ExtrasFlasktests(Modeltests): output2_text = output2.get_data(as_text=True) self.assertIn( - '' % (TODAY + timedelta(days=14)), output2_text ) @@ -146,11 +146,10 @@ class ExtrasFlasktests(Modeltests): output2_text = output2.get_data(as_text=True) self.assertIn( - '' % (TODAY), output2_text ) - @flask10_only def test_start_date_delete_meeting_form(self): """ Test the content of the start_date in the delete meeting form. """ @@ -168,6 +167,8 @@ class ExtrasFlasktests(Modeltests): calendar_name='test_calendar', recursion_frequency=14, recursion_ends=TODAY + timedelta(days=90)) + self.session.add(obj) + self.session.flush() obj.add_manager(self.session, 'pingou,') obj.save(self.session) self.session.commit() @@ -206,7 +207,7 @@ class ExtrasFlasktests(Modeltests): self.assertEqual(output2.status_code, 200) output_text = output2.get_data(as_text=True) - self.assertIn('
  • Date: %s
  • ' % next_date, output_text) + self.assertIn('
  • Date: %s
  • ' % (TODAY + timedelta(days=14)), output_text) # If an old date in the future is specified, return the first date output2 = self.app.get('/meeting/delete/1/?from_date=2000-01-01')