Example #1
0
def es_app(request):
    """Flask application with records fixture."""
    app = Flask(__name__)
    app.config.update(
        JSONSCHEMAS_ENDPOINT='/',
        JSONSCHEMAS_HOST='http://localhost:5000',
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
    )

    Babel(app)
    if not hasattr(app, 'cli'):
        from flask_cli import FlaskCLI
        FlaskCLI(app)
    InvenioDB(app)
    InvenioRecords(app)
    InvenioMARC21(app)
    search = InvenioSearch(app)
    InvenioIndexer(app)
    InvenioJSONSchemas(app)

    with app.app_context():
        db.create_all()
        list(search.create())
        sleep(10)

    def teardown():
        with app.app_context():
            db.drop_all()
            list(search.delete())

    request.addfinalizer(teardown)

    return app
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app_ = Flask(__name__, instance_path=instance_path)
    app_.config.update(
        FILES_REST_PERMISSION_FACTORY=lambda *a, **kw: type(
            'Allow', (object, ), {'can': lambda self: True}
        )(),
        SECRET_KEY='CHANGE_ME',
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI', 'sqlite://'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )
    app_.register_blueprint(files_rest_blueprint)
    InvenioDB(app_)
    InvenioRecords(app_)
    InvenioFilesREST(app_)
    InvenioIndexer(app_)
    search = InvenioSearch(app_)
    search.register_mappings('records-files', 'data')

    with app_.app_context():
        yield app_

    shutil.rmtree(instance_path)
def test_client_reference():
    """Test client reference."""
    client1 = {'name': 'client1'}
    client2 = {'name': 'client2'}

    app1 = Flask('testapp1')
    FlaskCLI(app1)
    app2 = Flask('testapp2')
    FlaskCLI(app2)

    ext = InvenioSearch()
    assert 'invenio-search' not in app1.extensions
    assert 'invenio-search' not in app2.extensions

    ext.init_app(app1, elasticsearch=client1)
    assert 'invenio-search' in app1.extensions

    ext.init_app(app2, elasticsearch=client2)
    assert 'invenio-search' in app2.extensions

    with app1.app_context():
        assert current_search_client == client1

    with app2.app_context():
        assert current_search_client == client2
def test_percolator(app, request):
    """Test percolator."""
    def teardown():
        with app.app_context():
            current_collections.unregister_signals()
            list(current_search.delete())

    request.addfinalizer(teardown)

    with app.test_request_context():
        app.config.update(
            COLLECTIONS_USE_PERCOLATOR=True,
            SEARCH_ELASTIC_KEYWORD_MAPPING={None: ['_all']},
        )

        search = InvenioSearch(app)
        search.register_mappings('records', 'data')

        InvenioIndexer(app)

        current_collections.unregister_signals()
        current_collections.register_signals()

        list(current_search.create())

        _try_populate_collections()
def app():
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND='cache',
        JSONSCHEMAS_HOST='inveniosoftware.org',
        TESTING=True,
        SECRET_KEY='CHANGE_ME',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite://'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='app',
        OAISERVER_RECORD_INDEX='_all',
        # Disable set signals because the celery tasks cannot be run
        # synchronously
        OAISERVER_REGISTER_SET_SIGNALS=False,
        SEARCH_ELASTIC_KEYWORD_MAPPING={None: ['_all']},
    )
    if not hasattr(app, 'cli'):
        from flask_cli import FlaskCLI
        FlaskCLI(app)
    InvenioDB(app)
    FlaskCeleryExt(app)
    InvenioJSONSchemas(app)
    InvenioRecords(app)
    InvenioPIDStore(app)
    InvenioMARC21(app)
    client = Elasticsearch(hosts=[os.environ.get('ES_HOST', 'localhost')])
    search = InvenioSearch(app, client=client)
    search.register_mappings('records', 'data')
    InvenioIndexer(app)
    InvenioOAIServer(app)

    app.register_blueprint(blueprint)

    with app.app_context():
        if str(db.engine.url) != 'sqlite://' and \
           not database_exists(str(db.engine.url)):
                create_database(str(db.engine.url))
        db.create_all()
        list(search.create(ignore=[400]))
        sleep(5)

    with app.app_context():
        yield app

    with app.app_context():
        db.session.close()
        if str(db.engine.url) != 'sqlite://':
            drop_database(str(db.engine.url))
        list(search.delete(ignore=[404]))
    shutil.rmtree(instance_path)
def test_init():
    """Test extension initialization."""
    app = Flask('testapp')
    ext = InvenioSearch(app)
    assert 'invenio-search' in app.extensions

    app = Flask('testapp')
    ext = InvenioSearch()
    assert 'invenio-search' not in app.extensions
    ext.init_app(app)
    assert 'invenio-search' in app.extensions
Example #7
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        TESTING=True,
        SECRET_KEY='CHANGE_ME',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite://'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='app',
        OAISERVER_RECORD_INDEX='records-record-v1.0.0',
        OAISERVER_METADATA_FORMATS={
            'oai_dc': {
                'serializer': (
                    'conftest:dump_etree',
                    {
                        'xslt_filename': pkg_resources.resource_filename(
                            'invenio_oaiserver', 'static/xsl/oai2.v1.0.xsl')
                    }
                ),
                'schema': 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd',
                'namespace': 'http://www.openarchives.org/OAI/2.0/oai_dc/',
            }
        },
    )
    FlaskCLI(app)
    InvenioDB(app)
    InvenioRecords(app)
    InvenioPIDStore(app)
    search = InvenioSearch(app)
    search.register_mappings('records', 'data')
    InvenioIndexer(app)
    InvenioOAIServer(app)

    with app.app_context():
        db.create_all()
        search.client.indices.delete_alias('_all', '_all', ignore=[400, 404])
        search.client.indices.delete('*')
        list(search.create(ignore=[400]))

    def teardown():
        with app.app_context():
            list(search.delete(ignore=[404]))
            db.drop_all()
        shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    return app
