openlp/tests/functional/openlp_plugins/presentations/test_maclocontroller.py

458 lines
17 KiB
Python

# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
Functional tests to test the Mac LibreOffice class and related methods.
"""
import shutil
from tempfile import mkdtemp
from unittest import TestCase, SkipTest
from unittest.mock import MagicMock, patch, call
from openlp.core.common import is_macosx
from openlp.core.common.path import Path
from openlp.plugins.presentations.lib.maclocontroller import MacLOController, MacLODocument
from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH
try:
import Pyro4 # noqa: F401
except ImportError:
raise SkipTest('Pyro4 is not installed, skipping testing the Mac LibreOffice controller')
if not is_macosx():
raise SkipTest('Not on macOS, skipping testing the Mac LibreOffice controller')
class TestMacLOController(TestCase, TestMixin):
"""
Test the MacLOController Class
"""
def setUp(self):
"""
Set up the patches and mocks need for all tests.
"""
self.setup_application()
self.build_settings()
self.mock_plugin = MagicMock()
self.temp_folder = mkdtemp()
self.mock_plugin.settings_section = self.temp_folder
def tearDown(self):
"""
Stop the patches
"""
self.destroy_settings()
shutil.rmtree(self.temp_folder)
@patch('openlp.plugins.presentations.lib.maclocontroller.MacLOController._start_server')
def test_constructor(self, mocked_start_server):
"""
Test the Constructor from the MacLOController
"""
# GIVEN: No presentation controller
controller = None
# WHEN: The presentation controller object is created
controller = MacLOController(plugin=self.mock_plugin)
# THEN: The name of the presentation controller should be correct
assert controller.name == 'maclo', \
'The name of the presentation controller should be correct'
assert controller.display_name == 'Impress on macOS', \
'The display name of the presentation controller should be correct'
mocked_start_server.assert_called_once_with()
@patch('openlp.plugins.presentations.lib.maclocontroller.MacLOController._start_server')
@patch('openlp.plugins.presentations.lib.maclocontroller.Proxy')
def test_client(self, MockedProxy, mocked_start_server):
"""
Test the client property of the Controller
"""
# GIVEN: A controller without a client and a mocked out Pyro
controller = MacLOController(plugin=self.mock_plugin)
mocked_client = MagicMock()
MockedProxy.return_value = mocked_client
mocked_client._pyroConnection = None
# WHEN: the client property is called the first time
client = controller.client
# THEN: a client is created
assert client == mocked_client
MockedProxy.assert_called_once_with('PYRO:openlp.libreofficeserver@localhost:4310')
mocked_client._pyroReconnect.assert_called_once_with()
@patch('openlp.plugins.presentations.lib.maclocontroller.MacLOController._start_server')
def test_check_available(self, mocked_start_server):
"""
Test the check_available() method
"""
from openlp.plugins.presentations.lib.maclocontroller import macuno_available
# GIVEN: A controller
controller = MacLOController(plugin=self.mock_plugin)
# WHEN: check_available() is run
result = controller.check_available()
# THEN: it should return false
assert result == macuno_available
@patch('openlp.plugins.presentations.lib.maclocontroller.MacLOController._start_server')
def test_start_process(self, mocked_start_server):
"""
Test the start_process() method
"""
# GIVEN: A controller and a client
controller = MacLOController(plugin=self.mock_plugin)
controller._client = MagicMock()
# WHEN: start_process() is called
controller.start_process()
# THEN: The client's start_process() should have been called
controller._client.start_process.assert_called_once_with()
@patch('openlp.plugins.presentations.lib.maclocontroller.MacLOController._start_server')
def test_kill(self, mocked_start_server):
"""
Test the kill() method
"""
# GIVEN: A controller and a client
controller = MacLOController(plugin=self.mock_plugin)
controller._client = MagicMock()
controller.server_process = MagicMock()
# WHEN: start_process() is called
controller.kill()
# THEN: The client's start_process() should have been called
controller._client.shutdown.assert_called_once_with()
controller.server_process.kill.assert_called_once_with()
class TestMacLODocument(TestCase):
"""
Test the MacLODocument Class
"""
def setUp(self):
mocked_plugin = MagicMock()
mocked_plugin.settings_section = 'presentations'
self.file_name = Path(TEST_RESOURCES_PATH) / 'presentations' / 'test.odp'
self.mocked_client = MagicMock()
with patch('openlp.plugins.presentations.lib.maclocontroller.MacLOController._start_server'):
self.controller = MacLOController(mocked_plugin)
self.controller._client = self.mocked_client
self.document = MacLODocument(self.controller, self.file_name)
@patch('openlp.plugins.presentations.lib.maclocontroller.ScreenList')
def test_load_presentation_cannot_load(self, MockedScreenList):
"""
Test the load_presentation() method when the server can't load the presentation
"""
# GIVEN: A document and a mocked client
mocked_screen_list = MagicMock()
MockedScreenList.return_value = mocked_screen_list
mocked_screen_list.current.number = 0
self.mocked_client.load_presentation.return_value = False
# WHEN: load_presentation() is called
result = self.document.load_presentation()
# THEN: Stuff should work right
self.mocked_client.load_presentation.assert_called_once_with(str(self.file_name), 1)
assert result is False
@patch('openlp.plugins.presentations.lib.maclocontroller.ScreenList')
def test_load_presentation(self, MockedScreenList):
"""
Test the load_presentation() method
"""
# GIVEN: A document and a mocked client
mocked_screen_list = MagicMock()
MockedScreenList.return_value = mocked_screen_list
mocked_screen_list.current.number = 0
self.mocked_client.load_presentation.return_value = True
# WHEN: load_presentation() is called
with patch.object(self.document, 'create_thumbnails') as mocked_create_thumbnails, \
patch.object(self.document, 'create_titles_and_notes') as mocked_create_titles_and_notes:
result = self.document.load_presentation()
# THEN: Stuff should work right
self.mocked_client.load_presentation.assert_called_once_with(str(self.file_name), 1)
mocked_create_thumbnails.assert_called_once_with()
mocked_create_titles_and_notes.assert_called_once_with()
assert result is True
def test_create_thumbnails_already_exist(self):
"""
Test the create_thumbnails() method when thumbnails already exist
"""
# GIVEN: thumbnails that exist and a mocked client
self.document.check_thumbnails = MagicMock(return_value=True)
# WHEN: create_thumbnails() is called
self.document.create_thumbnails()
# THEN: The method should exit early
assert self.mocked_client.extract_thumbnails.call_count == 0
@patch('openlp.plugins.presentations.lib.maclocontroller.delete_file')
def test_create_thumbnails(self, mocked_delete_file):
"""
Test the create_thumbnails() method
"""
# GIVEN: thumbnails that don't exist and a mocked client
self.document.check_thumbnails = MagicMock(return_value=False)
self.mocked_client.extract_thumbnails.return_value = ['thumb1.png', 'thumb2.png']
# WHEN: create_thumbnails() is called
with patch.object(self.document, 'convert_thumbnail') as mocked_convert_thumbnail, \
patch.object(self.document, 'get_temp_folder') as mocked_get_temp_folder:
mocked_get_temp_folder.return_value = 'temp'
self.document.create_thumbnails()
# THEN: The method should complete successfully
self.mocked_client.extract_thumbnails.assert_called_once_with('temp')
assert mocked_convert_thumbnail.call_args_list == [
call(Path('thumb1.png'), 1), call(Path('thumb2.png'), 2)]
assert mocked_delete_file.call_args_list == [call(Path('thumb1.png')), call(Path('thumb2.png'))]
def test_create_titles_and_notes(self):
"""
Test create_titles_and_notes() method
"""
# GIVEN: mocked client and mocked save_titles_and_notes() method
self.mocked_client.get_titles_and_notes.return_value = ('OpenLP', 'This is a note')
# WHEN: create_titles_and_notes() is called
with patch.object(self.document, 'save_titles_and_notes') as mocked_save_titles_and_notes:
self.document.create_titles_and_notes()
# THEN save_titles_and_notes should have been called
self.mocked_client.get_titles_and_notes.assert_called_once_with()
mocked_save_titles_and_notes.assert_called_once_with('OpenLP', 'This is a note')
def test_close_presentation(self):
"""
Test the close_presentation() method
"""
# GIVEN: A mocked client and mocked remove_doc() method
# WHEN: close_presentation() is called
with patch.object(self.controller, 'remove_doc') as mocked_remove_doc:
self.document.close_presentation()
# THEN: The presentation should have been closed
self.mocked_client.close_presentation.assert_called_once_with()
mocked_remove_doc.assert_called_once_with(self.document)
def test_is_loaded(self):
"""
Test the is_loaded() method
"""
# GIVEN: A mocked client
self.mocked_client.is_loaded.return_value = True
# WHEN: is_loaded() is called
result = self.document.is_loaded()
# THEN: Then the result should be correct
assert result is True
def test_is_active(self):
"""
Test the is_active() method
"""
# GIVEN: A mocked client
self.mocked_client.is_active.return_value = True
# WHEN: is_active() is called
result = self.document.is_active()
# THEN: Then the result should be correct
assert result is True
def test_unblank_screen(self):
"""
Test the unblank_screen() method
"""
# GIVEN: A mocked client
self.mocked_client.unblank_screen.return_value = True
# WHEN: unblank_screen() is called
result = self.document.unblank_screen()
# THEN: Then the result should be correct
self.mocked_client.unblank_screen.assert_called_once_with()
assert result is True
def test_blank_screen(self):
"""
Test the blank_screen() method
"""
# GIVEN: A mocked client
self.mocked_client.blank_screen.return_value = True
# WHEN: blank_screen() is called
self.document.blank_screen()
# THEN: Then the result should be correct
self.mocked_client.blank_screen.assert_called_once_with()
def test_is_blank(self):
"""
Test the is_blank() method
"""
# GIVEN: A mocked client
self.mocked_client.is_blank.return_value = True
# WHEN: is_blank() is called
result = self.document.is_blank()
# THEN: Then the result should be correct
assert result is True
def test_stop_presentation(self):
"""
Test the stop_presentation() method
"""
# GIVEN: A mocked client
self.mocked_client.stop_presentation.return_value = True
# WHEN: stop_presentation() is called
self.document.stop_presentation()
# THEN: Then the result should be correct
self.mocked_client.stop_presentation.assert_called_once_with()
@patch('openlp.plugins.presentations.lib.maclocontroller.ScreenList')
@patch('openlp.plugins.presentations.lib.maclocontroller.Registry')
def test_start_presentation(self, MockedRegistry, MockedScreenList):
"""
Test the start_presentation() method
"""
# GIVEN: a mocked client, and multiple screens
mocked_screen_list = MagicMock()
mocked_screen_list.__len__.return_value = 2
mocked_registry = MagicMock()
mocked_main_window = MagicMock()
MockedScreenList.return_value = mocked_screen_list
MockedRegistry.return_value = mocked_registry
mocked_screen_list.screen_list = [0, 1]
mocked_registry.get.return_value = mocked_main_window
# WHEN: start_presentation() is called
self.document.start_presentation()
# THEN: The presentation should be started
self.mocked_client.start_presentation.assert_called_once_with()
mocked_registry.get.assert_called_once_with('main_window')
mocked_main_window.activateWindow.assert_called_once_with()
def test_get_slide_number(self):
"""
Test the get_slide_number() method
"""
# GIVEN: A mocked client
self.mocked_client.get_slide_number.return_value = 5
# WHEN: get_slide_number() is called
result = self.document.get_slide_number()
# THEN: Then the result should be correct
assert result == 5
def test_get_slide_count(self):
"""
Test the get_slide_count() method
"""
# GIVEN: A mocked client
self.mocked_client.get_slide_count.return_value = 8
# WHEN: get_slide_count() is called
result = self.document.get_slide_count()
# THEN: Then the result should be correct
assert result == 8
def test_goto_slide(self):
"""
Test the goto_slide() method
"""
# GIVEN: A mocked client
# WHEN: goto_slide() is called
self.document.goto_slide(3)
# THEN: Then the result should be correct
self.mocked_client.goto_slide.assert_called_once_with(3)
def test_next_step(self):
"""
Test the next_step() method
"""
# GIVEN: A mocked client
# WHEN: next_step() is called
self.document.next_step()
# THEN: Then the result should be correct
self.mocked_client.next_step.assert_called_once_with()
def test_previous_step(self):
"""
Test the previous_step() method
"""
# GIVEN: A mocked client
# WHEN: previous_step() is called
self.document.previous_step()
# THEN: Then the result should be correct
self.mocked_client.previous_step.assert_called_once_with()
def test_get_slide_text(self):
"""
Test the get_slide_text() method
"""
# GIVEN: A mocked client
self.mocked_client.get_slide_text.return_value = 'Some slide text'
# WHEN: get_slide_text() is called
result = self.document.get_slide_text(1)
# THEN: Then the result should be correct
self.mocked_client.get_slide_text.assert_called_once_with(1)
assert result == 'Some slide text'
def test_get_slide_notes(self):
"""
Test the get_slide_notes() method
"""
# GIVEN: A mocked client
self.mocked_client.get_slide_notes.return_value = 'This is a note'
# WHEN: get_slide_notes() is called
result = self.document.get_slide_notes(2)
# THEN: Then the result should be correct
self.mocked_client.get_slide_notes.assert_called_once_with(2)
assert result == 'This is a note'