From 4c86c9cd07c1bf6721e22483c1c4a81d38959c91 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Fri, 10 Jan 2014 18:47:21 +0100 Subject: [PATCH] Fix list_of_speaker overlay * Issue a warning message, if a overlay raises a exception * Fixed #1131 --- openslides/agenda/signals.py | 2 +- openslides/projector/exceptions.py | 5 +++++ openslides/projector/projector.py | 17 +++++++++++------ tests/agenda/test_list_of_speakers.py | 14 ++++++++++++++ tests/projector/test_overlays.py | 19 +++++++------------ 5 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 openslides/projector/exceptions.py diff --git a/openslides/agenda/signals.py b/openslides/agenda/signals.py index 353a4649e..ec4c5a5ee 100644 --- a/openslides/agenda/signals.py +++ b/openslides/agenda/signals.py @@ -98,7 +98,7 @@ def agenda_list_of_speakers(sender, **kwargs): list-of-speakers slide. """ slide = get_active_object() - if isinstance(slide, Item): + if slide is None or isinstance(slide, Item): item = slide else: # TODO: If there are more the one items, use the first one in the diff --git a/openslides/projector/exceptions.py b/openslides/projector/exceptions.py new file mode 100644 index 000000000..88bf6dc00 --- /dev/null +++ b/openslides/projector/exceptions.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + +class ProjectorExceptionWarning(RuntimeWarning): + pass diff --git a/openslides/projector/projector.py b/openslides/projector/projector.py index 9c66fb652..f1b068c4b 100644 --- a/openslides/projector/projector.py +++ b/openslides/projector/projector.py @@ -1,12 +1,15 @@ # -*- coding: utf-8 -*- -from django.conf import settings +import warnings + from django.template import RequestContext from django.template.loader import render_to_string from openslides.config.api import config from openslides.utils.exceptions import OpenSlidesError +from .exceptions import ProjectorExceptionWarning + class Widget(object): """ @@ -72,6 +75,9 @@ class Overlay(object): self.javascript_callback = get_javascript self.allways_active = allways_active + def __repr__(self): + return self.name + def get_widget_html(self): """ Returns the html code for the overlay widget. @@ -90,11 +96,10 @@ class Overlay(object): try: value = self.get_html_wrapper(self.projector_html_callback()) except Exception as exception: - if settings.DEBUG: - raise exception - else: - # Catch all errors, so an overlay can not kill the projector - value = '' + warnings.warn('%s in overlay "%s": %s' + % (type(exception).__name__, self, exception), + ProjectorExceptionWarning) + value = '' return value def get_javascript(self): diff --git a/tests/agenda/test_list_of_speakers.py b/tests/agenda/test_list_of_speakers.py index f74bbb662..e98a583eb 100644 --- a/tests/agenda/test_list_of_speakers.py +++ b/tests/agenda/test_list_of_speakers.py @@ -5,6 +5,7 @@ from django.test.client import Client from mock import patch, MagicMock from openslides.agenda.models import Item, Speaker +from openslides.agenda.signals import agenda_list_of_speakers from openslides.config.api import config from openslides.participant.models import Group, User from openslides.projector.api import set_active_slide @@ -300,3 +301,16 @@ class GlobalListOfSpeakersLinks(SpeakerViewTestCase): response = self.admin_client.get('/agenda/list_of_speakers/end_speach/') self.assertRedirects(response, '/projector/dashboard/') self.assertTrue(Speaker.objects.get(item__pk='1').end_time is not None) + + +class TestOverlay(TestCase): + def test_overlay_with_no_model_slide(self): + """ + When a slide is active, that is not a model (for example the agenda) + an Attribute Error was raised. + """ + config['projector_active_slide'] = {'callback': None} + + value = agenda_list_of_speakers(sender='test').get_projector_html() + + self.assertEqual(value, '') diff --git a/tests/projector/test_overlays.py b/tests/projector/test_overlays.py index c59927c50..c9e8fdddf 100644 --- a/tests/projector/test_overlays.py +++ b/tests/projector/test_overlays.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- -from mock import MagicMock, patch +import warnings + +from mock import MagicMock from openslides.projector.projector import Overlay from openslides.utils.test import TestCase @@ -9,18 +11,11 @@ from openslides.utils.test import TestCase class OverlayTest(TestCase): def test_error_in_html(self): """ - Tests that the methof get_projector_html does not raise any errors. + Tests that the method get_projector_html does not raise any errors. """ get_projector_html = MagicMock(side_effect=Exception('no good error')) overlay = Overlay('test_overlay', lambda: 'widget_html', get_projector_html) - # Test in productive mode - with patch('openslides.projector.projector.settings.DEBUG', False): - self.assertEqual(overlay.get_projector_html(), '') - - # Test in debug mode - with patch('openslides.projector.projector.settings.DEBUG', True): - self.assertRaisesMessage( - Exception, - 'no good error', - overlay.get_projector_html) + with warnings.catch_warnings(record=True) as warning: + overlay.get_projector_html() + self.assertEqual(warning[0].message.message, 'Exception in overlay "test_overlay": no good error')