~tomasgroth/openlp/portable-path

« back to all changes in this revision

Viewing changes to tests/functional/openlp_core/ui/test_maindisplay.py

  • Committer: Tomas Groth
  • Date: 2019-04-30 19:02:42 UTC
  • mfrom: (2829.2.32 openlp)
  • Revision ID: tomasgroth@yahoo.dk-20190430190242-6zwjk8724tyux70m
trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
3
 
 
4
 
###############################################################################
5
 
# OpenLP - Open Source Lyrics Projection                                      #
6
 
# --------------------------------------------------------------------------- #
7
 
# Copyright (c) 2008-2017 OpenLP Developers                                   #
8
 
# --------------------------------------------------------------------------- #
9
 
# This program is free software; you can redistribute it and/or modify it     #
10
 
# under the terms of the GNU General Public License as published by the Free  #
11
 
# Software Foundation; version 2 of the License.                              #
12
 
#                                                                             #
13
 
# This program is distributed in the hope that it will be useful, but WITHOUT #
14
 
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
15
 
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
16
 
# more details.                                                               #
17
 
#                                                                             #
18
 
# You should have received a copy of the GNU General Public License along     #
19
 
# with this program; if not, write to the Free Software Foundation, Inc., 59  #
20
 
# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
21
 
###############################################################################
22
 
"""
23
 
Package to test the openlp.core.ui.slidecontroller package.
24
 
"""
25
 
from unittest import TestCase, skipUnless
26
 
from unittest.mock import MagicMock, patch
27
 
 
28
 
from PyQt5 import QtCore
29
 
 
30
 
from openlp.core.common import is_macosx
31
 
from openlp.core.common.path import Path
32
 
from openlp.core.common.registry import Registry
33
 
from openlp.core.display.screens import ScreenList
34
 
from openlp.core.lib import PluginManager
35
 
from openlp.core.ui import MainDisplay, AudioPlayer
36
 
from openlp.core.ui.maindisplay import TRANSPARENT_STYLESHEET, OPAQUE_STYLESHEET
37
 
from tests.helpers.testmixin import TestMixin
38
 
 
39
 
if is_macosx():
40
 
    from ctypes import pythonapi, c_void_p, c_char_p, py_object
41
 
    from sip import voidptr
42
 
    from objc import objc_object
43
 
    from AppKit import NSMainMenuWindowLevel, NSWindowCollectionBehaviorManaged
44
 
 
45
 
 
46
 
class TestMainDisplay(TestCase, TestMixin):
47
 
 
48
 
    def setUp(self):
49
 
        """
50
 
        Set up the components need for all tests.
51
 
        """
52
 
        # Mocked out desktop object
53
 
        self.desktop = MagicMock()
54
 
        self.desktop.primaryScreen.return_value = 0
55
 
        self.desktop.screenCount.return_value = 2
56
 
        self.desktop.screenGeometry.side_effect = lambda x: {0: QtCore.QRect(0, 0, 1024, 768),
57
 
                                                             1: QtCore.QRect(0, 0, 1024, 768)}[x]
58
 
        self.screens = ScreenList.create(self.desktop)
59
 
        Registry.create()
60
 
        self.registry = Registry()
61
 
        self.setup_application()
62
 
        Registry().register('application', self.app)
63
 
        self.mocked_audio_player = patch('openlp.core.ui.maindisplay.AudioPlayer')
64
 
        self.mocked_audio_player.start()
65
 
 
66
 
    def tearDown(self):
67
 
        """
68
 
        Delete QApplication.
69
 
        """
70
 
        self.mocked_audio_player.stop()
71
 
        del self.screens
72
 
 
73
 
    def test_initial_main_display(self):
74
 
        """
75
 
        Test the initial Main Display state
76
 
        """
77
 
        # GIVEN: A new SlideController instance.
78
 
        display = MagicMock()
79
 
        display.is_live = True
80
 
 
81
 
        # WHEN: The default controller is built.
82
 
        main_display = MainDisplay(display)
83
 
 
84
 
        # THEN: The controller should be a live controller.
85
 
        assert main_display.is_live is True, 'The main display should be a live controller'
86
 
 
87
 
    def test_set_transparency_enabled(self):
88
 
        """
89
 
        Test setting the display to be transparent
90
 
        """
91
 
        # GIVEN: An instance of MainDisplay
92
 
        display = MagicMock()
93
 
        main_display = MainDisplay(display)
94
 
 
95
 
        # WHEN: Transparency is enabled
96
 
        main_display.set_transparency(True)
97
 
 
98
 
        # THEN: The transparent stylesheet should be used
99
 
        assert TRANSPARENT_STYLESHEET == main_display.styleSheet(), \
100
 
            'The MainDisplay should use the transparent stylesheet'
101
 
        assert main_display.autoFillBackground() is False, \
102
 
            'The MainDisplay should not have autoFillBackground set'
103
 
        assert main_display.testAttribute(QtCore.Qt.WA_TranslucentBackground) is True, \
104
 
            'The MainDisplay should have a translucent background'
105
 
 
106
 
    def test_set_transparency_disabled(self):
