Invalidate the service item cache when the theme changes

This commit is contained in:
Raoul Snyman 2024-02-13 21:57:55 -07:00
parent d73d387923
commit 4591c6bf06
10 changed files with 53 additions and 30 deletions

View File

@ -865,6 +865,8 @@ class ServiceItem(RegistryProperties):
"""
self.theme_overwritten = (theme is None)
self.theme = theme
if self.is_text():
self._clear_slides_cache()
self._new_item()
def remove_invalid_frames(self, invalid_paths=None):

View File

@ -33,7 +33,7 @@ from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.lib.ui import create_widget_action
from openlp.core.projectors import DialogSourceStyle
from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, E_SOCKET_TIMEOUT,\
from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, E_SOCKET_TIMEOUT, \
E_UNKNOWN_SOCKET_ERROR, PJLINK_PORT, QSOCKET_STATE, S_CONNECTED, S_CONNECTING, S_COOLDOWN, S_INITIALIZE, \
S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP, STATUS_CODE, STATUS_MSG

View File

@ -29,7 +29,7 @@ try:
except ImportError:
APPLESCRIPT_AVAILABLE = False
from openlp.plugins.presentations.lib.applescriptbasecontroller import AppleScriptBaseController,\
from openlp.plugins.presentations.lib.applescriptbasecontroller import AppleScriptBaseController, \
AppleScriptBaseDocument

View File

@ -34,7 +34,7 @@ try:
except ImportError:
PYMUPDF_AVAILABLE = False
from openlp.plugins.presentations.lib.applescriptbasecontroller import AppleScriptBaseController,\
from openlp.plugins.presentations.lib.applescriptbasecontroller import AppleScriptBaseController, \
AppleScriptBaseDocument

View File

@ -168,11 +168,11 @@ def test_service_item_load_image_from_service(state_media, settings):
'file_hash': fake_hash2}]}}
# WHEN: adding an image from a saved Service and mocked exists
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path,\
patch('openlp.core.lib.serviceitem.AppLocation.get_data_path') as mocked_get_data_path,\
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash,\
patch('openlp.core.lib.serviceitem.copy'),\
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists, \
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path, \
patch('openlp.core.lib.serviceitem.AppLocation.get_data_path') as mocked_get_data_path, \
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash, \
patch('openlp.core.lib.serviceitem.copy'), \
patch('openlp.core.lib.serviceitem.move'):
mocked_sha256_file_hash.side_effect = [fake_hash1, fake_hash2]
mocked_exists.return_value = True
@ -208,9 +208,9 @@ def test_old_service_item_load_image_from_service(state_media, settings):
# WHEN: adding an image from a saved Service and mocked exists
line = convert_file_service_item(TEST_PATH, 'serviceitem_image_1.osj')
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path,\
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash,\
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists, \
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path, \
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash, \
patch('openlp.core.lib.serviceitem.move'):
mocked_sha256_file_hash.return_value = fake_hash
mocked_exists.return_value = True
@ -329,7 +329,7 @@ def test_add_from_command_for_a_presentation():
'display_title': display_title, 'notes': notes, 'thumbnail': image}
# WHEN: adding presentation to service_item
with patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash,\
with patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash, \
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path:
mocked_sha256_file_hash.return_value = 'abcd'
mocked_get_section_data_path.return_value = Path('.')
@ -353,7 +353,7 @@ def test_add_from_command_without_display_title_and_notes():
'display_title': None, 'notes': None, 'thumbnail': image}
# WHEN: adding image to service_item
with patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash,\
with patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash, \
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path:
mocked_sha256_file_hash.return_value = 'abcd'
mocked_get_section_data_path.return_value = Path('.')
@ -402,7 +402,7 @@ def test_service_item_load_optical_media_from_service(state_media):
service_item.add_icon = MagicMock()
# WHEN: We load a serviceitem with optical media
line = convert_file_service_item(TEST_PATH, 'serviceitem-dvd.osj')
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists, \
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash:
mocked_sha256_file_hash.return_value = 'abcd'
mocked_exists.return_value = True
@ -426,7 +426,7 @@ def test_service_item_load_optical_media_from_service_no_vlc(state_media):
State().modules["media"].pass_preconditions = False
# WHEN: We load a serviceitem with optical media
line = convert_file_service_item(TEST_PATH, 'serviceitem-dvd.osj')
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists, \
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash:
mocked_sha256_file_hash.return_value = 'abcd'
mocked_exists.return_value = True
@ -1049,7 +1049,7 @@ def test_to_dict_presentation_item(mocked_image_uri, mocked_get_data_path, state
mocked_image_uri.side_effect = lambda x: 'your img uri at: {}'.format(x.as_posix())
# WHEN: adding presentation to service_item
with patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash,\
with patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash, \
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as mocked_get_section_data_path:
mocked_sha256_file_hash.return_value = '4a067fed6834ea2bc4b8819f11636365'
mocked_get_section_data_path.return_value = Path('/path/to/presentations/')
@ -1173,3 +1173,25 @@ def test_get_service_repr_song(registry: Registry):
assert rep['header'].get('plugin') == 'songs'
assert rep['header'].get('theme') == 'Default'
assert rep['header'].get('title') == 'Test Song'
@pytest.mark.parametrize('is_text, is_clear_called', ((True, True), (False, False)))
def test_update_theme(registry: Registry, is_text: bool, is_clear_called: bool):
"""Test that the update_theme() method invalidates the cache when the theme changes for text items"""
# GIVEN: A service item
registry.register('renderer', MagicMock())
service_item = ServiceItem()
service_item._clear_slides_cache = MagicMock()
if is_text:
service_item.service_item_type = ServiceItemType.Text
else:
service_item.service_item_type = ServiceItemType.Image
# WHEN: update_theme() is called
service_item.update_theme('Snow')
# THEN: The clear method should or should not have been called
if is_clear_called:
service_item._clear_slides_cache.assert_called_once()
else:
service_item._clear_slides_cache.assert_not_called()

View File

@ -67,8 +67,7 @@ def test_udp_listen_add_new(mock_registry, mock_udp, projector_manager, caplog):
# THEN: Appropriate listener and log entries
assert 20 in projector_manager.pjlink_udp, "Port not added"
assert 2 == len(projector_manager.pjlink_udp), "Invalid ports in list"
assert type(projector_manager.pjlink_udp[20]) == FakePJLinkUDP, \
'PJLinkUDP instance should have been added'
assert isinstance(projector_manager.pjlink_udp[20], FakePJLinkUDP), 'PJLinkUDP instance should have been added'
assert mocked_registry.execute.has_call('udp_broadcast_add', port=20)
assert caplog.messages == log_entries, 'Invalid log entries'

View File

@ -389,9 +389,9 @@ def test_unzip_theme_invalid_version(registry):
Test that themes with invalid (< 2.0) or with no version attributes are rejected
"""
# GIVEN: An instance of ThemeManager whilst mocking a theme that returns a theme with no version attribute
with patch('openlp.core.ui.thememanager.zipfile.ZipFile') as mocked_zip_file,\
patch('openlp.core.ui.thememanager.ElementTree.getroot') as mocked_getroot,\
patch('openlp.core.ui.thememanager.XML'),\
with patch('openlp.core.ui.thememanager.zipfile.ZipFile') as mocked_zip_file, \
patch('openlp.core.ui.thememanager.ElementTree.getroot') as mocked_getroot, \
patch('openlp.core.ui.thememanager.XML'), \
patch('openlp.core.ui.thememanager.critical_error_message_box') as mocked_critical_error_message_box:
mocked_zip_file.return_value = MagicMock(**{'namelist.return_value': [os.path.join('theme', 'theme.xml')]})

