Add tests for the projector code
This commit is contained in:
parent
29dc8cf200
commit
71666094e7
@ -67,6 +67,9 @@ def update_projector_overlay(overlay):
|
|||||||
def call_on_projector(calls):
|
def call_on_projector(calls):
|
||||||
"""
|
"""
|
||||||
Sends data to the projector.
|
Sends data to the projector.
|
||||||
|
|
||||||
|
The argument call has to be a dictionary with the javascript function name
|
||||||
|
as key and the argument for it as value.
|
||||||
"""
|
"""
|
||||||
projector_js_cache = config['projector_js_cache']
|
projector_js_cache = config['projector_js_cache']
|
||||||
projector_js_cache.update(calls)
|
projector_js_cache.update(calls)
|
||||||
@ -76,16 +79,21 @@ def call_on_projector(calls):
|
|||||||
|
|
||||||
def get_projector_content(slide_dict=None):
|
def get_projector_content(slide_dict=None):
|
||||||
"""
|
"""
|
||||||
Returns the HTML-Content block of the projector.
|
Returns the HTML-Content block for the projector.
|
||||||
|
|
||||||
|
Slide_dict has to be an dictonary with the key 'callback'.
|
||||||
|
|
||||||
|
If slide_dict is None, use the active slide from the database.
|
||||||
"""
|
"""
|
||||||
if slide_dict is None:
|
if slide_dict is None:
|
||||||
slide_dict = config['projector_active_slide'].copy()
|
slide_dict = config['projector_active_slide'].copy()
|
||||||
callback = slide_dict.pop('callback', None)
|
callback = slide_dict.pop('callback', None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return slide_callback[callback](**slide_dict)
|
slide_content = slide_callback[callback](**slide_dict)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return default_slide()
|
slide_content = default_slide()
|
||||||
|
return slide_content
|
||||||
|
|
||||||
|
|
||||||
def default_slide():
|
def default_slide():
|
||||||
@ -120,7 +128,7 @@ def get_projector_overlays():
|
|||||||
|
|
||||||
def get_projector_overlays_js():
|
def get_projector_overlays_js():
|
||||||
"""
|
"""
|
||||||
Returns JS-Code for the overlays.
|
Returns JS-Code for the active overlays.
|
||||||
|
|
||||||
The retuned value is a list of json objects.
|
The retuned value is a list of json objects.
|
||||||
"""
|
"""
|
||||||
|
@ -17,16 +17,16 @@ from . import views
|
|||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'',
|
'',
|
||||||
url(r'^$',
|
url(r'^$',
|
||||||
views.Projector.as_view(),
|
views.ProjectorView.as_view(),
|
||||||
name='projector_show'),
|
name='projector_show'),
|
||||||
|
|
||||||
url(r'^preview/$',
|
url(r'^preview/$',
|
||||||
views.Projector.as_view(),
|
views.ProjectorView.as_view(),
|
||||||
{'callback': None},
|
{'callback': None},
|
||||||
name='projctor_preview_welcomepage'),
|
name='projctor_preview_welcomepage'),
|
||||||
|
|
||||||
url(r'^preview/(?P<callback>[^/]*)/$',
|
url(r'^preview/(?P<callback>[^/]*)/$',
|
||||||
views.Projector.as_view(),
|
views.ProjectorView.as_view(),
|
||||||
name='projector_preview'),
|
name='projector_preview'),
|
||||||
|
|
||||||
url(r'^activate/(?P<callback>[^/]*)/$',
|
url(r'^activate/(?P<callback>[^/]*)/$',
|
||||||
|
@ -48,7 +48,7 @@ class DashboardView(AjaxMixin, TemplateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class Projector(TemplateView):
|
class ProjectorView(TemplateView):
|
||||||
"""
|
"""
|
||||||
The Projector-Page.
|
The Projector-Page.
|
||||||
"""
|
"""
|
||||||
@ -56,12 +56,9 @@ class Projector(TemplateView):
|
|||||||
template_name = 'projector.html'
|
template_name = 'projector.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
slide_dict = dict(self.request.GET.items())
|
|
||||||
callback = self.kwargs.get('callback', None)
|
callback = self.kwargs.get('callback', None)
|
||||||
if callback:
|
|
||||||
slide_dict['callback'] = callback
|
|
||||||
|
|
||||||
if not slide_dict:
|
if callback is None:
|
||||||
kwargs.update({
|
kwargs.update({
|
||||||
'content': get_projector_content(),
|
'content': get_projector_content(),
|
||||||
'overlays': get_projector_overlays(),
|
'overlays': get_projector_overlays(),
|
||||||
@ -70,11 +67,13 @@ class Projector(TemplateView):
|
|||||||
'calls': config['projector_js_cache']})
|
'calls': config['projector_js_cache']})
|
||||||
# For the Preview
|
# For the Preview
|
||||||
else:
|
else:
|
||||||
|
slide_dict = dict(self.request.GET.items())
|
||||||
|
slide_dict['callback'] = callback
|
||||||
kwargs.update({
|
kwargs.update({
|
||||||
'content': get_projector_content(slide_dict),
|
'content': get_projector_content(slide_dict),
|
||||||
'reload': False})
|
'reload': False})
|
||||||
|
|
||||||
return super(Projector, self).get_context_data(**kwargs)
|
return super(ProjectorView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ActivateView(RedirectView):
|
class ActivateView(RedirectView):
|
||||||
@ -86,10 +85,11 @@ class ActivateView(RedirectView):
|
|||||||
allow_ajax = True
|
allow_ajax = True
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
def pre_redirect(self, request, *args, **kwargs):
|
||||||
if kwargs['callback'] == 'mediafile' and \
|
if (kwargs['callback'] == 'mediafile' and
|
||||||
get_active_slide()['callback'] == 'mediafile':
|
get_active_slide()['callback'] == 'mediafile'):
|
||||||
# If the current slide is a pdf and the new page is also a slide, we dont have to use
|
# If the current slide is a pdf and the new page is also a slide,
|
||||||
# set_active_slide, because is causes a content reload.
|
# we dont have to use set_active_slide, because is causes a content
|
||||||
|
# reload.
|
||||||
kwargs.update({'page_num': 1, 'pk': request.GET.get('pk')})
|
kwargs.update({'page_num': 1, 'pk': request.GET.get('pk')})
|
||||||
url = Mediafile.objects.get(pk=kwargs['pk'], is_presentable=True).mediafile.url
|
url = Mediafile.objects.get(pk=kwargs['pk'], is_presentable=True).mediafile.url
|
||||||
config['projector_active_slide'] = kwargs
|
config['projector_active_slide'] = kwargs
|
||||||
|
189
tests/projector/test_api.py
Normal file
189
tests/projector/test_api.py
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Tests for openslides projector api
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
:copyright: 2011–2013 by OpenSlides team, see AUTHORS.
|
||||||
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from mock import MagicMock, patch
|
||||||
|
|
||||||
|
from openslides.projector import api as projector_api
|
||||||
|
from openslides.utils.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class ApiFunctions(TestCase):
|
||||||
|
@patch('openslides.projector.api.get_projector_content')
|
||||||
|
@patch('openslides.projector.api.ProjectorSocketHandler')
|
||||||
|
def test_update_projector(self, mock_ProjectorSocketHandler,
|
||||||
|
mock_get_projector_content):
|
||||||
|
mock_get_projector_content.return_value = 'mock_string'
|
||||||
|
projector_api.update_projector()
|
||||||
|
mock_ProjectorSocketHandler.send_updates.assert_called_with(
|
||||||
|
{'content': 'mock_string'})
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.get_overlays')
|
||||||
|
@patch('openslides.projector.api.ProjectorSocketHandler')
|
||||||
|
def test_update_projector_overlay(self, mock_ProjectorSocketHandler,
|
||||||
|
mock_get_overlays):
|
||||||
|
mock_overlay = MagicMock()
|
||||||
|
mock_overlay.name = 'mock_overlay_name'
|
||||||
|
mock_overlay.get_projector_html.return_value = 'mock_html_code'
|
||||||
|
mock_overlay.get_javascript.return_value = 'mock_javascript'
|
||||||
|
mock_get_overlays.return_value = {'mock_overlay': mock_overlay}
|
||||||
|
|
||||||
|
# Test with active overlay
|
||||||
|
mock_overlay.is_active.return_value = False
|
||||||
|
projector_api.update_projector_overlay(None)
|
||||||
|
mock_ProjectorSocketHandler.send_updates.assert_called_with(
|
||||||
|
{'overlays': {'mock_overlay_name': None}})
|
||||||
|
|
||||||
|
# Test with active overlay
|
||||||
|
mock_overlay.is_active.return_value = True
|
||||||
|
projector_api.update_projector_overlay(None)
|
||||||
|
expected_data = {'overlays': {'mock_overlay_name': {
|
||||||
|
'html': 'mock_html_code',
|
||||||
|
'javascript': 'mock_javascript'}}}
|
||||||
|
mock_ProjectorSocketHandler.send_updates.assert_called_with(expected_data)
|
||||||
|
|
||||||
|
# Test with overlay name as argument
|
||||||
|
projector_api.update_projector_overlay('mock_overlay')
|
||||||
|
mock_ProjectorSocketHandler.send_updates.assert_called_with(expected_data)
|
||||||
|
|
||||||
|
# Test with overlay object as argument
|
||||||
|
projector_api.update_projector_overlay(mock_overlay)
|
||||||
|
mock_ProjectorSocketHandler.send_updates.assert_called_with(expected_data)
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.config')
|
||||||
|
@patch('openslides.projector.api.ProjectorSocketHandler')
|
||||||
|
def test_call_on_projector(self, mock_ProjectorSocketHandler, mock_config):
|
||||||
|
mock_config.__getitem__.return_value = {}
|
||||||
|
data = {'some_call': 'argument'}
|
||||||
|
projector_api.call_on_projector(data)
|
||||||
|
mock_ProjectorSocketHandler.send_updates.assert_called_with(
|
||||||
|
{'calls': data})
|
||||||
|
mock_config.__getitem__.assert_called_with('projector_js_cache')
|
||||||
|
mock_config.__setitem__.assert_called_with('projector_js_cache', data)
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.default_slide')
|
||||||
|
def test_get_projector_content(self, mock_default_slide):
|
||||||
|
mock_slide = MagicMock()
|
||||||
|
mock_slide.return_value = 'slide content'
|
||||||
|
|
||||||
|
with patch.dict('openslides.projector.api.slide_callback',
|
||||||
|
values={'mock_slide': mock_slide}):
|
||||||
|
value = projector_api.get_projector_content({'callback': 'mock_slide'})
|
||||||
|
self.assertEqual(value, 'slide content')
|
||||||
|
|
||||||
|
projector_api.get_projector_content({'callback': 'unknown_slide'})
|
||||||
|
self.assertTrue(mock_default_slide.called)
|
||||||
|
|
||||||
|
with patch('openslides.projector.api.config',
|
||||||
|
{'projector_active_slide': {'callback': 'mock_slide'}}):
|
||||||
|
value = projector_api.get_projector_content()
|
||||||
|
self.assertEqual(value, 'slide content')
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.render_to_string')
|
||||||
|
def test_default_slide(self, mock_render_to_string):
|
||||||
|
projector_api.default_slide()
|
||||||
|
mock_render_to_string.assert_called_with('projector/default_slide.html')
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.projector_overlays')
|
||||||
|
def test_get_overlays(self, mock_projector_overlays):
|
||||||
|
mock_overlay = MagicMock()
|
||||||
|
mock_overlay.name = 'mock_overlay'
|
||||||
|
mock_projector_overlays.send.return_value = ((None, mock_overlay), )
|
||||||
|
|
||||||
|
value = projector_api.get_overlays()
|
||||||
|
self.assertEqual(value, {'mock_overlay': mock_overlay})
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.render_to_string')
|
||||||
|
@patch('openslides.projector.api.get_overlays')
|
||||||
|
def test_get_projector_overlays(self, mock_get_overlays, mock_render_to_string):
|
||||||
|
mock_overlay = MagicMock()
|
||||||
|
mock_overlay.get_projector_html.return_value = 'some html'
|
||||||
|
mock_get_overlays.return_value = {'overlay_name': mock_overlay}
|
||||||
|
|
||||||
|
# Test with inactive overlay
|
||||||
|
mock_overlay.is_active.return_value = False
|
||||||
|
projector_api.get_projector_overlays()
|
||||||
|
mock_render_to_string.assert_called_with(
|
||||||
|
'projector/all_overlays.html',
|
||||||
|
{'overlays': []})
|
||||||
|
|
||||||
|
# Test with active overlay
|
||||||
|
mock_overlay.is_active.return_value = True
|
||||||
|
projector_api.get_projector_overlays()
|
||||||
|
mock_render_to_string.assert_Called_with(
|
||||||
|
'projector/all_overlays.html',
|
||||||
|
{'overlays': [{'name': 'overlay_name', 'html': 'some html'}]})
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.get_overlays')
|
||||||
|
def test_get_projector_overlays_js(self, mock_get_overlays):
|
||||||
|
overlay = MagicMock()
|
||||||
|
mock_get_overlays.return_value = {'overlay': overlay}
|
||||||
|
|
||||||
|
# Test with inactive overlay
|
||||||
|
overlay.is_active.return_value = False
|
||||||
|
value = projector_api.get_projector_overlays_js()
|
||||||
|
self.assertEqual(value, [])
|
||||||
|
|
||||||
|
# Test with active overlay without js
|
||||||
|
overlay.is_active.return_value = True
|
||||||
|
overlay.get_javascript.return_value = None
|
||||||
|
value = projector_api.get_projector_overlays_js()
|
||||||
|
self.assertEqual(value, [])
|
||||||
|
|
||||||
|
# Test with active overlay with js
|
||||||
|
overlay.get_javascript.return_value = 'some javascript'
|
||||||
|
value = projector_api.get_projector_overlays_js()
|
||||||
|
self.assertEqual(value, ['some javascript'])
|
||||||
|
|
||||||
|
def test_register_slide(self):
|
||||||
|
mock_slide_callback = {}
|
||||||
|
with patch('openslides.projector.api.slide_callback', mock_slide_callback):
|
||||||
|
projector_api.register_slide('some name', 'some callback')
|
||||||
|
self.assertEqual(mock_slide_callback, {'some name': 'some callback'})
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.render_to_string')
|
||||||
|
@patch('openslides.projector.api.register_slide')
|
||||||
|
def test_register_slide_model(self, mock_register_slide, mock_render_to_string):
|
||||||
|
mock_SlideModel = MagicMock()
|
||||||
|
mock_SlideModel.slide_callback_name = 'mock_callback_name'
|
||||||
|
mock_SlideModel.DoesNotExist = Exception
|
||||||
|
mock_slide_object = MagicMock()
|
||||||
|
mock_slide_object.get_slide_context.return_value = 'some context'
|
||||||
|
mock_SlideModel.objects.get.return_value = mock_slide_object
|
||||||
|
|
||||||
|
projector_api.register_slide_model(mock_SlideModel, 'some template')
|
||||||
|
used_args, __ = mock_register_slide.call_args
|
||||||
|
self.assertEqual(used_args[0], 'mock_callback_name')
|
||||||
|
|
||||||
|
# Test the generated slide function
|
||||||
|
used_args[1](pk=1)
|
||||||
|
mock_render_to_string.assert_called_with('some template', 'some context')
|
||||||
|
|
||||||
|
# Test with non existing object
|
||||||
|
mock_SlideModel.objects.get.side_effect = Exception
|
||||||
|
used_args[1](pk=1)
|
||||||
|
mock_render_to_string.assert_called_with('some template', {'slide': None})
|
||||||
|
|
||||||
|
@patch('openslides.projector.api.update_projector_overlay')
|
||||||
|
@patch('openslides.projector.api.update_projector')
|
||||||
|
def test_set_active_slide(self, mock_update_projector, mock_update_projector_overlay):
|
||||||
|
mock_config = {}
|
||||||
|
with patch('openslides.projector.api.config', mock_config):
|
||||||
|
projector_api.set_active_slide('callback_name', {'some': 'kwargs'})
|
||||||
|
self.assertEqual(mock_config,
|
||||||
|
{'projector_active_slide': {'callback': 'callback_name',
|
||||||
|
'some': 'kwargs'}})
|
||||||
|
mock_update_projector.assert_called_with()
|
||||||
|
mock_update_projector_overlay.assert_called_with(None)
|
||||||
|
|
||||||
|
def test_get_active_slide(self):
|
||||||
|
mock_config = {'projector_active_slide': 'value'}
|
||||||
|
with patch('openslides.projector.api.config', mock_config):
|
||||||
|
value = projector_api.get_active_slide()
|
||||||
|
self.assertEqual(value, 'value')
|
@ -10,12 +10,62 @@
|
|||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.test.client import Client
|
from django.test.client import Client, RequestFactory
|
||||||
|
from mock import call, patch
|
||||||
|
|
||||||
from openslides.projector.models import ProjectorSlide
|
from openslides.projector.models import ProjectorSlide
|
||||||
|
from openslides.projector import views
|
||||||
from openslides.utils.test import TestCase
|
from openslides.utils.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectorViewTest(TestCase):
|
||||||
|
rf = RequestFactory()
|
||||||
|
|
||||||
|
@patch('openslides.projector.views.get_projector_overlays_js')
|
||||||
|
@patch('openslides.projector.views.get_projector_overlays')
|
||||||
|
@patch('openslides.projector.views.get_projector_content')
|
||||||
|
def test_get(self, mock_get_projector_content, mock_get_projector_overlays,
|
||||||
|
mock_get_projector_overlays_js):
|
||||||
|
view = views.ProjectorView()
|
||||||
|
view.request = self.rf.get('/')
|
||||||
|
|
||||||
|
# Test preview
|
||||||
|
view.kwargs = {'callback': 'slide_callback'}
|
||||||
|
context = view.get_context_data()
|
||||||
|
mock_get_projector_content.assert_called_with(
|
||||||
|
{'callback': 'slide_callback'})
|
||||||
|
self.assertFalse(context['reload'])
|
||||||
|
|
||||||
|
# Test live view
|
||||||
|
view.kwargs = {}
|
||||||
|
mock_config = {'projector_js_cache': 'js_cache'}
|
||||||
|
with patch('openslides.projector.views.config', mock_config):
|
||||||
|
context = view.get_context_data()
|
||||||
|
mock_get_projector_content.assert_called_with()
|
||||||
|
mock_get_projector_overlays.assert_called_with()
|
||||||
|
mock_get_projector_overlays_js.assert_called_with()
|
||||||
|
self.assertTrue(context['reload'])
|
||||||
|
self.assertEqual(context['calls'], 'js_cache')
|
||||||
|
|
||||||
|
|
||||||
|
class ActivateViewTest(TestCase):
|
||||||
|
rf = RequestFactory()
|
||||||
|
|
||||||
|
@patch('openslides.projector.views.config')
|
||||||
|
@patch('openslides.projector.views.set_active_slide')
|
||||||
|
def test_get(self, mock_set_active_slide, mock_config):
|
||||||
|
view = views.ActivateView()
|
||||||
|
view.request = self.rf.get('/?some_key=some_value')
|
||||||
|
|
||||||
|
view.pre_redirect(view.request, callback='some_callback')
|
||||||
|
|
||||||
|
mock_set_active_slide.called_with('some_callback',
|
||||||
|
{'some_key': 'some_value'})
|
||||||
|
mock_config.get_default.assert_has_calls([call('projector_scroll'),
|
||||||
|
call('projector_scale')])
|
||||||
|
self.assertEqual(mock_config.__setitem__.call_count, 2)
|
||||||
|
|
||||||
|
|
||||||
class CustomSlidesTest(TestCase):
|
class CustomSlidesTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.admin_client = Client()
|
self.admin_client = Client()
|
||||||
|
Loading…
Reference in New Issue
Block a user