Example #8
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND='cache',
        TESTING=True,
        SECRET_KEY='CHANGE_ME',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite://'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='app',
        OAISERVER_RECORD_INDEX='_all',
        # Disable set signals because the celery tasks cannot be run
        # synchronously
        OAISERVER_REGISTER_SET_SIGNALS=False,
        SEARCH_ELASTIC_KEYWORD_MAPPING={None: ['_all']},
    )

    FlaskCLI(app)
    InvenioDB(app)
    FlaskCeleryExt(app)
    InvenioRecords(app)
    InvenioPIDStore(app)
    InvenioMARC21(app)
    client = Elasticsearch(hosts=[os.environ.get('ES_HOST', 'localhost')])
    search = InvenioSearch(app, client=client)
    search.register_mappings('records', 'data')
    InvenioIndexer(app)
    InvenioOAIServer(app)

    with app.app_context():
        db.create_all()
        list(search.create(ignore=[400]))
        sleep(5)

    def teardown():
        with app.app_context():
            list(search.delete(ignore=[404]))
            db.drop_all()
        shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    return app
def test_load_entry_point_group():
    """Test entry point loading."""
    app = Flask('testapp')
    ext = InvenioSearch(app)
    ep_group = 'test'

    def mock_entry_points(group=None):
        assert group == ep_group

        class ep(object):

            name = 'records'
            module_name = 'data'

        yield ep

    assert len(ext.mappings) == 0
    with patch('invenio_search.ext.iter_entry_points', mock_entry_points):
        ext.load_entry_point_group(entry_point_group=ep_group)
    assert len(ext.mappings) == 3
Example #10
0
def es(app):
    """Provide elasticsearch access."""
    InvenioSearch(app)
    try:
        list(current_search.create())
    except RequestError:
        list(current_search.delete(ignore=[404]))
        list(current_search.create(ignore=[400]))
    current_search_client.indices.refresh()
    yield current_search_client
    list(current_search.delete(ignore=[404]))
def test_load_entry_point_group():
    """Test entry point loading."""
    app = Flask('testapp')
    ext = InvenioSearch(app)
    ep_group = 'test'

    def mock_entry_points(group=None):
        assert group == ep_group

        class ep(object):

            name = 'records'
            module_name = 'data'

        yield ep

    assert len(ext.mappings) == 0
    with patch('invenio_search.ext.iter_entry_points', mock_entry_points):
        ext.load_entry_point_group(entry_point_group=ep_group)
    assert len(ext.mappings) == 3
