diff --git a/core/opds2_import.py b/core/opds2_import.py index 28f3e1cd6..62e39a08c 100644 --- a/core/opds2_import.py +++ b/core/opds2_import.py @@ -438,9 +438,8 @@ def _extract_contributors( roles=contributor.roles if contributor.roles else default_role, ) # If the feed is missing contributor name information, record the information to our metadata - if ( - contributor_metadata.sort_name is None - and contributor_metadata.display_name is None + if not ( + contributor_metadata.sort_name or contributor_metadata.display_name ): contributor_metadata.sort_name = Edition.UNKNOWN_AUTHOR contributor_metadata.display_name = Edition.UNKNOWN_AUTHOR diff --git a/tests/core/files/opds2/feed.json b/tests/core/files/opds2/feed.json index affd46455..415c07dec 100644 --- a/tests/core/files/opds2/feed.json +++ b/tests/core/files/opds2/feed.json @@ -275,6 +275,76 @@ "width": 800 } ] + }, + { + "metadata": { + "@type": "http://schema.org/Book", + "title": "Test Book with author empty string", + "author": { + "name": "" + }, + "description": "Test Book description with author empty string", + "identifier": "urn:isbn:978-0-06-112008-4", + "language": [ + "eng" + ], + "publisher": { + "name": "Test Publisher" + }, + "published": "2014-09-28T00:00:00Z", + "modified": "2015-09-29T17:00:00Z", + "subject": [ + { + "scheme": "http://schema.org/audience", + "code": "juvenile-fiction", + "name": "Juvenile Fiction", + "links": [] + } + ] + }, + "links": [ + { + "type": "application/opds-publication+json", + "rel": "http://opds-spec.org/acquisition/borrow", + "href": "http://example.org/huckleberry-finn", + "properties": { + "availability": { + "state": "available" + }, + "indirectAcquisition": [ + { + "type": "application/vnd.adobe.adept+xml", + "child": [ + { + "type": "application/epub+zip" + } + ] + }, + { + "type": "application/vnd.readium.lcp.license.v1.0+json", + "child": [ + { + "type": "application/epub+zip" + } + ] + } + ] + } + }, + { + "rel": "http://opds-spec.org/acquisition/sample", + "type": "application/epub+zip", + "href": "https://example.com/medias/e5/318061475b11cf8c8e3752da2a1cf68384d8bf.epub" + } + ], + "images": [ + { + "href": "http://example.org/cover.jpg", + "type": "image/jpeg", + "height": 1400, + "width": 800 + } + ] } ] } diff --git a/tests/core/test_opds2_import.py b/tests/core/test_opds2_import.py index dd60e0f2f..0f54ef328 100644 --- a/tests/core/test_opds2_import.py +++ b/tests/core/test_opds2_import.py @@ -123,6 +123,7 @@ class TestOPDS2Importer(OPDS2Test): "urn:librarysimplified.org/terms/id/ProQuest%20Doc%20ID/181639" ) BOOK_WITHOUT_AUTHOR_IDENTIFIER = "urn:isbn:9789523565593" + BOOK_AUTHOR_EMPTY_STRING_IDENTIFIER = "urn:isbn:978-0-06-112008-4" @pytest.mark.parametrize( "name,manifest_type", @@ -164,7 +165,7 @@ def test_opds2_importer_correctly_imports_valid_opds2_feed( # 1. Make sure that editions contain all required metadata assert isinstance(imported_editions, list) - assert 4 == len(imported_editions) + assert 5 == len(imported_editions) # 1.1. Edition with open-access links (Moby-Dick) moby_dick_edition = self._get_edition_by_identifier( @@ -258,7 +259,7 @@ def test_opds2_importer_correctly_imports_valid_opds2_feed( # 2. Make sure that license pools have correct configuration assert isinstance(pools, list) - assert 4 == len(pools) + assert 5 == len(pools) # 2.1. Edition with open-access links (Moby-Dick) moby_dick_license_pool = self._get_license_pool_by_identifier( @@ -365,7 +366,7 @@ def test_opds2_importer_correctly_imports_valid_opds2_feed( # 3. Make sure that work objects contain all the required metadata assert isinstance(works, list) - assert 4 == len(works) + assert 5 == len(works) # 3.1. Work (Moby-Dick) moby_dick_work = self._get_work_by_identifier( @@ -390,7 +391,7 @@ def test_opds2_importer_correctly_imports_valid_opds2_feed( == huckleberry_finn_work.summary_text ) - # 4.1 Author name is null + # 4.1 Author name is null or empty string edition_author_null = self._get_edition_by_identifier( imported_editions, self.BOOK_WITHOUT_AUTHOR_IDENTIFIER ) @@ -408,6 +409,12 @@ def test_opds2_importer_correctly_imports_valid_opds2_feed( assert isinstance(book_without_author, Work) assert "[Unknown]" == book_without_author.author + edition_author_empty_string = self._get_edition_by_identifier( + imported_editions, self.BOOK_AUTHOR_EMPTY_STRING_IDENTIFIER + ) + assert isinstance(edition_author_empty_string, Edition) + assert "[Unknown]" == edition_author_empty_string.author + @pytest.mark.parametrize( "this_identifier_type,ignore_identifier_type,identifier", [ @@ -473,7 +480,7 @@ def test_opds2_importer_skips_publications_with_unsupported_identifier_types( assert isinstance(imported_editions, list) if this_identifier_type == IdentifierType.ISBN: - assert 2 == len(imported_editions) + assert 3 == len(imported_editions) assert ( imported_editions[0].primary_identifier.type == this_identifier_type.value