1
# -*- coding: utf-8 -*-
2
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
4
###############################################################################
5
# OpenLP - Open Source Lyrics Projection #
6
# --------------------------------------------------------------------------- #
7
# Copyright (c) 2008-2017 OpenLP Developers #
8
# --------------------------------------------------------------------------- #
9
# This program is free software; you can redistribute it and/or modify it #
10
# under the terms of the GNU General Public License as published by the Free #
11
# Software Foundation; version 2 of the License. #
13
# This program is distributed in the hope that it will be useful, but WITHOUT #
14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
15
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
18
# You should have received a copy of the GNU General Public License along #
19
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
20
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21
###############################################################################
23
Functional tests to test the PowerPointController class and related methods.
27
from unittest import TestCase
28
from tempfile import mkdtemp
30
from tests.functional import patch, MagicMock
31
from tests.helpers.testmixin import TestMixin
32
from tests.utils.constants import TEST_RESOURCES_PATH
34
from openlp.plugins.presentations.lib.powerpointcontroller import PowerpointController, PowerpointDocument,\
36
from openlp.core.common import is_win, Settings
41
__default_settings__ = {
42
'presentations/powerpoint slide click advance': True
46
class TestPowerpointController(TestCase, TestMixin):
48
Test the PowerpointController Class
53
Set up the patches and mocks need for all tests.
55
self.setup_application()
57
self.mock_plugin = MagicMock()
58
self.temp_folder = mkdtemp()
59
self.mock_plugin.settings_section = self.temp_folder
65
self.destroy_settings()
66
shutil.rmtree(self.temp_folder)
68
def test_constructor(self):
70
Test the Constructor from the PowerpointController
72
# GIVEN: No presentation controller
75
# WHEN: The presentation controller object is created
76
controller = PowerpointController(plugin=self.mock_plugin)
78
# THEN: The name of the presentation controller should be correct
79
self.assertEqual('Powerpoint', controller.name,
80
'The name of the presentation controller should be correct')
83
class TestPowerpointDocument(TestCase, TestMixin):
85
Test the PowerpointDocument Class
90
Set up the patches and mocks need for all tests.
92
self.setup_application()
94
self.mock_plugin = MagicMock()
95
self.temp_folder = mkdtemp()
96
self.mock_plugin.settings_section = self.temp_folder
97
self.powerpoint_document_stop_presentation_patcher = patch(
98
'openlp.plugins.presentations.lib.powerpointcontroller.PowerpointDocument.stop_presentation')
99
self.presentation_document_get_temp_folder_patcher = patch(
100
'openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument.get_temp_folder')
101
self.presentation_document_setup_patcher = patch(
102
'openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument._setup')
103
self.mock_powerpoint_document_stop_presentation = self.powerpoint_document_stop_presentation_patcher.start()
104
self.mock_presentation_document_get_temp_folder = self.presentation_document_get_temp_folder_patcher.start()
105
self.mock_presentation_document_setup = self.presentation_document_setup_patcher.start()
106
self.mock_controller = MagicMock()
107
self.mock_presentation = MagicMock()
108
self.mock_presentation_document_get_temp_folder.return_value = 'temp folder'
109
self.file_name = os.path.join(TEST_RESOURCES_PATH, 'presentations', 'test.pptx')
110
self.real_controller = PowerpointController(self.mock_plugin)
111
Settings().extend_default_settings(__default_settings__)
117
self.powerpoint_document_stop_presentation_patcher.stop()
118
self.presentation_document_get_temp_folder_patcher.stop()
119
self.presentation_document_setup_patcher.stop()
120
self.destroy_settings()
121
shutil.rmtree(self.temp_folder)
123
def test_show_error_msg(self):
125
Test the PowerpointDocument.show_error_msg() method gets called on com exception
128
# GIVEN: A PowerpointDocument with mocked controller and presentation
129
with patch('openlp.plugins.presentations.lib.powerpointcontroller.critical_error_message_box') as \
130
mocked_critical_error_message_box:
131
instance = PowerpointDocument(self.mock_controller, self.mock_presentation)
132
instance.presentation = MagicMock()
133
instance.presentation.SlideShowWindow.View.GotoSlide = MagicMock(side_effect=pywintypes.com_error('1'))
134
instance.index_map[42] = 42
136
# WHEN: Calling goto_slide which will throw an exception
137
instance.goto_slide(42)
139
# THEN: mocked_critical_error_message_box should have been called
140
mocked_critical_error_message_box.assert_called_with('Error', 'An error occurred in the PowerPoint '
141
'integration and the presentation will be stopped.'
142
' Restart the presentation if you wish to '
145
# add _test to the following if necessary
146
def verify_loading_document(self):
148
Test loading a document in PowerPoint
150
if is_win() and self.real_controller.check_available():
151
# GIVEN: A PowerpointDocument and a presentation
152
doc = PowerpointDocument(self.real_controller, self.file_name)
154
# WHEN: loading the filename
155
doc.load_presentation()
156
result = doc.is_loaded()
158
# THEN: result should be true
159
self.assertEqual(result, True, 'The result should be True')
161
self.skipTest('Powerpoint not available, skipping test.')
163
def test_create_titles_and_notes(self):
165
Test creating the titles from PowerPoint
167
# GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides
168
self.doc = PowerpointDocument(self.mock_controller, self.file_name)
169
self.doc.get_slide_count = MagicMock()
170
self.doc.get_slide_count.return_value = 2
171
self.doc.index_map = {1: 1, 2: 2}
172
self.doc.save_titles_and_notes = MagicMock()
173
self.doc._PowerpointDocument__get_text_from_shapes = MagicMock()
175
slide.Shapes.Title.TextFrame.TextRange.Text = 'SlideText'
177
pres.Slides = MagicMock(side_effect=[slide, slide])
178
self.doc.presentation = pres
180
# WHEN reading the titles and notes
181
self.doc.create_titles_and_notes()
183
# THEN the save should have been called exactly once with 2 titles and 2 notes
184
self.doc.save_titles_and_notes.assert_called_once_with(['SlideText\n', 'SlideText\n'], [' ', ' '])
186
def test_create_titles_and_notes_with_no_slides(self):
188
Test creating the titles from PowerPoint when it returns no slides
190
# GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides
191
doc = PowerpointDocument(self.mock_controller, self.file_name)
192
doc.save_titles_and_notes = MagicMock()
193
doc._PowerpointDocument__get_text_from_shapes = MagicMock()
196
doc.presentation = pres
198
# WHEN reading the titles and notes
199
doc.create_titles_and_notes()
201
# THEN the save should have been called exactly once with empty titles and notes
202
doc.save_titles_and_notes.assert_called_once_with([], [])
204
def test_get_text_from_shapes(self):
206
Test getting text from powerpoint shapes
208
# GIVEN: mocked shapes
210
shape.PlaceholderFormat.Type = 2
211
shape.HasTextFrame = shape.TextFrame.HasText = True
212
shape.TextFrame.TextRange.Text = 'slideText'
213
shapes = [shape, shape]
215
# WHEN: getting the text
216
result = _get_text_from_shapes(shapes)
218
# THEN: it should return the text
219
self.assertEqual(result, 'slideText\nslideText\n', 'result should match \'slideText\nslideText\n\'')
221
def test_get_text_from_shapes_with_no_shapes(self):
223
Test getting text from powerpoint shapes with no shapes
225
# GIVEN: empty shapes array
228
# WHEN: getting the text
229
result = _get_text_from_shapes(shapes)
231
# THEN: it should not fail but return empty string
232
self.assertEqual(result, '', 'result should be empty')
234
def test_goto_slide(self):
236
Test that goto_slide goes to next effect if the slide is already displayed
238
# GIVEN: A Document with mocked controller, presentation, and mocked functions get_slide_number and next_step
239
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
240
doc.presentation = MagicMock()
241
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 1
242
doc.presentation.SlideShowWindow.View.GetClickCount.return_value = 2
243
doc.get_slide_number = MagicMock()
244
doc.get_slide_number.return_value = 1
245
doc.next_step = MagicMock()
248
# WHEN: Calling goto_slide
251
# THEN: next_step() should be call to try to advance to the next effect.
252
self.assertTrue(doc.next_step.called, 'next_step() should have been called!')
254
def test_blank_screen(self):
256
Test that blank_screen works as expected
258
# GIVEN: A Document with mocked controller, presentation, and mocked function get_slide_number
259
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
260
doc.presentation = MagicMock()
261
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
262
doc.presentation.Application.Version = 14.0
263
doc.get_slide_number = MagicMock()
264
doc.get_slide_number.return_value = 2
266
# WHEN: Calling goto_slide
269
# THEN: The view state, doc.blank_slide and doc.blank_click should have new values
270
self.assertEquals(doc.presentation.SlideShowWindow.View.State, 3, 'The View State should be 3')
271
self.assertEquals(doc.blank_slide, 2, 'doc.blank_slide should be 2 because of the PowerPoint version')
272
self.assertEquals(doc.blank_click, 3, 'doc.blank_click should be 3 because of the PowerPoint version')
274
def test_unblank_screen(self):
276
Test that unblank_screen works as expected
278
# GIVEN: A Document with mocked controller, presentation, ScreenList, and mocked function get_slide_number
279
with patch('openlp.plugins.presentations.lib.powerpointcontroller.ScreenList') as mocked_screen_list:
280
mocked_screen_list_ret = MagicMock()
281
mocked_screen_list_ret.screen_list = [1]
282
mocked_screen_list.return_value = mocked_screen_list_ret
283
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
284
doc.presentation = MagicMock()
285
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
286
doc.presentation.Application.Version = 14.0
287
doc.get_slide_number = MagicMock()
288
doc.get_slide_number.return_value = 2
293
# WHEN: Calling goto_slide
296
# THEN: The view state have new value, and several function should have been called
297
self.assertEquals(doc.presentation.SlideShowWindow.View.State, 1, 'The View State should be 1')
298
self.assertEquals(doc.presentation.SlideShowWindow.Activate.called, True,
299
'SlideShowWindow.Activate should have been called')
300
self.assertEquals(doc.presentation.SlideShowWindow.View.GotoSlide.called, True,
301
'View.GotoSlide should have been called because of the PowerPoint version')
302
self.assertEquals(doc.presentation.SlideShowWindow.View.GotoClick.called, True,
303
'View.GotoClick should have been called because of the PowerPoint version')
1
# -*- coding: utf-8 -*-
2
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
4
###############################################################################
5
# OpenLP - Open Source Lyrics Projection #
6
# --------------------------------------------------------------------------- #
7
# Copyright (c) 2008-2017 OpenLP Developers #
8
# --------------------------------------------------------------------------- #
9
# This program is free software; you can redistribute it and/or modify it #
10
# under the terms of the GNU General Public License as published by the Free #
11
# Software Foundation; version 2 of the License. #
13
# This program is distributed in the hope that it will be useful, but WITHOUT #
14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
15
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
18
# You should have received a copy of the GNU General Public License along #
19
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
20
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21
###############################################################################
23
Functional tests to test the PowerPointController class and related methods.
27
from unittest import TestCase
28
from unittest.mock import patch, MagicMock
29
from tempfile import mkdtemp
31
from openlp.plugins.presentations.lib.powerpointcontroller import PowerpointController, PowerpointDocument,\
33
from openlp.core.common import is_win, Settings
35
from tests.helpers.testmixin import TestMixin
36
from tests.utils.constants import TEST_RESOURCES_PATH
41
__default_settings__ = {
42
'presentations/powerpoint slide click advance': True
46
class TestPowerpointController(TestCase, TestMixin):
48
Test the PowerpointController Class
53
Set up the patches and mocks need for all tests.
55
self.setup_application()
57
self.mock_plugin = MagicMock()
58
self.temp_folder = mkdtemp()
59
self.mock_plugin.settings_section = self.temp_folder
65
self.destroy_settings()
66
shutil.rmtree(self.temp_folder)
68
def test_constructor(self):
70
Test the Constructor from the PowerpointController
72
# GIVEN: No presentation controller
75
# WHEN: The presentation controller object is created
76
controller = PowerpointController(plugin=self.mock_plugin)
78
# THEN: The name of the presentation controller should be correct
79
self.assertEqual('Powerpoint', controller.name,
80
'The name of the presentation controller should be correct')
83
class TestPowerpointDocument(TestCase, TestMixin):
85
Test the PowerpointDocument Class
90
Set up the patches and mocks need for all tests.
92
self.setup_application()
94
self.mock_plugin = MagicMock()
95
self.temp_folder = mkdtemp()
96
self.mock_plugin.settings_section = self.temp_folder
97
self.powerpoint_document_stop_presentation_patcher = patch(
98
'openlp.plugins.presentations.lib.powerpointcontroller.PowerpointDocument.stop_presentation')
99
self.presentation_document_get_temp_folder_patcher = patch(
100
'openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument.get_temp_folder')
101
self.presentation_document_setup_patcher = patch(
102
'openlp.plugins.presentations.lib.powerpointcontroller.PresentationDocument._setup')
103
self.mock_powerpoint_document_stop_presentation = self.powerpoint_document_stop_presentation_patcher.start()
104
self.mock_presentation_document_get_temp_folder = self.presentation_document_get_temp_folder_patcher.start()
105
self.mock_presentation_document_setup = self.presentation_document_setup_patcher.start()
106
self.mock_controller = MagicMock()
107
self.mock_presentation = MagicMock()
108
self.mock_presentation_document_get_temp_folder.return_value = 'temp folder'
109
self.file_name = os.path.join(TEST_RESOURCES_PATH, 'presentations', 'test.pptx')
110
self.real_controller = PowerpointController(self.mock_plugin)
111
Settings().extend_default_settings(__default_settings__)
117
self.powerpoint_document_stop_presentation_patcher.stop()
118
self.presentation_document_get_temp_folder_patcher.stop()
119
self.presentation_document_setup_patcher.stop()
120
self.destroy_settings()
121
shutil.rmtree(self.temp_folder)
123
def test_show_error_msg(self):
125
Test the PowerpointDocument.show_error_msg() method gets called on com exception
128
# GIVEN: A PowerpointDocument with mocked controller and presentation
129
with patch('openlp.plugins.presentations.lib.powerpointcontroller.critical_error_message_box') as \
130
mocked_critical_error_message_box:
131
instance = PowerpointDocument(self.mock_controller, self.mock_presentation)
132
instance.presentation = MagicMock()
133
instance.presentation.SlideShowWindow.View.GotoSlide = MagicMock(side_effect=pywintypes.com_error('1'))
134
instance.index_map[42] = 42
136
# WHEN: Calling goto_slide which will throw an exception
137
instance.goto_slide(42)
139
# THEN: mocked_critical_error_message_box should have been called
140
mocked_critical_error_message_box.assert_called_with('Error', 'An error occurred in the PowerPoint '
141
'integration and the presentation will be stopped.'
142
' Restart the presentation if you wish to '
145
# add _test to the following if necessary
146
def verify_loading_document(self):
148
Test loading a document in PowerPoint
150
if is_win() and self.real_controller.check_available():
151
# GIVEN: A PowerpointDocument and a presentation
152
doc = PowerpointDocument(self.real_controller, self.file_name)
154
# WHEN: loading the filename
155
doc.load_presentation()
156
result = doc.is_loaded()
158
# THEN: result should be true
159
self.assertEqual(result, True, 'The result should be True')
161
self.skipTest('Powerpoint not available, skipping test.')
163
def test_create_titles_and_notes(self):
165
Test creating the titles from PowerPoint
167
# GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides
168
self.doc = PowerpointDocument(self.mock_controller, self.file_name)
169
self.doc.get_slide_count = MagicMock()
170
self.doc.get_slide_count.return_value = 2
171
self.doc.index_map = {1: 1, 2: 2}
172
self.doc.save_titles_and_notes = MagicMock()
173
self.doc._PowerpointDocument__get_text_from_shapes = MagicMock()
175
slide.Shapes.Title.TextFrame.TextRange.Text = 'SlideText'
177
pres.Slides = MagicMock(side_effect=[slide, slide])
178
self.doc.presentation = pres
180
# WHEN reading the titles and notes
181
self.doc.create_titles_and_notes()
183
# THEN the save should have been called exactly once with 2 titles and 2 notes
184
self.doc.save_titles_and_notes.assert_called_once_with(['SlideText\n', 'SlideText\n'], [' ', ' '])
186
def test_create_titles_and_notes_with_no_slides(self):
188
Test creating the titles from PowerPoint when it returns no slides
190
# GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two mocked slides
191
doc = PowerpointDocument(self.mock_controller, self.file_name)
192
doc.save_titles_and_notes = MagicMock()
193
doc._PowerpointDocument__get_text_from_shapes = MagicMock()
196
doc.presentation = pres
198
# WHEN reading the titles and notes
199
doc.create_titles_and_notes()
201
# THEN the save should have been called exactly once with empty titles and notes
202
doc.save_titles_and_notes.assert_called_once_with([], [])
204
def test_get_text_from_shapes(self):
206
Test getting text from powerpoint shapes
208
# GIVEN: mocked shapes
210
shape.PlaceholderFormat.Type = 2
211
shape.HasTextFrame = shape.TextFrame.HasText = True
212
shape.TextFrame.TextRange.Text = 'slideText'
213
shapes = [shape, shape]
215
# WHEN: getting the text
216
result = _get_text_from_shapes(shapes)
218
# THEN: it should return the text
219
self.assertEqual(result, 'slideText\nslideText\n', 'result should match \'slideText\nslideText\n\'')
221
def test_get_text_from_shapes_with_no_shapes(self):
223
Test getting text from powerpoint shapes with no shapes
225
# GIVEN: empty shapes array
228
# WHEN: getting the text
229
result = _get_text_from_shapes(shapes)
231
# THEN: it should not fail but return empty string
232
self.assertEqual(result, '', 'result should be empty')
234
def test_goto_slide(self):
236
Test that goto_slide goes to next effect if the slide is already displayed
238
# GIVEN: A Document with mocked controller, presentation, and mocked functions get_slide_number and next_step
239
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
240
doc.presentation = MagicMock()
241
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 1
242
doc.presentation.SlideShowWindow.View.GetClickCount.return_value = 2
243
doc.get_slide_number = MagicMock()
244
doc.get_slide_number.return_value = 1
245
doc.next_step = MagicMock()
248
# WHEN: Calling goto_slide
251
# THEN: next_step() should be call to try to advance to the next effect.
252
self.assertTrue(doc.next_step.called, 'next_step() should have been called!')
254
def test_blank_screen(self):
256
Test that blank_screen works as expected
258
# GIVEN: A Document with mocked controller, presentation, and mocked function get_slide_number
259
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
260
doc.presentation = MagicMock()
261
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
262
doc.presentation.Application.Version = 14.0
263
doc.get_slide_number = MagicMock()
264
doc.get_slide_number.return_value = 2
266
# WHEN: Calling goto_slide
269
# THEN: The view state, doc.blank_slide and doc.blank_click should have new values
270
self.assertEquals(doc.presentation.SlideShowWindow.View.State, 3, 'The View State should be 3')
271
self.assertEquals(doc.blank_slide, 2, 'doc.blank_slide should be 2 because of the PowerPoint version')
272
self.assertEquals(doc.blank_click, 3, 'doc.blank_click should be 3 because of the PowerPoint version')
274
def test_unblank_screen(self):
276
Test that unblank_screen works as expected
278
# GIVEN: A Document with mocked controller, presentation, ScreenList, and mocked function get_slide_number
279
with patch('openlp.plugins.presentations.lib.powerpointcontroller.ScreenList') as mocked_screen_list:
280
mocked_screen_list_ret = MagicMock()
281
mocked_screen_list_ret.screen_list = [1]
282
mocked_screen_list.return_value = mocked_screen_list_ret
283
doc = PowerpointDocument(self.mock_controller, self.mock_presentation)
284
doc.presentation = MagicMock()
285
doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
286
doc.presentation.Application.Version = 14.0
287
doc.get_slide_number = MagicMock()
288
doc.get_slide_number.return_value = 2
293
# WHEN: Calling goto_slide
296
# THEN: The view state have new value, and several function should have been called
297
self.assertEquals(doc.presentation.SlideShowWindow.View.State, 1, 'The View State should be 1')
298
self.assertEquals(doc.presentation.SlideShowWindow.Activate.called, True,
299
'SlideShowWindow.Activate should have been called')
300
self.assertEquals(doc.presentation.SlideShowWindow.View.GotoSlide.called, True,
301
'View.GotoSlide should have been called because of the PowerPoint version')
302
self.assertEquals(doc.presentation.SlideShowWindow.View.GotoClick.called, True,
303
'View.GotoClick should have been called because of the PowerPoint version')