Example #12
0
def app_deposit():
    """App configuration for using InvenioDeposit."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        TESTING=True,
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND='cache',
        JSONSCHEMAS_URL_SCHEME='http',
        SECRET_KEY='CHANGE_ME',
        SECURITY_PASSWORD_SALT='CHANGE_ME_ALSO',
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SQLALCHEMY_ECHO=False,
        WTF_CSRF_ENABLED=False,
        DEPOSIT_SEARCH_API='/api/search',
        SECURITY_PASSWORD_HASH='plaintext',
        SECURITY_PASSWORD_SCHEMES=['plaintext'],
        SECURITY_DEPRECATED_PASSWORD_SCHEMES=[],
        OAUTHLIB_INSECURE_TRANSPORT=True,
        OAUTH2_CACHE_TYPE='simple',
    )
    app.url_map.converters['pid'] = PIDConverter
    Babel(app)
    FlaskCeleryExt(app)
    InvenioDB(app)
    Breadcrumbs(app)
    InvenioAccounts(app)
    InvenioAccess(app)
    app.register_blueprint(accounts_blueprint)
    InvenioAssets(app)
    InvenioJSONSchemas(app)
    InvenioRecords(app)
    app.url_map.converters['pid'] = PIDConverter
    InvenioRecordsREST(app)
    InvenioPIDStore(app)
    InvenioIndexer(app)
    InvenioDeposit(app)
    InvenioSearchUI(app)
    InvenioRecordsUI(app)
    InvenioFilesREST(app)
    OAuth2Provider(app)
    InvenioOAuth2Server(app)
    InvenioOAuth2ServerREST(app)
    app.register_blueprint(oauth2server_settings_blueprint)
    InvenioDepositREST(app)
    InvenioSSE(app)
    InvenioSearch(app)

    with app.app_context():
        yield app
Example #13
0
def test_client_config():
    """Test Elasticsearch client configuration."""
    app = Flask('testapp')
    app.config['SEARCH_CLIENT_CONFIG'] = {'timeout': 30, 'foo': 'bar'}
    with patch('elasticsearch.Elasticsearch.__init__') as mock_es_init:
        mock_es_init.return_value = None
        ext = InvenioSearch(app)
        es_client = ext.client  # trigger client initialization
        mock_es_init.assert_called_once_with(
            hosts=None, connection_class=RequestsHttpConnection,
            timeout=30, foo='bar')
def test_load_entry_point_group(template_entrypoints):
    """Test entry point loading."""
    app = Flask("testapp")
    ext = InvenioSearch(app)
    ep_group = "test"

    def mock_entry_points_mappings(group=None):
        assert group == ep_group

        class ep(object):

            name = "records"
            module_name = "mock_module.mappings"

        yield ep

    assert len(ext.mappings) == 0
    with patch("invenio_search.ext.iter_entry_points",
               mock_entry_points_mappings):
        ext.load_entry_point_group_mappings(
            entry_point_group_mappings=ep_group)
    assert len(ext.mappings) == 3
    # Check that mappings are loaded from the correct folder depending on the
    # ES version.
    if ES_VERSION[0] > 2:
        mappings_dir = "mock_module/mappings/v{}/records".format(ES_VERSION[0])
        assert all(mappings_dir in path for path in ext.mappings.values())

    with patch(
            "invenio_search.ext.iter_entry_points",
            return_value=template_entrypoints("invenio_search.templates"),
    ):
        if ES_VERSION[0] == 2:
            assert set(ext.templates.keys()) == {
                "subdirectory-file-download-v1",
                "record-view-v1",
            }
        elif ES_VERSION[0] == 5:
            assert set(ext.templates.keys()) == {
                "record-view-v{}".format(ES_VERSION[0])
            }
def es(app):
    """Provide elasticsearch access."""
    app.config.update(dict(SEARCH_AUTOINDEX=[], ))
    InvenioSearch(app)
    with app.app_context():
        try:
            list(current_search.create())
        except RequestError:
            list(current_search.delete(ignore=[404]))
            list(current_search.create())
        yield current_search
        list(current_search.delete(ignore=[404]))
def test_bibliographic_data(es_app):
    """Test indexation using bibliographic data."""
    search = InvenioSearch(es_app)
    search.create()
    indexer = RecordIndexer()
    with es_app.test_request_context():
        data_filename = pkg_resources.resource_filename(
            'invenio_records', 'data/marc21/bibliographic.xml')
        records_data = load(data_filename)
        records = []
        for item in records_data:
            record = Record.create(item)
            record['$schema'] = "mappings/marc21_holdings.json"
            es_record = indexer.index(record)
            records.append(es_record)

    for record in records:
        search.client.get(index=record['_index'],
                          doc_type=record['_type'],
                          id=record['_id'])
    search.delete()
Example #17
0
def app(request):
    """Test mdcobject."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)

    app.config.update(ACCOUNTS_JWT_ENABLE=False,
                      INDEXER_DEFAULT_DOC_TYPE='record-v1.0.0',
                      RECORDS_REST_ENDPOINTS={},
                      RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY=None,
                      RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY=None,
                      RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY=None,
                      RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY=None,
                      SERVER_NAME='localhost:5000',
                      JSONSCHEMAS_HOST='localhost:5000',
                      CELERY_ALWAYS_EAGER=True,
                      CELERY_RESULT_BACKEND='cache',
                      CELERY_CACHE_BACKEND='memory',
                      FLASK_TAXONOMIES_URL_PREFIX='/2.0/taxonomies/',
                      CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
                      SQLALCHEMY_DATABASE_URI=os.environ.get(
                          'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
                      SQLALCHEMY_TRACK_MODIFICATIONS=True,
                      SUPPORTED_LANGUAGES=["cs", "en"],
                      TESTING=True,
                      ELASTICSEARCH_DEFAULT_LANGUAGE_TEMPLATE={
                          "type": "text",
                          "fields": {
                              "keywords": {
                                  "type": "keyword"
                              }
                          }
                      })

    app.secret_key = 'changeme'

    InvenioDB(app)
    OarepoTaxonomies(app)
    OARepoReferences(app)
    InvenioRecords(app)
    InvenioJSONSchemas(app)
    InvenioPIDStore(app)
    InvenioSearch(app)
    InvenioIndexer(app)
    OARepoMappingIncludesExt(app)

    #
    app_loaded.send(app, app=app)

    with app.app_context():
        yield app

    # Teardown instance path.
    shutil.rmtree(instance_path)
def test_client_reference():
    """Test client reference."""
    client1 = {'name': 'client1'}
    client2 = {'name': 'client2'}

    app1 = Flask('testapp1')
    FlaskCLI(app1)
    app2 = Flask('testapp2')
    FlaskCLI(app2)

    ext = InvenioSearch()
    assert 'invenio-search' not in app1.extensions
    assert 'invenio-search' not in app2.extensions

    ext.init_app(app1, client=client1)
    assert 'invenio-search' in app1.extensions

    ext.init_app(app2, client=client2)
    assert 'invenio-search' in app2.extensions

    with app1.app_context():
        assert current_search_client == client1

    with app2.app_context():
        assert current_search_client == client2
Example #19
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()

    app_ = Flask(__name__, instance_path=instance_path)
    app_.config.update(
        SQLALCHEMY_DATABASE_URI=os.getenv(
            'SQLALCHEMY_DATABASE_URI',
            'postgresql+psycopg2://localhost/circulation_test'),
        OAUTH2SERVER_CLIENT_ID_SALT_LEN=40,
        OAUTH2SERVER_CLIENT_SECRET_SALT_LEN=60,
        OAUTH2SERVER_TOKEN_PERSONAL_SALT_LEN=60,
        SECRET_KEY='changeme',
        SERVER_NAME='localhost:5000',
        REPLACE_REFS=False,
        TESTING=True,
        CIRCULATION_ACTION_LOAN_URL=(
            '/hooks/receivers/circulation_loan/events/'),
        CIRCULATION_ACTION_REQUEST_URL=(
            '/hooks/receivers/circulation_request/events/'),
        CIRCULATION_ACTION_RETURN_URL=(
            '/hooks/receivers/circulation_return/events/'),
    )

    app_.url_map.converters['pid'] = PIDConverter

    Babel(app_)
    Menu(app_)
    Breadcrumbs(app_)
    InvenioAccounts(app_)
    InvenioAssets(app_)
    InvenioDB(app_)
    InvenioIndexer(app_)
    InvenioJSONSchemas(app_)
    InvenioPIDStore(app_)
    InvenioRecords(app_)
    InvenioRecordsREST(app_)
    InvenioWebhooks(app_)
    InvenioOAuth2Server(app_)
    InvenioCirculation(app_)
    InvenioCirculationREST(app_)
    InvenioSearch(app_)

    app_.register_blueprint(server_blueprint)
    app_.register_blueprint(settings_blueprint)
    app_.register_blueprint(webhooks_blueprint)
    app_.register_blueprint(circulation_blueprint)

    with app_.app_context():
        yield app_

    shutil.rmtree(instance_path)
Example #20
0
def app():
    """Flask application fixture."""
    # Set temporary instance path for sqlite
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(TESTING=True)
    InvenioSearch(app)

    with app.app_context():
        yield app

    # Teardown instance path.
    shutil.rmtree(instance_path)
Example #21
0
 def init_app(app_):
     app_.config.update(
         CELERY_ALWAYS_EAGER=True,
         CELERY_CACHE_BACKEND='memory',
         CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
         CELERY_RESULT_BACKEND='cache',
         JSONSCHEMAS_URL_SCHEME='http',
         SECRET_KEY='CHANGE_ME',
         SECURITY_PASSWORD_SALT='CHANGE_ME_ALSO',
         SQLALCHEMY_DATABASE_URI=os.environ.get(
             'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
         SQLALCHEMY_TRACK_MODIFICATIONS=True,
         SQLALCHEMY_ECHO=False,
         TESTING=True,
         WTF_CSRF_ENABLED=False,
         DEPOSIT_SEARCH_API='/api/search',
         SECURITY_PASSWORD_HASH='plaintext',
         SECURITY_PASSWORD_SCHEMES=['plaintext'],
         SECURITY_DEPRECATED_PASSWORD_SCHEMES=[],
         OAUTHLIB_INSECURE_TRANSPORT=True,
         OAUTH2_CACHE_TYPE='simple',
         ACCOUNTS_JWT_ENABLE=False,
     )
     Babel(app_)
     FlaskCeleryExt(app_)
     Breadcrumbs(app_)
     OAuth2Provider(app_)
     InvenioDB(app_)
     InvenioAccounts(app_)
     InvenioAccess(app_)
     InvenioIndexer(app_)
     InvenioJSONSchemas(app_)
     InvenioOAuth2Server(app_)
     InvenioFilesREST(app_)
     InvenioPIDStore(app_)
     InvenioRecords(app_)
     search = InvenioSearch(app_)
     search.register_mappings('deposits', 'invenio_deposit.mappings')
def base_app(base_app):
    """Flask base application fixture."""
    base_app.url_map.converters['pid'] = PIDConverter
    InvenioDB(base_app)
    InvenioRecords(base_app)
    InvenioRecordsREST(base_app)
    InvenioPIDStore(base_app)
    InvenioIndexer(base_app)
    InvenioPIDStore(base_app)
    InvenioSearch(base_app)
    InvenioCirculation(base_app)
    InvenioJSONSchemas(base_app)
    base_app.register_blueprint(create_blueprint_from_app(base_app))
    yield base_app
Example #23
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        BROKER_URL=os.environ.get('BROKER_URL', 'memory://'),
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND="memory",
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND="cache",
        INDEXER_DEFAULT_INDEX='records-default-v1.0.0',
        INDEXER_DEFAULT_DOC_TYPE='default-v1.0.0',
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )
    FlaskCLI(app)
    FlaskCeleryExt(app)
    InvenioDB(app)
    InvenioRecords(app)
    search = InvenioSearch(app, entry_point_group=None)
    search.register_mappings('records', 'data')
    InvenioIndexer(app)

    with app.app_context():
        if not database_exists(str(db.engine.url)):
            create_database(str(db.engine.url))
        db.create_all()

    def teardown():
        with app.app_context():
            drop_database(str(db.engine.url))
        shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    return app
Example #24
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        BROKER_URL=os.environ.get('BROKER_URL', 'memory://'),
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND="memory",
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND="cache",
        INDEXER_DEFAULT_INDEX='records-default-v1.0.0',
        INDEXER_DEFAULT_DOC_TYPE='default-v1.0.0',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )
    FlaskCLI(app)
    FlaskCeleryExt(app)
    InvenioDB(app)
    InvenioRecords(app)
    search = InvenioSearch(app)
    search.register_mappings('records', 'data')
    InvenioIndexer(app)

    with app.app_context():
        if not database_exists(str(db.engine.url)):
            create_database(str(db.engine.url))
        db.create_all()

    def teardown():
        with app.app_context():
            drop_database(str(db.engine.url))
        shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    return app
