From d5e2bf49763ad24d32e5f5b7773b4420c01850a3 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Oct 14 2020 11:18:40 +0000 Subject: Make fedocal rely on fedocal-messages to check the structure of the messages sent Signed-off-by: Pierre-Yves Chibon --- diff --git a/fedocal/fedocallib/fedmsgshim.py b/fedocal/fedocallib/fedmsgshim.py index 1937c3b..65ab3e8 100644 --- a/fedocal/fedocallib/fedmsgshim.py +++ b/fedocal/fedocallib/fedmsgshim.py @@ -11,6 +11,8 @@ import logging import fedora_messaging.api from fedora_messaging.exceptions import PublishReturned, ConnectionException +import fedocal_messages.messages as schema + _log = logging.getLogger(__name__) @@ -18,10 +20,59 @@ _log = logging.getLogger(__name__) def publish(topic, msg): # pragma: no cover _log.debug('Publishing a message for %s: %s', topic, msg) try: - message = fedora_messaging.api.Message( - topic='fedocal.%s' % topic, - body=msg - ) + if topic == "reminder": + message = schema.ReminderV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "calendar.new": + message = schema.CalendarNewV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "calendar.update": + message = schema.CalendarUpdateV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "calendar.upload": + message = schema.CalendarUploadV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "calendar.delete": + message = schema.CalendarDeleteV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "calendar.clear": + message = schema.CalendarClearV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "meeting.new": + message = schema.MeetingNewV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "meeting.update": + message = schema.MeetingUpdateV1( + topic='fedocal.%s' % topic, + body=msg + ) + elif topic == "meeting.delete": + message = schema.MeetingDeleteV1( + topic='fedocal.%s' % topic, + body=msg + ) + else: + _log.warning( + "fedocal is about to send a message that has no schemas" + ) + message = fedora_messaging.api.Message( + topic='fedocal.%s' % topic, + body=msg + ) fedora_messaging.api.publish(message) _log.debug("Sent to fedora_messaging") except PublishReturned as e: diff --git a/requirements.txt b/requirements.txt index 4b90907..48ba10c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,3 +23,4 @@ flask_multistatic flask_oidc fedora-messaging email_validator +fedocal-messages>=1.1.0 diff --git a/tests/test_cron.py b/tests/test_cron.py index 2973a5e..23a5b46 100644 --- a/tests/test_cron.py +++ b/tests/test_cron.py @@ -36,7 +36,8 @@ import os from datetime import timedelta, datetime -from fedora_messaging import api, testing +import fedocal_messages.messages as schema +from fedora_messaging import testing from mock import ANY, patch sys.path.insert(0, os.path.join(os.path.dirname( @@ -180,7 +181,7 @@ class Crontests(Modeltests): self.session.commit() self.assertNotEqual(obj, None) - with testing.mock_sends(api.Message( + with testing.mock_sends(schema.ReminderV1( topic="fedocal.reminder", body={ 'meeting': { @@ -244,7 +245,7 @@ class Crontests(Modeltests): self.session.commit() self.assertNotEqual(obj, None) - with testing.mock_sends(api.Message( + with testing.mock_sends(schema.ReminderV1( topic="fedocal.reminder", body={ 'meeting': { diff --git a/tests/test_flask.py b/tests/test_flask.py index b0947b1..b4c56a2 100644 --- a/tests/test_flask.py +++ b/tests/test_flask.py @@ -42,6 +42,10 @@ from datetime import timedelta import flask import six +import fedocal_messages.messages as schema +from fedora_messaging import testing +from mock import ANY, patch + sys.path.insert(0, os.path.join(os.path.dirname( os.path.abspath(__file__)), '..')) @@ -1024,12 +1028,26 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/calendar/add/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - '
  • Calendar added
  • ', output_text) + with testing.mock_sends(schema.CalendarNewV1( + topic="fedocal.calendar.new", + body={ + 'agent': 'username', + 'calendar': { + 'calendar_name': 'election1', + 'calendar_contact': 'election1', + 'calendar_description': '', + 'calendar_editor_group': '', + 'calendar_admin_group': '', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/calendar/add/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Calendar added
  • ', output_text) # This calendar already exists data = { @@ -1124,18 +1142,32 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/calendar/delete/test_calendar/', - data=data, follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - 'Home - Fedocal', output_text) - self.assertIn( - '
  • Calendar deleted
  • ', - output_text) - self.assertNotIn( - 'test_calendar', - output_text) + with testing.mock_sends(schema.CalendarDeleteV1( + topic="fedocal.calendar.delete", + body={ + 'agent': 'kevin', + 'calendar': { + 'calendar_name': 'test_calendar', + 'calendar_contact': 'test@example.com', + 'calendar_description': 'This is a test calendar', + 'calendar_editor_group': 'fi-apprentice', + 'calendar_admin_group': 'infrastructure-main2', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/calendar/delete/test_calendar/', + data=data, follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Home - Fedocal', output_text) + self.assertIn( + '
  • Calendar deleted
  • ', + output_text) + self.assertNotIn( + 'test_calendar', + output_text) def test_clear_calendar(self): """ Test the clear_calendar function. """ @@ -1217,17 +1249,31 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/calendar/clear/test_calendar/', - data=data, follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - 'test_calendar - Fedocal', output_text) - self.assertIn( - 'test_calendar - Fedocal', output_text) - self.assertIn( - '
  • Calendar cleared
  • ', - output_text) + with testing.mock_sends(schema.CalendarClearV1( + topic="fedocal.calendar.clear", + body={ + 'agent': 'kevin', + 'calendar': { + 'calendar_name': 'test_calendar', + 'calendar_contact': 'test@example.com', + 'calendar_description': 'This is a test calendar', + 'calendar_editor_group': 'fi-apprentice', + 'calendar_admin_group': 'infrastructure-main2', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/calendar/clear/test_calendar/', + data=data, follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'test_calendar - Fedocal', output_text) + self.assertIn( + 'test_calendar - Fedocal', output_text) + self.assertIn( + '
  • Calendar cleared
  • ', + output_text) def test_edit_calendar(self): """ Test the edit_calendar function. """ @@ -1310,21 +1356,35 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/calendar/edit/test_calendar/', - data=data, follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - 'Election1 - Fedocal', output_text) - self.assertIn( - '
  • Calendar updated
  • ', - output_text) - self.assertNotIn( - 'test_calendar', - output_text) - self.assertNotIn( - 'election1', - output_text) + with testing.mock_sends(schema.CalendarUpdateV1( + topic="fedocal.calendar.update", + body={ + 'agent': 'kevin', + 'calendar': { + 'calendar_name': 'Election1', + 'calendar_contact': 'election1', + 'calendar_description': '', + 'calendar_editor_group': '', + 'calendar_admin_group': '', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/calendar/edit/test_calendar/', + data=data, follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Election1 - Fedocal', output_text) + self.assertIn( + '
  • Calendar updated
  • ', + output_text) + self.assertNotIn( + 'test_calendar', + output_text) + self.assertNotIn( + 'election1', + output_text) def test_auth_logout(self): """ Test the auth_logout function. """ @@ -1534,16 +1594,43 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/test_calendar/add/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - '
  • Meeting added
  • ', output_text) - self.assertIn( - 'href="/meeting/16/?from_date=', output_text) - self.assertNotIn( - 'href="/meeting/17/?from_date=', output_text) + with testing.mock_sends(schema.MeetingNewV1( + topic="fedocal.meeting.new", + body={ + 'agent': 'pingou', + 'meeting': { + 'meeting_id': 16, + 'meeting_name': 'guess what?', + 'meeting_manager': ['pingou'], + 'meeting_date': TODAY.strftime('%Y-%m-%d'), + 'meeting_date_end': TODAY.strftime('%Y-%m-%d'), + 'meeting_time_start': '13:00:00', + 'meeting_time_stop': '14:00:00', + 'meeting_timezone': 'Europe/Paris', + 'meeting_information': '', + 'meeting_location': '', + 'calendar_name': 'test_calendar' + }, + 'calendar': { + 'calendar_name': 'test_calendar', + 'calendar_contact': 'test@example.com', + 'calendar_description': 'This is a test calendar', + 'calendar_editor_group': 'fi-apprentice', + 'calendar_admin_group': 'infrastructure-main2', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/test_calendar/add/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Meeting added
  • ', output_text) + self.assertIn( + 'href="/meeting/16/?from_date=', output_text) + self.assertNotIn( + 'href="/meeting/17/?from_date=', output_text) # Works - with a wiki_link data = { @@ -1824,14 +1911,41 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/meeting/edit/1/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - '
  • Meeting updated
  • ', output_text) - self.assertIn( - 'Meeting "guess what?" - Fedocal', output_text) + with testing.mock_sends(schema.MeetingUpdateV1( + topic="fedocal.meeting.update", + body={ + 'agent': 'pingou', + 'meeting': { + 'meeting_id': 1, + 'meeting_name': 'guess what?', + 'meeting_manager': ['pingou'], + 'meeting_date': TODAY.strftime('%Y-%m-%d'), + 'meeting_date_end': TODAY.strftime('%Y-%m-%d'), + 'meeting_time_start': '13:00:00', + 'meeting_time_stop': '14:00:00', + 'meeting_timezone': 'Europe/Paris', + 'meeting_information': '', + 'meeting_location': None, + 'calendar_name': 'test_calendar' + }, + 'calendar': { + 'calendar_name': 'test_calendar', + 'calendar_contact': 'test@example.com', + 'calendar_description': 'This is a test calendar', + 'calendar_editor_group': 'fi-apprentice', + 'calendar_admin_group': 'infrastructure-main2', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/meeting/edit/1/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
  • Meeting updated
  • ', output_text) + self.assertIn( + 'Meeting "guess what?" - Fedocal', output_text) # Calendar disabled data = { @@ -2032,14 +2146,41 @@ class Flasktests(Modeltests): 'csrf_token': csrf_token, } - output = self.app.post('/meeting/delete/1/', data=data, - follow_redirects=True) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn( - 'test_calendar - Fedocal', output_text) - self.assertIn( - '
  • Meeting deleted
  • ', output_text) + with testing.mock_sends(schema.MeetingDeleteV1( + topic="fedocal.meeting.delete", + body={ + 'agent': 'pingou', + 'meeting': { + 'meeting_id': 1, + 'meeting_name': 'Fedora-fr-test-meeting', + 'meeting_manager': [], + 'meeting_date': TODAY.strftime('%Y-%m-%d'), + 'meeting_date_end': TODAY.strftime('%Y-%m-%d'), + 'meeting_time_start': '19:50:00', + 'meeting_time_stop': '20:50:00', + 'meeting_timezone': 'UTC', + 'meeting_information': 'This is a test meeting', + 'meeting_location': None, + 'calendar_name': 'test_calendar' + }, + 'calendar': { + 'calendar_name': 'test_calendar', + 'calendar_contact': 'test@example.com', + 'calendar_description': 'This is a test calendar', + 'calendar_editor_group': 'fi-apprentice', + 'calendar_admin_group': 'infrastructure-main2', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/meeting/delete/1/', data=data, + follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'test_calendar - Fedocal', output_text) + self.assertIn( + '
  • Meeting deleted
  • ', output_text) # Delete all data = { @@ -2320,24 +2461,38 @@ class Flasktests(Modeltests): 'enctype': 'multipart/form-data', 'csrf_token': csrf_token, } - output = self.app.post('/calendar/upload/test_calendar/', - follow_redirects=True, data=data) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - if '
  • ' not in output_text: - self.assertIn( - 'test_calendar - Fedocal', - output_text) - self.assertIn( - '

    This is a test calendar

    ', output_text) - self.assertIn( - 'li class="message">Calendar uploaded
  • ', - output_text) - else: - self.assertIn( - '
  • The submitted candidate has the ' - 'MIME type "application/octet-stream" which ' - 'is not an allowed MIME type
  • ', output_text) + with testing.mock_sends(schema.CalendarUploadV1( + topic="fedocal.calendar.upload", + body={ + 'agent': 'kevin', + 'calendar': { + 'calendar_name': 'test_calendar', + 'calendar_contact': 'test@example.com', + 'calendar_description': 'This is a test calendar', + 'calendar_editor_group': 'fi-apprentice', + 'calendar_admin_group': 'infrastructure-main2', + 'calendar_status': 'Enabled' + } + } + )): + output = self.app.post('/calendar/upload/test_calendar/', + follow_redirects=True, data=data) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + if '
  • ' not in output_text: + self.assertIn( + 'test_calendar - Fedocal', + output_text) + self.assertIn( + '

    This is a test calendar

    ', output_text) + self.assertIn( + 'li class="message">Calendar uploaded
  • ', + output_text) + else: + self.assertIn( + '
  • The submitted candidate has the ' + 'MIME type "application/octet-stream" which ' + 'is not an allowed MIME type
  • ', output_text) with open(ICS_FILE_NOTOK, 'rb') as stream: data = {