def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) self.mocked_plugin = MagicMock() with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(None, self.mocked_plugin) self.media_item.save_auto_select_id = MagicMock() self.media_item.list_view = MagicMock() self.media_item.list_view.save_auto_select_id = MagicMock() self.media_item.list_view.clear = MagicMock() self.media_item.list_view.addItem = MagicMock() self.media_item.list_view.setCurrentItem = MagicMock() self.media_item.auto_select_id = -1 self.media_item.display_songbook = False self.media_item.display_copyright_symbol = False self.setup_application() self.build_settings() Settings().extend_default_settings(__default_settings__) self.settings = self.setting Registry().register('settings', self.settings) QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(None, MagicMock()) self.media_item.display_songbook = False self.media_item.display_copyright_symbol = False self.setup_application() self.build_settings() QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) with patch('openlp.core.lib.mediamanageritem.MediaManagerItem.__init__'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(MagicMock(), MagicMock()) fd, self.ini_file = mkstemp('.ini') Settings().set_filename(self.ini_file) self.application = QtGui.QApplication.instance() QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
def mocked_media_item(mock_settings): Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) mocked_plugin = MagicMock() with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): media_item = SongMediaItem(None, mocked_plugin) media_item.save_auto_select_id = MagicMock() media_item.list_view = MagicMock() media_item.list_view.save_auto_select_id = MagicMock() media_item.list_view.clear = MagicMock() media_item.list_view.addItem = MagicMock() media_item.list_view.setCurrentItem = MagicMock() media_item.auto_select_id = -1 media_item.display_songbook = False media_item.display_copyright_symbol = False settings = Registry().get('settings') settings.extend_default_settings(__default_settings__) QtCore.QLocale.setDefault(QtCore.QLocale('en_GB')) yield media_item
class TestMediaItem(TestCase, TestMixin): """ Test the functions in the :mod:`lib` module. """ def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) self.mocked_plugin = MagicMock() with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(None, self.mocked_plugin) self.media_item.save_auto_select_id = MagicMock() self.media_item.list_view = MagicMock() self.media_item.list_view.save_auto_select_id = MagicMock() self.media_item.list_view.clear = MagicMock() self.media_item.list_view.addItem = MagicMock() self.media_item.list_view.setCurrentItem = MagicMock() self.media_item.auto_select_id = -1 self.media_item.display_songbook = False self.media_item.display_copyright_symbol = False self.setup_application() self.build_settings() QtCore.QLocale.setDefault(QtCore.QLocale('en_GB')) def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ self.destroy_settings() def test_display_results_song(self): """ Test displaying song search results with basic song """ # GIVEN: Search results, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_song = MagicMock() mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.authors = [] mock_song_temp = MagicMock() mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.authors = [] mock_author = MagicMock() mock_author.display_name = 'My Author' mock_song.authors.append(mock_author) mock_song_temp.authors.append(mock_author) mock_song.temporary = False mock_song_temp.temporary = True mock_search_results.append(mock_song) mock_search_results.append(mock_song_temp) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget self.media_item.auto_select_id = 1 # WHEN: I display song search results self.media_item.display_results_song(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() self.media_item.save_auto_select_id.assert_called_with() MockedQListWidgetItem.assert_called_once_with( 'My Song (My Author)') mock_qlist_widget.setData.assert_called_once_with( MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with( mock_qlist_widget) self.media_item.list_view.setCurrentItem.assert_called_with( mock_qlist_widget) def test_display_results_author(self): """ Test displaying song search results grouped by author with basic song """ # GIVEN: Search results grouped by author, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_author = MagicMock() mock_song = MagicMock() mock_song_temp = MagicMock() mock_author.display_name = 'My Author' mock_author.songs = [] mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.temporary = True mock_author.songs.append(mock_song) mock_author.songs.append(mock_song_temp) mock_search_results.append(mock_author) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by author self.media_item.display_results_author(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with( 'My Author (My Song)') mock_qlist_widget.setData.assert_called_once_with( MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with( mock_qlist_widget) def test_display_results_book(self): """ Test displaying song search results grouped by book and entry with basic song """ # GIVEN: Search results grouped by book and entry, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [('1', 'My Book', 'My Song', 1)] mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by book self.media_item.display_results_book(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with( 'My Book #1: My Song') mock_qlist_widget.setData.assert_called_once_with( MockedUserRole, 1) self.media_item.list_view.addItem.assert_called_once_with( mock_qlist_widget) def test_songbook_natural_sorting(self): """ Test that songbooks are sorted naturally """ # GIVEN: Search results grouped by book and entry, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem' ) as MockedQListWidgetItem: mock_search_results = [('2', 'Thy Book', 'Thy Song', 50), ('2', 'My Book', 'Your Song', 7), ('10', 'My Book', 'Our Song', 12), ('1', 'My Book', 'My Song', 1), ('2', 'Thy Book', 'A Song', 8)] mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by book self.media_item.display_results_book(mock_search_results) # THEN: The songbooks are inserted in the right (natural) order, # grouped first by book, then by number, then by song title calls = [ call('My Book #1: My Song'), call().setData(QtCore.Qt.UserRole, 1), call('My Book #2: Your Song'), call().setData(QtCore.Qt.UserRole, 7), call('My Book #10: Our Song'), call().setData(QtCore.Qt.UserRole, 12), call('Thy Book #2: A Song'), call().setData(QtCore.Qt.UserRole, 8), call('Thy Book #2: Thy Song'), call().setData(QtCore.Qt.UserRole, 50) ] MockedQListWidgetItem.assert_has_calls(calls) def test_display_results_topic(self): """ Test displaying song search results grouped by topic with basic song """ # GIVEN: Search results grouped by topic, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_topic = MagicMock() mock_song = MagicMock() mock_song_temp = MagicMock() mock_topic.name = 'My Topic' mock_topic.songs = [] mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.temporary = True mock_topic.songs.append(mock_song) mock_topic.songs.append(mock_song_temp) mock_search_results.append(mock_topic) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by topic self.media_item.display_results_topic(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Topic (My Song)') mock_qlist_widget.setData.assert_called_once_with( MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with( mock_qlist_widget) def test_display_results_themes(self): """ Test displaying song search results sorted by theme with basic song """ # GIVEN: Search results sorted by theme, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_song = MagicMock() mock_song_temp = MagicMock() mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.theme_name = 'My Theme' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.theme_name = 'My Theme' mock_song_temp.temporary = True mock_search_results.append(mock_song) mock_search_results.append(mock_song_temp) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results sorted by theme self.media_item.display_results_themes(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Theme (My Song)') mock_qlist_widget.setData.assert_called_once_with( MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with( mock_qlist_widget) def test_display_results_cclinumber(self): """ Test displaying song search results sorted by CCLI number with basic song """ # GIVEN: Search results sorted by CCLI number, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_song = MagicMock() mock_song_temp = MagicMock() mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.ccli_number = '12345' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.ccli_number = '12346' mock_song_temp.temporary = True mock_search_results.append(mock_song) mock_search_results.append(mock_song_temp) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results sorted by CCLI number self.media_item.display_results_cclinumber(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('12345 (My Song)') mock_qlist_widget.setData.assert_called_once_with( MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with( mock_qlist_widget) @patch(u'openlp.plugins.songs.lib.mediaitem.Settings') def test_build_song_footer_one_author_show_written_by( self, MockedSettings): """ Test build songs footer with basic song and one author """ # GIVEN: A Song and a Service Item, mocked settings: True for 'songs/display written by' # and False for 'core/ccli number' (ccli will cause traceback if true) mocked_settings = MagicMock() mocked_settings.value.side_effect = [True, False] MockedSettings.return_value = mocked_settings mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned assert service_item.raw_footer == ['My Song', 'Written by: my author', 'My copyright'], \ 'The array should be returned correctly with a song, one author and copyright' assert author_list == [ 'my author' ], 'The author list should be returned correctly with one author' @patch(u'openlp.plugins.songs.lib.mediaitem.Settings') def test_build_song_footer_one_author_hide_written_by( self, MockedSettings): """ Test build songs footer with basic song and one author """ # GIVEN: A Song and a Service Item, mocked settings: False for 'songs/display written by' # and False for 'core/ccli number' (ccli will cause traceback if true) mocked_settings = MagicMock() mocked_settings.value.side_effect = [False, False] MockedSettings.return_value = mocked_settings mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned assert service_item.raw_footer == ['My Song', 'my author', 'My copyright'], \ 'The array should be returned correctly with a song, one author and copyright, ' \ 'text Written by should not be part of the text.' assert author_list == [ 'my author' ], 'The author list should be returned correctly with one author' def test_build_song_footer_two_authors(self): """ Test build songs footer with basic song and two authors """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Music mock_song.authors_songs.append(mock_author_song) mock_author = MagicMock() mock_author.display_name = 'another author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Words mock_song.authors_songs.append(mock_author_song) mock_author = MagicMock() mock_author.display_name = 'translator' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Translation mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned assert service_item.raw_footer == ['My Song', 'Words: another author', 'Music: my author', 'Translation: translator', 'My copyright'], \ 'The array should be returned correctly with a song, two authors and copyright' assert author_list == ['another author', 'my author', 'translator'], \ 'The author list should be returned correctly with two authors' def test_build_song_footer_base_ccli(self): """ Test build songs footer with basic song and a CCLI number """ # GIVEN: A Song and a Service Item and a configured CCLI license mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) Settings().setValue('core/ccli number', '1234') # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned assert service_item.raw_footer == ['My Song', 'My copyright', 'CCLI License: 1234'], \ 'The array should be returned correctly with a song, an author, copyright and ccli' # WHEN: I amend the CCLI value Settings().setValue('core/ccli number', '4321') self.media_item.generate_footer(service_item, mock_song) # THEN: I would get an amended footer string assert service_item.raw_footer == ['My Song', 'My copyright', 'CCLI License: 4321'], \ 'The array should be returned correctly with a song, an author, copyright and amended ccli' def test_build_song_footer_base_songbook(self): """ Test build songs footer with basic song and multiple songbooks """ # GIVEN: A Song and a Service Item song = Song() song.title = 'My Song' song.alternate_title = '' song.copyright = 'My copyright' song.authors_songs = [] song.songbook_entries = [] song.ccli_number = '' song.topics = None book1 = MagicMock() book1.name = 'My songbook' book2 = MagicMock() book2.name = 'Thy songbook' song.songbookentries = [] song.add_songbook_entry(book1, '12') song.add_songbook_entry(book2, '502A') service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, song) # THEN: The songbook should not be in the footer assert service_item.raw_footer == ['My Song', 'My copyright'] # WHEN: I activate the "display songbook" option self.media_item.display_songbook = True self.media_item.generate_footer(service_item, song) # THEN: The songbook should be in the footer assert service_item.raw_footer == [ 'My Song', 'My copyright', 'My songbook #12, Thy songbook #502A' ] def test_build_song_footer_copyright_enabled(self): """ Test building song footer with displaying the copyright symbol """ # GIVEN: A Song and a Service Item; displaying the copyright symbol is enabled self.media_item.display_copyright_symbol = True mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The copyright symbol should be in the footer assert service_item.raw_footer == ['My Song', '© My copyright'] def test_build_song_footer_copyright_disabled(self): """ Test building song footer without displaying the copyright symbol """ # GIVEN: A Song and a Service Item; displaying the copyright symbol should be disabled by default mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The copyright symbol should not be in the footer assert service_item.raw_footer == ['My Song', 'My copyright'] def test_authors_match(self): """ Test the author matching when importing a song from a service """ # GIVEN: A song and a string with authors song = MagicMock() song.authors = [] author = MagicMock() author.display_name = "Hans Wurst" song.authors.append(author) author2 = MagicMock() author2.display_name = "Max Mustermann" song.authors.append(author2) # There are occasions where an author appears twice in a song (with different types). # We need to make sure that this case works (lp#1313538) author3 = MagicMock() author3.display_name = "Max Mustermann" song.authors.append(author3) authors_str = "Hans Wurst, Max Mustermann, Max Mustermann" # WHEN: Checking for matching result = self.media_item._authors_match(song, authors_str) # THEN: They should match assert result is True, "Authors should match" def test_authors_dont_match(self): # GIVEN: A song and a string with authors song = MagicMock() song.authors = [] author = MagicMock() author.display_name = "Hans Wurst" song.authors.append(author) author2 = MagicMock() author2.display_name = "Max Mustermann" song.authors.append(author2) # There are occasions where an author appears twice in a song (with different types). # We need to make sure that this case works (lp#1313538) author3 = MagicMock() author3.display_name = "Max Mustermann" song.authors.append(author3) # WHEN: An author is missing in the string authors_str = "Hans Wurst, Max Mustermann" result = self.media_item._authors_match(song, authors_str) # THEN: They should not match assert result is False, "Authors should not match" def test_build_remote_search(self): """ Test results for the remote search api """ # GIVEN: A Song and a search a JSON array should be returned. mock_song = MagicMock() mock_song.id = 123 mock_song.title = 'My Song' mock_song.search_title = 'My Song' mock_song.alternate_title = 'My alternative' self.media_item.search_entire = MagicMock() self.media_item.search_entire.return_value = [mock_song] # WHEN: I process a search search_results = self.media_item.search('My Song', False) # THEN: The correct formatted results are returned assert search_results == [[123, 'My Song', 'My alternative']] @patch('openlp.plugins.songs.lib.mediaitem.Book') @patch('openlp.plugins.songs.lib.mediaitem.SongBookEntry') @patch('openlp.plugins.songs.lib.mediaitem.Song') @patch('openlp.plugins.songs.lib.mediaitem.or_') def test_entire_song_search(self, mocked_or, MockedSong, MockedSongBookEntry, MockedBook): """ Test that searching the entire song does the right queries """ # GIVEN: A song media item, a keyword and some mocks keyword = 'Jesus' mocked_or.side_effect = lambda a, b, c, d, e: ' '.join([a, b, c, d, e]) MockedSong.search_title.like.side_effect = lambda a: a MockedSong.search_lyrics.like.side_effect = lambda a: a MockedSong.comments.like.side_effect = lambda a: a MockedSongBookEntry.entry.like.side_effect = lambda a: a MockedBook.name.like.side_effect = lambda a: a # WHEN: search_entire_song() is called with the keyword self.media_item.search_entire(keyword) # THEN: The correct calls were made MockedSong.search_title.like.assert_called_once_with('%jesus%') MockedSong.search_lyrics.like.assert_called_once_with('%jesus%') MockedSong.comments.like.assert_called_once_with('%jesus%') MockedSongBookEntry.entry.like.assert_called_once_with('%jesus%') MockedBook.name.like.assert_called_once_with('%jesus%') mocked_or.assert_called_once_with('%jesus%', '%jesus%', '%jesus%', '%jesus%', '%jesus%') self.mocked_plugin.manager.session.query.assert_called_once_with( MockedSong) assert self.mocked_plugin.manager.session.query.mock_calls[4][ 0] == '().join().join().filter().all'
def test_less_mocking_service_refreshed_when_refresh_button_clicked_test( self): """ Test that a service is refreshed when the "Refresh Service" button is clicked """ # GIVEN: An SelectPlanForm instance with airplane mode enabled, resources available, # mocked out "on_new_service_clicked" with patch('PyQt5.QtWidgets.QDialog.exec'), \ patch('openlp.plugins.planningcenter.forms.selectplanform.date') as mock_date: # need to always return 9/29/2019 for date.today() mock_date.today.return_value = date(2019, 9, 29) mock_date.side_effect = lambda *args, **kw: date(*args, **kw) # init ServiceManager Registry().register('plugin_manager', MagicMock()) Registry().register('application', MagicMock()) Registry().register('renderer', MagicMock()) self.service_manager = ServiceManager() self.service_manager.setup_ui(self.service_manager) # init songs plugin with patch('openlp.plugins.songs.lib.mediaitem.EditSongForm'), \ patch('openlp.plugins.custom.lib.mediaitem.EditCustomForm'), \ patch('openlp.core.lib.mediamanageritem.create_widget_action'), \ patch('openlp.core.widgets.toolbar.create_widget_action'): # init songs plugin songs_plugin = SongsPlugin() song_media_item = SongMediaItem(None, songs_plugin) song_media_item.search_text_edit = MagicMock() song_media_item.settings_section = 'songs' song_media_item.initialise() # init custom plugin custom_plugin = CustomPlugin() CustomMediaItem(None, custom_plugin) # init bible plugin bible_plugin = BiblePlugin() bible_media_item = BibleMediaItem(None, bible_plugin) bible_media_item.build_display_results = MagicMock() self.form.exec() # WHEN: # The Service Type combo is set to index 1 and "Import New" button is clicked self.form.service_type_combo_box.setCurrentIndex(1) QtTest.QTest.mouseClick(self.form.import_as_new_button, QtCore.Qt.LeftButton) # make changes to the now imported service items # first, for serviceitem[0] update last_updated in xml_string and change "sweet" to "sublime" old_match = re.search( 'modifiedDate="(.+?)Z*"', self.service_manager.service_items[0] ['service_item'].xml_version) old_string = old_match.group(1) now_string = datetime.now().strftime('%Y-%m-%dT%H:%M:%S') self.service_manager.service_items[0]['service_item'].xml_version = \ self.service_manager.service_items[0]['service_item'].xml_version.replace(old_string, now_string) self.service_manager.service_items[0]['service_item'].xml_version = \ self.service_manager.service_items[0]['service_item'].xml_version.replace("sweet", "sublime") # second, add the word modified to the slide text for serviceitem[1] self.service_manager.service_items[1]['service_item'].slides[0]['text'] = \ self.service_manager.service_items[1]['service_item'].slides[0]['text'].replace("Test", "Modified Test") # third, delete serviceitems[2] and serviceitem[3] del self.service_manager.service_items[3] del self.service_manager.service_items[2] # last, draw the form again and request refresh self.form.exec() self.form.service_type_combo_box.setCurrentIndex(1) QtTest.QTest.mouseClick(self.form.update_existing_button, QtCore.Qt.LeftButton) # THEN: # There should be 4 service items added self.assertEqual(len(self.service_manager.service_items), 5, '5 items should be in the ServiceManager') # Amazon Grace should still include sublime self.assertTrue('sublime' in self.service_manager.service_items[0] ['service_item'].xml_version) # Slides in service_item[1] should still contain the word "Modified" self.assertTrue('Modified' in self.service_manager.service_items[1] ['service_item'].slides[0]['text'])
class TestMediaItem(TestCase, TestMixin): """ Test the functions in the :mod:`lib` module. """ def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(None, MagicMock()) self.media_item.save_auto_select_id = MagicMock() self.media_item.list_view = MagicMock() self.media_item.list_view.save_auto_select_id = MagicMock() self.media_item.list_view.clear = MagicMock() self.media_item.list_view.addItem = MagicMock() self.media_item.list_view.setCurrentItem = MagicMock() self.media_item.auto_select_id = -1 self.media_item.display_songbook = False self.media_item.display_copyright_symbol = False self.setup_application() self.build_settings() QtCore.QLocale.setDefault(QtCore.QLocale('en_GB')) def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ self.destroy_settings() def test_display_results_song(self): """ Test displaying song search results with basic song """ # GIVEN: Search results, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_song = MagicMock() mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.authors = [] mock_song_temp = MagicMock() mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.authors = [] mock_author = MagicMock() mock_author.display_name = 'My Author' mock_song.authors.append(mock_author) mock_song_temp.authors.append(mock_author) mock_song.temporary = False mock_song_temp.temporary = True mock_search_results.append(mock_song) mock_search_results.append(mock_song_temp) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget self.media_item.auto_select_id = 1 # WHEN: I display song search results self.media_item.display_results_song(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() self.media_item.save_auto_select_id.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Song (My Author)') mock_qlist_widget.setData.assert_called_once_with(MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with(mock_qlist_widget) self.media_item.list_view.setCurrentItem.assert_called_with(mock_qlist_widget) def test_display_results_author(self): """ Test displaying song search results grouped by author with basic song """ # GIVEN: Search results grouped by author, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_author = MagicMock() mock_song = MagicMock() mock_song_temp = MagicMock() mock_author.display_name = 'My Author' mock_author.songs = [] mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.temporary = True mock_author.songs.append(mock_song) mock_author.songs.append(mock_song_temp) mock_search_results.append(mock_author) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by author self.media_item.display_results_author(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Author (My Song)') mock_qlist_widget.setData.assert_called_once_with(MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with(mock_qlist_widget) def test_display_results_book(self): """ Test displaying song search results grouped by book and entry with basic song """ # GIVEN: Search results grouped by book and entry, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [('1', 'My Book', 'My Song', 1)] mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by book self.media_item.display_results_book(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Book #1: My Song') mock_qlist_widget.setData.assert_called_once_with(MockedUserRole, 1) self.media_item.list_view.addItem.assert_called_once_with(mock_qlist_widget) def test_songbook_natural_sorting(self): """ Test that songbooks are sorted naturally """ # GIVEN: Search results grouped by book and entry, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem: mock_search_results = [('2', 'Thy Book', 'Thy Song', 50), ('2', 'My Book', 'Your Song', 7), ('10', 'My Book', 'Our Song', 12), ('1', 'My Book', 'My Song', 1), ('2', 'Thy Book', 'A Song', 8)] mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by book self.media_item.display_results_book(mock_search_results) # THEN: The songbooks are inserted in the right (natural) order, # grouped first by book, then by number, then by song title calls = [call('My Book #1: My Song'), call().setData(QtCore.Qt.UserRole, 1), call('My Book #2: Your Song'), call().setData(QtCore.Qt.UserRole, 7), call('My Book #10: Our Song'), call().setData(QtCore.Qt.UserRole, 12), call('Thy Book #2: A Song'), call().setData(QtCore.Qt.UserRole, 8), call('Thy Book #2: Thy Song'), call().setData(QtCore.Qt.UserRole, 50)] MockedQListWidgetItem.assert_has_calls(calls) def test_display_results_topic(self): """ Test displaying song search results grouped by topic with basic song """ # GIVEN: Search results grouped by topic, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_topic = MagicMock() mock_song = MagicMock() mock_song_temp = MagicMock() mock_topic.name = 'My Topic' mock_topic.songs = [] mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.temporary = True mock_topic.songs.append(mock_song) mock_topic.songs.append(mock_song_temp) mock_search_results.append(mock_topic) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results grouped by topic self.media_item.display_results_topic(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Topic (My Song)') mock_qlist_widget.setData.assert_called_once_with(MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with(mock_qlist_widget) def test_display_results_themes(self): """ Test displaying song search results sorted by theme with basic song """ # GIVEN: Search results sorted by theme, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_song = MagicMock() mock_song_temp = MagicMock() mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.theme_name = 'My Theme' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.theme_name = 'My Theme' mock_song_temp.temporary = True mock_search_results.append(mock_song) mock_search_results.append(mock_song_temp) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results sorted by theme self.media_item.display_results_themes(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('My Theme (My Song)') mock_qlist_widget.setData.assert_called_once_with(MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with(mock_qlist_widget) def test_display_results_cclinumber(self): """ Test displaying song search results sorted by CCLI number with basic song """ # GIVEN: Search results sorted by CCLI number, plus a mocked QtListWidgetItem with patch('openlp.core.lib.QtWidgets.QListWidgetItem') as MockedQListWidgetItem, \ patch('openlp.core.lib.QtCore.Qt.UserRole') as MockedUserRole: mock_search_results = [] mock_song = MagicMock() mock_song_temp = MagicMock() mock_song.id = 1 mock_song.title = 'My Song' mock_song.sort_key = 'My Song' mock_song.ccli_number = '12345' mock_song.temporary = False mock_song_temp.id = 2 mock_song_temp.title = 'My Temporary' mock_song_temp.sort_key = 'My Temporary' mock_song_temp.ccli_number = '12346' mock_song_temp.temporary = True mock_search_results.append(mock_song) mock_search_results.append(mock_song_temp) mock_qlist_widget = MagicMock() MockedQListWidgetItem.return_value = mock_qlist_widget # WHEN: I display song search results sorted by CCLI number self.media_item.display_results_cclinumber(mock_search_results) # THEN: The current list view is cleared, the widget is created, and the relevant attributes set self.media_item.list_view.clear.assert_called_with() MockedQListWidgetItem.assert_called_once_with('12345 (My Song)') mock_qlist_widget.setData.assert_called_once_with(MockedUserRole, mock_song.id) self.media_item.list_view.addItem.assert_called_once_with(mock_qlist_widget) @patch(u'openlp.plugins.songs.lib.mediaitem.Settings') def test_build_song_footer_one_author_show_written_by(self, MockedSettings): """ Test build songs footer with basic song and one author """ # GIVEN: A Song and a Service Item, mocked settings: True for 'songs/display written by' # and False for 'core/ccli number' (ccli will cause traceback if true) mocked_settings = MagicMock() mocked_settings.value.side_effect = [True, False] MockedSettings.return_value = mocked_settings mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'Written by: my author', 'My copyright'], 'The array should be returned correctly with a song, one author and copyright') self.assertEqual(author_list, ['my author'], 'The author list should be returned correctly with one author') @patch(u'openlp.plugins.songs.lib.mediaitem.Settings') def test_build_song_footer_one_author_hide_written_by(self, MockedSettings): """ Test build songs footer with basic song and one author """ # GIVEN: A Song and a Service Item, mocked settings: False for 'songs/display written by' # and False for 'core/ccli number' (ccli will cause traceback if true) mocked_settings = MagicMock() mocked_settings.value.side_effect = [False, False] MockedSettings.return_value = mocked_settings mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'my author', 'My copyright'], 'The array should be returned correctly with a song, one author and copyright,' 'text Written by should not be part of the text.') self.assertEqual(author_list, ['my author'], 'The author list should be returned correctly with one author') def test_build_song_footer_two_authors(self): """ Test build songs footer with basic song and two authors """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Music mock_song.authors_songs.append(mock_author_song) mock_author = MagicMock() mock_author.display_name = 'another author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Words mock_song.authors_songs.append(mock_author_song) mock_author = MagicMock() mock_author.display_name = 'translator' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Translation mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'Words: another author', 'Music: my author', 'Translation: translator', 'My copyright'], 'The array should be returned correctly with a song, two authors and copyright') self.assertEqual(author_list, ['another author', 'my author', 'translator'], 'The author list should be returned correctly with two authors') def test_build_song_footer_base_ccli(self): """ Test build songs footer with basic song and a CCLI number """ # GIVEN: A Song and a Service Item and a configured CCLI license mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) Settings().setValue('core/ccli number', '1234') # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright', 'CCLI License: 1234'], 'The array should be returned correctly with a song, an author, copyright and ccli') # WHEN: I amend the CCLI value Settings().setValue('core/ccli number', '4321') self.media_item.generate_footer(service_item, mock_song) # THEN: I would get an amended footer string self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright', 'CCLI License: 4321'], 'The array should be returned correctly with a song, an author, copyright and amended ccli') def test_build_song_footer_base_songbook(self): """ Test build songs footer with basic song and multiple songbooks """ # GIVEN: A Song and a Service Item song = Song() song.title = 'My Song' song.copyright = 'My copyright' song.authors_songs = [] song.songbook_entries = [] song.ccli_number = '' book1 = MagicMock() book1.name = "My songbook" book2 = MagicMock() book2.name = "Thy songbook" song.songbookentries = [] song.add_songbook_entry(book1, '12') song.add_songbook_entry(book2, '502A') service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, song) # THEN: The songbook should not be in the footer self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright']) # WHEN: I activate the "display songbook" option self.media_item.display_songbook = True self.media_item.generate_footer(service_item, song) # THEN: The songbook should be in the footer self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright', 'My songbook #12, Thy songbook #502A']) def test_build_song_footer_copyright_enabled(self): """ Test building song footer with displaying the copyright symbol """ # GIVEN: A Song and a Service Item; displaying the copyright symbol is enabled self.media_item.display_copyright_symbol = True mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The copyright symbol should be in the footer self.assertEqual(service_item.raw_footer, ['My Song', '© My copyright']) def test_build_song_footer_copyright_disabled(self): """ Test building song footer without displaying the copyright symbol """ # GIVEN: A Song and a Service Item; displaying the copyright symbol should be disabled by default mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The copyright symbol should not be in the footer self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright']) def test_authors_match(self): """ Test the author matching when importing a song from a service """ # GIVEN: A song and a string with authors song = MagicMock() song.authors = [] author = MagicMock() author.display_name = "Hans Wurst" song.authors.append(author) author2 = MagicMock() author2.display_name = "Max Mustermann" song.authors.append(author2) # There are occasions where an author appears twice in a song (with different types). # We need to make sure that this case works (lp#1313538) author3 = MagicMock() author3.display_name = "Max Mustermann" song.authors.append(author3) authors_str = "Hans Wurst, Max Mustermann, Max Mustermann" # WHEN: Checking for matching result = self.media_item._authors_match(song, authors_str) # THEN: They should match self.assertTrue(result, "Authors should match") def test_authors_dont_match(self): # GIVEN: A song and a string with authors song = MagicMock() song.authors = [] author = MagicMock() author.display_name = "Hans Wurst" song.authors.append(author) author2 = MagicMock() author2.display_name = "Max Mustermann" song.authors.append(author2) # There are occasions where an author appears twice in a song (with different types). # We need to make sure that this case works (lp#1313538) author3 = MagicMock() author3.display_name = "Max Mustermann" song.authors.append(author3) # WHEN: An author is missing in the string authors_str = "Hans Wurst, Max Mustermann" result = self.media_item._authors_match(song, authors_str) # THEN: They should not match self.assertFalse(result, "Authors should not match") def test_build_remote_search(self): """ Test results for the remote search api """ # GIVEN: A Song and a search a JSON array should be returned. mock_song = MagicMock() mock_song.id = 123 mock_song.title = 'My Song' mock_song.search_title = 'My Song' mock_song.alternate_title = 'My alternative' self.media_item.search_entire = MagicMock() self.media_item.search_entire.return_value = [mock_song] # WHEN: I process a search search_results = self.media_item.search('My Song', False) # THEN: The correct formatted results are returned self.assertEqual(search_results, [[123, 'My Song', 'My alternative']])
class TestMediaItem(TestCase): """ Test the functions in the :mod:`lib` module. """ def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) with patch('openlp.core.lib.mediamanageritem.MediaManagerItem.__init__'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(MagicMock(), MagicMock()) fd, self.ini_file = mkstemp('.ini') Settings().set_filename(self.ini_file) self.application = QtGui.QApplication.instance() QtCore.QLocale.setDefault(QtCore.QLocale('en_GB')) def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ del self.application # Not all tests use settings! try: os.unlink(self.ini_file) os.unlink(Settings().fileName()) except Exception: pass def build_song_footer_one_author_test(self): """ Test build songs footer with basic song and one author """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_author = MagicMock() mock_author.display_name = 'my author' mock_song.authors = [] mock_song.authors.append(mock_author) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'my author', 'My copyright'], 'The array should be returned correctly with a song, one author and copyright') self.assertEqual(author_list, ['my author'], 'The author list should be returned correctly with one author') def build_song_footer_two_authors_test(self): """ Test build songs footer with basic song and two authors """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_author = MagicMock() mock_author.display_name = 'my author' mock_song.authors = [] mock_song.authors.append(mock_author) mock_author = MagicMock() mock_author.display_name = 'another author' mock_song.authors.append(mock_author) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'my author and another author', 'My copyright'], 'The array should be returned correctly with a song, two authors and copyright') self.assertEqual(author_list, ['my author', 'another author'], 'The author list should be returned correctly with two authors') def build_song_footer_base_ccli_test(self): """ Test build songs footer with basic song and two authors """ # GIVEN: A Song and a Service Item and a configured CCLI license mock_song = MagicMock() mock_song.title = 'My Song' mock_author = MagicMock() mock_author.display_name = 'my author' mock_song.authors = [] mock_song.authors.append(mock_author) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) Settings().setValue('core/ccli number', '1234') # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'my author', 'My copyright', 'CCLI License: 1234'], 'The array should be returned correctly with a song, an author, copyright and ccli') # WHEN: I amend the CCLI value Settings().setValue('core/ccli number', '4321') self.media_item.generate_footer(service_item, mock_song) # THEN: I would get an amended footer string self.assertEqual(service_item.raw_footer, ['My Song', 'my author', 'My copyright', 'CCLI License: 4321'], 'The array should be returned correctly with a song, an author, copyright and amended ccli')
class TestMediaItem(TestCase, TestMixin): """ Test the functions in the :mod:`lib` module. """ def setUp(self): """ Set up the components need for all tests. """ Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): self.media_item = SongMediaItem(None, MagicMock()) self.media_item.display_songbook = False self.media_item.display_copyright_symbol = False self.setup_application() self.build_settings() QtCore.QLocale.setDefault(QtCore.QLocale('en_GB')) def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ self.destroy_settings() def build_song_footer_one_author_test(self): """ Test build songs footer with basic song and one author """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'Written by: my author', 'My copyright'], 'The array should be returned correctly with a song, one author and copyright') self.assertEqual(author_list, ['my author'], 'The author list should be returned correctly with one author') def build_song_footer_two_authors_test(self): """ Test build songs footer with basic song and two authors """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_song.authors_songs = [] mock_author = MagicMock() mock_author.display_name = 'my author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Music mock_song.authors_songs.append(mock_author_song) mock_author = MagicMock() mock_author.display_name = 'another author' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Words mock_song.authors_songs.append(mock_author_song) mock_author = MagicMock() mock_author.display_name = 'translator' mock_author_song = MagicMock() mock_author_song.author = mock_author mock_author_song.author_type = AuthorType.Translation mock_song.authors_songs.append(mock_author_song) mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings author_list = self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'Words: another author', 'Music: my author', 'Translation: translator', 'My copyright'], 'The array should be returned correctly with a song, two authors and copyright') self.assertEqual(author_list, ['another author', 'my author', 'translator'], 'The author list should be returned correctly with two authors') def build_song_footer_base_ccli_test(self): """ Test build songs footer with basic song and a CCLI number """ # GIVEN: A Song and a Service Item and a configured CCLI license mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) Settings().setValue('core/ccli number', '1234') # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: I get the following Array returned self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright', 'CCLI License: 1234'], 'The array should be returned correctly with a song, an author, copyright and ccli') # WHEN: I amend the CCLI value Settings().setValue('core/ccli number', '4321') self.media_item.generate_footer(service_item, mock_song) # THEN: I would get an amended footer string self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright', 'CCLI License: 4321'], 'The array should be returned correctly with a song, an author, copyright and amended ccli') def build_song_footer_base_songbook_test(self): """ Test build songs footer with basic song and a songbook """ # GIVEN: A Song and a Service Item mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' mock_song.book = MagicMock() mock_song.book.name = "My songbook" mock_song.song_number = 12 service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The songbook should not be in the footer self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright']) # WHEN: I activate the "display songbook" option self.media_item.display_songbook = True self.media_item.generate_footer(service_item, mock_song) # THEN: The songbook should be in the footer self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright', 'My songbook #12']) def build_song_footer_copyright_enabled_test(self): """ Test building song footer with displaying the copyright symbol """ # GIVEN: A Song and a Service Item; displaying the copyright symbol is enabled self.media_item.display_copyright_symbol = True mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The copyright symbol should be in the footer self.assertEqual(service_item.raw_footer, ['My Song', '© My copyright']) def build_song_footer_copyright_disabled_test(self): """ Test building song footer without displaying the copyright symbol """ # GIVEN: A Song and a Service Item; displaying the copyright symbol should be disabled by default mock_song = MagicMock() mock_song.title = 'My Song' mock_song.copyright = 'My copyright' service_item = ServiceItem(None) # WHEN: I generate the Footer with default settings self.media_item.generate_footer(service_item, mock_song) # THEN: The copyright symbol should not be in the footer self.assertEqual(service_item.raw_footer, ['My Song', 'My copyright']) def authors_match_test(self): """ Test the author matching when importing a song from a service """ # GIVEN: A song and a string with authors song = MagicMock() song.authors = [] author = MagicMock() author.display_name = "Hans Wurst" song.authors.append(author) author2 = MagicMock() author2.display_name = "Max Mustermann" song.authors.append(author2) # There are occasions where an author appears twice in a song (with different types). # We need to make sure that this case works (lp#1313538) author3 = MagicMock() author3.display_name = "Max Mustermann" song.authors.append(author3) authors_str = "Hans Wurst, Max Mustermann, Max Mustermann" # WHEN: Checking for matching result = self.media_item._authors_match(song, authors_str) # THEN: They should match self.assertTrue(result, "Authors should match") def authors_dont_match_test(self): # GIVEN: A song and a string with authors song = MagicMock() song.authors = [] author = MagicMock() author.display_name = "Hans Wurst" song.authors.append(author) author2 = MagicMock() author2.display_name = "Max Mustermann" song.authors.append(author2) # There are occasions where an author appears twice in a song (with different types). # We need to make sure that this case works (lp#1313538) author3 = MagicMock() author3.display_name = "Max Mustermann" song.authors.append(author3) # WHEN: An author is missing in the string authors_str = "Hans Wurst, Max Mustermann" result = self.media_item._authors_match(song, authors_str) # THEN: They should not match self.assertFalse(result, "Authors should not match")