Example #25
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app_ = Flask(__name__, instance_path=instance_path)
    app_.config.update(
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND='cache',
        SECRET_KEY='CHANGE_ME',
        SECURITY_PASSWORD_SALT='CHANGE_ME_ALSO',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
        WTF_CSRF_ENABLED=False,
        SECURITY_PASSWORD_HASH='plaintext',
        SECURITY_PASSWORD_SCHEMES=['plaintext'],
        SECURITY_DEPRECATED_PASSWORD_SCHEMES=[],
        OAUTHLIB_INSECURE_TRANSPORT=True,
        OAUTH2_CACHE_TYPE='simple',
    )
    app_.url_map.converters['pid'] = PIDConverter
    FlaskCLI(app_)
    Babel(app_)
    FlaskCeleryExt(app_)
    InvenioDB(app_)
    Breadcrumbs(app_)
    InvenioAccounts(app_)
    app_.register_blueprint(accounts_blueprint)
    InvenioJSONSchemas(app_)
    InvenioSearch(app_)
    InvenioRecords(app_)
    app_.url_map.converters['pid'] = PIDConverter
    InvenioRecordsREST(app_)
    InvenioPIDStore(app_)
    InvenioIndexer(app_)
    InvenioDeposit(app_)
    InvenioFilesREST(app_)
    OAuth2Provider(app_)
    InvenioOAuth2Server(app_)
    InvenioOAuth2ServerREST(app_)
    app_.register_blueprint(oauth2server_settings_blueprint)
    InvenioDepositREST(app_)

    with app_.app_context():
        yield app_

    shutil.rmtree(instance_path)