107
 
        """
108
 
        Test setting the display to be opaque
109
 
        """
110
 
        # GIVEN: An instance of MainDisplay
111
 
        display = MagicMock()
112
 
        main_display = MainDisplay(display)
113
 
 
114
 
        # WHEN: Transparency is disabled
115
 
        main_display.set_transparency(False)
116
 
 
117
 
        # THEN: The opaque stylesheet should be used
118
 
        assert OPAQUE_STYLESHEET == main_display.styleSheet(), \
119
 
            'The MainDisplay should use the opaque stylesheet'
120
 
        assert main_display.testAttribute(QtCore.Qt.WA_TranslucentBackground) is False, \
121
 
            'The MainDisplay should not have a translucent background'
122
 
 
123
 
    def test_css_changed(self):
124
 
        """
125
 
        Test that when the CSS changes, the plugins are looped over and given an opportunity to update the CSS
126
 
        """
127
 
        # GIVEN: A mocked list of plugins, a mocked display and a MainDisplay
128
 
        mocked_songs_plugin = MagicMock()
129
 
        mocked_bibles_plugin = MagicMock()
130
 
        mocked_plugin_manager = MagicMock()
131
 
        mocked_plugin_manager.plugins = [mocked_songs_plugin, mocked_bibles_plugin]
132
 
        Registry().register('plugin_manager', mocked_plugin_manager)
133
 
        display = MagicMock()
134
 
        main_display = MainDisplay(display)
135
 
        # This is set up dynamically, so we need to mock it out for now
136
 
        main_display.frame = MagicMock()
137
 
 
138
 
        # WHEN: The css_changed() method is triggered
139
 
        main_display.css_changed()
140
 
 
141
 
        # THEN: The plugins should have each been given an opportunity to add their bit to the CSS
142
 
        mocked_songs_plugin.refresh_css.assert_called_with(main_display.frame)
143
 
        mocked_bibles_plugin.refresh_css.assert_called_with(main_display.frame)
144
 
 
145
 
    @skipUnless(is_macosx(), 'Can only run test on Mac OS X due to pyobjc dependency.')
146
 
    def test_macosx_display_window_flags_state(self):
147
 
        """
148
 
        Test that on Mac OS X we set the proper window flags
149
 
        """
150
 
        # GIVEN: A new SlideController instance on Mac OS X.
151
 
        self.screens.set_current_display(0)
152
 
        display = MagicMock()
153
 
 
154
 
        # WHEN: The default controller is built.
155
 
        main_display = MainDisplay(display)
156
 
 
157
 
        # THEN: The window flags should be the same as those needed on Mac OS X.
158
 
        assert QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint | QtCore.Qt.NoDropShadowWindowHint == \
159
 
            main_display.windowFlags(), \
160
 
            'The window flags should be Qt.Window, Qt.FramelessWindowHint, and Qt.NoDropShadowWindowHint.'
161
 
 
162
 
    @skipUnless(is_macosx(), 'Can only run test on Mac OS X due to pyobjc dependency.')
163
 
    def test_macosx_display(self):
164
 
        """
165
 
        Test display on Mac OS X
166
 
        """
167
 
        # GIVEN: A new SlideController instance on Mac OS X.
168
 
        self.screens.set_current_display(0)
169
 
        display = MagicMock()
170
 
 
171
 
        # WHEN: The default controller is built and a reference to the underlying NSView is stored.
172
 
        main_display = MainDisplay(display)
173
 
        try:
174
 
            nsview_pointer = main_display.winId().ascapsule()
175
 
        except:
176
 
            nsview_pointer = voidptr(main_display.winId()).ascapsule()
177
 
        pythonapi.PyCapsule_SetName.restype = c_void_p
178
 
        pythonapi.PyCapsule_SetName.argtypes = [py_object, c_char_p]
179
 
        pythonapi.PyCapsule_SetName(nsview_pointer, c_char_p(b"objc.__object__"))
180
 
        pyobjc_nsview = objc_object(cobject=nsview_pointer)
181
 
 
182
 
        # THEN: The window level and collection behavior should be the same as those needed for Mac OS X.
183
 
        assert pyobjc_nsview.window().level() == NSMainMenuWindowLevel + 2, \
184
 
            'Window level should be NSMainMenuWindowLevel + 2'
185
 
        assert pyobjc_nsview.window().collectionBehavior() == NSWindowCollectionBehaviorManaged, \
186
 
            'Window collection behavior should be NSWindowCollectionBehaviorManaged'
187
 
 
188
 
    @patch('openlp.core.ui.maindisplay.Settings')
189
 
    def test_show_display_startup_logo(self, MockedSettings):
190
 
        # GIVEN: Mocked show_display, setting for logo visibility
191
 
        display = MagicMock()
192
 
        main_display = MainDisplay(display)
193
 
        main_display.frame = MagicMock()
194
 
        main_display.isHidden = MagicMock()
195
 
        main_display.isHidden.return_value = True
196
 
        main_display.setVisible = MagicMock()
197
 
        mocked_settings = MagicMock()
