Ejemplo n.º 1
0
def test_handles_wrongly_formatted_response(
        mocker, esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{'references': ['John.1.1'], 'words': []}])
    mock_response(mocker, lambda: {'wrong': 'keys'})
    with pytest.raises(ProbableBugError) as excinfo:
        esv_provider.add_translations(result)
    assert excinfo.value.message == 'Could not understand response from ESV API'
Ejemplo n.º 2
0
def test_handles_wrongly_formatted_query_result(
        mocker, esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{'references': [], 'words': []}])
    mock_response(mocker, lambda: None)
    with pytest.raises(ProbableBugError) as excinfo:
        esv_provider.add_translations(result)
    assert excinfo.value.message == 'Result has no references'
Ejemplo n.º 3
0
def test_chunks_translation_api_requests_by_verse_number(
        mocker, esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{
        'references': ['John.1.1'],
        'words': []
    } for _ in range(900)])
    mock_get = mock_response(
        mocker, lambda: {'passages': ['text of John.1.1' for _ in range(300)]})
    esv_provider.add_translations(result)
    assert mock_get.call_count == 3
Ejemplo n.º 4
0
def test_includes_proper_request_params(
        mocker, esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{'references': ['John.1.1'], 'words': []}])
    mock_get = mock_response(mocker, lambda: {'passages': ['text']})
    esv_provider.add_translations(result)
    get_params = mock_get.call_args.kwargs['params']
    assert get_params['include-passage-references'] == 'false'
    assert get_params['include-verse-numbers'] == 'false'
    assert get_params['include-first-verse-numbers'] == 'false'
    assert get_params['include-footnotes'] == 'false'
    assert get_params['include-headings'] == 'false'
    assert get_params['include-short-copyright'] == 'true'
    assert get_params['indent-paragraphs'] == '0'
Ejemplo n.º 5
0
def test_handles_content_type_error(mocker,
                                    esv_provider: ESVApiTranslationProvider):
    mock_exception = make_mock_exception(mocker, 'aiohttp.ContentTypeError')

    def raise_mock_exception():
        raise mock_exception

    mock_response(mocker, raise_mock_exception)

    result = query_result_for_json([{'references': ['John.1.1'], 'words': []}])
    with pytest.raises(ServerOverwhelmedError) as excinfo:
        esv_provider.add_translations(result)
    assert excinfo.value.message == 'ESV API did not return JSON'
Ejemplo n.º 6
0
def test_handles_quota_exceeded(mocker,
                                esv_provider: ESVApiTranslationProvider):
    mock_exception = make_mock_exception(mocker, 'aiohttp.ClientResponseError')
    mock_exception.status = 502

    def raise_mock_exception():
        raise mock_exception

    mock_response(mocker, raise_mock_exception)

    result = query_result_for_json([{'references': ['John.1.1'], 'words': []}])
    with pytest.raises(ServerOverwhelmedError) as excinfo:
        esv_provider.add_translations(result)
    assert excinfo.value.message == 'ESV API quota exceeded'
Ejemplo n.º 7
0
def test_chunks_translation_api_request_by_query_string_length(
        mocker, esv_provider: ESVApiTranslationProvider):
    long_reference = ''.join(['a' for _ in range(3861)]) + '.1.1'
    result = query_result_for_json([
        {
            'references': [long_reference],
            'words': [],
        },
        {
            'references': [long_reference],
            'words': [],
        },
    ])
    mock_get = mock_response(mocker, lambda: {'passages': ['text']})
    esv_provider.add_translations(result)
    assert mock_get.call_count == 2
Ejemplo n.º 8
0
def test_properly_formats_verse_query_string(
        mocker, esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{
        'references': ['Mark.1.1'],
        'words': []
    }, {
        'references': ['Matt.1.1', 'Matt.1.2'],
        'words': []
    }, {
        'references': ['John.1.1', 'John.1.2', 'John.1.3'],
        'words': []
    }])
    mock_get = mock_response(mocker,
                             lambda: {'passages': ['text' for _ in range(3)]})
    esv_provider.add_translations(result)
    get_params = mock_get.call_args.kwargs['params']
    assert get_params['q'] == 'Mark.1.1;Matt.1.1-Matt.1.2;John.1.1-John.1.3'
Ejemplo n.º 9
0
def test_gets_translations_for_few_results(
        mocker, esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{
        'references': ['Mark.1.1'],
        'words': []
    }, {
        'references': ['Matt.1.1', 'Matt.1.2'],
        'words': []
    }])
    mock_response(
        mocker, lambda:
        {'passages': [
            'text of Mark.1.1',
            'text of Matt.1.1-Matt.1.2',
        ]})
    esv_provider.add_translations(result)
    assert result.passages[0].translation == 'text of Mark.1.1'
    assert result.passages[1].translation == 'text of Matt.1.1-Matt.1.2'
Ejemplo n.º 10
0
from flask_limiter import Limiter
from typing import Any, Dict, Union
from translation_providers.ESVApiTranslationProvider import ESVApiTranslationProvider
from text_providers.Nestle1904LowfatProvider import Nestle1904LowfatProvider
from text_providers.TextProvider import TextProvider
from werkzeug.http import HTTP_STATUS_CODES
from AnoixoError import AnoixoError, ProbableBugError, TooManyRequestsError
from TextQuery import TextQuery
from translation_providers.TranslationProvider import TranslationProvider

app = Flask(__name__)
CORS(app)

text_providers: Dict[str, TextProvider] = {'nlf': Nestle1904LowfatProvider()}
translation_providers: Dict[str, TranslationProvider] = {
    'esv': ESVApiTranslationProvider()
}


def _get_address_for_request():
    """
    In the default Nginx configuration for Anoixo, this Flask server is behind a proxy, and Nginx sets a 'X-Real-Ip'
    header with the original remote address whenever it forwards requests to Flask.

    If that header is not present (e.g. in a testing/development situation where a proxy server isn't set up), we are
    presumably not behind a proxy and can just use the original remote address.

    Please note this system means that IP addresses can be easily spoofed if the app is deployed NOT behind a proxy! All
    the spoofer would need to do is set a bogus X-Real-Ip header. So please make sure to deploy Anoixo behind a proxy
    in production environments.
Ejemplo n.º 11
0
def test_requests_proper_endpoint(mocker,
                                  esv_provider: ESVApiTranslationProvider):
    result = query_result_for_json([{'references': ['John.1.1'], 'words': []}])
    mock_get = mock_response(mocker, lambda: {'passages': ['text']})
    esv_provider.add_translations(result)
    assert mock_get.call_args.args[0] == 'https://api.esv.org/v3/passage/text'
Ejemplo n.º 12
0
def esv_provider():
    return ESVApiTranslationProvider()