def es(app):
    """Provide elasticsearch access."""
    InvenioSearch(app)
    try:
        list(current_search.create())
    except RequestError:
        list(current_search.delete(ignore=[404]))
        list(current_search.create(ignore=[400]))
    current_search_client.indices.refresh()
    queue = app.config['INDEXER_MQ_QUEUE']
    with establish_connection() as c:
        q = queue(c)
        q.declare()
    yield current_search_client
    list(current_search.delete(ignore=[404]))
def es_app(request):
    """Flask application with records fixture."""
    app = Flask(__name__)
    app.config.update(
        JSONSCHEMAS_ENDPOINT="/",
        JSONSCHEMAS_HOST="http://localhost:5000",
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            "SQLALCHEMY_DATABASE_URI", "sqlite:///test.db"
        ),
    )

    Babel(app)
    if not hasattr(app, "cli"):
        from flask_cli import FlaskCLI

        FlaskCLI(app)
    InvenioDB(app)
    InvenioRecords(app)
    InvenioMARC21(app)
    search = InvenioSearch(app)
    InvenioIndexer(app)
    InvenioJSONSchemas(app)

    with app.app_context():
        db.create_all()
        list(search.create())
        sleep(10)

    def teardown():
        with app.app_context():
            db.drop_all()
            list(search.delete())

    request.addfinalizer(teardown)

    return app