198
 
        mocked_settings.value.return_value = False
199
 
        MockedSettings.return_value = mocked_settings
200
 
        main_display.shake_web_view = MagicMock()
201
 
 
202
 
        # WHEN: show_display is called.
203
 
        main_display.show_display()
204
 
 
205
 
        # THEN: setVisible should had been called with "True"
206
 
        main_display.setVisible.assert_called_once_with(True)
207
 
 
208
 
    @patch('openlp.core.ui.maindisplay.Settings')
209
 
    def test_show_display_hide_startup_logo(self, MockedSettings):
210
 
        # GIVEN: Mocked show_display, setting for logo visibility
211
 
        display = MagicMock()
212
 
        main_display = MainDisplay(display)
213
 
        main_display.frame = MagicMock()
214
 
        main_display.isHidden = MagicMock()
215
 
        main_display.isHidden.return_value = False
216
 
        main_display.setVisible = MagicMock()
217
 
        mocked_settings = MagicMock()
218
 
        mocked_settings.value.return_value = False
219
 
        MockedSettings.return_value = mocked_settings
220
 
        main_display.shake_web_view = MagicMock()
221
 
 
222
 
        # WHEN: show_display is called.
223
 
        main_display.show_display()
224
 
 
225
 
        # THEN: setVisible should had not been called
226
 
        main_display.setVisible.assert_not_called()
227
 
 
228
 
    @patch('openlp.core.ui.maindisplay.Settings')
229
 
    @patch('openlp.core.ui.maindisplay.build_html')
230
 
    def test_build_html_no_video(self, MockedSettings, Mocked_build_html):
231
 
        # GIVEN: Mocked display
232
 
        display = MagicMock()
233
 
        mocked_media_controller = MagicMock()
234
 
        Registry.create()
235
 
        Registry().register('media_controller', mocked_media_controller)
236
 
        main_display = MainDisplay(display)
237
 
        main_display.frame = MagicMock()
238
 
        mocked_settings = MagicMock()
239
 
        mocked_settings.value.return_value = False
240
 
        MockedSettings.return_value = mocked_settings
241
 
        main_display.shake_web_view = MagicMock()
242
 
        service_item = MagicMock()
243
 
        mocked_plugin = MagicMock()
244
 
        display.plugin_manager = PluginManager()
245
 
        display.plugin_manager.plugins = [mocked_plugin]
246
 
        main_display.web_view = MagicMock()
247
 
 
248
 
        # WHEN: build_html is called with a normal service item and a non video theme.
249
 
        main_display.build_html(service_item)
250
 
 
251
 
        # THEN: the following should had not been called
252
 
        assert main_display.web_view.setHtml.call_count == 1, 'setHTML should be called once'
253
 
        assert main_display.media_controller.video.call_count == 0, \
254
 
            'Media Controller video should not have been called'
255
 
 
256
 
    @patch('openlp.core.ui.maindisplay.Settings')
257
 
    @patch('openlp.core.ui.maindisplay.build_html')
258
 
    def test_build_html_video(self, MockedSettings, Mocked_build_html):
259
 
        # GIVEN: Mocked display
260
 
        display = MagicMock()
261
 
        mocked_media_controller = MagicMock()
262
 
        Registry.create()
263
 
        Registry().register('media_controller', mocked_media_controller)
264
 
        main_display = MainDisplay(display)
265
 
        main_display.frame = MagicMock()
266
 
        mocked_settings = MagicMock()
267
 
        mocked_settings.value.return_value = False
268
 
        MockedSettings.return_value = mocked_settings
269
 
        main_display.shake_web_view = MagicMock()
270
 
        service_item = MagicMock()
271
 
        service_item.theme_data = MagicMock()
272
 
        service_item.theme_data.background_type = 'video'
273
 
        service_item.theme_data.theme_name = 'name'
274
 
        service_item.theme_data.background_filename = Path('background_filename')
275
 
        mocked_plugin = MagicMock()
276
 
        display.plugin_manager = PluginManager()
277
 
        display.plugin_manager.plugins = [mocked_plugin]
278
 
        main_display.web_view = MagicMock()
279
 
 
280
 
        # WHEN: build_html is called with a normal service item and a video theme.
281
 
        main_display.build_html(service_item)
282
 
 
283
 
        # THEN: the following should had not been called
284
 
        assert main_display.web_view.setHtml.call_count == 1, 'setHTML should be called once'
285
 
        assert main_display.media_controller.video.call_count == 1, \
286
 
            'Media Controller video should have been called once'
287
 
 
288
 
 
289
 
def test_calling_next_item_in_playlist():
290
 
    """
291
 
    Test the AudioPlayer.next() method
292
 
    """
293
 
    # GIVEN: An instance of AudioPlayer with a mocked out playlist
294
 
    audio_player = AudioPlayer(None)
295
 
 
296
 
    # WHEN: next is called.
297
 
    with patch.object(audio_player, 'playlist') as mocked_playlist:
298
 
        audio_player.next()
299
 
 
300
 
    # THEN: playlist.next should had been called once.
301
 
    mocked_playlist.next.assert_called_once_with()