forked from openlp/openlp
Tests plugin 2
This commit is contained in:
parent
79950b6a85
commit
7d532778bd
|
@ -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 <https://www.gnu.org/licenses/>. #
|
||||||
|
##########################################################################
|
||||||
|
"""
|
||||||
|
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)
|
|
@ -21,295 +21,271 @@
|
||||||
"""
|
"""
|
||||||
Functional tests to test the Impress class and related methods.
|
Functional tests to test the Impress class and related methods.
|
||||||
"""
|
"""
|
||||||
import shutil
|
import pytest
|
||||||
from tempfile import mkdtemp
|
|
||||||
from unittest import TestCase
|
|
||||||
from unittest.mock import MagicMock, call, patch
|
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 openlp.plugins.presentations.lib.impresscontroller import ImpressController, ImpressDocument, TextType
|
||||||
from tests.helpers.testmixin import TestMixin
|
|
||||||
from tests.utils.constants import RESOURCE_PATH
|
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):
|
# WHEN: The presentation controller object is created
|
||||||
"""
|
controller = ImpressController(plugin=mock_plugin)
|
||||||
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())
|
|
||||||
|
|
||||||
def tearDown(self):
|
# THEN: The name of the presentation controller should be correct
|
||||||
"""
|
assert 'Impress' == controller.name, 'The name of the presentation controller should be correct'
|
||||||
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')
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
# GIVEN: An instance of :class:`ImpressController`
|
||||||
mocked_plugin = MagicMock()
|
controller = ImpressController(plugin=mock_plugin)
|
||||||
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)
|
|
||||||
|
|
||||||
def test_create_titles_and_notes(self):
|
# 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), \
|
||||||
Test ImpressDocument.create_titles_and_notes
|
patch.object(controller, 'get_com_servicemanager', return_value=None) as mocked_get_com_servicemanager:
|
||||||
"""
|
result = controller.check_available()
|
||||||
# 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 reading the titles and notes
|
# THEN: `check_available` should return False
|
||||||
self.doc.create_titles_and_notes()
|
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
|
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
|
||||||
self.doc.save_titles_and_notes.reset_mock()
|
def test_check_available_on_windows(mocked_log, settings, mock_plugin):
|
||||||
self.doc.document.getDrawPages().getCount.return_value = 2
|
"""
|
||||||
|
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
|
# WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns an object
|
||||||
self.doc.create_titles_and_notes()
|
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
|
# THEN: `check_available` should return True
|
||||||
# two arrays of two elements
|
assert mocked_get_com_servicemanager.called is True
|
||||||
# self.doc.save_titles_and_notes.assert_called_once_with(['\n', '\n'], [' ', ' '])
|
assert result is True
|
||||||
self.doc.save_titles_and_notes.assert_called_once_with(['', ''], [' ', ' '])
|
|
||||||
|
|
||||||
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
|
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(0, TextType.Notes)
|
@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
|
# WHEN: `check_available` is called on Windows and `uno_available` is True
|
||||||
assert result == '', 'Result should be an empty string'
|
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
|
# THEN: `check_available` should return True
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(0, TextType.Title)
|
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
|
@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True)
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(2, TextType.SlideText)
|
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
|
# WHEN: start_process() is called
|
||||||
# have never been called
|
controller.start_process()
|
||||||
assert result == '', 'Result should be an empty string'
|
|
||||||
assert self.doc.document.getDrawPages().getByIndex.call_count == 0, 'There should be no call to getByIndex'
|
|
||||||
|
|
||||||
def test_get_text_from_page_wrong_type(self):
|
# THEN: The correct methods should have been called
|
||||||
"""
|
controller.get_com_servicemanager.assert_called_once()
|
||||||
Test ImpressDocument.__get_text_from_page with wrong TextType
|
assert controller.manager._FlagAsMethod.call_args_list == [call('Bridge_GetStruct'),
|
||||||
"""
|
call('Bridge_GetValueObject')]
|
||||||
# GIVEN: mocked LibreOffice Document with one slide, two notes and
|
|
||||||
# three texts
|
|
||||||
self.doc.document = self._mock_a_LibreOffice_document(1, 2, 3)
|
|
||||||
|
|
||||||
# WHEN: called with TextType 3
|
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(1, 3)
|
|
||||||
|
|
||||||
# THEN: result should be an empty string
|
@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False)
|
||||||
assert result == '', 'Result should be and empty string'
|
@patch('openlp.plugins.presentations.lib.impresscontroller.get_uno_command', return_value='libreoffice')
|
||||||
assert self.doc.document.getDrawPages().getByIndex.call_count == 0, 'There should be no call to getByIndex'
|
@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):
|
# WHEN: start_process() is called
|
||||||
"""
|
controller.start_process()
|
||||||
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: __get_text_from_page is called to get the Notes
|
# THEN: The correct methods should have been called
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(1, TextType.Notes)
|
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
|
def test_create_titles_and_notes(doc):
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(1, TextType.Title)
|
"""
|
||||||
|
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'
|
# WHEN reading the titles and notes
|
||||||
assert result == 'Title\n', 'Result should be exactly \'Title\\n\''
|
doc.create_titles_and_notes()
|
||||||
|
|
||||||
# WHEN: get all text
|
# THEN save_titles_and_notes should have been called with empty arrays
|
||||||
result = self.doc._ImpressDocument__get_text_from_page(1, TextType.SlideText)
|
doc.save_titles_and_notes.assert_called_once_with([], [])
|
||||||
|
|
||||||
# THEN: result should be 'Title\nString\nString\n'
|
# GIVEN: reset mock and set it to 2 pages
|
||||||
assert result == 'Title\nString\nString\n', 'Result should be exactly \'Title\\nString\\nString\\n\''
|
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):
|
# WHEN: a new call to create_titles_and_notes
|
||||||
"""
|
doc.create_titles_and_notes()
|
||||||
Helper function, creates a mock libreoffice document.
|
|
||||||
|
|
||||||
:param page_count: Number of pages in the document
|
# THEN: save_titles_and_notes should have been called once with
|
||||||
:param note_count: Number of note pages in the document
|
# two arrays of two elements
|
||||||
:param text_count: Number of text pages in the document
|
# self.doc.save_titles_and_notes.assert_called_once_with(['\n', '\n'], [' ', ' '])
|
||||||
"""
|
doc.save_titles_and_notes.assert_called_once_with(['', ''], [' ', ' '])
|
||||||
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
|
|
||||||
|
|
||||||
def _get_page_shape_side_effect(*args):
|
|
||||||
"""
|
def test_get_text_from_page_out_of_bound(doc):
|
||||||
Helper function.
|
"""
|
||||||
"""
|
Test ImpressDocument.__get_text_from_page with out-of-bounds index
|
||||||
page_shape = MagicMock()
|
"""
|
||||||
page_shape.supportsService.return_value = True
|
# GIVEN: mocked LibreOffice Document with one slide,
|
||||||
if args[1] == 0:
|
# two notes and three texts
|
||||||
page_shape.getShapeType.return_value = 'com.sun.star.presentation.TitleTextShape'
|
doc.document = _mock_a_LibreOffice_document(1, 2, 3)
|
||||||
page_shape.getString.return_value = 'Title'
|
|
||||||
else:
|
# WHEN: __get_text_from_page is called with an index of 0x00
|
||||||
page_shape.getString.return_value = 'String'
|
result = doc._ImpressDocument__get_text_from_page(0, TextType.Notes)
|
||||||
return page_shape
|
|
||||||
|
# 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
|
||||||
|
|
|
@ -22,145 +22,130 @@
|
||||||
This module contains tests for the lib submodule of the Presentations plugin.
|
This module contains tests for the lib submodule of the Presentations plugin.
|
||||||
"""
|
"""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
|
||||||
from unittest.mock import MagicMock, PropertyMock, call, patch
|
from unittest.mock import MagicMock, PropertyMock, call, patch
|
||||||
|
|
||||||
from openlp.core.common.registry import Registry
|
from openlp.core.common.registry import Registry
|
||||||
from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem
|
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):
|
# GIVEN: Different controllers.
|
||||||
"""
|
impress_controller = MagicMock()
|
||||||
Set up the components need for all tests.
|
impress_controller.enabled.return_value = True
|
||||||
"""
|
impress_controller.supports = ['odp']
|
||||||
Registry.create()
|
impress_controller.also_supports = ['ppt']
|
||||||
Registry().register('service_manager', MagicMock())
|
presentation_controller = MagicMock()
|
||||||
Registry().register('main_window', MagicMock())
|
presentation_controller.enabled.return_value = True
|
||||||
with patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup'), \
|
presentation_controller.supports = ['ppt']
|
||||||
patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item'):
|
presentation_controller.also_supports = []
|
||||||
self.media_item = PresentationMediaItem(None, MagicMock, MagicMock())
|
presentation_viewer_controller = MagicMock()
|
||||||
self.setup_application()
|
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):
|
# WHEN: Build the file mask.
|
||||||
"""
|
with patch('openlp.plugins.presentations.lib.mediaitem.translate') as mocked_translate:
|
||||||
Test the build_file_mask_string() method
|
mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate
|
||||||
"""
|
media_item.build_file_mask_string()
|
||||||
# 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.
|
# THEN: The file mask should be generated correctly
|
||||||
with patch('openlp.plugins.presentations.lib.mediaitem.translate') as mocked_translate:
|
assert '*.odp' in media_item.on_new_file_masks, 'The file mask should contain the odp extension'
|
||||||
mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate
|
assert '*.ppt' in media_item.on_new_file_masks, 'The file mask should contain the ppt extension'
|
||||||
self.media_item.build_file_mask_string()
|
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):
|
def test_clean_up_thumbnails(media_item):
|
||||||
"""
|
"""
|
||||||
Test that the clean_up_thumbnails method works as expected when files exists.
|
Test that the clean_up_thumbnails method works as expected when files exists.
|
||||||
"""
|
"""
|
||||||
# GIVEN: A mocked controller, and mocked os.path.getmtime
|
# GIVEN: A mocked controller, and mocked os.path.getmtime
|
||||||
mocked_disabled_controller = MagicMock()
|
mocked_disabled_controller = MagicMock()
|
||||||
mocked_disabled_controller.enabled.return_value = False
|
mocked_disabled_controller.enabled.return_value = False
|
||||||
mocked_disabled_supports = PropertyMock()
|
mocked_disabled_supports = PropertyMock()
|
||||||
type(mocked_disabled_controller).supports = mocked_disabled_supports
|
type(mocked_disabled_controller).supports = mocked_disabled_supports
|
||||||
mocked_enabled_controller = MagicMock()
|
mocked_enabled_controller = MagicMock()
|
||||||
mocked_enabled_controller.enabled.return_value = True
|
mocked_enabled_controller.enabled.return_value = True
|
||||||
mocked_doc = MagicMock(**{'get_thumbnail_path.return_value': Path()})
|
mocked_doc = MagicMock(**{'get_thumbnail_path.return_value': Path()})
|
||||||
mocked_enabled_controller.add_document.return_value = mocked_doc
|
mocked_enabled_controller.add_document.return_value = mocked_doc
|
||||||
mocked_enabled_controller.supports = ['tmp']
|
mocked_enabled_controller.supports = ['tmp']
|
||||||
self.media_item.controllers = {
|
media_item.controllers = {
|
||||||
'Enabled': mocked_enabled_controller,
|
'Enabled': mocked_enabled_controller,
|
||||||
'Disabled': mocked_disabled_controller
|
'Disabled': mocked_disabled_controller
|
||||||
}
|
}
|
||||||
|
|
||||||
thumb_path = MagicMock(st_mtime=100)
|
thumb_path = MagicMock(st_mtime=100)
|
||||||
file_path = MagicMock(st_mtime=400)
|
file_path = MagicMock(st_mtime=400)
|
||||||
with patch.object(Path, 'stat', side_effect=[thumb_path, file_path]), \
|
with patch.object(Path, 'stat', side_effect=[thumb_path, file_path]), \
|
||||||
patch.object(Path, 'exists', return_value=True):
|
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
|
|
||||||
}
|
|
||||||
presentation_file = Path('file.tmp')
|
presentation_file = Path('file.tmp')
|
||||||
with patch.object(Path, 'exists', return_value=False):
|
|
||||||
|
|
||||||
# WHEN: calling clean_up_thumbnails
|
# WHEN: calling clean_up_thumbnails
|
||||||
self.media_item.clean_up_thumbnails(presentation_file, True)
|
media_item.clean_up_thumbnails(presentation_file, True)
|
||||||
|
|
||||||
# THEN: doc.presentation_deleted should have been called since the presentation file did not exists.
|
# THEN: doc.presentation_deleted should have been called since the thumbnails mtime will be greater than
|
||||||
mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True)
|
# 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
|
def test_clean_up_thumbnails_missing_file(media_item):
|
||||||
results = media_item.search('IMPRE', False)
|
"""
|
||||||
|
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
|
# WHEN: calling clean_up_thumbnails
|
||||||
assert results == [[str(path_1), 'Impress_file_1'], [str(path_2), 'impress_file_2']]
|
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']]
|
||||||
|
|
|
@ -21,129 +21,108 @@
|
||||||
"""
|
"""
|
||||||
This module contains tests for the lib submodule of the Presentations plugin.
|
This module contains tests for the lib submodule of the Presentations plugin.
|
||||||
"""
|
"""
|
||||||
from unittest import TestCase
|
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from openlp.core.common.registry import Registry
|
from openlp.plugins.presentations.lib.mediaitem import MessageListener
|
||||||
from openlp.plugins.presentations.lib.mediaitem import MessageListener, PresentationMediaItem
|
|
||||||
from openlp.plugins.presentations.lib.messagelistener import Controller
|
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):
|
# GIVEN: A single controller and service item wanting to use the controller
|
||||||
"""
|
mock_item = MagicMock()
|
||||||
Set up the components need for all tests.
|
mock_item.processor = 'Powerpoint'
|
||||||
"""
|
mock_item.get_frame_path.return_value = "test.ppt"
|
||||||
Registry.create()
|
media_item.automatic = False
|
||||||
Registry().register('service_manager', MagicMock())
|
mocked_controller = MagicMock()
|
||||||
Registry().register('main_window', MagicMock())
|
mocked_controller.available = True
|
||||||
with patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup'), \
|
mocked_controller.supports = ['ppt']
|
||||||
patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item'):
|
controllers = {
|
||||||
self.media_item = PresentationMediaItem(None, MagicMock, MagicMock())
|
'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')
|
# WHEN: request the presentation to start
|
||||||
def test_start_presentation(self, media_mock):
|
ml.startup([mock_item, False, False, False])
|
||||||
"""
|
|
||||||
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
|
# THEN: The controllers will be setup.
|
||||||
ml.startup([mock_item, False, False, False])
|
assert len(controllers) > 0, 'We have loaded a controller'
|
||||||
|
|
||||||
# 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'
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
# WHEN: request the presentation to start
|
||||||
"""
|
ml.startup([mock_item, False, False, False])
|
||||||
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
|
# THEN: The controllers will be setup.
|
||||||
controller.add_handler(mocked_doc_controller, MagicMock(), True, 0)
|
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'
|
||||||
|
|
|
@ -26,25 +26,30 @@ import pytest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from shutil import rmtree, which
|
from shutil import rmtree, which
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from unittest import TestCase, skipIf
|
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.common import is_macosx, is_linux, is_win
|
from openlp.core.common import is_macosx, is_linux, is_win
|
||||||
from openlp.core.common.settings import Settings
|
from openlp.core.common.settings import Settings
|
||||||
from openlp.core.common.registry import Registry
|
|
||||||
from openlp.core.display.screens import ScreenList
|
from openlp.core.display.screens import ScreenList
|
||||||
from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument
|
from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument
|
||||||
from tests.helpers.testmixin import TestMixin
|
|
||||||
from tests.utils.constants import RESOURCE_PATH
|
from tests.utils.constants import RESOURCE_PATH
|
||||||
|
|
||||||
|
|
||||||
__default_settings__ = {
|
@pytest.yield_fixture()
|
||||||
'presentations/enable_pdf_program': True,
|
def pdf_env(settings, mock_plugin):
|
||||||
'presentations/pdf_program': None,
|
temp_folder_path = Path(mkdtemp())
|
||||||
'presentations/thumbnail_scheme': ''
|
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 = {
|
SCREEN = {
|
||||||
'primary': False,
|
'primary': False,
|
||||||
|
@ -66,195 +71,178 @@ def get_screen_resolution():
|
||||||
from win32api import GetSystemMetrics
|
from win32api import GetSystemMetrics
|
||||||
return GetSystemMetrics(0), GetSystemMetrics(1)
|
return GetSystemMetrics(0), GetSystemMetrics(1)
|
||||||
elif is_linux():
|
elif is_linux():
|
||||||
from Xlib.display import Display
|
if IS_CI:
|
||||||
resolution = Display().screen().root.get_geometry()
|
return 1024, 768
|
||||||
return resolution.width, resolution.height
|
else:
|
||||||
|
from Xlib.display import Display
|
||||||
|
resolution = Display().screen().root.get_geometry()
|
||||||
|
return resolution.width, resolution.height
|
||||||
else:
|
else:
|
||||||
return 1024, 768
|
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):
|
# GIVEN: No presentation controller
|
||||||
"""
|
controller = None
|
||||||
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
|
|
||||||
|
|
||||||
def tearDown(self):
|
# WHEN: The presentation controller object is created
|
||||||
"""
|
controller = PdfController(plugin=mock_plugin)
|
||||||
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)
|
|
||||||
|
|
||||||
def test_constructor(self):
|
# THEN: The name of the presentation controller should be correct
|
||||||
"""
|
assert 'Pdf' == controller.name, 'The name of the presentation controller should be correct'
|
||||||
Test the Constructor from the PdfController
|
|
||||||
"""
|
|
||||||
# GIVEN: No presentation controller
|
|
||||||
controller = None
|
|
||||||
|
|
||||||
# WHEN: The presentation controller object is created
|
|
||||||
controller = PdfController(plugin=self.mock_plugin)
|
|
||||||
|
|
||||||
# THEN: The name of the presentation controller should be correct
|
def load_pdf(exe_path, pdf_env):
|
||||||
assert 'Pdf' == controller.name, 'The name of the presentation controller should be correct'
|
"""
|
||||||
|
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")
|
# WHEN: The Pdf is loaded
|
||||||
def load_pdf(self, exe_path):
|
settings = pdf_env[0]
|
||||||
"""
|
mock_plugin = pdf_env[1]
|
||||||
Test loading a Pdf using the PdfController
|
temp_folder_path = pdf_env[2]
|
||||||
"""
|
thumbnail_folder_path = pdf_env[3]
|
||||||
# GIVEN: A Pdf-file
|
settings.setValue('presentations/pdf_program', exe_path)
|
||||||
test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf'
|
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
|
# THEN: The load should succeed and we should be able to get a pagecount
|
||||||
Settings().setValue('presentations/pdf_program', exe_path)
|
assert loaded is True, 'The loading of the PDF should succeed.'
|
||||||
controller = PdfController(plugin=self.mock_plugin)
|
assert 3 == document.get_slide_count(), 'The pagecount of the PDF should be 3.'
|
||||||
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.'
|
|
||||||
|
|
||||||
def load_pdf_pictures(self, exe_path):
|
def load_pdf_pictures(exe_path, pdf_env):
|
||||||
"""
|
"""
|
||||||
Test loading a Pdf and check the generated pictures' size
|
Test loading a Pdf and check the generated pictures' size
|
||||||
"""
|
"""
|
||||||
# GIVEN: A Pdf-file
|
# GIVEN: A Pdf-file
|
||||||
test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf'
|
test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf'
|
||||||
|
|
||||||
# WHEN: The Pdf is loaded
|
# WHEN: The Pdf is loaded
|
||||||
Settings().setValue('presentations/pdf_program', exe_path)
|
mock_plugin = pdf_env[1]
|
||||||
controller = PdfController(plugin=self.mock_plugin)
|
temp_folder_path = pdf_env[2]
|
||||||
controller.temp_folder = self.temp_folder_path
|
thumbnail_folder_path = pdf_env[3]
|
||||||
controller.thumbnail_folder = self.thumbnail_folder_path
|
Settings().setValue('presentations/pdf_program', exe_path)
|
||||||
document = PdfDocument(controller, test_file_path)
|
controller = PdfController(plugin=mock_plugin)
|
||||||
loaded = document.load_presentation()
|
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
|
# 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.'
|
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'))
|
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
|
# Based on the converter used the resolution will differ a bit
|
||||||
if controller.gsbin:
|
if controller.gsbin:
|
||||||
assert 1076 == image.height(), 'The height should be 1076'
|
assert 1076 == image.height(), 'The height should be 1076'
|
||||||
assert 760 == image.width(), 'The width should be 760'
|
assert 760 == image.width(), 'The width should be 760'
|
||||||
else:
|
else:
|
||||||
width, height = get_screen_resolution()
|
width, height = get_screen_resolution()
|
||||||
# Calculate the width of the PDF based on the aspect ratio of the PDF
|
# Calculate the width of the PDF based on the aspect ratio of the PDF
|
||||||
width = int(round(height * 0.70703125, 0))
|
width = int(round(height * 0.70703125, 0))
|
||||||
assert image.height() == height, 'The height should be {height}'.format(height=height)
|
assert image.height() == height, 'The height should be {height}'.format(height=height)
|
||||||
assert image.width() == width, 'The width should be {width}'.format(width=width)
|
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):
|
def test_load_pdf(pdf_env):
|
||||||
try:
|
"""
|
||||||
import fitz # noqa: F401
|
Test loading a Pdf with each of the installed backends
|
||||||
except ImportError:
|
"""
|
||||||
pytest.skip('PyMuPDF is not installed')
|
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_loading_pdf_using_pymupdf():
|
||||||
def test_process_check_binary_mudraw(self, mocked_check_binary_exists):
|
try:
|
||||||
"""
|
import fitz # noqa: F401
|
||||||
Test that the correct output from mudraw is detected
|
except ImportError:
|
||||||
"""
|
pytest.skip('PyMuPDF is not installed')
|
||||||
# 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
|
load_pdf(None)
|
||||||
ret = PdfController.process_check_binary('test')
|
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')
|
@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists')
|
||||||
def test_process_check_binary_new_motool(self, mocked_check_binary_exists):
|
def test_process_check_binary_mudraw(mocked_check_binary_exists):
|
||||||
"""
|
"""
|
||||||
Test that the correct output from the new mutool is detected
|
Test that the correct output from mudraw is detected
|
||||||
"""
|
"""
|
||||||
# GIVEN: A mocked check_binary_exists that returns new mutool output
|
# GIVEN: A mocked check_binary_exists that returns mudraw output
|
||||||
new_mutool_output = (b'usage: mutool <command> [options]\n\tdraw\t-- convert document\n\trun\t-- run javascript'
|
mudraw_output = (b'usage: mudraw [options] input [pages]\n\t-o -\toutput filename (%d for page number)n\t\tsupp'
|
||||||
b'\n\tclean\t-- rewrite pdf file\n\textract\t-- extract font and image resources\n\tinfo\t'
|
b'orted formats: pgm, ppm, pam, png, pbmn\t-p -\tpasswordn\t-r -\tresolution in dpi (default: '
|
||||||
b'-- show information about pdf resources\n\tpages\t-- show information about pdf pages\n'
|
b'72)n\t-w -\twidth (in pixels) (maximum width if -r is specified)n\t-h -\theight (in pixels) '
|
||||||
b'\tposter\t-- split large page into many tiles\n\tshow\t-- show internal pdf objects\n\t'
|
b'(maximum height if -r is specified)')
|
||||||
b'create\t-- create pdf document\n\tmerge\t-- merge pages from multiple pdf sources into a'
|
mocked_check_binary_exists.return_value = mudraw_output
|
||||||
b'new pdf\n')
|
|
||||||
mocked_check_binary_exists.return_value = new_mutool_output
|
|
||||||
|
|
||||||
# WHEN: Calling process_check_binary
|
# WHEN: Calling process_check_binary
|
||||||
ret = PdfController.process_check_binary('test')
|
ret = PdfController.process_check_binary('test')
|
||||||
|
|
||||||
# THEN: mutool should be detected
|
# THEN: mudraw should be detected
|
||||||
assert 'mutool' == ret, 'mutool should have been 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 <command> [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
|
@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists')
|
||||||
ret = PdfController.process_check_binary('test')
|
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 <command> [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
|
# WHEN: Calling process_check_binary
|
||||||
assert ret is None, 'old mutool should not be accepted!'
|
ret = PdfController.process_check_binary('test')
|
||||||
|
|
||||||
@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists')
|
# THEN: mutool should be detected
|
||||||
def test_process_check_binary_gs(self, mocked_check_binary_exists):
|
assert 'mutool' == ret, 'mutool should have been detected'
|
||||||
"""
|
|
||||||
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
|
@patch('openlp.plugins.presentations.lib.pdfcontroller.check_binary_exists')
|
||||||
assert 'gs' == ret, 'mutool should have been detected'
|
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 <command> [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'
|
||||||
|
|
|
@ -21,287 +21,208 @@
|
||||||
"""
|
"""
|
||||||
Functional tests to test the PowerPointController class and related methods.
|
Functional tests to test the PowerPointController class and related methods.
|
||||||
"""
|
"""
|
||||||
import os
|
import pytest
|
||||||
import shutil
|
|
||||||
from tempfile import mkdtemp
|
|
||||||
from unittest import TestCase
|
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from openlp.core.common import is_win
|
from openlp.core.common import is_win
|
||||||
from openlp.core.common.registry import Registry
|
from openlp.core.common.registry import Registry
|
||||||
from openlp.core.common.settings import Settings
|
|
||||||
from openlp.plugins.presentations.lib.powerpointcontroller import PowerpointController, PowerpointDocument, \
|
from openlp.plugins.presentations.lib.powerpointcontroller import PowerpointController, PowerpointDocument, \
|
||||||
_get_text_from_shapes
|
_get_text_from_shapes
|
||||||
from tests.helpers.testmixin import TestMixin
|
|
||||||
from tests.utils.constants import TEST_RESOURCES_PATH
|
|
||||||
|
|
||||||
|
|
||||||
if is_win():
|
if is_win():
|
||||||
import pywintypes
|
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):
|
# WHEN: The presentation controller object is created
|
||||||
"""
|
controller = PowerpointController(plugin=mock_plugin)
|
||||||
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())
|
|
||||||
|
|
||||||
def tearDown(self):
|
# THEN: The name of the presentation controller should be correct
|
||||||
"""
|
assert 'Powerpoint' == controller.name, 'The name of the presentation controller should be correct'
|
||||||
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'
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
# WHEN: Calling goto_slide which will throw an exception
|
||||||
"""
|
instance.goto_slide(42)
|
||||||
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__)
|
|
||||||
|
|
||||||
def tearDown(self):
|
# 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 '
|
||||||
Stop the patches
|
'integration and the presentation will be stopped.'
|
||||||
"""
|
' Restart the presentation if you wish to '
|
||||||
self.powerpoint_document_stop_presentation_patcher.stop()
|
'present it.')
|
||||||
self.presentation_document_get_temp_folder_patcher.stop()
|
|
||||||
self.presentation_document_setup_patcher.stop()
|
|
||||||
self.destroy_settings()
|
|
||||||
shutil.rmtree(self.temp_folder)
|
|
||||||
|
|
||||||
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
|
def test_create_titles_and_notes(get_thumbnail_folder):
|
||||||
instance.goto_slide(42)
|
"""
|
||||||
|
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
|
# WHEN reading the titles and notes
|
||||||
mocked_critical_error_message_box.assert_called_with('Error', 'An error occurred in the PowerPoint '
|
doc.create_titles_and_notes()
|
||||||
'integration and the presentation will be stopped.'
|
|
||||||
' Restart the presentation if you wish to '
|
|
||||||
'present it.')
|
|
||||||
|
|
||||||
# add _test to the following if necessary
|
# THEN the save should have been called exactly once with 2 titles and 2 notes
|
||||||
def verify_loading_document(self):
|
doc.save_titles_and_notes.assert_called_once_with(['SlideText', 'SlideText'], [' ', ' '])
|
||||||
"""
|
|
||||||
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)
|
|
||||||
|
|
||||||
# WHEN: loading the filename
|
|
||||||
doc.load_presentation()
|
|
||||||
result = doc.is_loaded()
|
|
||||||
|
|
||||||
# THEN: result should be true
|
def test_create_titles_and_notes_with_no_slides(get_thumbnail_folder):
|
||||||
assert result is True, 'The result should be True'
|
"""
|
||||||
else:
|
Test creating the titles from PowerPoint when it returns no slides
|
||||||
self.skipTest('Powerpoint not available, skipping test.')
|
"""
|
||||||
|
# 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):
|
# WHEN reading the titles and notes
|
||||||
"""
|
doc.create_titles_and_notes()
|
||||||
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
|
# THEN the save should have been called exactly once with empty titles and notes
|
||||||
self.doc.create_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):
|
def test_get_text_from_shapes():
|
||||||
"""
|
"""
|
||||||
Test creating the titles from PowerPoint when it returns no slides
|
Test getting text from powerpoint shapes
|
||||||
"""
|
"""
|
||||||
# GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides
|
# GIVEN: mocked shapes
|
||||||
doc = PowerpointDocument(self.mock_controller, self.file_name)
|
shape = MagicMock()
|
||||||
doc.save_titles_and_notes = MagicMock()
|
shape.PlaceholderFormat.Type = 2
|
||||||
doc._PowerpointDocument__get_text_from_shapes = MagicMock()
|
shape.HasTextFrame = shape.TextFrame.HasText = True
|
||||||
pres = MagicMock()
|
shape.TextFrame.TextRange.Text = 'slideText'
|
||||||
pres.Slides = []
|
shapes = [shape, shape]
|
||||||
doc.presentation = pres
|
|
||||||
|
|
||||||
# WHEN reading the titles and notes
|
# WHEN: getting the text
|
||||||
doc.create_titles_and_notes()
|
result = _get_text_from_shapes(shapes)
|
||||||
|
|
||||||
# THEN the save should have been called exactly once with empty titles and notes
|
# THEN: it should return the text
|
||||||
doc.save_titles_and_notes.assert_called_once_with([], [])
|
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
|
def test_get_text_from_shapes_with_no_shapes():
|
||||||
result = _get_text_from_shapes(shapes)
|
"""
|
||||||
|
Test getting text from powerpoint shapes with no shapes
|
||||||
|
"""
|
||||||
|
# GIVEN: empty shapes array
|
||||||
|
shapes = []
|
||||||
|
|
||||||
# THEN: it should return the text
|
# WHEN: getting the text
|
||||||
assert result == 'slideText\nslideText\n', 'result should match \'slideText\nslideText\n\''
|
result = _get_text_from_shapes(shapes)
|
||||||
|
|
||||||
def test_get_text_from_shapes_with_no_shapes(self):
|
# THEN: it should not fail but return empty string
|
||||||
"""
|
assert result == '', 'result should be empty'
|
||||||
Test getting text from powerpoint shapes with no shapes
|
|
||||||
"""
|
|
||||||
# GIVEN: empty shapes array
|
|
||||||
shapes = []
|
|
||||||
|
|
||||||
# WHEN: getting the text
|
|
||||||
result = _get_text_from_shapes(shapes)
|
|
||||||
|
|
||||||
# THEN: it should not fail but return empty string
|
def test_goto_slide(get_thumbnail_folder):
|
||||||
assert result == '', 'result should be empty'
|
"""
|
||||||
|
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):
|
# WHEN: Calling goto_slide
|
||||||
"""
|
doc.goto_slide(1)
|
||||||
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
|
# THEN: next_step() should be call to try to advance to the next effect.
|
||||||
doc.goto_slide(1)
|
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):
|
def test_blank_screen(get_thumbnail_folder):
|
||||||
"""
|
"""
|
||||||
Test that blank_screen works as expected
|
Test that blank_screen works as expected
|
||||||
"""
|
"""
|
||||||
# GIVEN: A Document with mocked controller, presentation, and mocked function get_slide_number
|
# GIVEN: A Document with mocked controller, presentation, and mocked function get_slide_number
|
||||||
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
|
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 = MagicMock()
|
||||||
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
|
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
|
||||||
doc.presentation.Application.Version = 14.0
|
doc.presentation.Application.Version = 14.0
|
||||||
doc.get_slide_number = MagicMock()
|
doc.get_slide_number = MagicMock()
|
||||||
doc.get_slide_number.return_value = 2
|
doc.get_slide_number.return_value = 2
|
||||||
|
doc.index_map[1] = 1
|
||||||
|
doc.blank_slide = 1
|
||||||
|
doc.blank_click = 1
|
||||||
|
|
||||||
# WHEN: Calling goto_slide
|
# 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
|
# THEN: The view state have new value, and several function should have been called
|
||||||
assert doc.presentation.SlideShowWindow.View.State == 3, 'The View State should be 3'
|
assert doc.presentation.SlideShowWindow.View.State == 1, 'The View State should be 1'
|
||||||
assert doc.blank_slide == 2, 'doc.blank_slide should be 2 because of the PowerPoint version'
|
assert doc.presentation.SlideShowWindow.Activate.called is True, \
|
||||||
assert doc.blank_click == 3, 'doc.blank_click should be 3 because of the PowerPoint version'
|
'SlideShowWindow.Activate should have been called'
|
||||||
|
assert doc.presentation.SlideShowWindow.View.GotoSlide.called is True, \
|
||||||
def test_unblank_screen(self):
|
'View.GotoSlide should have been called because of the PowerPoint version'
|
||||||
"""
|
assert doc.presentation.SlideShowWindow.View.GotoClick.called is True, \
|
||||||
Test that unblank_screen works as expected
|
'View.GotoClick should have been called because of the PowerPoint version'
|
||||||
"""
|
|
||||||
# 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'
|
|
||||||
|
|
|
@ -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 <https://www.gnu.org/licenses/>. #
|
|
||||||
##########################################################################
|
|
||||||
"""
|
|
||||||
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'
|
|
|
@ -22,213 +22,196 @@
|
||||||
Functional tests to test the PresentationController and PresentationDocument
|
Functional tests to test the PresentationController and PresentationDocument
|
||||||
classes and related methods.
|
classes and related methods.
|
||||||
"""
|
"""
|
||||||
|
import pytest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
|
||||||
from unittest.mock import MagicMock, call, patch
|
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
|
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
|
||||||
|
|
||||||
|
|
||||||
FOLDER_TO_PATCH = 'openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder'
|
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):
|
# GIVEN: A mocked plugin
|
||||||
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, '')
|
|
||||||
|
|
||||||
def tearDown(self):
|
# WHEN: The PresentationController is created
|
||||||
self.get_thumbnail_folder_patcher.stop()
|
|
||||||
|
|
||||||
def test_constructor(self):
|
# THEN: The name of the presentation controller should be correct
|
||||||
"""
|
assert 'PresentationController' == presentation.name, \
|
||||||
Test the Constructor
|
'The name of the presentation controller should be correct'
|
||||||
"""
|
|
||||||
# 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'
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
# 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, \
|
||||||
Set up the patches and mocks need for all tests.
|
patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder:
|
||||||
"""
|
titles = ['uno', 'dos']
|
||||||
Registry().create()
|
notes = ['one', 'two']
|
||||||
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')
|
|
||||||
|
|
||||||
self.mock_create_paths = self.create_paths_patcher.start()
|
# WHEN: calling save_titles_and_notes
|
||||||
self.mock_get_thumbnail_folder = self.get_thumbnail_folder_patcher.start()
|
mocked_get_thumbnail_folder.return_value = Path('test')
|
||||||
self.mock_setup = self._setup_patcher.start()
|
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):
|
def test_save_titles_and_notes_with_none(document):
|
||||||
"""
|
"""
|
||||||
Stop the patches
|
Test PresentationDocument.save_titles_and_notes method with no data
|
||||||
"""
|
"""
|
||||||
self.create_paths_patcher.stop()
|
# GIVEN: None and an empty list and a mocked open and get_thumbnail_folder
|
||||||
self.get_thumbnail_folder_patcher.stop()
|
with patch('builtins.open') as mocked_open, patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder:
|
||||||
self._setup_patcher.stop()
|
titles = None
|
||||||
|
notes = None
|
||||||
|
|
||||||
def test_initialise_presentation_document(self):
|
# WHEN: calling save_titles_and_notes
|
||||||
"""
|
mocked_get_thumbnail_folder.return_value = 'test'
|
||||||
Test the PresentationDocument __init__ method when initialising the PresentationDocument Class
|
document.save_titles_and_notes(titles, notes)
|
||||||
"""
|
|
||||||
# GIVEN: A mocked setup method and mocked controller
|
|
||||||
self.mock_setup.reset()
|
|
||||||
|
|
||||||
# WHEN: Creating an instance of PresentationDocument
|
# THEN: No file should have been created
|
||||||
PresentationDocument(self.mock_controller, 'Name')
|
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):
|
def test_get_titles_and_notes(document):
|
||||||
"""
|
"""
|
||||||
Test the PresentationDocument _setup method when initialising the PresentationDocument Class
|
Test PresentationDocument.get_titles_and_notes method
|
||||||
"""
|
"""
|
||||||
self._setup_patcher.stop()
|
# 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
|
# WHEN: calling get_titles_and_notes
|
||||||
PresentationDocument(self.mock_controller, 'Name')
|
result_titles, result_notes = document.get_titles_and_notes()
|
||||||
|
|
||||||
# THEN: create_paths should have been called with 'returned/path/'
|
# THEN: it should return two items for the titles and two empty strings for the notes
|
||||||
self.mock_create_paths.assert_called_once_with(Path('returned', 'path/'))
|
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):
|
def test_get_titles_and_notes_with_file_not_found(document):
|
||||||
"""
|
"""
|
||||||
Test the PresentationDocument.load_presentation method.
|
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
|
# WHEN: calling get_titles_and_notes
|
||||||
instance = PresentationDocument(self.mock_controller, 'Name')
|
result_titles, result_notes = document.get_titles_and_notes()
|
||||||
|
|
||||||
# WHEN: Calling load_presentation()
|
# THEN: it should return two empty lists
|
||||||
result = instance.load_presentation()
|
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."
|
||||||
|
|
Loading…
Reference in New Issue