def base_app(request):
    """Base application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask("testapp", instance_path=instance_path)
    app.config.update(
        CELERY_BROKER_URL=os.environ.get(
            "BROKER_URL", "amqp://*****:*****@localhost:5672//"),
        CELERY_TASK_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND="memory",
        CELERY_TASK_EAGER_PROPAGATES=True,
        CELERY_RESULT_BACKEND="cache",
        INDEXER_DEFAULT_INDEX="records-default-v1.0.0",
        INDEXER_DEFAULT_DOC_TYPE="default-v1.0.0",
        SQLALCHEMY_DATABASE_URI=os.environ.get("SQLALCHEMY_DATABASE_URI",
                                               "sqlite:///test.db"),
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        TESTING=True,
    )
    FlaskCeleryExt(app)
    InvenioDB(app)
    InvenioRecords(app)
    search = InvenioSearch(app, entry_point_group=None)
    search.register_mappings("records", "data")

    with app.app_context():
        if not database_exists(str(db.engine.url)):
            create_database(str(db.engine.url))
        db.create_all()

    def teardown():
        with app.app_context():
            drop_database(str(db.engine.url))
        shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    return app
Example #29
0
def base_app(events_config, aggregations_config):
    """Flask application fixture without InvenioStats."""
    instance_path = tempfile.mkdtemp()
    app_ = Flask('testapp', instance_path=instance_path)
    app_.config.update(dict(
        CELERY_ALWAYS_EAGER=True,
        CELERY_TASK_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_TASK_EAGER_PROPAGATES=True,
        CELERY_RESULT_BACKEND='cache',
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI', 'sqlite://'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        # Bump the ES client timeout for slower environments (like Travis CI)
        SEARCH_CLIENT_CONFIG={'timeout': 30, 'max_retries': 5},
        TESTING=True,
        OAUTH2SERVER_CLIENT_ID_SALT_LEN=64,
        OAUTH2SERVER_CLIENT_SECRET_SALT_LEN=60,
        OAUTH2SERVER_TOKEN_PERSONAL_SALT_LEN=60,
        STATS_MQ_EXCHANGE=Exchange(
            'test_events',
            type='direct',
            delivery_mode='transient',  # in-memory queue
            durable=True,
        ),
        SECRET_KEY='asecretkey',
        SERVER_NAME='localhost',
        STATS_QUERIES={},
        STATS_EVENTS=events_config,
        STATS_AGGREGATIONS=aggregations_config,
    ))
    FlaskCeleryExt(app_)
    InvenioAccounts(app_)
    InvenioAccountsREST(app_)
    InvenioDB(app_)
    InvenioRecords(app_)
    InvenioFilesREST(app_)
    InvenioPIDStore(app_)
    InvenioCache(app_)
    InvenioQueues(app_)
    InvenioOAuth2Server(app_)
    InvenioOAuth2ServerREST(app_)
    InvenioSearch(app_, entry_point_group=None)
    with app_.app_context():
        yield app_
    shutil.rmtree(instance_path)
def test_init():
    """Test extension initialization."""
    app = Flask('testapp')
    ext = InvenioSearch(app)
    assert 'invenio-search' in app.extensions

    app = Flask('testapp')
    ext = InvenioSearch()
    assert 'invenio-search' not in app.extensions
    ext.init_app(app)
    assert 'invenio-search' in app.extensions
Example #31
0
def app():
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND='cache',
        JSONSCHEMAS_HOST='inveniosoftware.org',
        TESTING=True,
        SECRET_KEY='CHANGE_ME',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite://'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SERVER_NAME='app',
        OAISERVER_RECORD_INDEX='_all',
        OAISERVER_REGISTER_SET_SIGNALS=True,
        SEARCH_ELASTIC_KEYWORD_MAPPING={None: ['_all']},
    )
    if not hasattr(app, 'cli'):
        from flask_cli import FlaskCLI
        FlaskCLI(app)
    InvenioDB(app)
    FlaskCeleryExt(app)
    InvenioJSONSchemas(app)
    InvenioRecords(app)
    InvenioPIDStore(app)
    InvenioMARC21(app)
    client = Elasticsearch(hosts=[os.environ.get('ES_HOST', 'localhost')])
    search = InvenioSearch(app, client=client)
    search.register_mappings('records', 'data')
    InvenioIndexer(app)
    InvenioOAIServer(app)

    app.register_blueprint(blueprint)

    with app.app_context():
        if str(db.engine.url) != 'sqlite://' and \
           not database_exists(str(db.engine.url)):
            create_database(str(db.engine.url))
        db.create_all()
        list(search.create(ignore=[400]))
        sleep(5)

    with app.app_context():
        yield app

    with app.app_context():
        db.session.close()
        if str(db.engine.url) != 'sqlite://':
            drop_database(str(db.engine.url))
        list(search.delete(ignore=[404]))
    shutil.rmtree(instance_path)
def base_app(instance_path):
    """Flask application fixture."""
    app_ = Flask('testapp', instance_path=instance_path)
    app_.config.update(
        SECRET_KEY='SECRET_KEY',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )
    InvenioPIDStore(app_)
    InvenioDB(app_)
    InvenioPIDRelations(app_)
    InvenioRecords(app_)
    InvenioIndexer(app_)
    InvenioSearch(app_)
    Babel(app_)
    return app_
Example #33
0
def app(request):
    """Flask application fixture."""
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        TESTING=True,
        CELERY_ALWAYS_EAGER=True,
        CELERY_CACHE_BACKEND="memory",
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        CELERY_RESULT_BACKEND="cache",
        COMMUNITIES_MAIL_ENABLED=False,
        SECRET_KEY='CHANGE_ME',
        SECURITY_PASSWORD_SALT='CHANGE_ME_ALSO',
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SEARCH_ELASTIC_HOSTS=os.environ.get('SEARCH_ELASTIC_HOSTS', None),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        OAISERVER_REGISTER_RECORD_SIGNALS=True,
        OAISERVER_REGISTER_SET_SIGNALS=False,
        OAISERVER_ID_PREFIX='oai:localhost:recid/',
        SERVER_NAME='inveniosoftware.org',
        THEME_SITEURL='https://inveniosoftware.org',
        MAIL_SUPPRESS_SEND=True,
    )
    FlaskCeleryExt(app)
    Menu(app)
    Babel(app)
    InvenioDB(app)
    InvenioAccounts(app)
    InvenioAssets(app)
    InvenioSearch(app)
    InvenioRecords(app)
    InvenioIndexer(app)
    InvenioOAIServer(app)
    InvenioCommunities(app)
    InvenioMail(app)

    app.register_blueprint(ui_blueprint)
    app.register_blueprint(api_blueprint, url_prefix='/api/communities')

    with app.app_context():
        yield app

    shutil.rmtree(instance_path)
Example #34
0
def app(request):
    """Basic Flask application."""
    instance_path = tempfile.mkdtemp()
    app = Flask("testapp")
    app.config.update(
        SQLALCHEMY_DATABASE_URI=os.getenv("SQLALCHEMY_DATABASE_URI",
                                          "sqlite://"),
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        TESTING=True,
        SECRET_KEY="testing",
        # SERVER_NAME='localhost:5000',
    )

    app.url_map.converters['pid'] = PIDConverter

    InvenioDB(app)
    InvenioPIDStore(app)
    InvenioRecords(app)
    InvenioAccounts(app)
    InvenioAccess(app)
    InvenioIndexer(app)
    InvenioSearch(app)
    InvenioREST(app)
    InvenioRecordsREST(app)
    InvenioConfigDefault(app)

    with app.app_context():
        db_url = str(db.engine.url)
        if db_url != "sqlite://" and not database_exists(db_url):
            create_database(db_url)
        db.create_all()

    def teardown():
        with app.app_context():
            db_url = str(db.engine.url)
            db.session.close()
            if db_url != "sqlite://":
                drop_database(db_url)
            shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    app.test_request_context().push()

    return app
Example #35
0
def base_app():
    """Flask applicat-ion fixture."""
    instance_path = os.path.join(sys.prefix, 'var', 'test-instance')

    # empty the instance path
    if os.path.exists(instance_path):
        shutil.rmtree(instance_path)
    os.makedirs(instance_path)

    os.environ['INVENIO_INSTANCE_PATH'] = instance_path

    app_ = Flask('oai-testapp', instance_path=instance_path)
    app_.config.update(
        TESTING=True,
        JSON_AS_ASCII=True,
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        #SQLALCHEMY_DATABASE_URI=os.environ.get(
        #    'SQLALCHEMY_DATABASE_URI',
        #    'sqlite:///:memory:'),
        SQLALCHEMY_DATABASE_URI='sqlite://',
        SERVER_NAME='localhost:5000',
        SECURITY_PASSWORD_SALT='TEST_SECURITY_PASSWORD_SALT',
        SECRET_KEY='TEST_SECRET_KEY',
        INVENIO_INSTANCE_PATH=instance_path,
        SEARCH_INDEX_PREFIX='test-',
        JSONSCHEMAS_HOST='localhost:5000',
        SEARCH_ELASTIC_HOSTS=os.environ.get('SEARCH_ELASTIC_HOSTS', None),
        PIDSTORE_RECID_FIELD='id',
        FILES_REST_PERMISSION_FACTORY=allow_all,
        CELERY_ALWAYS_EAGER=True,
        OAISERVER_RECORDS_INDEX='max21',
        OAISERVER_ID_PREFIX='oai:example:',
    )
    app_.register_blueprint(blueprint)
    InvenioDB(app_)
    InvenioIndexer(app_)
    InvenioSearch(app_)
    FlaskCeleryExt(app_)
    InvenioOAIServer(app_)
    if not hasattr(app_, 'cli'):
        ext_cli = FlaskCLI(app_)

    return app_
Example #36
0
def base_app():
    """Flask applicat-ion fixture."""
    instance_path = os.path.join(sys.prefix, 'var', 'tests-instance')

    # empty the instance path
    if os.path.exists(instance_path):
        shutil.rmtree(instance_path)
    os.makedirs(instance_path)

    os.environ['INVENIO_INSTANCE_PATH'] = instance_path

    app_ = Flask('invenio-model-testapp', instance_path=instance_path)
    app_.config.update(
        TESTING=True,
        JSON_AS_ASCII=True,
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI',
            'sqlite:///:memory:'),
        SERVER_NAME='localhost:5000',
        SECURITY_PASSWORD_SALT='TEST_SECURITY_PASSWORD_SALT',
        SECRET_KEY='TEST_SECRET_KEY',
        INVENIO_INSTANCE_PATH=instance_path,
        SEARCH_INDEX_PREFIX='tests-',
        JSONSCHEMAS_HOST='localhost:5000',
        SEARCH_ELASTIC_HOSTS=os.environ.get('SEARCH_ELASTIC_HOSTS', None),
        PIDSTORE_RECID_FIELD='id',
        SUPPORTED_LANGUAGES = ["cs", "en", "it"],
        ELASTICSEARCH_DEFAULT_LANGUAGE_TEMPLATE={
            "type": "text",
            "fields": {
                "keywords": {
                    "type": "keyword"
                }
            }
        }
    )

    InvenioDB(app_)
    InvenioIndexer(app_)
    InvenioSearch(app_)
    OARepoMultilingualExt(app_)
    return app_
def base_app(request):
    """Basic Flask application."""
    instance_path = tempfile.mkdtemp()
    app = Flask("testapp")
    app.config.update(
        MADMP_HOST_URL="https://test.invenio.cern.ch",
        MADMP_HOST_TITLE="Invenio",
        MADMP_FALLBACK_RECORD_CONVERTER=RDMRecordConverter(),
        SQLALCHEMY_DATABASE_URI=os.getenv("SQLALCHEMY_DATABASE_URI",
                                          "sqlite://"),
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
    )
    Babel(app)
    InvenioConfigDefault(app)
    InvenioDB(app)
    InvenioRecords(app)
    InvenioPIDStore(app)
    InvenioPIDRelations(app)
    InvenioAccounts(app)
    InvenioAccess(app)
    InvenioIndexer(app)
    InvenioSearch(app)
    InvenioMaDMP(app)

    with app.app_context():
        db_url = str(db.engine.url)
        if db_url != "sqlite://" and not database_exists(db_url):
            create_database(db_url)
        db.create_all()

    def teardown():
        with app.app_context():
            db_url = str(db.engine.url)
            db.session.close()
            if db_url != "sqlite://":
                drop_database(db_url)
            shutil.rmtree(instance_path)

    request.addfinalizer(teardown)
    app.test_request_context().push()

    return app
Example #38
0
def app(env_config, zenodo_config, config, instance_path):
    """Flask application fixture."""
    app_ = Flask(__name__, instance_path=instance_path)
    app_.config.update(zenodo_config)
    app_.config.update(config)

    FlaskCeleryExt(app_)
    InvenioDB(app_)
    InvenioAccounts(app_)
    InvenioOAuthClient(app_)
    InvenioOAuth2Server(app_)
    InvenioRecords(app_)
    InvenioIndexer(app_)
    InvenioJSONSchemas(app_)
    InvenioSearch(app_)
    InvenioPIDStore(app_)
    ZenodoMigrator(app_)

    with app_.app_context():
        yield app_
Example #39
0
 def factory(**config):
     app = Flask('testapp', instance_path=instance_path)
     app.config.update(
         TESTING=True,
         JSON_AS_ASCII=True,
         SQLALCHEMY_TRACK_MODIFICATIONS=True,
         SQLALCHEMY_DATABASE_URI=os.environ.get(
             'SQLALCHEMY_DATABASE_URI',
             'sqlite:///:memory:'),
         SERVER_NAME='localhost',
         SECURITY_PASSWORD_SALT='TEST_SECURITY_PASSWORD_SALT',
         SECRET_KEY='TEST_SECRET_KEY',
     )
     Babel(app)
     InvenioDB(app)
     InvenioJSONSchemas(app)
     InvenioRecords(app)
     InvenioSearch(app)
     OARepoReferences(app)
     return app
Example #40
0
def app(request):
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)

    app.config.update(
        ACCOUNTS_JWT_ENABLE=False,
        INDEXER_DEFAULT_DOC_TYPE='record-v1.0.0',
        RECORDS_REST_ENDPOINTS={},
        RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY=None,
        SERVER_NAME='localhost:5000',
        CELERY_ALWAYS_EAGER=True,
        CELERY_RESULT_BACKEND='cache',
        CELERY_CACHE_BACKEND='memory',
        CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
        SQLALCHEMY_DATABASE_URI=os.environ.get('SQLALCHEMY_DATABASE_URI',
                                               'sqlite:///test.db'),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )

    app.secret_key = 'changeme'

    InvenioDB(app)
    InvenioRecords(app)
    InvenioJSONSchemas(app)
    InvenioPIDStore(app)
    InvenioSearch(app)
    InvenioIndexer(app)
    OARepoMappingIncludesExt(app)

    app_loaded.send(app, app=app)

    with app.app_context():
        yield app

    # Teardown instance path.
    shutil.rmtree(instance_path)
Example #41
0
def app(base_app):
    """Flask application fixture."""

    base_app._internal_jsonschemas = InvenioJSONSchemas(base_app)

    InvenioREST(base_app)
    InvenioRecordsREST(base_app)
    InvenioRecords(base_app)
    InvenioPIDStore(base_app)
    OARepoValidate(base_app)
    Actions(base_app)
    base_app.url_map.converters['pid'] = PIDConverter
    SampleExt(base_app)
    OARepoMappingIncludesExt(base_app)
    InvenioSearch(base_app)

    base_app.register_blueprint(create_blueprint_from_app(base_app))

    app_loaded.send(None, app=base_app)

    with base_app.app_context():
        yield base_app
Example #42
0
)

FlaskCLI(app)
Babel(app)

# Set jinja loader to first grab templates from the app's folder.
app.jinja_loader = jinja2.ChoiceLoader([
    jinja2.FileSystemLoader(join(dirname(__file__), "templates")),
    app.jinja_loader
 ])

InvenioDB(app)
InvenioTheme(app)
InvenioRecords(app)
InvenioRecordsUI(app)
search = InvenioSearch(app)
search.register_mappings('records', 'data')
InvenioSearchUI(app)
InvenioIndexer(app)
InvenioPIDStore(app)

InvenioRecordsREST(app)

assets = InvenioAssets(app)
assets.init_cli(app.cli)

# Register assets
assets.env.register('invenio_search_ui_search_js', js)


@app.cli.group()
Example #43
0
    CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
    CELERY_RESULT_BACKEND="cache",
    MAIL_SUPPRESS_SEND=True,
    SECRET_KEY="CHANGE_ME",
    SECURITY_PASSWORD_SALT="CHANGE_ME_ALSO",
    SEARCH_ELASTIC_KEYWORD_MAPPING={None: ['_all']},
    SQLALCHEMY_DATABASE_URI=os.getenv('SQLALCHEMY_DATABASE_URI',
                                      'sqlite:///app.db'),
)
Menu(app)
InvenioDB(app)
InvenioAccounts(app)

app.register_blueprint(blueprint)

search = InvenioSearch(app)

if ES_VERSION[0] == 2:
    search.register_mappings('demo', 'data.elastic_v2')
elif ES_VERSION[0] == 5:
    search.register_mappings('demo', 'data.elastic_v5')
else:
    raise Exception('This example supports only elasticsearch version '
                    '2.x and 5.x')


class ExampleSearch(RecordsSearch):
    """Example search class."""

    class Meta:
        index = 'demo'
def app(request, search_class):
    """Flask application fixture.

    Note that RECORDS_REST_ENDPOINTS is used during application creation to
    create blueprints on the fly, hence once you have this fixture in a test,
    it's too late to customize the configuration variable. You can however
    customize it using parameterized tests:

    .. code-block:: python

    @pytest.mark.parametrize('app', [dict(
        endpoint=dict(
            search_class='conftest:TestSearch',
        )
    def test_mytest(app, db, es):
        # ...

    This will parameterize the default 'recid' endpoint in
    RECORDS_REST_ENDPOINTS.
    """
    instance_path = tempfile.mkdtemp()
    app = Flask('testapp', instance_path=instance_path)
    app.config.update(
        INDEXER_DEFAULT_DOC_TYPE='testrecord',
        INDEXER_DEFAULT_INDEX=search_class.Meta.index,
        RECORDS_REST_ENDPOINTS=config.RECORDS_REST_ENDPOINTS,
        RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY=None,
        RECORDS_REST_DEFAULT_SEARCH_INDEX=search_class.Meta.index,
        RECORDS_REST_FACETS={
            search_class.Meta.index: {
                'aggs': {
                    'stars': {'terms': {'field': 'stars'}}
                },
                'post_filters': {
                    'stars': terms_filter('stars'),
                }
            }
        },
        RECORDS_REST_SORT_OPTIONS={
            search_class.Meta.index: dict(
                year=dict(
                    fields=['year'],
                )
            )
        },
        SERVER_NAME='localhost:5000',
        SQLALCHEMY_DATABASE_URI=os.environ.get(
            'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'
        ),
        SQLALCHEMY_TRACK_MODIFICATIONS=True,
        TESTING=True,
    )
    app.config['RECORDS_REST_ENDPOINTS']['recid']['search_class'] = \
        search_class

    # Parameterize application.
    if hasattr(request, 'param'):
        if 'endpoint' in request.param:
            app.config['RECORDS_REST_ENDPOINTS']['recid'].update(
                request.param['endpoint'])

    app.url_map.converters['pid'] = PIDConverter

    FlaskCLI(app)
    InvenioDB(app)
    InvenioREST(app)
    InvenioRecords(app)
    InvenioPIDStore(app)
    search = InvenioSearch(app)
    search.register_mappings(search_class.Meta.index, 'mappings')
    InvenioRecordsREST(app)

    with app.app_context():
        yield app

    # Teardown instance path.
    shutil.rmtree(instance_path)
    CELERY_RESULT_BACKEND="cache",
    MAIL_SUPPRESS_SEND=True,
    SECRET_KEY="CHANGE_ME",
    SECURITY_PASSWORD_SALT="CHANGE_ME_ALSO",
    SEARCH_ELASTIC_KEYWORD_MAPPING={None: ["_all"]},
)
FlaskCLI(app)
Babel(app)
Mail(app)
Menu(app)
InvenioDB(app)
InvenioAccounts(app)

app.register_blueprint(blueprint)

search = InvenioSearch(app)
search.register_mappings("records", "data")


def authenticated_query(query, **kwargs):
    """Enhance query with user authentication rules."""
    from invenio_query_parser.ast import AndOp, DoubleQuotedValue, Keyword, KeywordOp

    if not current_user.is_authenticated():
        query.body["_source"] = {"exclude": ["public"]}
        query.query = AndOp(KeywordOp(Keyword("public"), DoubleQuotedValue(1)), query.query)


app.config["SEARCH_QUERY_ENHANCERS"] = [authenticated_query]