forked from openlp/openlp
Standardize plugin search options
This commit is contained in:
parent
c7112a1f78
commit
d47a14a716
@ -54,6 +54,22 @@ def add(plugin_name, id):
|
||||
getattr(plugin.media_item, '{action}_add_to_service'.format(action=plugin_name)).emit([item_id, True])
|
||||
|
||||
|
||||
def get_options(plugin_name):
|
||||
plugin = Registry().get('plugin_manager').get_plugin_by_name(plugin_name)
|
||||
if plugin.status == PluginStatus.Active and plugin.media_item:
|
||||
options = plugin.media_item.search_options()
|
||||
return options
|
||||
return []
|
||||
|
||||
|
||||
def set_option(plugin_name, search_option, value):
|
||||
plugin = Registry().get('plugin_manager').get_plugin_by_name(plugin_name)
|
||||
success = False
|
||||
if plugin.status == PluginStatus.Active and plugin.media_item:
|
||||
success = plugin.media_item.set_search_option(search_option, value)
|
||||
return success
|
||||
|
||||
|
||||
@plugins.route('/<plugin>/search')
|
||||
@login_required
|
||||
def search_view(plugin):
|
||||
@ -93,13 +109,7 @@ def search_options(plugin):
|
||||
Get the plugin's search options
|
||||
"""
|
||||
log.debug(f'{plugin}/search-options called')
|
||||
if plugin == 'bibles':
|
||||
bible_plugin = Registry().get('bible_plugin')
|
||||
bibles = list(bible_plugin.manager.get_bibles().keys())
|
||||
primary = Registry().get('settings').value('bibles/primary bible')
|
||||
return jsonify(primary=primary, bibles=bibles)
|
||||
else:
|
||||
return '', 501
|
||||
return jsonify(get_options(plugin))
|
||||
|
||||
|
||||
@plugins.route('/<plugin>/search-options', methods=['POST'])
|
||||
@ -110,22 +120,17 @@ def set_search_option(plugin):
|
||||
"""
|
||||
log.debug(f'{plugin}/search-options-set called')
|
||||
data = request.json
|
||||
option = ''
|
||||
if not data:
|
||||
log.error('Missing request data')
|
||||
abort(400)
|
||||
elif type(data.get('option')) is not (str or int):
|
||||
abort(400)
|
||||
try:
|
||||
option = data.get('option')
|
||||
except ValueError:
|
||||
log.error('Invalid data passed: ' + option)
|
||||
option = data.get('option', None)
|
||||
value = data.get('value', None)
|
||||
if value is None:
|
||||
log.error('Invalid data passed in value')
|
||||
abort(400)
|
||||
|
||||
if plugin == 'bibles':
|
||||
Registry().get('settings').setValue('bibles/primary bible', option)
|
||||
Registry().execute('populate_bible_combo_boxes')
|
||||
if set_option(plugin, option, value):
|
||||
return '', 204
|
||||
else:
|
||||
log.error('Unimplemented method')
|
||||
return '', 501
|
||||
log.error('Invalid option or value')
|
||||
return '', 400
|
||||
|
@ -700,6 +700,27 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
if item:
|
||||
self.auto_select_id = item.data(QtCore.Qt.UserRole)
|
||||
|
||||
def search_options(self, option=None):
|
||||
"""
|
||||
Returns a list of search options and values for bibles
|
||||
Must return in this format:
|
||||
[{name:'<option_name>',list:[<possible values...>],selected:<selected_value>}]
|
||||
|
||||
:param option: Can be set to an option to only return that option
|
||||
"""
|
||||
# By default plugins have no search options
|
||||
return []
|
||||
|
||||
def set_search_option(self, search_option, value):
|
||||
"""
|
||||
Sets a search option
|
||||
|
||||
:param search_option: The option to be set
|
||||
:param value: The new value for the search option
|
||||
:return: True if the search_option was successfully set
|
||||
"""
|
||||
return False
|
||||
|
||||
def search(self, string, show_error=True):
|
||||
"""
|
||||
Performs a plugin specific search for items containing ``string``
|
||||
|
@ -1002,6 +1002,39 @@ class BibleMediaItem(MediaManagerItem):
|
||||
}[self.settings_tab.display_style]
|
||||
return '{{su}}{bracket[0]}{verse_text}{bracket[1]}{{/su}} '.format(verse_text=verse_text, bracket=bracket)
|
||||
|
||||
def search_options(self, option=None):
|
||||
"""
|
||||
Returns a list of search options and values for bibles
|
||||
|
||||
:param option: Can be set to an option to only return that option
|
||||
"""
|
||||
if (option is not None and option != 'primary bible'):
|
||||
return []
|
||||
bibles = list(self.plugin.manager.get_bibles().keys())
|
||||
primary = Registry().get('settings').value('bibles/primary bible')
|
||||
return [
|
||||
{
|
||||
'name': 'primary bible',
|
||||
'list': bibles,
|
||||
'selected': primary
|
||||
}
|
||||
]
|
||||
|
||||
def set_search_option(self, search_option, value):
|
||||
"""
|
||||
Sets a search option
|
||||
|
||||
:param search_option: The option to be set
|
||||
:param value: The new value for the search option
|
||||
:return: True if the search_option was successfully set
|
||||
"""
|
||||
if search_option == 'primary bible' and value in self.search_options('primary bible')[0]['list']:
|
||||
Registry().get('settings').setValue('bibles/primary bible', value)
|
||||
Registry().execute('populate_bible_combo_boxes')
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def search(self, string, show_error=True):
|
||||
"""
|
||||
Search for some Bible verses (by reference).
|
||||
|
@ -21,40 +21,70 @@
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.enum import PluginStatus
|
||||
|
||||
|
||||
# Search options tests
|
||||
def test_bibles_search_options_returns_bibles_list(flask_client, settings):
|
||||
Registry().register('bible_plugin', MagicMock())
|
||||
def test_bibles_search_options_returns_list(flask_client, settings):
|
||||
"""
|
||||
Test a list is returned when a plugin's search options are requested.
|
||||
|
||||
Returns an empty list here because the plugin is mocked so there are no options.
|
||||
"""
|
||||
# GIVEN: A mocked plugin
|
||||
mock_plugin_manager = MagicMock()
|
||||
mock_plugin_manager.get_plugin_by_name.return_value = MagicMock()
|
||||
Registry().register('plugin_manager', mock_plugin_manager)
|
||||
|
||||
# WHEN: Search options are requested
|
||||
res = flask_client.get('/api/v2/plugins/bibles/search-options').get_json()
|
||||
assert res.get('primary') == ""
|
||||
assert type(res.get('bibles')) is list
|
||||
|
||||
# THEN: A empty list should be returned
|
||||
assert res == []
|
||||
|
||||
|
||||
def test_bibles_set_search_options_sets_bible_version(flask_client, settings):
|
||||
Registry().register('bible_plugin', MagicMock())
|
||||
res = flask_client.post('/api/v2/plugins/bibles/search-options', json=dict(option='foo'))
|
||||
"""
|
||||
Test that a search option post request sends the correct values to the plugin,
|
||||
and returns the correct status code.
|
||||
"""
|
||||
# GIVEN: A mocked bible plugin
|
||||
mock_plugin_manager = MagicMock()
|
||||
mock_bible_plugin = MagicMock()
|
||||
mock_bible_plugin.status = PluginStatus.Active
|
||||
mock_bible_plugin.media_item = MagicMock(set_search_option=MagicMock(return_value=True))
|
||||
mock_plugin_manager.get_plugin_by_name.return_value = mock_bible_plugin
|
||||
Registry().register('plugin_manager', mock_plugin_manager)
|
||||
|
||||
# WHEN: The primary bible is requested to change via the api
|
||||
res = flask_client.post('/api/v2/plugins/bibles/search-options', json=dict(option='primary bible', value='foo'))
|
||||
|
||||
# THEN: Returns correct status code and sends correct values to plugin.
|
||||
assert res.status_code == 204
|
||||
assert Registry().get('settings').value('bibles/primary bible') == 'foo'
|
||||
mock_bible_plugin.media_item.set_search_option.assert_called_once_with('primary bible', 'foo')
|
||||
|
||||
|
||||
def test_plugin_set_search_option_aborts_if_no_option(flask_client, settings):
|
||||
Registry().register('plugin_manager', MagicMock())
|
||||
res = flask_client.post('/api/v2/plugins/songs/search-options')
|
||||
assert res.status_code == 400
|
||||
|
||||
|
||||
def test_plugin_set_search_option_aborts_if_invalid_option(flask_client, settings):
|
||||
Registry().register('plugin_manager', MagicMock())
|
||||
res1 = flask_client.post('/api/v2/plugins/songs/search-options', json=dict(option=['']))
|
||||
res2 = flask_client.post('/api/v2/plugins/songs/search-options', json=dict(option={1: '', 2: ''}))
|
||||
assert res1.status_code == 400
|
||||
assert res2.status_code == 400
|
||||
|
||||
|
||||
def test_plugin_search_options_returns_plugin_exception(flask_client, settings):
|
||||
def test_plugin_search_options_returns_no_search_options(flask_client, settings):
|
||||
Registry().register('plugin_manager', MagicMock())
|
||||
res = flask_client.get('/api/v2/plugins/songs/search-options')
|
||||
assert res.status_code == 501
|
||||
assert res.status_code == 200
|
||||
|
||||
|
||||
def test_plugin_set_search_option_returns_plugin_exception(flask_client, settings):
|
||||
Registry().register('plugin_manager', MagicMock())
|
||||
res = flask_client.post('/api/v2/plugins/songs/search-options', json=dict(option=''))
|
||||
assert res.status_code == 501
|
||||
assert res.status_code == 400
|
||||
|
@ -118,3 +118,31 @@ def test_on_double_clicked_single_click_preview(mocked_on_preview_click, mocked_
|
||||
# THEN: on_live_click() should have been called
|
||||
assert 0 == mocked_on_live_click.call_count, 'on_live_click() should not have been called'
|
||||
assert 0 == mocked_on_preview_click.call_count, 'on_preview_click() should not have been called'
|
||||
|
||||
|
||||
def test_search_options(media_env):
|
||||
"""
|
||||
Test that the default search options return a empty list
|
||||
"""
|
||||
# GIVEN: A media manager item
|
||||
mmi = MediaManagerItem(None)
|
||||
|
||||
# WHEN: The search options are requested
|
||||
result = mmi.search_options()
|
||||
|
||||
# THEN: should return a empty list
|
||||
assert result == []
|
||||
|
||||
|
||||
def test_set_search_option(media_env):
|
||||
"""
|
||||
Test that the default set search option return false because it's setting a non existant setting
|
||||
"""
|
||||
# GIVEN: A media manager item
|
||||
mmi = MediaManagerItem(None)
|
||||
|
||||
# WHEN: The a search option is set
|
||||
result = mmi.set_search_option('my option', 'my value')
|
||||
|
||||
# THEN: should return false
|
||||
assert result is False
|
||||
|
@ -1508,3 +1508,75 @@ def test_display_results_results(media_item):
|
||||
# THEN: addItem should have been with the display items
|
||||
mocked_add_built_results_to_list_widget.assert_called_once_with(
|
||||
[{'item_title': 'Title 1'}, {'item_title': 'Title 2'}])
|
||||
|
||||
|
||||
def test_search_options(media_item):
|
||||
"""
|
||||
Test that the bible search options are returned
|
||||
"""
|
||||
# GIVEN: An instance of BibleMediaItem, and mocked primary bible setting
|
||||
media_item.plugin.manager.get_bibles.return_value = MagicMock(keys=MagicMock(return_value=['a', 'b', 'c']))
|
||||
media_item.settings.value = lambda key: {'bibles/primary bible': 'b'}[key]
|
||||
|
||||
# WHEN: calling search_options
|
||||
result = media_item.search_options()
|
||||
|
||||
# THEN: result should be correct
|
||||
assert result == [{'name': 'primary bible', 'list': ['a', 'b', 'c'], 'selected': 'b'}]
|
||||
|
||||
|
||||
def test_set_search_option(media_item):
|
||||
"""
|
||||
Test that the bible set search option function works
|
||||
"""
|
||||
# GIVEN: An instance of BibleMediaItem, with a mocked get_bibles and a mocked populate_bible_combo_boxes function
|
||||
media_item.plugin.manager.get_bibles.return_value = MagicMock(keys=MagicMock(return_value=['a', 'b', 'c']))
|
||||
populate_bible_combo_boxes = MagicMock()
|
||||
Registry().remove_function('populate_bible_combo_boxes', media_item.populate_bible_combo_boxes)
|
||||
Registry().register_function('populate_bible_combo_boxes', populate_bible_combo_boxes)
|
||||
|
||||
# WHEN: calling set_search_option
|
||||
result = media_item.set_search_option('primary bible', 'c')
|
||||
|
||||
# THEN: result should be correct and the new bible set, and combo boxes updated
|
||||
assert result is True
|
||||
media_item.settings.setValue.assert_called_once_with('bibles/primary bible', 'c')
|
||||
populate_bible_combo_boxes.assert_called_once()
|
||||
|
||||
|
||||
def test_set_search_option_invalid_option(media_item):
|
||||
"""
|
||||
Test that the bible set search option function rejects when using non existing option
|
||||
"""
|
||||
# GIVEN: An instance of BibleMediaItem, with a mocked get_bibles and a mocked populate_bible_combo_boxes function
|
||||
media_item.plugin.manager.get_bibles.return_value = MagicMock(keys=MagicMock(return_value=['a', 'b', 'c']))
|
||||
populate_bible_combo_boxes = MagicMock()
|
||||
Registry().remove_function('populate_bible_combo_boxes', media_item.populate_bible_combo_boxes)
|
||||
Registry().register_function('populate_bible_combo_boxes', populate_bible_combo_boxes)
|
||||
|
||||
# WHEN: calling set_search_option with invalid option
|
||||
result = media_item.set_search_option('not an option', 'a')
|
||||
|
||||
# THEN: result should be False and nothing set, and combo boxes not updated
|
||||
assert result is False
|
||||
media_item.settings.setValue.assert_not_called()
|
||||
populate_bible_combo_boxes.assert_not_called()
|
||||
|
||||
|
||||
def test_set_search_option_invalid_value(media_item):
|
||||
"""
|
||||
Test that the bible set search option function rejects when using non existing value
|
||||
"""
|
||||
# GIVEN: An instance of BibleMediaItem, with a mocked get_bibles and a mocked populate_bible_combo_boxes function
|
||||
media_item.plugin.manager.get_bibles.return_value = MagicMock(keys=MagicMock(return_value=['a', 'b', 'c']))
|
||||
populate_bible_combo_boxes = MagicMock()
|
||||
Registry().remove_function('populate_bible_combo_boxes', media_item.populate_bible_combo_boxes)
|
||||
Registry().register_function('populate_bible_combo_boxes', populate_bible_combo_boxes)
|
||||
|
||||
# WHEN: calling set_search_option with invalid value
|
||||
result = media_item.set_search_option('primary bible', 'not a value')
|
||||
|
||||
# THEN: result should be False and nothing set, and combo boxes not updated
|
||||
assert result is False
|
||||
media_item.settings.setValue.assert_not_called()
|
||||
populate_bible_combo_boxes.assert_not_called()
|
||||
|
Loading…
Reference in New Issue
Block a user