#188 Improve the test suite and the multi-email validator
Closed a month ago by pingou. Opened 5 months ago by pingou.

file modified
+6 -5
@@ -28,6 +28,7 @@ 

  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 @@ 

      """ 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):

file modified
-13
@@ -71,19 +71,6 @@ 

      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."""

file modified
+18 -33
@@ -48,7 +48,7 @@ 

  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 @@ 

              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('<title>Home - Fedocal</title>', 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="errors">No location named foobar could be found</',

              output_text)

  

-     @flask10_only

      def test_admin(self):

          """ Test the admin function. """

          user = None
@@ -973,18 +969,12 @@ 

              self.assertIn(

                  'value="Delete">', 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(

-                 '<title>OpenID transaction in progress</title>'

-                 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 @@ 

                  '="errors">Could not add this calendar to the database</',

                  output_text)

  

-     @flask10_only

      def test_delete_calendar(self):

          """ Test the delete_calendar function. """

          self.__setup_db()
@@ -1148,7 +1137,6 @@ 

                  '<span class="calendar_name">test_calendar</span>',

                  output_text)

  

-     @flask10_only

      def test_clear_calendar(self):

          """ Test the clear_calendar function. """

          self.__setup_db()
@@ -1241,7 +1229,6 @@ 

                  '<li class="message">Calendar cleared</li>',

                  output_text)

  

-     @flask10_only

      def test_edit_calendar(self):

          """ Test the edit_calendar function. """

          self.__setup_db()
@@ -1307,7 +1294,7 @@ 

              self.assertEqual(output.status_code, 200)

              output_text = output.get_data(as_text=True)

              self.assertEqual(

-                 output_text.count('<td>This field is required.</td>'), 2)

+                 output_text.count('<td>This field is required.</td>'), 3)

              self.assertIn(

                  '<h2>Edit calendar "test_calendar"</h2>',

                  output_text)
@@ -1339,7 +1326,6 @@ 

                  '<span class="calendar_name">election1</span>',

                  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 @@ 

                  '<li class="message">You have been logged out</li>',

                  output_text)

  

-     @flask10_only

      def test_my_meetings(self):

          """ Test the my_meetings function. """

          self.__setup_db()
@@ -1397,7 +1382,6 @@ 

              self.assertIn(

                  '<td> Test meeting with reminder </td>', output_text)

  

-     @flask10_only

      def test_add_meeting(self):

          """ Test the add_meeting function. """

          self.__setup_db()
@@ -1615,8 +1599,8 @@ 

                  '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 @@ 

                  '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 @@ 

              self.assertIn(

                  '<h2>New meeting</h2>', output_text)

              self.assertIn(

-                 '<td>Invalid email address.</td>', output_text)

+                 '<td>The domain name fp is not valid. It should have a period.</td>',

+                 output_text)

  

              # Works - with one email as recipient of the reminder

              data = {
@@ -1663,7 +1648,7 @@ 

                  '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 @@ 

                  '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 @@ 

              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 @@ 

              self.assertEqual(output.status_code, 200)

              output_text = output.get_data(as_text=True)

              self.assertIn(

-                 '<td>Not a valid choice</td>', output_text)

+                 '<td>This field is required.</td>', output_text)

              self.assertIn(

                  '<title>Edit meeting - Fedocal</title>', output_text)

  
@@ -1883,6 +1867,8 @@ 

              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 @@ 

              self.assertEqual(

                  output_text.count('<span class="required">*</span>'), 6)

  

-     @flask10_only

      def test_delete_meeting(self):

          """ Test the delete_meeting function. """

          self.__setup_db()
@@ -2082,6 +2067,8 @@ 

              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 @@ 

          self.assertIn(

              '<p>This is a test calendar</p>', output_text)

  

-     @flask10_only

      def test_upload_calendar(self):

          """ Test the upload_calendar function. """

          self.__setup_db()
@@ -2371,7 +2357,6 @@ 

                      'extension &#34;txt&#34; which is not an allowed '

                      'format</li>', output_text)

  

-     @flask10_only

      def test_markdown_preview(self):

          """ Test the markdown_preview function. """

          user = FakeUser(['gitr2spec'], username='kevin')

file modified
+11 -10
@@ -45,7 +45,7 @@ 

  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 @@ 

          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 @@ 

              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 @@ 

  

              # If no date is specified, it returns the next occurence

              self.assertIn(

-                 '<input id="meeting_date" name="meeting_date" type="text" '

+                 '<input id="meeting_date" name="meeting_date" required type="text" '

                  'value="%s">' % (next_date), output_text

              )

  
@@ -123,9 +124,8 @@ 

              output2_text = output2.get_data(as_text=True)

  

              self.assertIn(

-                 '<input id="meeting_date" name="meeting_date" type="text" '

-                 'value="%s">' % (TODAY + timedelta(days=28)),

-                 output2_text

+                 '<input id="meeting_date" name="meeting_date" required type="text" '

+                 'value="%s">' % (TODAY + timedelta(days=28)), output2_text

              )

  

              # If an exact date in the future is specified, return that date
@@ -136,7 +136,7 @@ 

              output2_text = output2.get_data(as_text=True)

  

              self.assertIn(

-                 '<input id="meeting_date" name="meeting_date" type="text" '

+                 '<input id="meeting_date" name="meeting_date" required type="text" '

                  'value="%s">' % (TODAY + timedelta(days=14)), output2_text

              )

  
@@ -146,11 +146,10 @@ 

              output2_text = output2.get_data(as_text=True)

  

              self.assertIn(

-                 '<input id="meeting_date" name="meeting_date" type="text" '

+                 '<input id="meeting_date" name="meeting_date" required type="text" '

                  'value="%s">' % (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 @@ 

              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 @@ 

              self.assertEqual(output2.status_code, 200)

              output_text = output2.get_data(as_text=True)

  

-             self.assertIn('<li>Date: %s</li>' % next_date, output_text)

+             self.assertIn('<li>Date: %s</li>' % (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')

no initial comment

This was merged as part of https://pagure.io/fedocal/pull-request/189 so going to close this PR

Pull-Request has been closed by pingou

a month ago