diff --git a/tests/functional/openlp_plugins/presentations/conftest.py b/tests/functional/openlp_plugins/presentations/conftest.py new file mode 100644 index 000000000..fbbb7d343 --- /dev/null +++ b/tests/functional/openlp_plugins/presentations/conftest.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +########################################################################## +# OpenLP - Open Source Lyrics Projection # +# ---------------------------------------------------------------------- # +# Copyright (c) 2008-2020 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 . # +########################################################################## +""" +For the Presentation tests +""" +import pytest +import shutil +from unittest.mock import MagicMock, patch +from tempfile import mkdtemp + +from openlp.core.common.registry import Registry +from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem + + +@pytest.fixture +def media_item(settings): + """Local test setup""" + Registry().register('service_manager', MagicMock()) + Registry().register('main_window', MagicMock()) + with patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup'), \ + patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item'): + m_item = PresentationMediaItem(None, MagicMock, MagicMock()) + m_item.settings_section = 'media' + return m_item + + +@pytest.yield_fixture() +def mock_plugin(): + m_plugin = MagicMock() + temp_folder = mkdtemp() + m_plugin.settings_section = temp_folder + yield m_plugin + shutil.rmtree(temp_folder) diff --git a/tests/functional/openlp_plugins/presentations/test_impresscontroller.py b/tests/functional/openlp_plugins/presentations/test_impresscontroller.py index 39a71831c..ae8142e29 100644 --- a/tests/functional/openlp_plugins/presentations/test_impresscontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_impresscontroller.py @@ -21,295 +21,271 @@ """ Functional tests to test the Impress class and related methods. """ -import shutil -from tempfile import mkdtemp -from unittest import TestCase +import pytest from unittest.mock import MagicMock, call, patch -from openlp.core.common.registry import Registry -from openlp.core.common.settings import Settings from openlp.plugins.presentations.lib.impresscontroller import ImpressController, ImpressDocument, TextType -from tests.helpers.testmixin import TestMixin from tests.utils.constants import RESOURCE_PATH -class TestImpressController(TestCase, TestMixin): +@pytest.fixture() +def doc(settings): + mocked_plugin = MagicMock() + mocked_plugin.settings_section = 'presentations' + file_name = RESOURCE_PATH / 'presentations' / 'test.pptx' + ppc = ImpressController(mocked_plugin) + return ImpressDocument(ppc, file_name) + + +def test_constructor(settings, mock_plugin): """ - Test the ImpressController Class + Test the Constructor from the ImpressController """ + # GIVEN: No presentation controller + controller = None - 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 - Registry.create() - Registry().register('settings', Settings()) + # WHEN: The presentation controller object is created + controller = ImpressController(plugin=mock_plugin) - def tearDown(self): - """ - Stop the patches - """ - self.destroy_settings() - shutil.rmtree(self.temp_folder) - - def test_constructor(self): - """ - Test the Constructor from the ImpressController - """ - # GIVEN: No presentation controller - controller = None - - # WHEN: The presentation controller object is created - controller = ImpressController(plugin=self.mock_plugin) - - # THEN: The name of the presentation controller should be correct - assert 'Impress' == controller.name, 'The name of the presentation controller should be correct' - - @patch('openlp.plugins.presentations.lib.impresscontroller.log') - def test_check_available(self, mocked_log): - """ - Test `ImpressController.check_available` on Windows - """ - # GIVEN: An instance of :class:`ImpressController` - controller = ImpressController(plugin=self.mock_plugin) - - # WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns None - with patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True), \ - patch.object(controller, 'get_com_servicemanager', return_value=None) as mocked_get_com_servicemanager: - result = controller.check_available() - - # THEN: `check_available` should return False - assert mocked_get_com_servicemanager.called is True - assert result is False - - @patch('openlp.plugins.presentations.lib.impresscontroller.log') - def test_check_available_on_windows(self, mocked_log): - """ - Test `ImpressController.check_available` on Windows - """ - # GIVEN: An instance of :class:`ImpressController` - controller = ImpressController(plugin=self.mock_plugin) - - # WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns an object - mocked_com_object = MagicMock() - with patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True), \ - patch.object(controller, 'get_com_servicemanager', return_value=mocked_com_object) \ - as mocked_get_com_servicemanager: - result = controller.check_available() - - # THEN: `check_available` should return True - assert mocked_get_com_servicemanager.called is True - assert result is True - - @patch('openlp.plugins.presentations.lib.impresscontroller.log') - @patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False) - def test_check_available_on_linux(self, mocked_is_win, mocked_log): - """ - Test `ImpressController.check_available` when not on Windows - """ - # GIVEN: An instance of :class:`ImpressController` - controller = ImpressController(plugin=self.mock_plugin) - - # WHEN: `check_available` is called on Windows and `uno_available` is True - with patch('openlp.plugins.presentations.lib.impresscontroller.uno_available', True), \ - patch.object(controller, 'get_com_servicemanager') as mocked_get_com_servicemanager: - result = controller.check_available() - - # THEN: `check_available` should return True - assert mocked_get_com_servicemanager.called is False - assert result is True - - @patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True) - def test_start_process_on_windows(self, mocked_is_win): - """ - Test that start_process() on Windows starts the process - """ - # GIVEN: An ImpressController object - controller = ImpressController(plugin=self.mock_plugin) - controller.get_com_servicemanager = MagicMock(return_value=MagicMock()) - - # WHEN: start_process() is called - controller.start_process() - - # THEN: The correct methods should have been called - controller.get_com_servicemanager.assert_called_once() - assert controller.manager._FlagAsMethod.call_args_list == [call('Bridge_GetStruct'), - call('Bridge_GetValueObject')] - - @patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False) - @patch('openlp.plugins.presentations.lib.impresscontroller.get_uno_command', return_value='libreoffice') - @patch('openlp.plugins.presentations.lib.impresscontroller.QtCore.QProcess') - def test_start_process_on_linux(self, MockQProcess, mocked_get_uno_command, mocked_is_win): - """ - Test that start_process() on Linux starts the process - """ - # GIVEN: An ImpressController object - mocked_process = MagicMock() - MockQProcess.return_value = mocked_process - controller = ImpressController(plugin=self.mock_plugin) - - # WHEN: start_process() is called - controller.start_process() - - # THEN: The correct methods should have been called - mocked_get_uno_command.assert_called_once() - MockQProcess.assert_called_once() - assert controller.process is mocked_process - mocked_process.startDetached.assert_called_once_with('libreoffice') + # THEN: The name of the presentation controller should be correct + assert 'Impress' == controller.name, 'The name of the presentation controller should be correct' -class TestImpressDocument(TestCase): +@patch('openlp.plugins.presentations.lib.impresscontroller.log') +def test_check_available(mocked_log, settings, mock_plugin): """ - Test the ImpressDocument Class + Test `ImpressController.check_available` on Windows """ - def setUp(self): - mocked_plugin = MagicMock() - mocked_plugin.settings_section = 'presentations' - self.file_name = RESOURCE_PATH / 'presentations' / 'test.pptx' - self.settings = Settings() - Registry.create() - Registry().register('settings', self.settings) - self.ppc = ImpressController(mocked_plugin) - self.doc = ImpressDocument(self.ppc, self.file_name) + # GIVEN: An instance of :class:`ImpressController` + controller = ImpressController(plugin=mock_plugin) - def test_create_titles_and_notes(self): - """ - Test ImpressDocument.create_titles_and_notes - """ - # GIVEN: mocked PresentationController.save_titles_and_notes with - # 0 pages and the LibreOffice Document - self.doc.save_titles_and_notes = MagicMock() - self.doc.document = MagicMock() - self.doc.document.getDrawPages.return_value = MagicMock() - self.doc.document.getDrawPages().getCount.return_value = 0 + # WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns None + with patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True), \ + patch.object(controller, 'get_com_servicemanager', return_value=None) as mocked_get_com_servicemanager: + result = controller.check_available() - # WHEN reading the titles and notes - self.doc.create_titles_and_notes() + # THEN: `check_available` should return False + assert mocked_get_com_servicemanager.called is True + assert result is False - # THEN save_titles_and_notes should have been called with empty arrays - self.doc.save_titles_and_notes.assert_called_once_with([], []) - # GIVEN: reset mock and set it to 2 pages - self.doc.save_titles_and_notes.reset_mock() - self.doc.document.getDrawPages().getCount.return_value = 2 +@patch('openlp.plugins.presentations.lib.impresscontroller.log') +def test_check_available_on_windows(mocked_log, settings, mock_plugin): + """ + Test `ImpressController.check_available` on Windows + """ + # GIVEN: An instance of :class:`ImpressController` + controller = ImpressController(plugin=mock_plugin) - # WHEN: a new call to create_titles_and_notes - self.doc.create_titles_and_notes() + # WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns an object + mocked_com_object = MagicMock() + with patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True), \ + patch.object(controller, 'get_com_servicemanager', return_value=mocked_com_object) \ + as mocked_get_com_servicemanager: + result = controller.check_available() - # THEN: save_titles_and_notes should have been called once with - # two arrays of two elements - # self.doc.save_titles_and_notes.assert_called_once_with(['\n', '\n'], [' ', ' ']) - self.doc.save_titles_and_notes.assert_called_once_with(['', ''], [' ', ' ']) + # THEN: `check_available` should return True + assert mocked_get_com_servicemanager.called is True + assert result is True - def test_get_text_from_page_out_of_bound(self): - """ - Test ImpressDocument.__get_text_from_page with out-of-bounds index - """ - # GIVEN: mocked LibreOffice Document with one slide, - # two notes and three texts - self.doc.document = self._mock_a_LibreOffice_document(1, 2, 3) - # WHEN: __get_text_from_page is called with an index of 0x00 - result = self.doc._ImpressDocument__get_text_from_page(0, TextType.Notes) +@patch('openlp.plugins.presentations.lib.impresscontroller.log') +@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False) +def test_check_available_on_linux(mocked_is_win, mocked_log, settings, mock_plugin): + """ + Test `ImpressController.check_available` when not on Windows + """ + # GIVEN: An instance of :class:`ImpressController` + controller = ImpressController(plugin=mock_plugin) - # THEN: the result should be an empty string - assert result == '', 'Result should be an empty string' + # WHEN: `check_available` is called on Windows and `uno_available` is True + with patch('openlp.plugins.presentations.lib.impresscontroller.uno_available', True), \ + patch.object(controller, 'get_com_servicemanager') as mocked_get_com_servicemanager: + result = controller.check_available() - # WHEN: regardless of the type of text, index 0x00 is out of bounds - result = self.doc._ImpressDocument__get_text_from_page(0, TextType.Title) + # THEN: `check_available` should return True + assert mocked_get_com_servicemanager.called is False + assert result is True - # THEN: result should be an empty string - assert result == '', 'Result should be an empty string' - # WHEN: when called with 2, it should also be out of bounds - result = self.doc._ImpressDocument__get_text_from_page(2, TextType.SlideText) +@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True) +def test_start_process_on_windows(mocked_is_win, settings, mock_plugin): + """ + Test that start_process() on Windows starts the process + """ + # GIVEN: An ImpressController object + controller = ImpressController(plugin=mock_plugin) + controller.get_com_servicemanager = MagicMock(return_value=MagicMock()) - # THEN: result should be an empty string ... and, getByIndex should - # have never been called - assert result == '', 'Result should be an empty string' - assert self.doc.document.getDrawPages().getByIndex.call_count == 0, 'There should be no call to getByIndex' + # WHEN: start_process() is called + controller.start_process() - def test_get_text_from_page_wrong_type(self): - """ - Test ImpressDocument.__get_text_from_page with wrong TextType - """ - # GIVEN: mocked LibreOffice Document with one slide, two notes and - # three texts - self.doc.document = self._mock_a_LibreOffice_document(1, 2, 3) + # THEN: The correct methods should have been called + controller.get_com_servicemanager.assert_called_once() + assert controller.manager._FlagAsMethod.call_args_list == [call('Bridge_GetStruct'), + call('Bridge_GetValueObject')] - # WHEN: called with TextType 3 - result = self.doc._ImpressDocument__get_text_from_page(1, 3) - # THEN: result should be an empty string - assert result == '', 'Result should be and empty string' - assert self.doc.document.getDrawPages().getByIndex.call_count == 0, 'There should be no call to getByIndex' +@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False) +@patch('openlp.plugins.presentations.lib.impresscontroller.get_uno_command', return_value='libreoffice') +@patch('openlp.plugins.presentations.lib.impresscontroller.QtCore.QProcess') +def test_start_process_on_linux(MockQProcess, mocked_get_uno_command, mocked_is_win, settings, mock_plugin): + """ + Test that start_process() on Linux starts the process + """ + # GIVEN: An ImpressController object + mocked_process = MagicMock() + MockQProcess.return_value = mocked_process + controller = ImpressController(plugin=mock_plugin) - def test_get_text_from_page_valid_params(self): - """ - Test ImpressDocument.__get_text_from_page with valid parameters - """ - # GIVEN: mocked LibreOffice Document with one slide, - # two notes and three texts - self.doc.document = self._mock_a_LibreOffice_document(1, 2, 3) + # WHEN: start_process() is called + controller.start_process() - # WHEN: __get_text_from_page is called to get the Notes - result = self.doc._ImpressDocument__get_text_from_page(1, TextType.Notes) + # THEN: The correct methods should have been called + mocked_get_uno_command.assert_called_once() + MockQProcess.assert_called_once() + assert controller.process is mocked_process + mocked_process.startDetached.assert_called_once_with('libreoffice') - # THEN: result should be 'Note\nNote\n' - assert result == 'Note\nNote\n', 'Result should be \'Note\\n\' times the count of notes in the page' - # WHEN: get the Title - result = self.doc._ImpressDocument__get_text_from_page(1, TextType.Title) +def test_create_titles_and_notes(doc): + """ + Test ImpressDocument.create_titles_and_notes + """ + # GIVEN: mocked PresentationController.save_titles_and_notes with + # 0 pages and the LibreOffice Document + doc.save_titles_and_notes = MagicMock() + doc.document = MagicMock() + doc.document.getDrawPages.return_value = MagicMock() + doc.document.getDrawPages().getCount.return_value = 0 - # THEN: result should be 'Title\n' - assert result == 'Title\n', 'Result should be exactly \'Title\\n\'' + # WHEN reading the titles and notes + doc.create_titles_and_notes() - # WHEN: get all text - result = self.doc._ImpressDocument__get_text_from_page(1, TextType.SlideText) + # THEN save_titles_and_notes should have been called with empty arrays + doc.save_titles_and_notes.assert_called_once_with([], []) - # THEN: result should be 'Title\nString\nString\n' - assert result == 'Title\nString\nString\n', 'Result should be exactly \'Title\\nString\\nString\\n\'' + # GIVEN: reset mock and set it to 2 pages + doc.save_titles_and_notes.reset_mock() + doc.document.getDrawPages().getCount.return_value = 2 - def _mock_a_LibreOffice_document(self, page_count, note_count, text_count): - """ - Helper function, creates a mock libreoffice document. + # WHEN: a new call to create_titles_and_notes + doc.create_titles_and_notes() - :param page_count: Number of pages in the document - :param note_count: Number of note pages in the document - :param text_count: Number of text pages in the document - """ - pages = MagicMock() - page = MagicMock() - pages.getByIndex.return_value = page - notes_page = MagicMock() - notes_page.getCount.return_value = note_count - shape = MagicMock() - shape.supportsService.return_value = True - shape.getString.return_value = 'Note' - notes_page.getByIndex.return_value = shape - page.getNotesPage.return_value = notes_page - page.getCount.return_value = text_count - page.getByIndex.side_effect = self._get_page_shape_side_effect - pages.getCount.return_value = page_count - document = MagicMock() - document.getDrawPages.return_value = pages - document.getByIndex.return_value = page - return document + # THEN: save_titles_and_notes should have been called once with + # two arrays of two elements + # self.doc.save_titles_and_notes.assert_called_once_with(['\n', '\n'], [' ', ' ']) + doc.save_titles_and_notes.assert_called_once_with(['', ''], [' ', ' ']) - def _get_page_shape_side_effect(*args): - """ - Helper function. - """ - page_shape = MagicMock() - page_shape.supportsService.return_value = True - if args[1] == 0: - page_shape.getShapeType.return_value = 'com.sun.star.presentation.TitleTextShape' - page_shape.getString.return_value = 'Title' - else: - page_shape.getString.return_value = 'String' - return page_shape + +def test_get_text_from_page_out_of_bound(doc): + """ + Test ImpressDocument.__get_text_from_page with out-of-bounds index + """ + # GIVEN: mocked LibreOffice Document with one slide, + # two notes and three texts + doc.document = _mock_a_LibreOffice_document(1, 2, 3) + + # WHEN: __get_text_from_page is called with an index of 0x00 + result = doc._ImpressDocument__get_text_from_page(0, TextType.Notes) + + # THEN: the result should be an empty string + assert result == '', 'Result should be an empty string' + + # WHEN: regardless of the type of text, index 0x00 is out of bounds + result = doc._ImpressDocument__get_text_from_page(0, TextType.Title) + + # THEN: result should be an empty string + assert result == '', 'Result should be an empty string' + + # WHEN: when called with 2, it should also be out of bounds + result = doc._ImpressDocument__get_text_from_page(2, TextType.SlideText) + + # THEN: result should be an empty string ... and, getByIndex should + # have never been called + assert result == '', 'Result should be an empty string' + assert doc.document.getDrawPages().getByIndex.call_count == 0, 'There should be no call to getByIndex' + + +def test_get_text_from_page_wrong_type(doc): + """ + Test ImpressDocument.__get_text_from_page with wrong TextType + """ + # GIVEN: mocked LibreOffice Document with one slide, two notes and + # three texts + doc.document = _mock_a_LibreOffice_document(1, 2, 3) + + # WHEN: called with TextType 3 + result = doc._ImpressDocument__get_text_from_page(1, 3) + + # THEN: result should be an empty string + assert result == '', 'Result should be and empty string' + assert doc.document.getDrawPages().getByIndex.call_count == 0, 'There should be no call to getByIndex' + + +def test_get_text_from_page_valid_params(doc): + """ + Test ImpressDocument.__get_text_from_page with valid parameters + """ + # GIVEN: mocked LibreOffice Document with one slide, + # two notes and three texts + doc.document = _mock_a_LibreOffice_document(1, 2, 3) + + # WHEN: __get_text_from_page is called to get the Notes + result = doc._ImpressDocument__get_text_from_page(1, TextType.Notes) + + # THEN: result should be 'Note\nNote\n' + assert result == 'Note\nNote\n', 'Result should be \'Note\\n\' times the count of notes in the page' + + # WHEN: get the Title + result = doc._ImpressDocument__get_text_from_page(1, TextType.Title) + + # THEN: result should be 'Title\n' + assert result == 'Title\n', 'Result should be exactly \'Title\\n\'' + + # WHEN: get all text + result = doc._ImpressDocument__get_text_from_page(1, TextType.SlideText) + + # THEN: result should be 'Title\nString\nString\n' + assert result == 'Title\nString\nString\n', 'Result should be exactly \'Title\\nString\\nString\\n\'' + + +def _mock_a_LibreOffice_document(page_count, note_count, text_count): + """ + Helper function, creates a mock libreoffice document. + + :param page_count: Number of pages in the document + :param note_count: Number of note pages in the document + :param text_count: Number of text pages in the document + """ + pages = MagicMock() + page = MagicMock() + pages.getByIndex.return_value = page + notes_page = MagicMock() + notes_page.getCount.return_value = note_count + shape = MagicMock() + shape.supportsService.return_value = True + shape.getString.return_value = 'Note' + notes_page.getByIndex.return_value = shape + page.getNotesPage.return_value = notes_page + page.getCount.return_value = text_count + page.getByIndex.side_effect = _get_page_shape_side_effect + pages.getCount.return_value = page_count + document = MagicMock() + document.getDrawPages.return_value = pages + document.getByIndex.return_value = page + return document + + +def _get_page_shape_side_effect(*args): + """ + Helper function. + """ + page_shape = MagicMock() + page_shape.supportsService.return_value = True + if args[0] == 0: + page_shape.getShapeType.return_value = 'com.sun.star.presentation.TitleTextShape' + page_shape.getString.return_value = 'Title' + else: + page_shape.getString.return_value = 'String' + return page_shape diff --git a/tests/functional/openlp_plugins/presentations/test_mediaitem.py b/tests/functional/openlp_plugins/presentations/test_mediaitem.py index 2a3712ef6..cc7ac2f96 100644 --- a/tests/functional/openlp_plugins/presentations/test_mediaitem.py +++ b/tests/functional/openlp_plugins/presentations/test_mediaitem.py @@ -22,145 +22,130 @@ This module contains tests for the lib submodule of the Presentations plugin. """ from pathlib import Path -from unittest import TestCase from unittest.mock import MagicMock, PropertyMock, call, patch from openlp.core.common.registry import Registry from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem -from tests.helpers.testmixin import TestMixin -class TestMediaItem(TestCase, TestMixin): +def test_build_file_mask_string(media_item): """ - Test the mediaitem methods. + Test the build_file_mask_string() method """ - def setUp(self): - """ - Set up the components need for all tests. - """ - Registry.create() - Registry().register('service_manager', MagicMock()) - Registry().register('main_window', MagicMock()) - with patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup'), \ - patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item'): - self.media_item = PresentationMediaItem(None, MagicMock, MagicMock()) - self.setup_application() + # GIVEN: Different controllers. + impress_controller = MagicMock() + impress_controller.enabled.return_value = True + impress_controller.supports = ['odp'] + impress_controller.also_supports = ['ppt'] + presentation_controller = MagicMock() + presentation_controller.enabled.return_value = True + presentation_controller.supports = ['ppt'] + presentation_controller.also_supports = [] + presentation_viewer_controller = MagicMock() + presentation_viewer_controller.enabled.return_value = False + pdf_controller = MagicMock() + pdf_controller.enabled.return_value = True + pdf_controller.supports = ['pdf'] + pdf_controller.also_supports = ['xps', 'oxps', 'epub', 'cbz', 'fb2'] + # Mock the controllers. + media_item.controllers = { + 'Impress': impress_controller, + 'Powerpoint': presentation_controller, + 'Powerpoint Viewer': presentation_viewer_controller, + 'Pdf': pdf_controller + } - def test_build_file_mask_string(self): - """ - Test the build_file_mask_string() method - """ - # GIVEN: Different controllers. - impress_controller = MagicMock() - impress_controller.enabled.return_value = True - impress_controller.supports = ['odp'] - impress_controller.also_supports = ['ppt'] - presentation_controller = MagicMock() - presentation_controller.enabled.return_value = True - presentation_controller.supports = ['ppt'] - presentation_controller.also_supports = [] - presentation_viewer_controller = MagicMock() - presentation_viewer_controller.enabled.return_value = False - pdf_controller = MagicMock() - pdf_controller.enabled.return_value = True - pdf_controller.supports = ['pdf'] - pdf_controller.also_supports = ['xps', 'oxps', 'epub', 'cbz', 'fb2'] - # Mock the controllers. - self.media_item.controllers = { - 'Impress': impress_controller, - 'Powerpoint': presentation_controller, - 'Powerpoint Viewer': presentation_viewer_controller, - 'Pdf': pdf_controller - } + # WHEN: Build the file mask. + with patch('openlp.plugins.presentations.lib.mediaitem.translate') as mocked_translate: + mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate + media_item.build_file_mask_string() - # WHEN: Build the file mask. - with patch('openlp.plugins.presentations.lib.mediaitem.translate') as mocked_translate: - mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate - self.media_item.build_file_mask_string() + # THEN: The file mask should be generated correctly + assert '*.odp' in media_item.on_new_file_masks, 'The file mask should contain the odp extension' + assert '*.ppt' in media_item.on_new_file_masks, 'The file mask should contain the ppt extension' + assert '*.pdf' in media_item.on_new_file_masks, 'The file mask should contain the pdf extension' + assert '*.xps' in media_item.on_new_file_masks, 'The file mask should contain the xps extension' + assert '*.oxps' in media_item.on_new_file_masks, 'The file mask should contain the oxps extension' + assert '*.epub' in media_item.on_new_file_masks, 'The file mask should contain the epub extension' + assert '*.cbz' in media_item.on_new_file_masks, 'The file mask should contain the cbz extension' + assert '*.fb2' in media_item.on_new_file_masks, 'The file mask should contain the fb2 extension' - # THEN: The file mask should be generated correctly - assert '*.odp' in self.media_item.on_new_file_masks, 'The file mask should contain the odp extension' - assert '*.ppt' in self.media_item.on_new_file_masks, 'The file mask should contain the ppt extension' - assert '*.pdf' in self.media_item.on_new_file_masks, 'The file mask should contain the pdf extension' - assert '*.xps' in self.media_item.on_new_file_masks, 'The file mask should contain the xps extension' - assert '*.oxps' in self.media_item.on_new_file_masks, 'The file mask should contain the oxps extension' - assert '*.epub' in self.media_item.on_new_file_masks, 'The file mask should contain the epub extension' - assert '*.cbz' in self.media_item.on_new_file_masks, 'The file mask should contain the cbz extension' - assert '*.fb2' in self.media_item.on_new_file_masks, 'The file mask should contain the fb2 extension' - def test_clean_up_thumbnails(self): - """ - Test that the clean_up_thumbnails method works as expected when files exists. - """ - # GIVEN: A mocked controller, and mocked os.path.getmtime - mocked_disabled_controller = MagicMock() - mocked_disabled_controller.enabled.return_value = False - mocked_disabled_supports = PropertyMock() - type(mocked_disabled_controller).supports = mocked_disabled_supports - mocked_enabled_controller = MagicMock() - mocked_enabled_controller.enabled.return_value = True - mocked_doc = MagicMock(**{'get_thumbnail_path.return_value': Path()}) - mocked_enabled_controller.add_document.return_value = mocked_doc - mocked_enabled_controller.supports = ['tmp'] - self.media_item.controllers = { - 'Enabled': mocked_enabled_controller, - 'Disabled': mocked_disabled_controller - } +def test_clean_up_thumbnails(media_item): + """ + Test that the clean_up_thumbnails method works as expected when files exists. + """ + # GIVEN: A mocked controller, and mocked os.path.getmtime + mocked_disabled_controller = MagicMock() + mocked_disabled_controller.enabled.return_value = False + mocked_disabled_supports = PropertyMock() + type(mocked_disabled_controller).supports = mocked_disabled_supports + mocked_enabled_controller = MagicMock() + mocked_enabled_controller.enabled.return_value = True + mocked_doc = MagicMock(**{'get_thumbnail_path.return_value': Path()}) + mocked_enabled_controller.add_document.return_value = mocked_doc + mocked_enabled_controller.supports = ['tmp'] + media_item.controllers = { + 'Enabled': mocked_enabled_controller, + 'Disabled': mocked_disabled_controller + } - thumb_path = MagicMock(st_mtime=100) - file_path = MagicMock(st_mtime=400) - with patch.object(Path, 'stat', side_effect=[thumb_path, file_path]), \ - patch.object(Path, 'exists', return_value=True): - presentation_file = Path('file.tmp') - - # WHEN: calling clean_up_thumbnails - self.media_item.clean_up_thumbnails(presentation_file, True) - - # THEN: doc.presentation_deleted should have been called since the thumbnails mtime will be greater than - # the presentation_file's mtime. - mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True) - assert mocked_disabled_supports.call_count == 0 - - def test_clean_up_thumbnails_missing_file(self): - """ - Test that the clean_up_thumbnails method works as expected when file is missing. - """ - # GIVEN: A mocked controller, and mocked os.path.exists - mocked_controller = MagicMock() - mocked_doc = MagicMock() - mocked_controller.add_document.return_value = mocked_doc - mocked_controller.supports = ['tmp'] - self.media_item.controllers = { - 'Mocked': mocked_controller - } + thumb_path = MagicMock(st_mtime=100) + file_path = MagicMock(st_mtime=400) + with patch.object(Path, 'stat', side_effect=[thumb_path, file_path]), \ + patch.object(Path, 'exists', return_value=True): presentation_file = Path('file.tmp') - with patch.object(Path, 'exists', return_value=False): - # WHEN: calling clean_up_thumbnails - self.media_item.clean_up_thumbnails(presentation_file, True) + # WHEN: calling clean_up_thumbnails + media_item.clean_up_thumbnails(presentation_file, True) - # THEN: doc.presentation_deleted should have been called since the presentation file did not exists. - mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True) + # THEN: doc.presentation_deleted should have been called since the thumbnails mtime will be greater than + # the presentation_file's mtime. + mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True) + assert mocked_disabled_supports.call_count == 0 - @patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup') - @patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item') - def test_search(self, *unreferenced_mocks): - """ - Test that the search method finds the correct results - """ - # GIVEN: A mocked Settings class which returns a list of Path objects, - # and an instance of the PresentationMediaItem - path_1 = Path('some_dir', 'Impress_file_1') - path_2 = Path('some_other_dir', 'impress_file_2') - path_3 = Path('another_dir', 'ppt_file') - mocked_returned_settings = MagicMock() - mocked_returned_settings.value.return_value = [path_1, path_2, path_3] - Registry().register('settings', mocked_returned_settings) - media_item = PresentationMediaItem(None, MagicMock(), None) - media_item.settings_section = '' - # WHEN: Calling search - results = media_item.search('IMPRE', False) +def test_clean_up_thumbnails_missing_file(media_item): + """ + Test that the clean_up_thumbnails method works as expected when file is missing. + """ + # GIVEN: A mocked controller, and mocked os.path.exists + mocked_controller = MagicMock() + mocked_doc = MagicMock() + mocked_controller.add_document.return_value = mocked_doc + mocked_controller.supports = ['tmp'] + media_item.controllers = { + 'Mocked': mocked_controller + } + presentation_file = Path('file.tmp') + with patch.object(Path, 'exists', return_value=False): - # THEN: The first two results should have been returned - assert results == [[str(path_1), 'Impress_file_1'], [str(path_2), 'impress_file_2']] + # WHEN: calling clean_up_thumbnails + media_item.clean_up_thumbnails(presentation_file, True) + + # THEN: doc.presentation_deleted should have been called since the presentation file did not exists. + mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True) + + +@patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup') +@patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item') +def test_search(mock_setup, mock_item, registry): + """ + Test that the search method finds the correct results + """ + # GIVEN: A mocked Settings class which returns a list of Path objects, + # and an instance of the PresentationMediaItem + path_1 = Path('some_dir', 'Impress_file_1') + path_2 = Path('some_other_dir', 'impress_file_2') + path_3 = Path('another_dir', 'ppt_file') + mocked_returned_settings = MagicMock() + mocked_returned_settings.value.return_value = [path_1, path_2, path_3] + Registry().register('settings', mocked_returned_settings) + media_item = PresentationMediaItem(None, MagicMock(), None) + media_item.settings_section = '' + + # WHEN: Calling search + results = media_item.search('IMPRE', False) + + # THEN: The first two results should have been returned + assert results == [[str(path_1), 'Impress_file_1'], [str(path_2), 'impress_file_2']] diff --git a/tests/functional/openlp_plugins/presentations/test_messagelistener.py b/tests/functional/openlp_plugins/presentations/test_messagelistener.py index bd719e1e9..c938063f5 100644 --- a/tests/functional/openlp_plugins/presentations/test_messagelistener.py +++ b/tests/functional/openlp_plugins/presentations/test_messagelistener.py @@ -21,129 +21,108 @@ """ This module contains tests for the lib submodule of the Presentations plugin. """ -from unittest import TestCase from unittest.mock import MagicMock, patch -from openlp.core.common.registry import Registry -from openlp.plugins.presentations.lib.mediaitem import MessageListener, PresentationMediaItem +from openlp.plugins.presentations.lib.mediaitem import MessageListener from openlp.plugins.presentations.lib.messagelistener import Controller -from tests.helpers.testmixin import TestMixin -class TestMessageListener(TestCase, TestMixin): +@patch('openlp.plugins.presentations.lib.mediaitem.MessageListener._setup') +def test_start_presentation(media_mock, media_item): """ - Test the Presentation Message Listener. + Find and chose a controller to play a presentations. """ - def setUp(self): - """ - Set up the components need for all tests. - """ - Registry.create() - Registry().register('service_manager', MagicMock()) - Registry().register('main_window', MagicMock()) - with patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup'), \ - patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item'): - self.media_item = PresentationMediaItem(None, MagicMock, MagicMock()) + # GIVEN: A single controller and service item wanting to use the controller + mock_item = MagicMock() + mock_item.processor = 'Powerpoint' + mock_item.get_frame_path.return_value = "test.ppt" + media_item.automatic = False + mocked_controller = MagicMock() + mocked_controller.available = True + mocked_controller.supports = ['ppt'] + controllers = { + 'Powerpoint': mocked_controller + } + ml = MessageListener(media_item) + ml.media_item = media_item + ml.controllers = controllers + ml.preview_handler = MagicMock() + ml.timer = MagicMock() - @patch('openlp.plugins.presentations.lib.mediaitem.MessageListener._setup') - def test_start_presentation(self, media_mock): - """ - Find and chose a controller to play a presentations. - """ - # GIVEN: A single controller and service item wanting to use the controller - mock_item = MagicMock() - mock_item.processor = 'Powerpoint' - mock_item.get_frame_path.return_value = "test.ppt" - self.media_item.automatic = False - mocked_controller = MagicMock() - mocked_controller.available = True - mocked_controller.supports = ['ppt'] - controllers = { - 'Powerpoint': mocked_controller - } - ml = MessageListener(self.media_item) - ml.media_item = self.media_item - ml.controllers = controllers - ml.preview_handler = MagicMock() - ml.timer = MagicMock() + # WHEN: request the presentation to start + ml.startup([mock_item, False, False, False]) - # WHEN: request the presentation to start - ml.startup([mock_item, False, False, False]) - - # THEN: The controllers will be setup. - assert len(controllers) > 0, 'We have loaded a controller' - - @patch('openlp.plugins.presentations.lib.mediaitem.MessageListener._setup') - def test_start_presentation_with_no_player(self, media_mock): - """ - Find and chose a controller to play a presentations when the player is not available. - """ - # GIVEN: A single controller and service item wanting to use the controller - mock_item = MagicMock() - mock_item.processor = 'Powerpoint' - mock_item.get_frame_path.return_value = "test.ppt" - self.media_item.automatic = False - mocked_controller = MagicMock() - mocked_controller.available = True - mocked_controller.supports = ['ppt'] - mocked_controller1 = MagicMock() - mocked_controller1.available = False - mocked_controller1.supports = ['ppt'] - controllers = { - 'Impress': mocked_controller, - 'Powerpoint': mocked_controller1 - } - ml = MessageListener(self.media_item) - ml.media_item = self.media_item - ml.controllers = controllers - ml.preview_handler = MagicMock() - ml.timer = MagicMock() - - # WHEN: request the presentation to start - ml.startup([mock_item, False, False, False]) - - # THEN: The controllers will be setup. - assert len(controllers) > 0, 'We have loaded a controller' - - @patch('openlp.plugins.presentations.lib.mediaitem.MessageListener._setup') - def test_start_pdf_presentation(self, media_mock): - """ - Test the startup of pdf presentation succeed. - """ - # GIVEN: A sservice item with a pdf - mock_item = MagicMock() - mock_item.processor = 'Pdf' - mock_item.get_frame_path.return_value = "test.pdf" - self.media_item.generate_slide_data = MagicMock() - ml = MessageListener(self.media_item) - ml.media_item = self.media_item - ml.preview_handler = MagicMock() - - # WHEN: request the presentation to start - ml.startup([mock_item, False, False, False]) - - # THEN: The handler should be set to None - assert ml.handler is None, 'The handler should be None' + # THEN: The controllers will be setup. + assert len(controllers) > 0, 'We have loaded a controller' -class TestController(TestCase, TestMixin): +@patch('openlp.plugins.presentations.lib.mediaitem.MessageListener._setup') +def test_start_presentation_with_no_player(media_mock, media_item): """ - Test the Presentation Controller. + Find and chose a controller to play a presentations when the player is not available. """ + # GIVEN: A single controller and service item wanting to use the controller + mock_item = MagicMock() + mock_item.processor = 'Powerpoint' + mock_item.get_frame_path.return_value = "test.ppt" + media_item.automatic = False + mocked_controller = MagicMock() + mocked_controller.available = True + mocked_controller.supports = ['ppt'] + mocked_controller1 = MagicMock() + mocked_controller1.available = False + mocked_controller1.supports = ['ppt'] + controllers = { + 'Impress': mocked_controller, + 'Powerpoint': mocked_controller1 + } + ml = MessageListener(media_item) + ml.media_item = media_item + ml.controllers = controllers + ml.preview_handler = MagicMock() + ml.timer = MagicMock() - def test_add_handler_failure(self): - """ - Test that add_handler does set doc.slidenumber to 0 in case filed loading - """ - # GIVEN: A Controller, a mocked doc-controller - controller = Controller(True) - mocked_doc_controller = MagicMock() - mocked_doc = MagicMock() - mocked_doc.load_presentation.return_value = False - mocked_doc_controller.add_document.return_value = mocked_doc + # WHEN: request the presentation to start + ml.startup([mock_item, False, False, False]) - # WHEN: calling add_handler that fails - controller.add_handler(mocked_doc_controller, MagicMock(), True, 0) + # THEN: The controllers will be setup. + assert len(controllers) > 0, 'We have loaded a controller' - # THEN: slidenumber should be 0 - assert controller.doc.slidenumber == 0, 'doc.slidenumber should be 0' + +@patch('openlp.plugins.presentations.lib.mediaitem.MessageListener._setup') +def test_start_pdf_presentation(media_mock, media_item): + """ + Test the startup of pdf presentation succeed. + """ + # GIVEN: A sservice item with a pdf + mock_item = MagicMock() + mock_item.processor = 'Pdf' + mock_item.get_frame_path.return_value = "test.pdf" + media_item.generate_slide_data = MagicMock() + ml = MessageListener(media_item) + ml.media_item = media_item + ml.preview_handler = MagicMock() + + # WHEN: request the presentation to start + ml.startup([mock_item, False, False, False]) + + # THEN: The handler should be set to None + assert ml.handler is None, 'The handler should be None' + + +def test_add_handler_failure(): + """ + Test that add_handler does set doc.slidenumber to 0 in case filed loading + """ + # GIVEN: A Controller, a mocked doc-controller + controller = Controller(True) + mocked_doc_controller = MagicMock() + mocked_doc = MagicMock() + mocked_doc.load_presentation.return_value = False + mocked_doc_controller.add_document.return_value = mocked_doc + + # WHEN: calling add_handler that fails + controller.add_handler(mocked_doc_controller, MagicMock(), True, 0) + + # THEN: slidenumber should be 0 + assert controller.doc.slidenumber == 0, 'doc.slidenumber should be 0' diff --git a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py index 61354bb2a..24dde8f42 100644 --- a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py @@ -26,25 +26,30 @@ import pytest from pathlib import Path from shutil import rmtree, which from tempfile import mkdtemp -from unittest import TestCase, skipIf from unittest.mock import MagicMock, patch from PyQt5 import QtCore, QtGui from openlp.core.common import is_macosx, is_linux, is_win from openlp.core.common.settings import Settings -from openlp.core.common.registry import Registry from openlp.core.display.screens import ScreenList from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument -from tests.helpers.testmixin import TestMixin from tests.utils.constants import RESOURCE_PATH -__default_settings__ = { - 'presentations/enable_pdf_program': True, - 'presentations/pdf_program': None, - 'presentations/thumbnail_scheme': '' -} +@pytest.yield_fixture() +def pdf_env(settings, mock_plugin): + temp_folder_path = Path(mkdtemp()) + thumbnail_folder_path = Path(mkdtemp()) + desktop = MagicMock() + desktop.primaryScreen.return_value = SCREEN['primary'] + desktop.screenCount.return_value = SCREEN['number'] + desktop.screenGeometry.return_value = SCREEN['size'] + ScreenList.create(desktop) + yield settings, mock_plugin, temp_folder_path, thumbnail_folder_path + rmtree(thumbnail_folder_path) + rmtree(temp_folder_path) + SCREEN = { 'primary': False, @@ -66,195 +71,178 @@ def get_screen_resolution(): from win32api import GetSystemMetrics return GetSystemMetrics(0), GetSystemMetrics(1) elif is_linux(): - from Xlib.display import Display - resolution = Display().screen().root.get_geometry() - return resolution.width, resolution.height + if IS_CI: + return 1024, 768 + else: + from Xlib.display import Display + resolution = Display().screen().root.get_geometry() + return resolution.width, resolution.height else: return 1024, 768 -class TestPdfController(TestCase, TestMixin): +def test_constructor(settings, mock_plugin): """ - Test the PdfController. + Test the Constructor from the PdfController """ - def setUp(self): - """ - Set up the components need for all tests. - """ - Registry().create() - self.setup_application() - self.build_settings() - # Mocked out desktop object - self.desktop = MagicMock() - self.desktop.primaryScreen.return_value = SCREEN['primary'] - self.desktop.screenCount.return_value = SCREEN['number'] - self.desktop.screenGeometry.return_value = SCREEN['size'] - Settings().extend_default_settings(__default_settings__) - Registry().register('settings', Settings()) - self.screens = ScreenList.create(self.desktop) - self.temp_folder_path = Path(mkdtemp()) - self.thumbnail_folder_path = Path(mkdtemp()) - self.mock_plugin = MagicMock() - self.mock_plugin.settings_section = self.temp_folder_path + # GIVEN: No presentation controller + controller = None - def tearDown(self): - """ - Delete all the C++ objects at the end so that we don't have a segfault - """ - del self.screens - Registry().remove('settings') - self.destroy_settings() - rmtree(self.thumbnail_folder_path) - rmtree(self.temp_folder_path) + # WHEN: The presentation controller object is created + controller = PdfController(plugin=mock_plugin) - def test_constructor(self): - """ - Test the Constructor from the PdfController - """ - # GIVEN: No presentation controller - controller = None + # THEN: The name of the presentation controller should be correct + assert 'Pdf' == controller.name, 'The name of the presentation controller should be correct' - # WHEN: The presentation controller object is created - controller = PdfController(plugin=self.mock_plugin) - # THEN: The name of the presentation controller should be correct - assert 'Pdf' == controller.name, 'The name of the presentation controller should be correct' +def load_pdf(exe_path, pdf_env): + """ + Test loading a Pdf using the PdfController + """ + # GIVEN: A Pdf-file + test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf' - @skipIf(IS_CI, "This is failing on CI, skip until we can figure out what the problem is") - def load_pdf(self, exe_path): - """ - Test loading a Pdf using the PdfController - """ - # GIVEN: A Pdf-file - test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf' + # WHEN: The Pdf is loaded + settings = pdf_env[0] + mock_plugin = pdf_env[1] + temp_folder_path = pdf_env[2] + thumbnail_folder_path = pdf_env[3] + settings.setValue('presentations/pdf_program', exe_path) + controller = PdfController(plugin=mock_plugin) + controller.temp_folder = temp_folder_path + controller.thumbnail_folder = thumbnail_folder_path + document = PdfDocument(controller, test_file_path) + loaded = document.load_presentation() - # WHEN: The Pdf is loaded - Settings().setValue('presentations/pdf_program', exe_path) - controller = PdfController(plugin=self.mock_plugin) - controller.temp_folder = self.temp_folder_path - controller.thumbnail_folder = self.thumbnail_folder_path - document = PdfDocument(controller, test_file_path) - loaded = document.load_presentation() + # THEN: The load should succeed and we should be able to get a pagecount + assert loaded is True, 'The loading of the PDF should succeed.' + assert 3 == document.get_slide_count(), 'The pagecount of the PDF should be 3.' - # THEN: The load should succeed and we should be able to get a pagecount - assert loaded is True, 'The loading of the PDF should succeed.' - assert 3 == document.get_slide_count(), 'The pagecount of the PDF should be 3.' - def load_pdf_pictures(self, exe_path): - """ - Test loading a Pdf and check the generated pictures' size - """ - # GIVEN: A Pdf-file - test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf' +def load_pdf_pictures(exe_path, pdf_env): + """ + Test loading a Pdf and check the generated pictures' size + """ + # GIVEN: A Pdf-file + test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf' - # WHEN: The Pdf is loaded - Settings().setValue('presentations/pdf_program', exe_path) - controller = PdfController(plugin=self.mock_plugin) - controller.temp_folder = self.temp_folder_path - controller.thumbnail_folder = self.thumbnail_folder_path - document = PdfDocument(controller, test_file_path) - loaded = document.load_presentation() + # WHEN: The Pdf is loaded + mock_plugin = pdf_env[1] + temp_folder_path = pdf_env[2] + thumbnail_folder_path = pdf_env[3] + Settings().setValue('presentations/pdf_program', exe_path) + controller = PdfController(plugin=mock_plugin) + controller.temp_folder = temp_folder_path + controller.thumbnail_folder = thumbnail_folder_path + document = PdfDocument(controller, test_file_path) + loaded = document.load_presentation() - # THEN: The load should succeed and pictures should be created and have been scaled to fit the screen - assert loaded is True, 'The loading of the PDF should succeed.' - image = QtGui.QImage(os.path.join(str(self.temp_folder_path), 'pdf_test1.pdf', 'mainslide001.png')) - # Based on the converter used the resolution will differ a bit - if controller.gsbin: - assert 1076 == image.height(), 'The height should be 1076' - assert 760 == image.width(), 'The width should be 760' - else: - width, height = get_screen_resolution() - # Calculate the width of the PDF based on the aspect ratio of the PDF - width = int(round(height * 0.70703125, 0)) - assert image.height() == height, 'The height should be {height}'.format(height=height) - assert image.width() == width, 'The width should be {width}'.format(width=width) + # THEN: The load should succeed and pictures should be created and have been scaled to fit the screen + assert loaded is True, 'The loading of the PDF should succeed.' + image = QtGui.QImage(os.path.join(str(temp_folder_path), 'pdf_test1.pdf', 'mainslide001.png')) + # Based on the converter used the resolution will differ a bit + if controller.gsbin: + assert 1076 == image.height(), 'The height should be 1076' + assert 760 == image.width(), 'The width should be 760' + else: + width, height = get_screen_resolution() + # Calculate the width of the PDF based on the aspect ratio of the PDF + width = int(round(height * 0.70703125, 0)) + assert image.height() == height, 'The height should be {height}'.format(height=height) + assert image.width() == width, 'The width should be {width}'.format(width=width) - def test_load_pdf(self): - """ - Test loading a Pdf with each of the installed backends - """ - for exe_name in ['gs', 'mutool', 'mudraw']: - exe_path = which(exe_name) - if exe_path: - self.load_pdf(exe_path) - self.load_pdf_pictures(exe_path) - def test_loading_pdf_using_pymupdf(self): - try: - import fitz # noqa: F401 - except ImportError: - pytest.skip('PyMuPDF is not installed') +def test_load_pdf(pdf_env): + """ + Test loading a Pdf with each of the installed backends + """ + for exe_name in ['gs', 'mutool', 'mudraw']: + exe_path = which(exe_name) + if exe_path: + load_pdf(exe_path, pdf_env) + load_pdf_pictures(exe_path, pdf_env) - self.load_pdf(None) - self.load_pdf_pictures(None) - @patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') - def test_process_check_binary_mudraw(self, mocked_check_binary_exists): - """ - Test that the correct output from mudraw is detected - """ - # GIVEN: A mocked check_binary_exists that returns mudraw output - mudraw_output = (b'usage: mudraw [options] input [pages]\n\t-o -\toutput filename (%d for page number)n\t\tsupp' - b'orted formats: pgm, ppm, pam, png, pbmn\t-p -\tpasswordn\t-r -\tresolution in dpi (default: ' - b'72)n\t-w -\twidth (in pixels) (maximum width if -r is specified)n\t-h -\theight (in pixels) ' - b'(maximum height if -r is specified)') - mocked_check_binary_exists.return_value = mudraw_output +def test_loading_pdf_using_pymupdf(): + try: + import fitz # noqa: F401 + except ImportError: + pytest.skip('PyMuPDF is not installed') - # WHEN: Calling process_check_binary - ret = PdfController.process_check_binary('test') + load_pdf(None) + load_pdf_pictures(None) - # THEN: mudraw should be detected - assert 'mudraw' == ret, 'mudraw should have been detected' - @patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') - def test_process_check_binary_new_motool(self, mocked_check_binary_exists): - """ - Test that the correct output from the new mutool is detected - """ - # GIVEN: A mocked check_binary_exists that returns new mutool output - new_mutool_output = (b'usage: mutool [options]\n\tdraw\t-- convert document\n\trun\t-- run javascript' - b'\n\tclean\t-- rewrite pdf file\n\textract\t-- extract font and image resources\n\tinfo\t' - b'-- show information about pdf resources\n\tpages\t-- show information about pdf pages\n' - b'\tposter\t-- split large page into many tiles\n\tshow\t-- show internal pdf objects\n\t' - b'create\t-- create pdf document\n\tmerge\t-- merge pages from multiple pdf sources into a' - b'new pdf\n') - mocked_check_binary_exists.return_value = new_mutool_output +@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') +def test_process_check_binary_mudraw(mocked_check_binary_exists): + """ + Test that the correct output from mudraw is detected + """ + # GIVEN: A mocked check_binary_exists that returns mudraw output + mudraw_output = (b'usage: mudraw [options] input [pages]\n\t-o -\toutput filename (%d for page number)n\t\tsupp' + b'orted formats: pgm, ppm, pam, png, pbmn\t-p -\tpasswordn\t-r -\tresolution in dpi (default: ' + b'72)n\t-w -\twidth (in pixels) (maximum width if -r is specified)n\t-h -\theight (in pixels) ' + b'(maximum height if -r is specified)') + mocked_check_binary_exists.return_value = mudraw_output - # WHEN: Calling process_check_binary - ret = PdfController.process_check_binary('test') + # WHEN: Calling process_check_binary + ret = PdfController.process_check_binary('test') - # THEN: mutool should be detected - assert 'mutool' == ret, 'mutool should have been detected' + # THEN: mudraw should be detected + assert 'mudraw' == ret, 'mudraw should have been detected' - @patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') - def test_process_check_binary_old_motool(self, mocked_check_binary_exists): - """ - Test that the output from the old mutool is not accepted - """ - # GIVEN: A mocked check_binary_exists that returns old mutool output - old_mutool_output = (b'usage: mutool [options]\n\tclean\t-- rewrite pdf file\n\textract\t-- extract ' - b'font and image resources\n\tinfo\t-- show information about pdf resources\n\tposter\t-- ' - b'split large page into many tiles\n\tshow\t-- show internal pdf objects') - mocked_check_binary_exists.return_value = old_mutool_output - # WHEN: Calling process_check_binary - ret = PdfController.process_check_binary('test') +@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') +def test_process_check_binary_new_motool(mocked_check_binary_exists): + """ + Test that the correct output from the new mutool is detected + """ + # GIVEN: A mocked check_binary_exists that returns new mutool output + new_mutool_output = (b'usage: mutool [options]\n\tdraw\t-- convert document\n\trun\t-- run javascript' + b'\n\tclean\t-- rewrite pdf file\n\textract\t-- extract font and image resources\n\tinfo\t' + b'-- show information about pdf resources\n\tpages\t-- show information about pdf pages\n' + b'\tposter\t-- split large page into many tiles\n\tshow\t-- show internal pdf objects\n\t' + b'create\t-- create pdf document\n\tmerge\t-- merge pages from multiple pdf sources into a' + b'new pdf\n') + mocked_check_binary_exists.return_value = new_mutool_output - # THEN: mutool should be detected - assert ret is None, 'old mutool should not be accepted!' + # WHEN: Calling process_check_binary + ret = PdfController.process_check_binary('test') - @patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') - def test_process_check_binary_gs(self, mocked_check_binary_exists): - """ - Test that the correct output from gs is detected - """ - # GIVEN: A mocked check_binary_exists that returns gs output - gs_output = (b'GPL Ghostscript 9.19 (2016-03-23)\nCopyright (C) 2016 Artifex Software, Inc. All rights reserv' - b'ed.\nUsage: gs [switches] [file1.ps file2.ps ...]') - mocked_check_binary_exists.return_value = gs_output + # THEN: mutool should be detected + assert 'mutool' == ret, 'mutool should have been detected' - # WHEN: Calling process_check_binary - ret = PdfController.process_check_binary('test') - # THEN: mutool should be detected - assert 'gs' == ret, 'mutool should have been detected' +@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') +def test_process_check_binary_old_motool(mocked_check_binary_exists): + """ + Test that the output from the old mutool is not accepted + """ + # GIVEN: A mocked check_binary_exists that returns old mutool output + old_mutool_output = (b'usage: mutool [options]\n\tclean\t-- rewrite pdf file\n\textract\t-- extract ' + b'font and image resources\n\tinfo\t-- show information about pdf resources\n\tposter\t-- ' + b'split large page into many tiles\n\tshow\t-- show internal pdf objects') + mocked_check_binary_exists.return_value = old_mutool_output + + # WHEN: Calling process_check_binary + ret = PdfController.process_check_binary('test') + + # THEN: mutool should be detected + assert ret is None, 'old mutool should not be accepted!' + + +@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists') +def test_process_check_binary_gs(mocked_check_binary_exists): + """ + Test that the correct output from gs is detected + """ + # GIVEN: A mocked check_binary_exists that returns gs output + gs_output = (b'GPL Ghostscript 9.19 (2016-03-23)\nCopyright (C) 2016 Artifex Software, Inc. All rights reserv' + b'ed.\nUsage: gs [switches] [file1.ps file2.ps ...]') + mocked_check_binary_exists.return_value = gs_output + + # WHEN: Calling process_check_binary + ret = PdfController.process_check_binary('test') + + # THEN: mutool should be detected + assert 'gs' == ret, 'mutool should have been detected' diff --git a/tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py b/tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py index 44db65423..5a9c9a8cd 100644 --- a/tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py @@ -21,287 +21,208 @@ """ Functional tests to test the PowerPointController class and related methods. """ -import os -import shutil -from tempfile import mkdtemp -from unittest import TestCase +import pytest from unittest.mock import MagicMock, patch from openlp.core.common import is_win from openlp.core.common.registry import Registry -from openlp.core.common.settings import Settings from openlp.plugins.presentations.lib.powerpointcontroller import PowerpointController, PowerpointDocument, \ _get_text_from_shapes -from tests.helpers.testmixin import TestMixin -from tests.utils.constants import TEST_RESOURCES_PATH if is_win(): import pywintypes -__default_settings__ = { - 'presentations/powerpoint slide click advance': True -} + +@pytest.fixture() +def get_thumbnail_folder(settings): + gtf = patch('openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument._setup') + yield gtf.start() + gtf.stop() -class TestPowerpointController(TestCase, TestMixin): +def test_constructor(settings, mock_plugin): """ - Test the PowerpointController Class + Test the Constructor from the PowerpointController """ + # GIVEN: No presentation controller + controller = None - 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 - Registry.create() - Registry().register('settings', Settings()) + # WHEN: The presentation controller object is created + controller = PowerpointController(plugin=mock_plugin) - def tearDown(self): - """ - Stop the patches - """ - self.destroy_settings() - shutil.rmtree(self.temp_folder) - - def test_constructor(self): - """ - Test the Constructor from the PowerpointController - """ - # GIVEN: No presentation controller - controller = None - - # WHEN: The presentation controller object is created - controller = PowerpointController(plugin=self.mock_plugin) - - # THEN: The name of the presentation controller should be correct - assert 'Powerpoint' == controller.name, 'The name of the presentation controller should be correct' + # THEN: The name of the presentation controller should be correct + assert 'Powerpoint' == controller.name, 'The name of the presentation controller should be correct' -class TestPowerpointDocument(TestCase, TestMixin): +def test_show_error_msg(): """ - Test the PowerpointDocument Class + Test the PowerpointDocument.show_error_msg() method gets called on com exception """ + if is_win(): + # GIVEN: A PowerpointDocument with mocked controller and presentation + with patch('openlp.plugins.presentations.lib.powerpointcontroller.critical_error_message_box') as \ + mocked_critical_error_message_box: + instance = PowerpointDocument(MagicMock(), MagicMock()) + instance.presentation = MagicMock() + instance.presentation.SlideShowWindow.View.GotoSlide = MagicMock(side_effect=pywintypes.com_error('1')) + instance.index_map[42] = 42 - def setUp(self): - """ - Set up the patches and mocks need for all tests. - """ - Registry.create() - Registry().register('settings', Settings()) - self.setup_application() - self.build_settings() - self.mock_plugin = MagicMock() - self.temp_folder = mkdtemp() - self.mock_plugin.settings_section = self.temp_folder - self.powerpoint_document_stop_presentation_patcher = patch( - 'openlp.plugins.presentations.lib.powerpointcontroller.PowerpointDocument.stop_presentation') - self.presentation_document_get_temp_folder_patcher = patch( - 'openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument.get_temp_folder') - self.presentation_document_setup_patcher = patch( - 'openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument._setup') - self.mock_powerpoint_document_stop_presentation = self.powerpoint_document_stop_presentation_patcher.start() - self.mock_presentation_document_get_temp_folder = self.presentation_document_get_temp_folder_patcher.start() - self.mock_presentation_document_setup = self.presentation_document_setup_patcher.start() - self.mock_controller = MagicMock() - self.mock_presentation = MagicMock() - self.mock_presentation_document_get_temp_folder.return_value = 'temp folder' - self.file_name = os.path.join(TEST_RESOURCES_PATH, 'presentations', 'test.pptx') - self.real_controller = PowerpointController(self.mock_plugin) - Settings().extend_default_settings(__default_settings__) + # WHEN: Calling goto_slide which will throw an exception + instance.goto_slide(42) - def tearDown(self): - """ - Stop the patches - """ - self.powerpoint_document_stop_presentation_patcher.stop() - self.presentation_document_get_temp_folder_patcher.stop() - self.presentation_document_setup_patcher.stop() - self.destroy_settings() - shutil.rmtree(self.temp_folder) + # THEN: mocked_critical_error_message_box should have been called + mocked_critical_error_message_box.assert_called_with('Error', 'An error occurred in the PowerPoint ' + 'integration and the presentation will be stopped.' + ' Restart the presentation if you wish to ' + 'present it.') - def test_show_error_msg(self): - """ - Test the PowerpointDocument.show_error_msg() method gets called on com exception - """ - if is_win(): - # GIVEN: A PowerpointDocument with mocked controller and presentation - with patch('openlp.plugins.presentations.lib.powerpointcontroller.critical_error_message_box') as \ - mocked_critical_error_message_box: - instance = PowerpointDocument(self.mock_controller, self.mock_presentation) - instance.presentation = MagicMock() - instance.presentation.SlideShowWindow.View.GotoSlide = MagicMock(side_effect=pywintypes.com_error('1')) - instance.index_map[42] = 42 - # WHEN: Calling goto_slide which will throw an exception - instance.goto_slide(42) +def test_create_titles_and_notes(get_thumbnail_folder): + """ + Test creating the titles from PowerPoint + """ + # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides + doc = PowerpointDocument(MagicMock(), MagicMock()) + doc.get_slide_count = MagicMock() + doc.get_slide_count.return_value = 2 + doc.index_map = {1: 1, 2: 2} + doc.save_titles_and_notes = MagicMock() + doc._PowerpointDocument__get_text_from_shapes = MagicMock() + slide = MagicMock() + slide.Shapes.Title.TextFrame.TextRange.Text = 'SlideText' + pres = MagicMock() + pres.Slides = MagicMock(side_effect=[slide, slide]) + doc.presentation = pres - # THEN: mocked_critical_error_message_box should have been called - mocked_critical_error_message_box.assert_called_with('Error', 'An error occurred in the PowerPoint ' - 'integration and the presentation will be stopped.' - ' Restart the presentation if you wish to ' - 'present it.') + # WHEN reading the titles and notes + doc.create_titles_and_notes() - # add _test to the following if necessary - def verify_loading_document(self): - """ - Test loading a document in PowerPoint - """ - if is_win() and self.real_controller.check_available(): - # GIVEN: A PowerpointDocument and a presentation - doc = PowerpointDocument(self.real_controller, self.file_name) + # THEN the save should have been called exactly once with 2 titles and 2 notes + doc.save_titles_and_notes.assert_called_once_with(['SlideText', 'SlideText'], [' ', ' ']) - # WHEN: loading the filename - doc.load_presentation() - result = doc.is_loaded() - # THEN: result should be true - assert result is True, 'The result should be True' - else: - self.skipTest('Powerpoint not available, skipping test.') +def test_create_titles_and_notes_with_no_slides(get_thumbnail_folder): + """ + Test creating the titles from PowerPoint when it returns no slides + """ + # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides + doc = PowerpointDocument(MagicMock(), MagicMock()) + doc.save_titles_and_notes = MagicMock() + doc._PowerpointDocument__get_text_from_shapes = MagicMock() + pres = MagicMock() + pres.Slides = [] + doc.presentation = pres - def test_create_titles_and_notes(self): - """ - Test creating the titles from PowerPoint - """ - # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides - self.doc = PowerpointDocument(self.mock_controller, self.file_name) - self.doc.get_slide_count = MagicMock() - self.doc.get_slide_count.return_value = 2 - self.doc.index_map = {1: 1, 2: 2} - self.doc.save_titles_and_notes = MagicMock() - self.doc._PowerpointDocument__get_text_from_shapes = MagicMock() - slide = MagicMock() - slide.Shapes.Title.TextFrame.TextRange.Text = 'SlideText' - pres = MagicMock() - pres.Slides = MagicMock(side_effect=[slide, slide]) - self.doc.presentation = pres + # WHEN reading the titles and notes + doc.create_titles_and_notes() - # WHEN reading the titles and notes - self.doc.create_titles_and_notes() + # THEN the save should have been called exactly once with empty titles and notes + doc.save_titles_and_notes.assert_called_once_with([], []) - # THEN the save should have been called exactly once with 2 titles and 2 notes - self.doc.save_titles_and_notes.assert_called_once_with(['SlideText', 'SlideText'], [' ', ' ']) - def test_create_titles_and_notes_with_no_slides(self): - """ - Test creating the titles from PowerPoint when it returns no slides - """ - # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides - doc = PowerpointDocument(self.mock_controller, self.file_name) - doc.save_titles_and_notes = MagicMock() - doc._PowerpointDocument__get_text_from_shapes = MagicMock() - pres = MagicMock() - pres.Slides = [] - doc.presentation = pres +def test_get_text_from_shapes(): + """ + Test getting text from powerpoint shapes + """ + # GIVEN: mocked shapes + shape = MagicMock() + shape.PlaceholderFormat.Type = 2 + shape.HasTextFrame = shape.TextFrame.HasText = True + shape.TextFrame.TextRange.Text = 'slideText' + shapes = [shape, shape] - # WHEN reading the titles and notes - doc.create_titles_and_notes() + # WHEN: getting the text + result = _get_text_from_shapes(shapes) - # THEN the save should have been called exactly once with empty titles and notes - doc.save_titles_and_notes.assert_called_once_with([], []) + # THEN: it should return the text + assert result == 'slideText\nslideText\n', 'result should match \'slideText\nslideText\n\'' - def test_get_text_from_shapes(self): - """ - Test getting text from powerpoint shapes - """ - # GIVEN: mocked shapes - shape = MagicMock() - shape.PlaceholderFormat.Type = 2 - shape.HasTextFrame = shape.TextFrame.HasText = True - shape.TextFrame.TextRange.Text = 'slideText' - shapes = [shape, shape] - # WHEN: getting the text - result = _get_text_from_shapes(shapes) +def test_get_text_from_shapes_with_no_shapes(): + """ + Test getting text from powerpoint shapes with no shapes + """ + # GIVEN: empty shapes array + shapes = [] - # THEN: it should return the text - assert result == 'slideText\nslideText\n', 'result should match \'slideText\nslideText\n\'' + # WHEN: getting the text + result = _get_text_from_shapes(shapes) - def test_get_text_from_shapes_with_no_shapes(self): - """ - Test getting text from powerpoint shapes with no shapes - """ - # GIVEN: empty shapes array - shapes = [] + # THEN: it should not fail but return empty string + assert result == '', 'result should be empty' - # WHEN: getting the text - result = _get_text_from_shapes(shapes) - # THEN: it should not fail but return empty string - assert result == '', 'result should be empty' +def test_goto_slide(get_thumbnail_folder): + """ + Test that goto_slide goes to next effect if the slide is already displayed + """ + # GIVEN: A Document with mocked controller, presentation, and mocked functions get_slide_number and next_step + Registry().get('settings').setValue('presentations/powerpoint slide click advance', True) + doc = PowerpointDocument(MagicMock(), MagicMock()) + doc.presentation = MagicMock() + doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 1 + doc.presentation.SlideShowWindow.View.GetClickCount.return_value = 2 + doc.get_slide_number = MagicMock() + doc.get_slide_number.return_value = 1 + doc.next_step = MagicMock() + doc.index_map[1] = 1 - def test_goto_slide(self): - """ - Test that goto_slide goes to next effect if the slide is already displayed - """ - # GIVEN: A Document with mocked controller, presentation, and mocked functions get_slide_number and next_step - doc = PowerpointDocument(self.mock_controller, self.mock_presentation) - doc.presentation = MagicMock() - doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 1 - doc.presentation.SlideShowWindow.View.GetClickCount.return_value = 2 - doc.get_slide_number = MagicMock() - doc.get_slide_number.return_value = 1 - doc.next_step = MagicMock() - doc.index_map[1] = 1 + # WHEN: Calling goto_slide + doc.goto_slide(1) - # WHEN: Calling goto_slide - doc.goto_slide(1) + # THEN: next_step() should be call to try to advance to the next effect. + assert doc.next_step.called is True, 'next_step() should have been called!' - # THEN: next_step() should be call to try to advance to the next effect. - assert doc.next_step.called is True, 'next_step() should have been called!' - def test_blank_screen(self): - """ - Test that blank_screen works as expected - """ - # GIVEN: A Document with mocked controller, presentation, and mocked function get_slide_number - doc = PowerpointDocument(self.mock_controller, self.mock_presentation) +def test_blank_screen(get_thumbnail_folder): + """ + Test that blank_screen works as expected + """ + # GIVEN: A Document with mocked controller, presentation, and mocked function get_slide_number + doc = PowerpointDocument(MagicMock(), MagicMock()) + doc.presentation = MagicMock() + doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3 + doc.presentation.Application.Version = 14.0 + doc.get_slide_number = MagicMock() + doc.get_slide_number.return_value = 2 + + # WHEN: Calling goto_slide + doc.blank_screen() + + # THEN: The view state, doc.blank_slide and doc.blank_click should have new values + assert doc.presentation.SlideShowWindow.View.State == 3, 'The View State should be 3' + assert doc.blank_slide == 2, 'doc.blank_slide should be 2 because of the PowerPoint version' + assert doc.blank_click == 3, 'doc.blank_click should be 3 because of the PowerPoint version' + + +def test_unblank_screen(get_thumbnail_folder): + """ + Test that unblank_screen works as expected + """ + # GIVEN: A Document with mocked controller, presentation, ScreenList, and mocked function get_slide_number + with patch('openlp.plugins.presentations.lib.powerpointcontroller.ScreenList') as mocked_screen_list: + mocked_screen_list_ret = MagicMock() + mocked_screen_list_ret.screen_list = [1] + mocked_screen_list.return_value = mocked_screen_list_ret + doc = PowerpointDocument(MagicMock(), MagicMock()) doc.presentation = MagicMock() doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3 doc.presentation.Application.Version = 14.0 doc.get_slide_number = MagicMock() doc.get_slide_number.return_value = 2 + doc.index_map[1] = 1 + doc.blank_slide = 1 + doc.blank_click = 1 # WHEN: Calling goto_slide - doc.blank_screen() + doc.unblank_screen() - # THEN: The view state, doc.blank_slide and doc.blank_click should have new values - assert doc.presentation.SlideShowWindow.View.State == 3, 'The View State should be 3' - assert doc.blank_slide == 2, 'doc.blank_slide should be 2 because of the PowerPoint version' - assert doc.blank_click == 3, 'doc.blank_click should be 3 because of the PowerPoint version' - - def test_unblank_screen(self): - """ - Test that unblank_screen works as expected - """ - # GIVEN: A Document with mocked controller, presentation, ScreenList, and mocked function get_slide_number - with patch('openlp.plugins.presentations.lib.powerpointcontroller.ScreenList') as mocked_screen_list: - mocked_screen_list_ret = MagicMock() - mocked_screen_list_ret.screen_list = [1] - mocked_screen_list.return_value = mocked_screen_list_ret - doc = PowerpointDocument(self.mock_controller, self.mock_presentation) - doc.presentation = MagicMock() - doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3 - doc.presentation.Application.Version = 14.0 - doc.get_slide_number = MagicMock() - doc.get_slide_number.return_value = 2 - doc.index_map[1] = 1 - doc.blank_slide = 1 - doc.blank_click = 1 - - # WHEN: Calling goto_slide - doc.unblank_screen() - - # THEN: The view state have new value, and several function should have been called - assert doc.presentation.SlideShowWindow.View.State == 1, 'The View State should be 1' - assert doc.presentation.SlideShowWindow.Activate.called is True, \ - 'SlideShowWindow.Activate should have been called' - assert doc.presentation.SlideShowWindow.View.GotoSlide.called is True, \ - 'View.GotoSlide should have been called because of the PowerPoint version' - assert doc.presentation.SlideShowWindow.View.GotoClick.called is True, \ - 'View.GotoClick should have been called because of the PowerPoint version' + # THEN: The view state have new value, and several function should have been called + assert doc.presentation.SlideShowWindow.View.State == 1, 'The View State should be 1' + assert doc.presentation.SlideShowWindow.Activate.called is True, \ + 'SlideShowWindow.Activate should have been called' + assert doc.presentation.SlideShowWindow.View.GotoSlide.called is True, \ + 'View.GotoSlide should have been called because of the PowerPoint version' + assert doc.presentation.SlideShowWindow.View.GotoClick.called is True, \ + 'View.GotoClick should have been called because of the PowerPoint version' diff --git a/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py.THIS b/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py.THIS deleted file mode 100644 index 0e0995f9f..000000000 --- a/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py.THIS +++ /dev/null @@ -1,224 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 - -########################################################################## -# OpenLP - Open Source Lyrics Projection # -# ---------------------------------------------------------------------- # -# Copyright (c) 2008-2020 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 . # -########################################################################## -""" -This module contains tests for the pptviewcontroller module of the Presentations plugin. -""" -import shutil -from tempfile import mkdtemp -from unittest import TestCase, skipIf -from unittest.mock import MagicMock, patch - -from openlp.core.common import is_win -from openlp.core.common.path import Path -from openlp.plugins.presentations.lib.pptviewcontroller import PptviewDocument, PptviewController -from tests.helpers.testmixin import TestMixin -from tests.utils.constants import RESOURCE_PATH - - -class TestPptviewController(TestCase, TestMixin): - """ - Test the PptviewController 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) - - def test_constructor(self): - """ - Test the Constructor from the PptViewController - """ - # GIVEN: No presentation controller - controller = None - - # WHEN: The presentation controller object is created - controller = PptviewController(plugin=self.mock_plugin) - - # THEN: The name of the presentation controller should be correct - assert 'Powerpoint Viewer' == controller.name, 'The name of the presentation controller should be correct' - - @skipIf(not is_win(), 'Not Windows') - @patch('openlp.plugins.presentations.lib.pptviewcontroller.cdll.LoadLibrary') - def test_check_available(self, mocked_load_library): - """ - Test check_available / check_installed - """ - # GIVEN: A mocked dll loader and a controller - mocked_process = MagicMock() - mocked_process.CheckInstalled.return_value = True - mocked_load_library.return_value = mocked_process - controller = PptviewController(plugin=self.mock_plugin) - - # WHEN: check_available is called - available = controller.check_available() - - # THEN: On windows it should return True, on other platforms False - assert available is True, 'check_available should return True on windows.' - - -class TestPptviewDocument(TestCase): - """ - Test the PptviewDocument Class - """ - def setUp(self): - """ - Set up the patches and mocks need for all tests. - """ - self.pptview_document_create_thumbnails_patcher = patch( - 'openlp.plugins.presentations.lib.pptviewcontroller.PptviewDocument.create_thumbnails') - self.pptview_document_stop_presentation_patcher = patch( - 'openlp.plugins.presentations.lib.pptviewcontroller.PptviewDocument.stop_presentation') - self.presentation_document_get_temp_folder_patcher = patch( - 'openlp.plugins.presentations.lib.pptviewcontroller.PresentationDocument.get_temp_folder') - self.presentation_document_setup_patcher = patch( - 'openlp.plugins.presentations.lib.pptviewcontroller.PresentationDocument._setup') - self.screen_list_patcher = patch('openlp.plugins.presentations.lib.pptviewcontroller.ScreenList') - self.rect_patcher = MagicMock() - self.mock_pptview_document_create_thumbnails = self.pptview_document_create_thumbnails_patcher.start() - self.mock_pptview_document_stop_presentation = self.pptview_document_stop_presentation_patcher.start() - self.mock_presentation_document_get_temp_folder = self.presentation_document_get_temp_folder_patcher.start() - self.mock_presentation_document_setup = self.presentation_document_setup_patcher.start() - self.mock_rect = self.rect_patcher.start() - self.mock_screen_list = self.screen_list_patcher.start() - self.mock_controller = MagicMock() - self.mock_presentation = MagicMock() - self.temp_folder = mkdtemp() - self.mock_presentation_document_get_temp_folder.return_value = self.temp_folder - - def tearDown(self): - """ - Stop the patches - """ - self.pptview_document_create_thumbnails_patcher.stop() - self.pptview_document_stop_presentation_patcher.stop() - self.presentation_document_get_temp_folder_patcher.stop() - self.presentation_document_setup_patcher.stop() - self.rect_patcher.stop() - self.screen_list_patcher.stop() - shutil.rmtree(self.temp_folder) - - @skipIf(not is_win(), 'Not Windows') - def test_load_presentation_succesful(self): - """ - Test the PptviewDocument.load_presentation() method when the PPT is successfully opened - """ - # GIVEN: A reset mocked_os - self.mock_controller.process.OpenPPT.return_value = 0 - instance = PptviewDocument(self.mock_controller, self.mock_presentation) - instance.file_path = 'test\path.ppt' - - # WHEN: The temporary directory exists and OpenPPT returns successfully (not -1) - result = instance.load_presentation() - - # THEN: PptviewDocument.load_presentation should return True - assert result is True - - @skipIf(not is_win(), 'Not Windows') - def test_load_presentation_un_succesful(self): - """ - Test the PptviewDocument.load_presentation() method when the temporary directory does not exist and the PPT is - not successfully opened - """ - # GIVEN: A reset mock_os_isdir - self.mock_controller.process.OpenPPT.return_value = -1 - instance = PptviewDocument(self.mock_controller, self.mock_presentation) - instance.file_path = 'test\path.ppt' - - # WHEN: The temporary directory does not exist and OpenPPT returns unsuccessfully (-1) - with patch.object(instance, 'get_temp_folder') as mocked_get_folder: - mocked_get_folder.return_value = MagicMock(spec=Path) - result = instance.load_presentation() - - # THEN: The temp folder should be created and PptviewDocument.load_presentation should return False - assert result is False - - def test_create_titles_and_notes(self): - """ - Test PowerpointController.create_titles_and_notes - """ - # GIVEN: mocked PresentationController.save_titles_and_notes and a pptx file - doc = PptviewDocument(self.mock_controller, self.mock_presentation) - doc.file_path = RESOURCE_PATH / 'presentations' / 'test.pptx' - doc.save_titles_and_notes = MagicMock() - - # WHEN reading the titles and notes - doc.create_titles_and_notes() - - # THEN save_titles_and_notes should have been called once with empty arrays - doc.save_titles_and_notes.assert_called_once_with(['Test 1\n', '\n', 'Test 2\n', 'Test 4\n', 'Test 3\n'], - ['Notes for slide 1', 'Inserted', 'Notes for slide 2', - 'Notes \nfor slide 4', 'Notes for slide 3']) - - def test_create_titles_and_notes_nonexistent_file(self): - """ - Test PowerpointController.create_titles_and_notes with nonexistent file - """ - # GIVEN: mocked PresentationController.save_titles_and_notes and an nonexistent file - with patch('builtins.open') as mocked_open, \ - patch.object(Path, 'exists') as mocked_path_exists, \ - patch('openlp.plugins.presentations.lib.presentationcontroller.create_paths') as \ - mocked_dir_exists: - mocked_path_exists.return_value = False - mocked_dir_exists.return_value = False - doc = PptviewDocument(self.mock_controller, self.mock_presentation) - doc.file_path = Path('Idontexist.pptx') - doc.save_titles_and_notes = MagicMock() - - # WHEN: Reading the titles and notes - doc.create_titles_and_notes() - - # THEN: File existens should have been checked, and not have been opened. - doc.save_titles_and_notes.assert_called_once_with(None, None) - mocked_path_exists.assert_called_with() - assert mocked_open.call_count == 0, 'There should be no calls to open a file.' - - def test_create_titles_and_notes_invalid_file(self): - """ - Test PowerpointController.create_titles_and_notes with invalid file - """ - # GIVEN: mocked PresentationController.save_titles_and_notes and an invalid file - with patch('builtins.open') as mocked_open, \ - patch('openlp.plugins.presentations.lib.pptviewcontroller.zipfile.is_zipfile') as mocked_is_zf: - mocked_is_zf.return_value = False - mocked_open.filesize = 10 - doc = PptviewDocument(self.mock_controller, self.mock_presentation) - doc.file_path = RESOURCE_PATH / 'presentations' / 'test.ppt' - doc.save_titles_and_notes = MagicMock() - - # WHEN: reading the titles and notes - doc.create_titles_and_notes() - - # THEN: - doc.save_titles_and_notes.assert_called_once_with(None, None) - assert mocked_is_zf.call_count == 1, 'is_zipfile should have been called once' diff --git a/tests/functional/openlp_plugins/presentations/test_presentationcontroller.py b/tests/functional/openlp_plugins/presentations/test_presentationcontroller.py index 071edd3ce..1778920b1 100644 --- a/tests/functional/openlp_plugins/presentations/test_presentationcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_presentationcontroller.py @@ -22,213 +22,196 @@ Functional tests to test the PresentationController and PresentationDocument classes and related methods. """ +import pytest from pathlib import Path -from unittest import TestCase from unittest.mock import MagicMock, call, patch -from openlp.core.common.registry import Registry -from openlp.core.common.settings import Settings from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument FOLDER_TO_PATCH = 'openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder' -class TestPresentationController(TestCase): +@pytest.yield_fixture() +def get_thumbnail_folder(settings): + gtf = patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder', + return_value=Path()) + yield gtf.start() + gtf.stop() + + +@pytest.yield_fixture() +def create_paths(settings): + c_paths = patch('openlp.plugins.presentations.lib.presentationcontroller.create_paths') + yield c_paths.start() + c_paths.stop() + + +@pytest.yield_fixture() +def setup(settings): + s_up = patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument._setup') + yield s_up.start() + s_up.stop() + + +@pytest.fixture() +def presentation(settings, get_thumbnail_folder): + mocked_plugin = MagicMock() + mocked_plugin.settings_section = 'presentations' + return PresentationController(mocked_plugin) + + +@pytest.fixture() +def document(presentation): + return PresentationDocument(presentation, Path('')) + + +def test_constructor(presentation): """ - Test the PresentationController. + Test the Constructor """ - def setUp(self): - Registry().create() - Registry().register('settings', Settings()) - self.get_thumbnail_folder_patcher = \ - patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder', - return_value=Path()) - self.get_thumbnail_folder_patcher.start() - mocked_plugin = MagicMock() - mocked_plugin.settings_section = 'presentations' - self.presentation = PresentationController(mocked_plugin) - self.document = PresentationDocument(self.presentation, '') + # GIVEN: A mocked plugin - def tearDown(self): - self.get_thumbnail_folder_patcher.stop() + # WHEN: The PresentationController is created - def test_constructor(self): - """ - Test the Constructor - """ - # GIVEN: A mocked plugin - - # WHEN: The PresentationController is created - - # THEN: The name of the presentation controller should be correct - assert 'PresentationController' == self.presentation.name, \ - 'The name of the presentation controller should be correct' - - def test_save_titles_and_notes(self): - """ - Test PresentationDocument.save_titles_and_notes method with two valid lists - """ - # GIVEN: two lists of length==2 and a mocked open and get_thumbnail_folder - with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.write_text') as mocked_write_text, \ - patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: - titles = ['uno', 'dos'] - notes = ['one', 'two'] - - # WHEN: calling save_titles_and_notes - mocked_get_thumbnail_folder.return_value = Path('test') - self.document.save_titles_and_notes(titles, notes) - - # THEN: the last call to open should have been for slideNotes2.txt - assert mocked_write_text.call_count == 3, 'There should be exactly three files written' - mocked_write_text.assert_has_calls([call('uno\ndos'), call('one'), call('two')]) - - def test_save_titles_and_notes_with_None(self): - """ - Test PresentationDocument.save_titles_and_notes method with no data - """ - # GIVEN: None and an empty list and a mocked open and get_thumbnail_folder - with patch('builtins.open') as mocked_open, patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: - titles = None - notes = None - - # WHEN: calling save_titles_and_notes - mocked_get_thumbnail_folder.return_value = 'test' - self.document.save_titles_and_notes(titles, notes) - - # THEN: No file should have been created - assert mocked_open.call_count == 0, 'No file should be created' - - def test_get_titles_and_notes(self): - """ - Test PresentationDocument.get_titles_and_notes method - """ - # GIVEN: A mocked open, get_thumbnail_folder and exists - - with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text', - return_value='uno\ndos\n') as mocked_read_text, \ - patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder, \ - patch('openlp.plugins.presentations.lib.presentationcontroller.Path.exists') as mocked_exists: - mocked_get_thumbnail_folder.return_value = Path('test') - mocked_exists.return_value = True - - # WHEN: calling get_titles_and_notes - result_titles, result_notes = self.document.get_titles_and_notes() - - # THEN: it should return two items for the titles and two empty strings for the notes - assert type(result_titles) is list, 'result_titles should be of type list' - assert len(result_titles) == 2, 'There should be two items in the titles' - assert type(result_notes) is list, 'result_notes should be of type list' - assert len(result_notes) == 2, 'There should be two items in the notes' - assert mocked_read_text.call_count == 3, 'Three files should be read' - - def test_get_titles_and_notes_with_file_not_found(self): - """ - Test PresentationDocument.get_titles_and_notes method with file not found - """ - # GIVEN: A mocked open, get_thumbnail_folder and exists - with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text') as mocked_read_text, \ - patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: - mocked_read_text.side_effect = FileNotFoundError() - mocked_get_thumbnail_folder.return_value = Path('test') - - # WHEN: calling get_titles_and_notes - result_titles, result_notes = self.document.get_titles_and_notes() - - # THEN: it should return two empty lists - assert isinstance(result_titles, list), 'result_titles should be of type list' - assert len(result_titles) == 0, 'there be no titles' - assert isinstance(result_notes, list), 'result_notes should be a list' - assert len(result_notes) == 0, 'but the list should be empty' - - def test_get_titles_and_notes_with_file_error(self): - """ - Test PresentationDocument.get_titles_and_notes method with file errors - """ - # GIVEN: A mocked open, get_thumbnail_folder and exists - with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text') as mocked_read_text, \ - patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: - mocked_read_text.side_effect = OSError() - mocked_get_thumbnail_folder.return_value = Path('test') - - # WHEN: calling get_titles_and_notes - result_titles, result_notes = self.document.get_titles_and_notes() - - # THEN: it should return two empty lists - assert type(result_titles) is list, 'result_titles should be a list' + # THEN: The name of the presentation controller should be correct + assert 'PresentationController' == presentation.name, \ + 'The name of the presentation controller should be correct' -class TestPresentationDocument(TestCase): +def test_save_titles_and_notes(document): """ - Test the PresentationDocument Class + Test PresentationDocument.save_titles_and_notes method with two valid lists """ - def setUp(self): - """ - Set up the patches and mocks need for all tests. - """ - Registry().create() - self.create_paths_patcher = \ - patch('openlp.plugins.presentations.lib.presentationcontroller.create_paths') - self.get_thumbnail_folder_patcher = \ - patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder') - self._setup_patcher = \ - patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument._setup') + # GIVEN: two lists of length==2 and a mocked open and get_thumbnail_folder + with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.write_text') as mocked_write_text, \ + patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: + titles = ['uno', 'dos'] + notes = ['one', 'two'] - self.mock_create_paths = self.create_paths_patcher.start() - self.mock_get_thumbnail_folder = self.get_thumbnail_folder_patcher.start() - self.mock_setup = self._setup_patcher.start() + # WHEN: calling save_titles_and_notes + mocked_get_thumbnail_folder.return_value = Path('test') + document.save_titles_and_notes(titles, notes) - self.mock_controller = MagicMock() + # THEN: the last call to open should have been for slideNotes2.txt + assert mocked_write_text.call_count == 3, 'There should be exactly three files written' + mocked_write_text.assert_has_calls([call('uno\ndos'), call('one'), call('two')]) - self.mock_get_thumbnail_folder.return_value = Path('returned/path/') - def tearDown(self): - """ - Stop the patches - """ - self.create_paths_patcher.stop() - self.get_thumbnail_folder_patcher.stop() - self._setup_patcher.stop() +def test_save_titles_and_notes_with_none(document): + """ + Test PresentationDocument.save_titles_and_notes method with no data + """ + # GIVEN: None and an empty list and a mocked open and get_thumbnail_folder + with patch('builtins.open') as mocked_open, patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: + titles = None + notes = None - def test_initialise_presentation_document(self): - """ - Test the PresentationDocument __init__ method when initialising the PresentationDocument Class - """ - # GIVEN: A mocked setup method and mocked controller - self.mock_setup.reset() + # WHEN: calling save_titles_and_notes + mocked_get_thumbnail_folder.return_value = 'test' + document.save_titles_and_notes(titles, notes) - # WHEN: Creating an instance of PresentationDocument - PresentationDocument(self.mock_controller, 'Name') + # THEN: No file should have been created + assert mocked_open.call_count == 0, 'No file should be created' - # THEN: PresentationDocument._setup should have been called with the argument 'Name' - self.mock_setup.assert_called_once_with('Name') - def test_presentation_document_setup(self): - """ - Test the PresentationDocument _setup method when initialising the PresentationDocument Class - """ - self._setup_patcher.stop() +def test_get_titles_and_notes(document): + """ + Test PresentationDocument.get_titles_and_notes method + """ + # GIVEN: A mocked open, get_thumbnail_folder and exists - # GIVEN: A mocked controller, patched create_paths and get_thumbnail_folder methods + with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text', + return_value='uno\ndos\n') as mocked_read_text, \ + patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder, \ + patch('openlp.plugins.presentations.lib.presentationcontroller.Path.exists') as mocked_exists: + mocked_get_thumbnail_folder.return_value = Path('test') + mocked_exists.return_value = True - # WHEN: Creating an instance of PresentationDocument - PresentationDocument(self.mock_controller, 'Name') + # WHEN: calling get_titles_and_notes + result_titles, result_notes = document.get_titles_and_notes() - # THEN: create_paths should have been called with 'returned/path/' - self.mock_create_paths.assert_called_once_with(Path('returned', 'path/')) + # THEN: it should return two items for the titles and two empty strings for the notes + assert type(result_titles) is list, 'result_titles should be of type list' + assert len(result_titles) == 2, 'There should be two items in the titles' + assert type(result_notes) is list, 'result_notes should be of type list' + assert len(result_notes) == 2, 'There should be two items in the notes' + assert mocked_read_text.call_count == 3, 'Three files should be read' - self._setup_patcher.start() - def test_load_presentation(self): - """ - Test the PresentationDocument.load_presentation method. - """ +def test_get_titles_and_notes_with_file_not_found(document): + """ + Test PresentationDocument.get_titles_and_notes method with file not found + """ + # GIVEN: A mocked open, get_thumbnail_folder and exists + with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text') as mocked_read_text, \ + patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: + mocked_read_text.side_effect = FileNotFoundError() + mocked_get_thumbnail_folder.return_value = Path('test') - # GIVEN: An instance of PresentationDocument - instance = PresentationDocument(self.mock_controller, 'Name') + # WHEN: calling get_titles_and_notes + result_titles, result_notes = document.get_titles_and_notes() - # WHEN: Calling load_presentation() - result = instance.load_presentation() + # THEN: it should return two empty lists + assert isinstance(result_titles, list), 'result_titles should be of type list' + assert len(result_titles) == 0, 'there be no titles' + assert isinstance(result_notes, list), 'result_notes should be a list' + assert len(result_notes) == 0, 'but the list should be empty' - # THEN: load_presentation should return false - assert result is False, "PresentationDocument.load_presentation should return false." + +def test_get_titles_and_notes_with_file_error(document): + """ + Test PresentationDocument.get_titles_and_notes method with file errors + """ + # GIVEN: A mocked open, get_thumbnail_folder and exists + with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text') as mocked_read_text, \ + patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: + mocked_read_text.side_effect = OSError() + mocked_get_thumbnail_folder.return_value = Path('test') + + # WHEN: calling get_titles_and_notes + result_titles, result_notes = document.get_titles_and_notes() + + # THEN: it should return two empty lists + assert type(result_titles) is list, 'result_titles should be a list' + + +def test_initialise_presentation_document(setup): + """ + Test the PresentationDocument __init__ method when initialising the PresentationDocument Class + """ + # GIVEN: A mocked setup method and mocked controller + # WHEN: Creating an instance of PresentationDocument + PresentationDocument(MagicMock(), 'Name') + + # THEN: PresentationDocument._setup should have been called with the argument 'Name' + setup.assert_called_once_with('Name') + + +def test_presentation_document_setup(create_paths, get_thumbnail_folder): + """ + Test the PresentationDocument _setup method when initialising the PresentationDocument Class + """ + # GIVEN: A mocked controller, patched create_paths and get_thumbnail_folder methods + get_thumbnail_folder.return_value = Path('returned/path/') + + # WHEN: Creating an instance of PresentationDocument + PresentationDocument(MagicMock(), 'Name') + + # THEN: create_paths should have been called with 'returned/path/' + create_paths.assert_called_once_with(Path('returned', 'path/')) + + +def test_load_presentation(get_thumbnail_folder): + """ + Test the PresentationDocument.load_presentation method. + """ + + # GIVEN: An instance of PresentationDocument + instance = PresentationDocument(MagicMock(), 'Name') + + # WHEN: Calling load_presentation() + result = instance.load_presentation() + + # THEN: load_presentation should return false + assert result is False, "PresentationDocument.load_presentation should return false."