def get_books_from_http_no_soup_test(self): """ Test the get_books_from_http method when get_soup_for_bible_ref returns a falsey value """ # GIVEN: An instance of BSExtract, and reset log, urllib & get_soup_for_bible_ref mocks instance = BSExtract() self.mock_log.debug.reset_mock() self.mock_urllib.reset_mock() self.mock_get_soup_for_bible_ref.reset_mock() # WHEN: get_books_from_http is called with 'NIV' and get_soup_for_bible_ref returns a None value self.mock_urllib.parse.quote.return_value = 'NIV' self.mock_get_soup_for_bible_ref.return_value = None result = instance.get_books_from_http('NIV') # THEN: The rest mocks should be called with known values and get_books_from_http should return None self.mock_log.debug.assert_called_once_with( 'BSExtract.get_books_from_http("%s")', 'NIV') self.mock_urllib.parse.quote.assert_called_once_with(b'NIV') self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.assertIsNone( result, 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a ' 'false value')
def get_books_from_http_no_content_test(self): """ Test the get_books_from_http method when the specified element cannot be found in the tag object returned from get_soup_for_bible_ref """ # GIVEN: An instance of BSExtract, and reset log, urllib, get_soup_for_bible_ref & soup mocks instance = BSExtract() self.mock_log.reset_mock() self.mock_urllib.reset_mock() self.mock_get_soup_for_bible_ref.reset_mock() self.mock_soup.reset_mock() # WHEN: get_books_from_http is called with 'NIV', get_soup_for_bible_ref returns a mocked_soup object and # mocked_soup.find returns None self.mock_urllib.parse.quote.return_value = 'NIV' self.mock_soup.find.return_value = None self.mock_get_soup_for_bible_ref.return_value = self.mock_soup result = instance.get_books_from_http('NIV') # THEN: The rest mocks should be called with known values and get_books_from_http should return None self.mock_log.debug.assert_called_once_with( 'BSExtract.get_books_from_http("%s")', 'NIV') self.mock_urllib.parse.quote.assert_called_once_with(b'NIV') self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.mock_soup.find.assert_called_once_with('ul') self.mock_log.error.assert_called_once_with( 'No books found in the Bibleserver response.') self.mock_send_error_message.assert_called_once_with('parse') self.assertIsNone( result, 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a ' 'false value')
def get_books_from_http_content_test(self): """ Test the get_books_from_http method with sample HTML Also a regression test for bug #1184869. (The anchor tag in the second list item is empty) """ # GIVEN: An instance of BSExtract, and reset log, urllib & get_soup_for_bible_ref mocks and sample HTML data self.test_html = '<ul><li><a href="/overlay/selectChapter?tocBook=1">Genesis</a></li>' \ '<li><a href="/overlay/selectChapter?tocBook=2"></a></li>' \ '<li><a href="/overlay/selectChapter?tocBook=3">Leviticus</a></li></ul>' self.test_soup = BeautifulSoup(self.test_html) instance = BSExtract() self.mock_log.reset_mock() self.mock_urllib.reset_mock() self.mock_get_soup_for_bible_ref.reset_mock() self.mock_send_error_message.reset_mock() # WHEN: get_books_from_http is called with 'NIV' and get_soup_for_bible_ref returns tag object based on the # supplied test data. self.mock_urllib.parse.quote.return_value = 'NIV' self.mock_get_soup_for_bible_ref.return_value = self.test_soup result = instance.get_books_from_http('NIV') # THEN: The rest mocks should be called with known values and get_books_from_http should return the two books # in the test data self.mock_log.debug.assert_called_once_with( 'BSExtract.get_books_from_http("%s")', 'NIV') self.mock_urllib.parse.quote.assert_called_once_with(b'NIV') self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.assertFalse(self.mock_log.error.called, 'log.error should not have been called') self.assertFalse(self.mock_send_error_message.called, 'send_error_message should not have been called') self.assertEqual(result, ['Genesis', 'Leviticus'])
def get_books_from_http_content_test(self): """ Test the get_books_from_http method with sample HTML Also a regression test for bug #1184869. (The anchor tag in the second list item is empty) """ # GIVEN: An instance of BSExtract, and reset log, urllib & get_soup_for_bible_ref mocks and sample HTML data self.test_html = '<ul><li><a href="/overlay/selectChapter?tocBook=1">Genesis</a></li>' \ '<li><a href="/overlay/selectChapter?tocBook=2"></a></li>' \ '<li><a href="/overlay/selectChapter?tocBook=3">Leviticus</a></li></ul>' self.test_soup = BeautifulSoup(self.test_html) instance = BSExtract() self.mock_log.reset_mock() self.mock_urllib.reset_mock() self.mock_get_soup_for_bible_ref.reset_mock() self.mock_send_error_message.reset_mock() # WHEN: get_books_from_http is called with 'NIV' and get_soup_for_bible_ref returns tag object based on the # supplied test data. self.mock_urllib.parse.quote.return_value = 'NIV' self.mock_get_soup_for_bible_ref.return_value = self.test_soup result = instance.get_books_from_http('NIV') # THEN: The rest mocks should be called with known values and get_books_from_http should return the two books # in the test data self.mock_log.debug.assert_called_once_with('BSExtract.get_books_from_http("%s")', 'NIV') self.mock_urllib.parse.quote.assert_called_once_with(b'NIV') self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.assertFalse(self.mock_log.error.called, 'log.error should not have been called') self.assertFalse(self.mock_send_error_message.called, 'send_error_message should not have been called') self.assertEqual(result, ['Genesis', 'Leviticus'])
def get_books_from_http_no_content_test(self): """ Test the get_books_from_http method when the specified element cannot be found in the tag object returned from get_soup_for_bible_ref """ # GIVEN: An instance of BSExtract, and reset log, urllib, get_soup_for_bible_ref & soup mocks instance = BSExtract() self.mock_log.reset_mock() self.mock_urllib.reset_mock() self.mock_get_soup_for_bible_ref.reset_mock() self.mock_soup.reset_mock() # WHEN: get_books_from_http is called with 'NIV', get_soup_for_bible_ref returns a mocked_soup object and # mocked_soup.find returns None self.mock_urllib.parse.quote.return_value = 'NIV' self.mock_soup.find.return_value = None self.mock_get_soup_for_bible_ref.return_value = self.mock_soup result = instance.get_books_from_http('NIV') # THEN: The rest mocks should be called with known values and get_books_from_http should return None self.mock_log.debug.assert_called_once_with('BSExtract.get_books_from_http("%s")', 'NIV') self.mock_urllib.parse.quote.assert_called_once_with(b'NIV') self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.mock_soup.find.assert_called_once_with('ul') self.mock_log.error.assert_called_once_with('No books found in the Bibleserver response.') self.mock_send_error_message.assert_called_once_with('parse') self.assertIsNone(result, 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a ' 'false value')
def bibleserver_get_bibles_test(self): """ Test getting list of bibles from BibleServer.com """ # GIVEN: A new Bible Server extraction class handler = BSExtract() # WHEN: downloading bible list from bibleserver bibles = handler.get_bibles_from_http() # THEN: The list should not be None, and some known bibles should be there self.assertIsNotNone(bibles) self.assertIn(('New Int. Readers Version', 'NIRV', 'en'), bibles) self.assertIn(('Българската Библия', 'BLG', 'bg'), bibles)
def on_web_update_button_clicked(self): """ Download list of bibles from Crosswalk, BibleServer and BibleGateway. """ # Download from Crosswalk, BiblesGateway, BibleServer self.web_bible_list = {} self.web_source_combo_box.setEnabled(False) self.web_translation_combo_box.setEnabled(False) self.web_update_button.setEnabled(False) self.web_progress_bar.setVisible(True) self.web_progress_bar.setValue(0) proxy_server = self.field('proxy_server') for (download_type, extractor) in ((WebDownload.Crosswalk, CWExtract(proxy_server)), (WebDownload.BibleGateway, BGExtract(proxy_server)), (WebDownload.Bibleserver, BSExtract(proxy_server))): try: bibles = extractor.get_bibles_from_http() except (urllib.error.URLError, ConnectionError) as err: critical_error_message_box(translate('BiblesPlugin.ImportWizardForm', 'Error during download'), translate('BiblesPlugin.ImportWizardForm', 'An error occurred while downloading the list of bibles from %s.')) bibles = None if bibles: self.web_bible_list[download_type] = {} for (bible_name, bible_key, language_code) in bibles: self.web_bible_list[download_type][bible_name] = (bible_key, language_code) self.web_progress_bar.setValue(download_type + 1) # Update combo box if something got into the list if self.web_bible_list: self.on_web_source_combo_box_index_changed(0) self.web_source_combo_box.setEnabled(True) self.web_translation_combo_box.setEnabled(True) self.web_update_button.setEnabled(True) self.web_progress_bar.setVisible(False)
def get_books_from_http_no_soup_test(self): """ Test the get_books_from_http method when get_soup_for_bible_ref returns a falsey value """ # GIVEN: An instance of BSExtract, and reset log, urllib & get_soup_for_bible_ref mocks instance = BSExtract() self.mock_log.debug.reset_mock() self.mock_urllib.reset_mock() self.mock_get_soup_for_bible_ref.reset_mock() # WHEN: get_books_from_http is called with 'NIV' and get_soup_for_bible_ref returns a None value self.mock_urllib.parse.quote.return_value = 'NIV' self.mock_get_soup_for_bible_ref.return_value = None result = instance.get_books_from_http('NIV') # THEN: The rest mocks should be called with known values and get_books_from_http should return None self.mock_log.debug.assert_called_once_with('BSExtract.get_books_from_http("%s")', 'NIV') self.mock_urllib.parse.quote.assert_called_once_with(b'NIV') self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.assertIsNone(result, 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a ' 'false value')
def perform_wizard(self): """ Perform the actual upgrade. """ self.includeWebBible = False proxy_server = None if not self.files: self.progress_label.setText( translate('BiblesPlugin.UpgradeWizardForm', 'There are no Bibles that need to be upgraded.')) self.progress_bar.hide() return max_bibles = 0 for number, file in enumerate(self.files): if self.checkBox[number].checkState() == QtCore.Qt.Checked: max_bibles += 1 old_bible = None for number, filename in enumerate(self.files): # Close the previous bible's connection. if old_bible is not None: old_bible.close_connection() # Set to None to make obvious that we have already closed the # database. old_bible = None if self.stop_import_flag: self.success[number] = False break if not self.checkBox[number].checkState() == QtCore.Qt.Checked: self.success[number] = False continue self.progress_bar.reset() old_bible = OldBibleDB(self.media_item, path=self.temp_dir, file=filename[0]) name = filename[1] self.progress_label.setText( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nUpgrading ...') % (number + 1, max_bibles, name)) self.new_bibles[number] = BibleDB(self.media_item, path=self.path, name=name, file=filename[0]) self.new_bibles[number].register(self.plugin.upgrade_wizard) metadata = old_bible.get_metadata() web_bible = False meta_data = {} for meta in metadata: # Upgrade the names of the metadata keys if meta['key'] == 'Version': meta['key'] = 'name' if meta['key'] == 'Bookname language': meta['key'] = 'book_name_language' meta['key'] = meta['key'].lower().replace(' ', '_') # Copy the metadata meta_data[meta['key']] = meta['value'] if meta['key'] != 'name' and meta['key'] != 'dbversion': self.new_bibles[number].save_meta(meta['key'], meta['value']) if meta['key'] == 'download_source': web_bible = True self.includeWebBible = True proxy_server = meta.get('proxy_server') if web_bible: if meta_data['download_source'].lower() == 'crosswalk': handler = CWExtract(proxy_server) elif meta_data['download_source'].lower() == 'biblegateway': handler = BGExtract(proxy_server) elif meta_data['download_source'].lower() == 'bibleserver': handler = BSExtract(proxy_server) books = handler.get_books_from_http(meta_data['download_name']) if not books: log.error( 'Upgrading books from %s - download name: "%s" failed' % (meta_data['download_source'], meta_data['download_name'])) self.new_bibles[number].session.close() del self.new_bibles[number] critical_error_message_box( translate('BiblesPlugin.UpgradeWizardForm', 'Download Error'), translate( 'BiblesPlugin.UpgradeWizardForm', 'To upgrade your Web Bibles an Internet connection is required.' )) self.increment_progress_bar( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name), self.progress_bar.maximum() - self.progress_bar.value()) self.success[number] = False continue bible = BiblesResourcesDB.get_webbible( meta_data['download_name'], meta_data['download_source'].lower()) if bible and bible['language_id']: language_id = bible['language_id'] self.new_bibles[number].save_meta('language_id', language_id) else: language_id = self.new_bibles[number].get_language(name) if not language_id: log.warning('Upgrading from "%s" failed' % filename[0]) self.new_bibles[number].session.close() del self.new_bibles[number] self.increment_progress_bar( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name), self.progress_bar.maximum() - self.progress_bar.value()) self.success[number] = False continue self.progress_bar.setMaximum(len(books)) for book in books: if self.stop_import_flag: self.success[number] = False break self.increment_progress_bar( translate( 'BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nUpgrading %s ...') % (number + 1, max_bibles, name, book)) book_ref_id = self.new_bibles[number].\ get_book_ref_id_by_name(book, len(books), language_id) if not book_ref_id: log.warning( 'Upgrading books from %s - download name: "%s" aborted by user' % (meta_data['download_source'], meta_data['download_name'])) self.new_bibles[number].session.close() del self.new_bibles[number] self.success[number] = False break book_details = BiblesResourcesDB.get_book_by_id( book_ref_id) db_book = self.new_bibles[number].create_book( book, book_ref_id, book_details['testament_id']) # Try to import already downloaded verses. oldbook = old_bible.get_book(book) if oldbook: verses = old_bible.get_verses(oldbook['id']) if not verses: log.warning( 'No verses found to import for book "%s"', book) continue for verse in verses: if self.stop_import_flag: self.success[number] = False break self.new_bibles[number].create_verse( db_book.id, int(verse['chapter']), int(verse['verse']), str(verse['text'])) self.application.process_events() self.new_bibles[number].session.commit() else: language_id = self.new_bibles[number].get_object( BibleMeta, 'language_id') if not language_id: language_id = self.new_bibles[number].get_language(name) if not language_id: log.warning('Upgrading books from "%s" failed' % name) self.new_bibles[number].session.close() del self.new_bibles[number] self.increment_progress_bar( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name), self.progress_bar.maximum() - self.progress_bar.value()) self.success[number] = False continue books = old_bible.get_books() self.progress_bar.setMaximum(len(books)) for book in books: if self.stop_import_flag: self.success[number] = False break self.increment_progress_bar( translate( 'BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nUpgrading %s ...') % (number + 1, max_bibles, name, book['name'])) book_ref_id = self.new_bibles[ number].get_book_ref_id_by_name( book['name'], len(books), language_id) if not book_ref_id: log.warning( 'Upgrading books from %s " failed - aborted by user' % name) self.new_bibles[number].session.close() del self.new_bibles[number] self.success[number] = False break book_details = BiblesResourcesDB.get_book_by_id( book_ref_id) db_book = self.new_bibles[number].create_book( book['name'], book_ref_id, book_details['testament_id']) verses = old_bible.get_verses(book['id']) if not verses: log.warning('No verses found to import for book "%s"', book['name']) self.new_bibles[number].delete_book(db_book) continue for verse in verses: if self.stop_import_flag: self.success[number] = False break self.new_bibles[number].create_verse( db_book.id, int(verse['chapter']), int(verse['verse']), str(verse['text'])) self.application.process_events() self.new_bibles[number].session.commit() if not self.success.get(number, True): self.increment_progress_bar( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name), self.progress_bar.maximum() - self.progress_bar.value()) else: self.success[number] = True self.new_bibles[number].save_meta('name', name) self.increment_progress_bar( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nComplete') % (number + 1, max_bibles, name)) if number in self.new_bibles: self.new_bibles[number].session.close() # Close the last bible's connection if possible. if old_bible is not None: old_bible.close_connection()