Source code for search.services.tests.test_metadata

"""Tests for :mod:`search.services.metadata`."""

import unittest
from unittest import mock
import json
import os
from itertools import cycle

from search.services import metadata
from search.factory import create_ui_web_app


[docs]class TestRetrieveExistantMetadata(unittest.TestCase): """Metadata is available for a paper."""
[docs] @mock.patch('search.services.metadata.requests.get') def test_calls_metadata_endpoint(self, mock_get): """:func:`.metadata.retrieve` calls passed endpoint with GET.""" base = 'https://asdf.com/' app = create_ui_web_app() app.config['METADATA_ENDPOINT'] = base response = mock.MagicMock() with open('tests/data/docmeta.json') as f: mock_content = json.load(f) type(response).json = mock.MagicMock(return_value=mock_content) response.status_code = 200 mock_get.return_value = response with app.app_context(): docmeta_session = metadata.get_session() try: docmeta_session.retrieve('1602.00123') except Exception as e: self.fail('Choked on valid response: %s' % e) try: args, _ = mock_get.call_args except Exception as e: self.fail('Did not call requests.get as expected: %s' % e) self.assertTrue(args[0].startswith(base))
[docs] @mock.patch('search.services.metadata.requests.get') def test_calls_metadata_endpoint_roundrobin(self, mock_get): """:func:`.metadata.retrieve` calls passed endpoint with GET.""" base = ['https://asdf.com/', 'https://asdf2.com/'] app = create_ui_web_app() app.config['METADATA_ENDPOINT'] = ','.join(base) app.config['METADATA_VERIFY_CERT'] = 'False' response = mock.MagicMock() with open('tests/data/docmeta.json') as f: mock_content = json.load(f) type(response).json = mock.MagicMock(return_value=mock_content) response.status_code = 200 mock_get.return_value = response with app.app_context(): docmeta_session = metadata.get_session() try: docmeta_session.retrieve('1602.00123') except Exception as e: self.fail('Choked on valid response: %s' % e) try: args, _ = mock_get.call_args except Exception as e: self.fail('Did not call requests.get as expected: %s' % e) self.assertTrue( args[0].startswith(base[0]), "Expected call to %s" % base[0] ) try: docmeta_session.retrieve('1602.00124') except Exception as e: self.fail('Choked on valid response: %s' % e) try: args, _ = mock_get.call_args except Exception as e: self.fail('Did not call requests.get as expected: %s' % e) self.assertTrue( args[0].startswith(base[1]), "Expected call to %s" % base[1] )
[docs]class TestRetrieveNonexistantRecord(unittest.TestCase): """Metadata is not available for a paper."""
[docs] @mock.patch('search.services.metadata.requests.get') def test_raise_ioerror_on_404(self, mock_get): """:func:`.metadata.retrieve` raises IOError when unvailable.""" response = mock.MagicMock() type(response).json = mock.MagicMock(return_value=None) response.status_code = 404 mock_get.return_value = response with self.assertRaises(IOError): metadata.retrieve('1234.5678v3')
[docs] @mock.patch('search.services.metadata.requests.get') def test_raise_ioerror_on_503(self, mock_get): """:func:`.metadata.retrieve` raises IOError when unvailable.""" response = mock.MagicMock() type(response).json = mock.MagicMock(return_value=None) response.status_code = 503 mock_get.return_value = response with self.assertRaises(IOError): metadata.retrieve('1234.5678v3')
[docs] @mock.patch('search.services.metadata.requests.get') def test_raise_ioerror_on_sslerror(self, mock_get): """:func:`.metadata.retrieve` raises IOError when SSL fails.""" from requests.exceptions import SSLError mock_get.side_effect = SSLError with self.assertRaises(IOError): try: metadata.retrieve('1234.5678v3') except Exception as e: if type(e) is SSLError: self.fail('Should not return dependency exception') raise
[docs]class TestRetrieveMalformedRecord(unittest.TestCase): """Metadata endpoint returns non-JSON response."""
[docs] @mock.patch('search.services.metadata.requests.get') def test_response_is_not_json(self, mock_get): """:func:`.metadata.retrieve` raises IOError when not valid JSON.""" from json.decoder import JSONDecodeError response = mock.MagicMock() # Ideally we would pass the exception itself as a side_effect, but it # doesn't have the expected signature. def raise_decodeerror(*args, **kwargs): raise JSONDecodeError('Nope', 'Nope', 0) type(response).json = mock.MagicMock(side_effect=raise_decodeerror) response.status_code = 200 mock_get.return_value = response with self.assertRaises(IOError): metadata.retrieve('1234.5678v3')