bookwyrm/bookwyrm/tests/connectors/test_inventaire_connector.py

286 lines
9.9 KiB
Python
Raw Normal View History

2021-04-29 00:20:14 +00:00
""" testing book data connectors """
2021-04-29 15:35:37 +00:00
import json
import pathlib
from unittest.mock import patch
2021-04-29 00:20:14 +00:00
from django.test import TestCase
import responses
from bookwyrm import models
from bookwyrm.connectors.inventaire import Connector, get_language_code
from bookwyrm.connectors.connector_manager import ConnectorException
2021-04-29 00:20:14 +00:00
class Inventaire(TestCase):
"""test loading data from inventaire.io"""
@classmethod
def setUpTestData(cls):
"""creates the connector in the database"""
2021-04-29 00:20:14 +00:00
models.Connector.objects.create(
identifier="inventaire.io",
name="Inventaire",
connector_file="inventaire",
base_url="https://inventaire.io",
books_url="https://inventaire.io",
covers_url="https://covers.inventaire.io",
search_url="https://inventaire.io/search?q=",
isbn_search_url="https://inventaire.io/isbn",
)
def setUp(self):
"""connector instance"""
2021-04-29 00:20:14 +00:00
self.connector = Connector("inventaire.io")
@responses.activate
def test_get_book_data(self):
"""flattens the default structure to make it easier to parse"""
responses.add(
responses.GET,
"https://test.url/ok",
json={
"entities": {
"isbn:9780375757853": {
"claims": {
"wdt:P31": ["wd:Q3331189"],
},
"uri": "isbn:9780375757853",
}
},
"redirects": {},
},
)
result = self.connector.get_book_data("https://test.url/ok")
self.assertEqual(result["wdt:P31"], ["wd:Q3331189"])
self.assertEqual(result["uri"], "isbn:9780375757853")
2021-04-29 15:35:37 +00:00
@responses.activate
def test_get_book_data_invalid(self):
"""error if there isn't any entity data"""
responses.add(
responses.GET,
"https://test.url/ok",
json={
"entities": {},
"redirects": {},
},
)
with self.assertRaises(ConnectorException):
self.connector.get_book_data("https://test.url/ok")
2022-05-30 23:16:10 +00:00
def test_parse_search_data(self):
2021-04-29 15:35:37 +00:00
"""json to search result objs"""
search_file = pathlib.Path(__file__).parent.joinpath(
"../data/inventaire_search.json"
)
search_results = json.loads(search_file.read_bytes())
2022-05-31 00:00:34 +00:00
formatted = list(self.connector.parse_search_data(search_results, 0))[0]
2021-04-29 15:35:37 +00:00
self.assertEqual(formatted.title, "The Stories of Vladimir Nabokov")
self.assertEqual(
formatted.key, "https://inventaire.io?action=by-uris&uris=wd:Q7766679"
)
self.assertEqual(
formatted.cover,
2021-05-18 19:51:57 +00:00
"https://covers.inventaire.io/img/entities/ddb32",
2021-04-29 15:35:37 +00:00
)
2021-04-29 16:06:17 +00:00
def test_get_cover_url(self):
"""figure out where the cover image is"""
cover_blob = {"url": "/img/entities/d46a8"}
result = self.connector.get_cover_url(cover_blob)
self.assertEqual(result, "https://covers.inventaire.io/img/entities/d46a8")
cover_blob = {
2021-05-18 19:51:57 +00:00
"url": "https://commons.wikimedia.org/wiki/d.jpg?width=1000",
2021-04-29 16:06:17 +00:00
"file": "The Moonstone 1st ed.jpg",
"credits": {
"text": "Wikimedia Commons",
2021-05-18 19:51:57 +00:00
"url": "https://commons.wikimedia.org/wiki/File:The Moonstone.jpg",
2021-04-29 16:06:17 +00:00
},
}
result = self.connector.get_cover_url(cover_blob)
self.assertEqual(
result,
2021-05-18 19:51:57 +00:00
"https://commons.wikimedia.org/wiki/d.jpg?width=1000",
2021-04-29 16:06:17 +00:00
)
@responses.activate
def test_resolve_keys(self):
"""makes an http request"""
responses.add(
responses.GET,
"https://inventaire.io?action=by-uris&uris=wd:Q465821",
json={
"entities": {
"wd:Q465821": {
"type": "genre",
"labels": {
"nl": "briefroman",
"en": "epistolary novel",
"de-ch": "Briefroman",
"en-ca": "Epistolary novel",
"nb": "brev- og dagbokroman",
},
"descriptions": {
"en": "novel written as a series of documents",
"es": "novela escrita como una serie de documentos",
"eo": "romano en la formo de serio de leteroj",
},
},
"redirects": {},
}
},
)
responses.add(
responses.GET,
"https://inventaire.io?action=by-uris&uris=wd:Q208505",
json={
"entities": {
"wd:Q208505": {
"type": "genre",
"labels": {
"en": "crime novel",
},
},
}
},
)
keys = [
"wd:Q465821",
"wd:Q208505",
]
result = self.connector.resolve_keys(keys)
self.assertEqual(result, ["epistolary novel", "crime novel"])
2021-04-29 16:54:42 +00:00
2022-05-30 23:16:10 +00:00
def test_pase_isbn_search_data(self):
2021-04-29 16:56:35 +00:00
"""another search type"""
2021-04-29 16:54:42 +00:00
search_file = pathlib.Path(__file__).parent.joinpath(
"../data/inventaire_isbn_search.json"
)
search_results = json.loads(search_file.read_bytes())
2022-05-30 23:16:10 +00:00
formatted = list(self.connector.parse_isbn_search_data(search_results))[0]
2021-04-29 16:54:42 +00:00
self.assertEqual(formatted.title, "L'homme aux cercles bleus")
self.assertEqual(
2021-04-29 16:56:35 +00:00
formatted.key,
"https://inventaire.io?action=by-uris&uris=isbn:9782290349229",
2021-04-29 16:54:42 +00:00
)
self.assertEqual(
formatted.cover,
"https://covers.inventaire.io/img/entities/12345",
)
2022-05-30 23:16:10 +00:00
def test_parse_isbn_search_data_empty(self):
"""another search type"""
search_results = {}
2022-05-30 23:16:10 +00:00
results = list(self.connector.parse_isbn_search_data(search_results))
self.assertEqual(results, [])
def test_is_work_data(self):
"""is it a work"""
work_file = pathlib.Path(__file__).parent.joinpath(
"../data/inventaire_work.json"
)
work_data = json.loads(work_file.read_bytes())
with patch("bookwyrm.connectors.inventaire.get_data") as get_data_mock:
get_data_mock.return_value = work_data
formatted = self.connector.get_book_data("hi")
self.assertTrue(self.connector.is_work_data(formatted))
edition_file = pathlib.Path(__file__).parent.joinpath(
"../data/inventaire_edition.json"
)
edition_data = json.loads(edition_file.read_bytes())
with patch("bookwyrm.connectors.inventaire.get_data") as get_data_mock:
get_data_mock.return_value = edition_data
formatted = self.connector.get_book_data("hi")
self.assertFalse(self.connector.is_work_data(formatted))
@responses.activate
def test_get_edition_from_work_data(self):
"""load edition"""
responses.add(
responses.GET,
"https://inventaire.io/?action=by-uris&uris=hello",
json={"entities": {}},
)
data = {"uri": "blah"}
with (
patch(
"bookwyrm.connectors.inventaire.Connector.load_edition_data"
) as loader_mock,
patch(
"bookwyrm.connectors.inventaire.Connector.get_book_data"
) as getter_mock,
):
loader_mock.return_value = {"uris": ["hello"]}
self.connector.get_edition_from_work_data(data)
self.assertTrue(getter_mock.called)
with patch(
"bookwyrm.connectors.inventaire.Connector.load_edition_data"
) as loader_mock:
loader_mock.return_value = {"uris": []}
with self.assertRaises(ConnectorException):
self.connector.get_edition_from_work_data(data)
@responses.activate
def test_get_work_from_edition_data(self):
"""load work"""
responses.add(
responses.GET,
"https://inventaire.io/?action=by-uris&uris=hello",
)
2021-11-16 18:16:28 +00:00
data = {"wdt:P629": ["hello"]}
with patch("bookwyrm.connectors.inventaire.Connector.get_book_data") as mock:
self.connector.get_work_from_edition_data(data)
self.assertEqual(mock.call_count, 1)
args = mock.call_args[0]
self.assertEqual(args[0], "https://inventaire.io?action=by-uris&uris=hello")
2021-11-16 18:16:28 +00:00
data = {"wdt:P629": [None]}
with self.assertRaises(ConnectorException):
self.connector.get_work_from_edition_data(data)
def test_get_language_code(self):
2021-04-30 19:52:20 +00:00
"""get english or whatever is in reach"""
options = {
"de": "bip",
"en": "hi",
"fr": "there",
}
self.assertEqual(get_language_code(options), "hi")
options = {
"fr": "there",
}
self.assertEqual(get_language_code(options), "there")
self.assertIsNone(get_language_code({}))
2021-08-06 01:16:23 +00:00
@responses.activate
def test_get_description(self):
"""extract a wikipedia excerpt"""
responses.add(
responses.GET,
"https://inventaire.io/api/data?action=wp-extract&lang=en&title=test_path",
json={"extract": "hi hi"},
)
extract = self.connector.get_description({"enwiki": "test_path"})
self.assertEqual(extract, "hi hi")
2021-12-07 21:53:25 +00:00
def test_remote_id_from_model(self):
"""figure out a url from an id"""
obj = models.Author.objects.create(name="hello", inventaire_id="123")
self.assertEqual(
self.connector.get_remote_id_from_model(obj),
"https://inventaire.io?action=by-uris&uris=123",
)