View File

@ -203,7 +203,7 @@ def test_parse_csv_file_csverror():
mocked_csv_file.__str__.return_value = 'file.csv'
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding',
return_value={'encoding': 'utf-8', 'confidence': 0.99}),\
return_value={'encoding': 'utf-8', 'confidence': 0.99}), \
patch('openlp.plugins.bibles.lib.importers.csvbible.reader', side_effect=csv.Error):
# WHEN: Calling CSVBible.parse_csv_file
@ -240,7 +240,7 @@ def test_process_books(registry):
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to False, and some sample data
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.bibleimport.BibleDB._setup'),\
with patch('openlp.plugins.bibles.lib.bibleimport.BibleDB._setup'), \
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
@ -289,7 +289,7 @@ def test_process_verses_successful(registry):
"""
# GIVEN: An instance of CSVBible with the application and wizard attributes mocked out, and some test data.
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.bibleimport.BibleDB._setup'),\
with patch('openlp.plugins.bibles.lib.bibleimport.BibleDB._setup'), \
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))

View File

@ -57,7 +57,7 @@ def test_image_filenames_table(db_url, settings):
Test that the ImageFilenames table is correctly upgraded to the latest version
"""
# GIVEN: An unversioned image database
with patch.object(AppLocation, 'get_data_path', return_value=Path('/', 'test', 'dir')),\
with patch.object(AppLocation, 'get_data_path', return_value=Path('/', 'test', 'dir')), \
patch('openlp.plugins.images.lib.upgrade.sha256_file_hash') as mocked_sha256_file_hash:
mocked_sha256_file_hash.return_value = 'abcd'
# WHEN: Initalising the database manager

View File

@ -79,8 +79,8 @@ def test_click_load_button(form):
"""
# GIVEN: Mocked methods.
with patch('openlp.plugins.media.forms.mediaclipselectorform.critical_error_message_box') as \
mocked_critical_error_message_box,\
patch('openlp.plugins.media.forms.mediaclipselectorform.os.path.exists') as mocked_os_path_exists,\
mocked_critical_error_message_box, \
patch('openlp.plugins.media.forms.mediaclipselectorform.os.path.exists') as mocked_os_path_exists, \
patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()
@ -97,7 +97,7 @@ def test_click_load_button(form):
QtTest.QTest.mouseClick(form.load_disc_button, QtCore.Qt.LeftButton)
# THEN: we should get an error
assert form.media_path_combobox.currentText() == '/non-existing/test-path.test',\
assert form.media_path_combobox.currentText() == '/non-existing/test-path.test', \
'The media path should be the given one.'
mocked_critical_error_message_box.assert_called_with(message='Given path does not exist')
@ -110,7 +110,7 @@ def test_click_load_button(form):
QtTest.QTest.mouseClick(form.load_disc_button, QtCore.Qt.LeftButton)
# THEN: we should get an error
assert form.media_path_combobox.currentText() == '/existing/test-path.test',\
assert form.media_path_combobox.currentText() == '/existing/test-path.test', \
'The media path should be the given one.'
mocked_critical_error_message_box.assert_called_with(message='VLC player failed playing the media')
@ -149,7 +149,7 @@ def test_click_save_button(form):
"""
# GIVEN: Mocked methods.
with patch('openlp.plugins.media.forms.mediaclipselectorform.critical_error_message_box') as \
mocked_critical_error_message_box,\
mocked_critical_error_message_box, \
patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()