Ejemplo n.º 1
0
def test_validate_with_format(app, db):
    """Test that validation can accept custom format rules."""
    with app.app_context():
        checker = FormatChecker()
        checker.checks("foo")(lambda el: el.startswith("foo"))
        data = {"bar": "foo", "$schema": {"properties": {"bar": {"format": "foo"}}}}

        # test record creation with valid data
        assert data == Record.create(data)
        record = Record.create(data, format_checker=checker)
        # test direct call to validate with valid data
        assert record.validate(format_checker=checker) is None
        # test commit with valid data
        record.commit(format_checker=checker)

        record["bar"] = "bar"
        # test direct call to validate with invalid data
        with pytest.raises(ValidationError) as excinfo:
            record.validate(format_checker=checker)
        assert "'bar' is not a 'foo'" in str(excinfo.value)
        # test commit with invalid data
        with pytest.raises(ValidationError) as excinfo:
            record.commit(format_checker=checker)
        assert "'bar' is not a 'foo'" in str(excinfo.value)

        data["bar"] = "bar"
        # test record creation with invalid data
        with pytest.raises(ValidationError) as excinfo:
            record = Record.create(data, format_checker=checker)
        assert "'bar' is not a 'foo'" in str(excinfo.value)
Ejemplo n.º 2
0
def test_validate_partial(app, db):
    """Test partial validation."""
    schema = {"properties": {"a": {"type": "string"}, "b": {"type": "string"}}, "required": ["b"]}
    data = {"a": "hello", "$schema": schema}
    with app.app_context():
        # Test validation on create()

        # normal validation should fail because 'b' is required
        with pytest.raises(ValidationError) as exc_info:
            Record.create(data)
        assert "'b' is a required property" == exc_info.value.message
        # validate with a less restrictive validator
        record = Record.create(data, validator=PartialDraft4Validator)
        # set wrong data types should fails in any case
        data_incorrect = copy.deepcopy(data)
        data_incorrect["a"] = 1
        with pytest.raises(ValidationError) as exc_info:
            Record.create(data_incorrect, validator=PartialDraft4Validator)
        assert "1 is not of type 'string'" == exc_info.value.message

        # Test validation on commit()

        # validation not passing with normal validator
        with pytest.raises(ValidationError) as exc_info:
            record.commit()
        assert "'b' is a required property" == exc_info.value.message
        # validation passing with less restrictive validator
        assert data == record.commit(validator=PartialDraft4Validator)
        # set wrong data types should fails in any case
        record["a"] = 1
        with pytest.raises(ValidationError) as exc_info:
            record.commit(validator=PartialDraft4Validator)
Ejemplo n.º 3
0
def records(db):
    """Create sample records with references."""
    return [
        Record.create({'$ref': 'ref1'}),
        Record.create({'$ref': 'ref2'}),
        Record.create({'reflist': [
            {'$ref': 'ref3'},
            {'$ref': 'ref4'}
        ]})
    ]
Ejemplo n.º 4
0
def test_file_permissions(app, db, test_object,  # fixtures
                          user, access_right, expected):
    """Test file permissions."""
    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(
        ActionUsers.allow(ActionNeed('admin-access'), user=admin)
    )

    # Create test record
    rec_uuid = uuid.uuid4()
    PersistentIdentifier.create(
        'recid',
        '1',
        object_type='rec',
        object_uuid=rec_uuid,
        status=PIDStatus.REGISTERED
    )
    Record.create({
        'recid': 1,
        'owners': [2],
        'access_right': access_right,
        '_files': [
            {
                'key': test_object.key,
                'bucket': str(test_object.bucket_id),
                'checksum': 'invalid'
            },
        ]
    }, id_=rec_uuid)
    db.session.add(
        RecordsBuckets(record_id=rec_uuid, bucket_id=test_object.bucket_id)
    )

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value='1',
        filename=test_object.key
    )

    db.session.commit()

    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
Ejemplo n.º 5
0
def files():
    """Load files."""
    data_path = os.path.join(os.path.dirname(__file__), 'data')

    # Create location
    loc = Location(name='local', uri=data_path, default=True)
    db.session.commit()

    # Bucket
    bucket = Bucket.create(loc)

    # Example files from the data folder
    example_files = (
        'markdown.md',
        'csvfile.csv',
        'zipfile.zip',
        'jsonfile.json',
        'xmlfile.xml',
        'notebook.ipynb',
        'jpgfile.jpg',
        'pngfile.png',
    )

    # Create single file records
    for f in example_files:
        with open(os.path.join(data_path, f), 'rb') as fp:
            create_object(bucket, f, fp)

    # Create a multi-file record
    rec_uuid = uuid4()
    provider = RecordIdProvider.create(object_type='rec', object_uuid=rec_uuid)
    data = {
        'pid_value': provider.pid.pid_value,
        'files': []
    }

    # Template to create different files
    template_file = {
        'uri': '/files/{0}/{1}',
        'key': '',
        'bucket': str(bucket.id),
        'local': True
    }

    for filename in example_files:
        file_data = template_file.copy()
        file_data['uri'] = file_data['uri'].format(str(bucket.id), filename)
        file_data['key'] = filename
        data['files'].append(file_data)

    Record.create(data, id_=rec_uuid)

    db.session.commit()
Ejemplo n.º 6
0
def files():
    """Load files."""
    data_path = os.path.join(os.path.dirname(__file__), 'data')

    # Create location
    loc = Location(name='local', uri=data_path, default=True)
    db.session.commit()

    # Bucket
    bucket = Bucket.create(loc)

    # Example files from the data folder
    example_files = (
        'markdown.md',
        'csvfile.csv',
        'zipfile.zip',
        'jsonfile.json',
        'xmlfile.xml',
        'notebook.ipynb',
        'jpgfile.jpg',
        'pngfile.png',
    )

    # Create single file records
    for f in example_files:
        with open(os.path.join(data_path, f), 'rb') as fp:
            create_object(bucket, f, fp)

    # Create a multi-file record
    rec_uuid = uuid4()
    provider = RecordIdProvider.create(object_type='rec', object_uuid=rec_uuid)
    data = {'pid_value': provider.pid.pid_value, 'files': []}

    # Template to create different files
    template_file = {
        'uri': '/files/{0}/{1}',
        'key': '',
        'bucket': str(bucket.id),
        'local': True
    }

    for filename in example_files:
        file_data = template_file.copy()
        file_data['uri'] = file_data['uri'].format(str(bucket.id), filename)
        file_data['key'] = filename
        data['files'].append(file_data)

    Record.create(data, id_=rec_uuid)

    db.session.commit()
Ejemplo n.º 7
0
def test_record_dump(app, db):
    """Test record dump method."""
    with app.app_context():
        record = Record.create({'foo': {'bar': 'Bazz', }, })
        record_dump = record.dumps()
        record_dump['foo']['bar'] = 'Spam'
        assert record_dump['foo']['bar'] != record['foo']['bar']
Ejemplo n.º 8
0
def record_upsert(json):
    """Insert or update a record."""
    control_number = json.get('control_number', json.get('recid'))
    if control_number:
        control_number = int(control_number)
        pid_type = InspireRecordIdProvider.schema_to_pid_type(json['$schema'])
        try:
            pid = PersistentIdentifier.get(pid_type, control_number)
            record = Record.get_record(pid.object_uuid)
            record.update(json)
            record.commit()
        except PIDDoesNotExistError:
            record = Record.create(json, id_=None)
            # Create persistent identifier.
            inspire_recid_minter(str(record.id), json)

        if json.get('deleted'):
            new_recid = get_recid_from_ref(json.get('new_record'))
            if new_recid:
                merged_record = get_db_record(pid_type, new_recid)
                merge_pidstores_of_two_merged_records(merged_record.id, record.id)
            else:
                soft_delete_pidstore_for_record(record.id)

        return record
Ejemplo n.º 9
0
def migrate_chunk(chunk, broken_output=None, dry_run=False):
    from invenio_indexer.api import RecordIndexer

    from ..pidstore.minters import inspire_recid_minter

    indexer = RecordIndexer()

    index_queue = []
    for raw_record in chunk:
        record = marc_create_record(raw_record, keep_singletons=False)
        json_record = create_record(record)
        if '$schema' in json_record:
            json_record['$schema'] = url_for(
                'invenio_jsonschemas.get_schema',
                schema_path="records/{0}".format(json_record['$schema'])
            )
        rec_uuid = str(Record.create(json_record, id_=None).id)

        # Create persistent identifier.
        pid = inspire_recid_minter(rec_uuid, json_record)

        index_queue.append(pid.object_uuid)

        db.session.commit()

    # Request record indexing
    for i in index_queue:
        indexer.index_by_id(i)

    # Send task to migrate files.
    return rec_uuid
Ejemplo n.º 10
0
def test_permission_factory(app, db, action, permission_factory):
    """Test revisions."""
    InvenioAccess(app)

    rec_uuid = uuid.uuid4()

    with db.session.begin_nested():
        user_all = User(email='*****@*****.**')
        user_one = User(email='*****@*****.**')
        user_none = User(email='*****@*****.**')
        db.session.add(user_all)
        db.session.add(user_one)
        db.session.add(user_none)

        db.session.add(ActionUsers(action=action, user=user_all,
                                   argument=None))
        db.session.add(
            ActionUsers(action=action, user=user_one, argument=str(rec_uuid)))

        record = Record.create({'title': 'permission test'}, id_=rec_uuid)

    # Create a record and assign permissions.
    permission = permission_factory(record)

    # Assert which permissions has access.
    assert permission.allows(FakeIdentity(UserNeed(user_all.id)))
    assert permission.allows(FakeIdentity(UserNeed(user_one.id)))
    assert not permission.allows(FakeIdentity(UserNeed(user_none.id)))
Ejemplo n.º 11
0
def store_record(obj, *args, **kwargs):
    """Create and index new record in main record space."""
    assert "$schema" in obj.data, "No $schema attribute found!"

    # Create record
    # FIXME: Do some preprocessing of obj.data before creating a record so that
    # we're sure that the schema will be validated without touching the full
    # holdingpen stack.
    record = Record.create(obj.data, id_=None)

    # Create persistent identifier.
    pid = inspire_recid_minter(str(record.id), record)

    # Commit any changes to record
    record.commit()

    # Dump any changes to record
    obj.data = record.dumps()

    # Commit to DB before indexing
    db.session.commit()

    # Index record
    indexer = RecordIndexer()
    indexer.index_by_id(pid.object_uuid)
Ejemplo n.º 12
0
def test_reindex(app, script_info):
    """Test reindex."""
    # load records
    with app.test_request_context():
        runner = CliRunner()
        rec_uuid = uuid.uuid4()
        data = {'title': 'Test0'}
        record = Record.create(data, id_=rec_uuid)
        db.session.commit()

        # Initialize queue
        res = runner.invoke(cli.queue, ['init', 'purge'],
                            obj=script_info)
        assert 0 == res.exit_code

        res = runner.invoke(cli.reindex, ['--yes-i-know'], obj=script_info)
        assert 0 == res.exit_code
        res = runner.invoke(cli.run, [], obj=script_info)
        assert 0 == res.exit_code

        sleep(5)
        indexer = RecordIndexer()
        index, doc_type = indexer.record_to_index(record)
        res = current_search_client.get(index=index, doc_type=doc_type,
                                        id=rec_uuid)
        assert res['found']

        # Destroy queue
        res = runner.invoke(cli.queue, ['delete'],
                            obj=script_info)
        assert 0 == res.exit_code
Ejemplo n.º 13
0
def create_record(ctx):
    """
    Creates the record in the database.
    :param ctx: The record metadata as a dictionary.
    :return: the recid and the uuid
    """
    record_information = create_data_structure(ctx)
    record_id = uuid.uuid4()
    pid = recid_minter(record_id, record_information)
    record_information['recid'] = int(pid.pid_value)
    record_information['uuid'] = str(record_id)

    Record.create(record_information, id_=record_id)
    db.session.commit()

    return record_information
Ejemplo n.º 14
0
def news():
    """Load demo news records."""
    from invenio_db import db
    from invenio_records import Record
    from invenio_indexer.api import RecordIndexer
    from cernopendata.modules.records.minters.artid import \
        cernopendata_articleid_minter

    indexer = RecordIndexer()
    schema = current_app.extensions['invenio-jsonschemas'].path_to_url(
        'records/article-v1.0.0.json'
    )
    data = pkg_resources.resource_filename('cernopendata',
                                           'modules/fixtures/data')
    articles_json = glob.glob(os.path.join(data, 'articles', 'news', '*.json'))

    for filename in articles_json:
        with open(filename, 'rb') as source:
            for data in json.load(source):
                if "collections" not in data and \
                   not isinstance(data.get("collections", None), basestring):
                    data["collections"] = []
                data["collections"].append({"primary": "News"})
                id = uuid.uuid4()
                cernopendata_articleid_minter(id, data)
                record = Record.create(data, id_=id)
                record['$schema'] = schema
                db.session.commit()
                indexer.index(record)
                db.session.expunge_all()
Ejemplo n.º 15
0
def test_reindex(app, script_info):
    """Test reindex."""
    # load records
    with app.test_request_context():
        runner = CliRunner()
        rec_uuid = uuid.uuid4()
        data = {'title': 'Test0'}
        record = Record.create(data, id_=rec_uuid)
        db.session.commit()

        # Initialize queue
        res = runner.invoke(cli.queue, ['init', 'purge'], obj=script_info)
        assert 0 == res.exit_code

        res = runner.invoke(cli.reindex, ['--yes-i-know'], obj=script_info)
        assert 0 == res.exit_code
        res = runner.invoke(cli.run, [], obj=script_info)
        assert 0 == res.exit_code

        sleep(5)
        indexer = RecordIndexer()
        index, doc_type = indexer.record_to_index(record)
        res = current_search_client.get(index=index,
                                        doc_type=doc_type,
                                        id=rec_uuid)
        assert res['found']

        # Destroy queue
        res = runner.invoke(cli.queue, ['delete'], obj=script_info)
        assert 0 == res.exit_code
Ejemplo n.º 16
0
def create_record(ctx):
    """
    Creates the record in the database.
    :param ctx: The record metadata as a dictionary.
    :return: the recid and the uuid
    """
    record_information = create_data_structure(ctx)
    record_id = uuid.uuid4()
    pid = recid_minter(record_id, record_information)
    record_information['recid'] = int(pid.pid_value)
    record_information['uuid'] = str(record_id)

    Record.create(record_information, id_=record_id)
    db.session.commit()

    return record_information
Ejemplo n.º 17
0
def records(pids, db):
    """Fixture for the records."""
    pid_versions = ['h1v1', 'h1v2', 'h2v1']
    schema = {
        'type': 'object',
        'properties': {
            'title': {
                'type': 'string'
            },
        },
    }
    data = {
        name: {
            'title': 'Test version {}'.format(name),
            'recid': pids[name].pid_value,
            '$schema': schema
        }
        for name in pid_versions
    }
    records = dict()
    for name in pid_versions:
        record = Record.create(data[name])
        pids[name].assign('rec', record.id)
        records[name] = record
    return records
Ejemplo n.º 18
0
def test_record_replace_refs(app):
    """Test the replacement of JSON references using JSONResolver."""
    with app.app_context():
        record = Record.create({
            'one': {'$ref': 'http://nest.ed/A'},
            'three': {'$ref': 'http://nest.ed/ABC'}
        })
        app.extensions['invenio-records'].loader_cls = json_loader_factory(
            JSONResolver(plugins=['demo.json_resolver']))
        out_json = record.replace_refs()
        expected_json = {
            'one': {
                'letter': 'A',
                'next': '.',
            },
            'three': {
                'letter': 'A',
                'next': {
                    'letter': 'B',
                    'next': {
                        'letter': 'C',
                        'next': '.',
                    },
                },
            },
        }
        assert out_json == expected_json
Ejemplo n.º 19
0
def migrate_chunk(chunk, broken_output=None, dry_run=False):
    from invenio_indexer.api import RecordIndexer

    from ..pidstore.minters import inspire_recid_minter

    indexer = RecordIndexer()

    index_queue = []
    for raw_record in chunk:
        record = marc_create_record(raw_record, keep_singletons=False)
        json_record = create_record(record)
        if '$schema' in json_record:
            json_record['$schema'] = url_for(
                'invenio_jsonschemas.get_schema',
                schema_path="records/{0}".format(json_record['$schema'])
            )
        rec_uuid = str(Record.create(json_record, id_=None).id)

        # Create persistent identifier.
        pid = inspire_recid_minter(rec_uuid, json_record)

        index_queue.append(pid.object_uuid)

        db.session.commit()

    # Request record indexing
    for i in index_queue:
        indexer.index_by_id(i)

    # Send task to migrate files.
    return rec_uuid
Ejemplo n.º 20
0
def test_valid_put(app):
    """Test VALID record patch request (PATCH .../records/<record_id>)."""
    with app.app_context():
        InvenioRecordsREST(app)
        # create the record using the internal API
        internal_record = Record.create(test_data)
        with app.test_client() as client:
            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            res = client.put(url_for(blueprint.name + '.' +
                                     RecordResource.view_name,
                                     record_id=internal_record.model.id),
                             data=json.dumps(test_data_patched),
                             headers=headers)
            assert res.status_code == 200
            # check that the returned record matches the given data
            response_data = json.loads(res.get_data(as_text=True))
            assert response_data['data'] == test_data_patched

            # check that an internal record returned id and that it contains
            # the same data
            assert 'id' in response_data.keys()
            internal_record = Record.get_record(response_data['id'])
            assert internal_record == response_data['data']

            # check that the returned self link returns the same data
            subtest_self_link(response_data, res.headers, client)
Ejemplo n.º 21
0
def test_record_update_mutable(app, db):
    """Test updating mutables in a record."""
    recid = uuid.UUID("262d2748-ba41-456f-a844-4d043a419a6f")

    # Create a new record with two mutables, a list and a dict
    rec = Record.create({"title": "Title", "list": ["foo"], "dict": {"moo": "boo"}}, id_=recid)
    # Make sure mutables are there before and after commit
    assert rec == {"title": "Title", "list": ["foo"], "dict": {"moo": "boo"}}
    db.session.commit()
    db.session.expunge_all()
    rec = Record.get_record(recid)
    assert rec == {"title": "Title", "list": ["foo"], "dict": {"moo": "boo"}}

    # Set the mutables under key
    rec["list"] = ["bar"]
    rec["dict"] = {"eggs": "bacon"}
    rec.commit()
    # Make sure it commits to DB
    assert rec == {"title": "Title", "list": ["bar"], "dict": {"eggs": "bacon"}}
    db.session.commit()
    db.session.expunge_all()
    rec = Record.get_record(recid)
    assert rec == {"title": "Title", "list": ["bar"], "dict": {"eggs": "bacon"}}

    # Update the mutables under key
    rec["list"].append("spam")
    rec["dict"]["ham"] = "chicken"
    rec.commit()
    # Make sure it commits to DB
    assert rec == {"title": "Title", "list": ["bar", "spam"], "dict": {"eggs": "bacon", "ham": "chicken"}}
    db.session.commit()
    db.session.expunge_all()
    rec = Record.get_record(recid)
    assert rec == {"title": "Title", "list": ["bar", "spam"], "dict": {"eggs": "bacon", "ham": "chicken"}}
Ejemplo n.º 22
0
def load_records(app, filename, schema, tries=5):
    """Try to index records."""
    indexer = RecordIndexer()
    records = []
    with app.app_context():
        with mock.patch('invenio_records.api.Record.validate',
                        return_value=None):
            data_filename = pkg_resources.resource_filename(
                'invenio_records', filename)
            records_data = load(data_filename)
            with db.session.begin_nested():
                for item in records_data:
                    record_id = uuid.uuid4()
                    item_dict = dict(marc21.do(item))
                    item_dict['$schema'] = schema
                    recid_minter(record_id, item_dict)
                    oaiid_minter(record_id, item_dict)
                    record = Record.create(item_dict, id_=record_id)
                    indexer.index(record)
                    records.append(record.id)
            db.session.commit()

        # Wait for indexer to finish
        for i in range(tries):
            response = current_search_client.search()
            if response['hits']['total'] >= len(records):
                break
            sleep(5)

    return records
Ejemplo n.º 23
0
def test_record_dump(app, db):
    """Test record dump method."""
    with app.app_context():
        record = Record.create({"foo": {"bar": "Bazz"}})
        record_dump = record.dumps()
        record_dump["foo"]["bar"] = "Spam"
        assert record_dump["foo"]["bar"] != record["foo"]["bar"]
def test_preprocessor_mixin_record(app):
    """Test preprocessor mixin."""
    with db.session.begin_nested():
        recuuid = uuid.uuid4()
        record = Record.create({
            'title': 'test', 'aref': {'$ref': '#/title'}}, id_=recuuid)
        record.model.created = datetime(2015, 10, 1, 11, 11, 11, 1)
        pid = PersistentIdentifier.create(
            'recid', '1', object_type='rec', object_uuid=recuuid,
            status=PIDStatus.REGISTERED)
    db.session.commit()

    data = PreprocessorMixin().preprocess_record(pid, record)
    for k in keys:
        assert k in data

    assert data['metadata']['title'] == 'test'
    assert data['metadata']['aref'] == {'$ref': '#/title'}
    assert data['created'] == '2015-10-01T11:11:11.000001+00:00'
    assert data['revision'] == 1

    data = PreprocessorMixin(replace_refs=True).preprocess_record(
        pid, Record({'title': 'test2', 'aref': {'$ref': '#/title'}}))
    assert data['created'] is None
    assert data['updated'] is None
    assert data['metadata']['aref'] == 'test2'
Ejemplo n.º 25
0
def test_permission_factory(app, action, permission_factory):
    """Test revisions."""
    InvenioAccess(app)
    with app.app_context():
        rec_uuid = uuid.uuid4()

        with db.session.begin_nested():
            user_all = User(email='*****@*****.**')
            user_one = User(email='*****@*****.**')
            user_none = User(email='*****@*****.**')
            db.session.add(user_all)
            db.session.add(user_one)
            db.session.add(user_none)

            db.session.add(ActionUsers(action=action,
                                       user=user_all, argument=None))
            db.session.add(ActionUsers(action=action,
                                       user=user_one, argument=str(rec_uuid)))

            record = Record.create({'title': 'permission test'}, id_=rec_uuid)

        # Create a record and assign permissions.
        permission = permission_factory(record)

        # Assert which permissions has access.
        assert permission.allows(FakeIdentity(UserNeed(user_all.id)))
        assert permission.allows(FakeIdentity(UserNeed(user_one.id)))
        assert not permission.allows(FakeIdentity(UserNeed(user_none.id)))
def test_valid_put(app):
    """Test VALID record patch request (PATCH .../records/<record_id>)."""
    with app.app_context():
        InvenioRecordsREST(app)
        # create the record using the internal API
        internal_record = Record.create(test_data)
        with app.test_client() as client:
            headers = [('Content-Type', 'application/json'),
                       ('Accept', 'application/json')]
            res = client.put(url_for(blueprint.name + '.' +
                                     RecordResource.view_name,
                                     record_id=internal_record.model.id),
                             data=json.dumps(test_data_patched),
                             headers=headers)
            assert res.status_code == 200
            # check that the returned record matches the given data
            response_data = json.loads(res.get_data(as_text=True))
            assert response_data['data'] == test_data_patched

            # check that an internal record returned id and that it contains
            # the same data
            assert 'id' in response_data.keys()
            internal_record = Record.get_record(response_data['id'])
            assert internal_record == response_data['data']

            # check that the returned self link returns the same data
            subtest_self_link(response_data, res.headers, client)
Ejemplo n.º 27
0
def load_records(app, filename, schema, tries=5):
    """Try to index records."""
    indexer = RecordIndexer()
    records = []
    with app.app_context():
        with mock.patch('invenio_records.api.Record.validate',
                        return_value=None):
            data_filename = pkg_resources.resource_filename(
                'invenio_records', filename)
            records_data = load(data_filename)
            with db.session.begin_nested():
                for item in records_data:
                    record_id = uuid.uuid4()
                    item_dict = dict(marc21.do(item))
                    item_dict['$schema'] = schema
                    recid_minter(record_id, item_dict)
                    oaiid_minter(record_id, item_dict)
                    record = Record.create(item_dict, id_=record_id)
                    indexer.index(record)
                    records.append(record.id)
            db.session.commit()

        # Wait for indexer to finish
        for i in range(tries):
            response = current_search_client.search()
            if response['hits']['total'] >= len(records):
                break
            current_search.flush_and_refresh('_all')

    return records
Ejemplo n.º 28
0
def test_record_replace_refs(app, db):
    """Test the replacement of JSON references using JSONResolver."""
    record = Record.create({
        'one': {
            '$ref': 'http://nest.ed/A'
        },
        'three': {
            '$ref': 'http://nest.ed/ABC'
        }
    })
    app.extensions['invenio-records'].loader_cls = json_loader_factory(
        JSONResolver(plugins=['demo.json_resolver']))
    out_json = record.replace_refs()
    expected_json = {
        'one': {
            'letter': 'A',
            'next': '.',
        },
        'three': {
            'letter': 'A',
            'next': {
                'letter': 'B',
                'next': {
                    'letter': 'C',
                    'next': '.',
                },
            },
        },
    }
    assert out_json == expected_json
Ejemplo n.º 29
0
def data_policies():
    """Load demo Data Policy records."""
    from invenio_db import db
    from invenio_records import Record
    from invenio_indexer.api import RecordIndexer
    from invenio_pidstore.errors import PIDDoesNotExistError, \
        PersistentIdentifierError
    from invenio_pidstore.models import PIDStatus, PersistentIdentifier
    from invenio_pidstore.fetchers import recid_fetcher
    from invenio_pidstore.minters import recid_minter
    from cernopendata.modules.records.minters.recid import \
        cernopendata_recid_minter

    indexer = RecordIndexer()
    schema = current_app.extensions['invenio-jsonschemas'].path_to_url(
        'records/data-policies-v1.0.0.json'
    )
    data = pkg_resources.resource_filename('cernopendata',
                                           'modules/fixtures/data')
    data_policies_json = glob.glob(os.path.join(data, '*.json'))

    for filename in data_policies_json:
        with open(filename, 'rb') as source:
            for data in json.load(source):
                id = uuid.uuid4()
                cernopendata_recid_minter(id, data)
                record = Record.create(data, id_=id)
                record['$schema'] = schema
                db.session.commit()
                indexer.index(record)
                db.session.expunge_all()
Ejemplo n.º 30
0
def store_record(obj, *args, **kwargs):
    """Create and index new record in main record space."""
    assert "$schema" in obj.data, "No $schema attribute found!"

    # Create record
    # FIXME: Do some preprocessing of obj.data before creating a record so that
    # we're sure that the schema will be validated without touching the full
    # holdingpen stack.
    record = Record.create(obj.data, id_=None)

    # Create persistent identifier.
    pid = inspire_recid_minter(str(record.id), record)

    # Commit any changes to record
    record.commit()

    # Dump any changes to record
    obj.data = record.dumps()

    # Commit to DB before indexing
    db.session.commit()

    # Index record
    indexer = RecordIndexer()
    indexer.index_by_id(pid.object_uuid)
Ejemplo n.º 31
0
def create_record(data):
    """Create a test record."""
    with db.session.begin_nested():
        data = copy.deepcopy(data)
        rec_uuid = uuid.uuid4()
        pid = current_pidstore.minters['cds_recid'](rec_uuid, data)
        record = Record.create(data, id_=rec_uuid)
    return pid, record
Ejemplo n.º 32
0
def create_object(bucket, file_name, stream):
    """Object creation inside the bucket using the file and its content."""
    obj = ObjectVersion.create(bucket, file_name, stream=stream)
    rec_uuid = uuid4()
    provider = RecordIdProvider.create(object_type='rec', object_uuid=rec_uuid)
    data = {
        'pid_value':
        provider.pid.pid_value,
        'files': [{
            'uri': '/files/{0}/{1}'.format(str(bucket.id), file_name),
            'key': file_name,
            'size': obj.file.size,
            'bucket': str(bucket.id),
            'local': True
        }]
    }
    Record.create(data, id_=rec_uuid)
Ejemplo n.º 33
0
def create_record(data):
    """Create a test record."""
    with db.session.begin_nested():
        data = copy.deepcopy(data)
        rec_uuid = uuid.uuid4()
        pid = current_pidstore.minters['recid'](rec_uuid, data)
        record = Record.create(data, id_=rec_uuid)
    return pid, record
def test_db():
    """Test database backend."""
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get(
        'SQLALCHEMY_DATABASE_URI', 'sqlite:///test.db'
    )
    FlaskCLI(app)
    InvenioDB(app)
    InvenioRecords(app)

    with app.app_context():
        create_database(db.engine.url)
        db.create_all()
        assert len(db.metadata.tables) == 3

    data = {'title': 'Test'}
    from invenio_records.models import RecordMetadata as RM

    # Create a record
    with app.app_context():
        assert RM.query.count() == 0

        record_uuid = Record.create(data).id
        db.session.commit()

        assert RM.query.count() == 1
        db.session.commit()

    # Retrieve created record
    with app.app_context():
        record = Record.get_record(record_uuid)
        assert record.dumps() == data
        with pytest.raises(NoResultFound):
            Record.get_record(uuid.uuid4())
        record['field'] = True
        record = record.patch([
            {'op': 'add', 'path': '/hello', 'value': ['world']}
        ])
        assert record['hello'] == ['world']
        record.commit()
        db.session.commit()

    with app.app_context():
        record2 = Record.get_record(record_uuid)
        assert record2.model.version_id == 2
        assert record2['field']
        assert record2['hello'] == ['world']
        db.session.commit()

    # Cannot commit record without model (i.e. Record.create_record)
    with app.app_context():
        record3 = Record({'title': 'Not possible'})
        with pytest.raises(RecordNotCommitableError):
            record3.commit()

    with app.app_context():
        db.drop_all()
        drop_database(db.engine.url)
Ejemplo n.º 35
0
def test_invalid_patch(app):
    """Test INVALID record patch request (PATCH .../records/<record_id>)."""
    with app.app_context():
        InvenioRecordsREST(app)
        with app.test_client() as client:
            # check that PATCH with non existing id will return 404
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=0),
                               data=json.dumps(test_patch),
                               headers=headers)
            assert res.status_code == 404

            # create the record using the internal API
            internal_record = Record.create(test_data)
            # check that PATCH with non accepted format will return 406
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'video/mp4')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data=json.dumps(test_patch),
                               headers=headers)
            assert res.status_code == 406

            # check that PATCH with non-json Content-Type will return 400
            headers = [('Content-Type', 'video/mp4'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data=json.dumps(test_patch),
                               headers=headers)
            assert res.status_code == 415

            # check that PATCH with invalid json-patch will return 400
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data=json.dumps([{
                                   'invalid': 'json-patch'
                               }]),
                               headers=headers)
            assert res.status_code == 400

            # check that PATCH with invalid json will return 400
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data='{sdfsdf',
                               headers=headers)
            assert res.status_code == 400
def test_api(app, tmpdir):
    """Test view."""
    hello = tmpdir.join('hello.txt')
    hello.write('Hello world!')

    bye = tmpdir.join('bye.txt')
    bye.write('Bye bye!')

    with app.app_context():
        record = Record.create({
            'title': 'Greetings',
            'document': hello.strpath
        })
        document = Document(record, '/document')

        assert document.open().read() == hello.read()

        # Change document uri
        document.uri = bye.strpath
        assert record['document'] == bye.strpath
        assert document.open().read() == bye.read()

        # Move bye.txt to done.txt
        done = tmpdir.join('done.txt')
        document.move(os.path.abspath(done.strpath))
        assert document.uri == done.strpath
        assert record['document'] == done.strpath
        assert 'Bye bye!' == document.open().read()

        # Copy done.txt to copy.txt
        copy = tmpdir.join('copy.txt')
        copy_patch = document.copy(copy.strpath)
        assert document.uri == done.strpath
        assert copy_patch[0]['value'] == copy.strpath
        assert done.read() == copy.read()

        # Set hello.txt to done.txt
        document.setcontents(hello)
        assert document.open().read() == hello.read()
        assert done.read() == hello.read()

        # Set copy.txt to done.txt via path
        document.setcontents(copy.strpath)
        assert document.open().read() == copy.read()
        assert done.read() == copy.read()

        # Remove done.txt from metadata
        document.remove()
        assert document.uri is None
        assert os.path.exists(done.strpath)

        # Remove copy.txt from filesystem
        assert os.path.exists(copy.strpath)
        document.uri = copy.strpath
        document.remove(force=True)
        assert document.uri is None
        assert not os.path.exists(copy.strpath)
Ejemplo n.º 37
0
def create_object(bucket, file_name, stream):
    """Object creation inside the bucket using the file and its content."""
    obj = ObjectVersion.create(bucket, file_name, stream=stream)
    rec_uuid = uuid4()
    provider = RecordIdProvider.create(object_type='rec', object_uuid=rec_uuid)
    data = {
        'pid_value': provider.pid.pid_value,
        'files': [
            {
                'uri': '/files/{0}/{1}'.format(str(bucket.id), file_name),
                'key': file_name,
                'size': obj.file.size,
                'bucket': str(bucket.id),
                'local': True
            }
        ]
    }
    Record.create(data, id_=rec_uuid)
def test_invalid_patch(app):
    """Test INVALID record patch request (PATCH .../records/<record_id>)."""
    with app.app_context():
        InvenioRecordsREST(app)
        with app.test_client() as client:
            # check that PATCH with non existing id will return 404
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name, record_id=0),
                               data=json.dumps(test_patch),
                               headers=headers)
            assert res.status_code == 404

            # create the record using the internal API
            internal_record = Record.create(test_data)
            # check that PATCH with non accepted format will return 406
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'video/mp4')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data=json.dumps(test_patch),
                               headers=headers)
            assert res.status_code == 406

            # check that PATCH with non-json Content-Type will return 400
            headers = [('Content-Type', 'video/mp4'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data=json.dumps(test_patch),
                               headers=headers)
            assert res.status_code == 415

            # check that PATCH with invalid json-patch will return 400
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data=json.dumps([
                                   {'invalid': 'json-patch'}
                               ]),
                               headers=headers)
            assert res.status_code == 400

            # check that PATCH with invalid json will return 400
            headers = [('Content-Type', 'application/json-patch+json'),
                       ('Accept', 'application/json')]
            res = client.patch(url_for(blueprint.name + '.' +
                                       RecordResource.view_name,
                                       record_id=internal_record.model.id),
                               data='{sdfsdf',
                               headers=headers)
            assert res.status_code == 400
def test_minimal_record(app, db, minimal_record):
    """Test minimal record."""
    # Create record and pid.
    record = Record.create(minimal_record)
    record.model.updated = datetime.utcnow()
    pid = PersistentIdentifier(pid_type='recid', pid_value='2')
    assert record.validate() is None

    expected = {
        u'date_and_time_of_latest_transaction': (
            record.model.updated.strftime("%Y%m%d%H%M%S.0")),
        u'publication_distribution_imprint': [{
            'date_of_publication_distribution': record['publication_date']
        }],
        u'control_number': '123',
        u'information_relating_to_copyright_status': {
            'copyright_status': 'open'
        },
        u'summary': {
            'summary': 'My description'
        },
        u'main_entry_personal_name': {
            'personal_name': 'Test'
        },
        u'resource_type': {
            'type': 'software'
        },
        u'title_statement': {
            'title': 'Test'
        },
        u'leader': {
            'base_address_of_data': '00000',
            'bibliographic_level': 'monograph_item',
            'character_coding_scheme': 'marc-8',
            'descriptive_cataloging_form': 'unknown',
            'encoding_level': 'unknown',
            'indicator_count': 2,
            'length_of_the_implementation_defined_portion': 0,
            'length_of_the_length_of_field_portion': 4,
            'length_of_the_starting_character_position_portion': 5,
            'multipart_resource_record_level':
                'not_specified_or_not_applicable',
            'record_length': '00000',
            'record_status': 'new',
            'subfield_code_count': 2,
            'type_of_control': 'no_specified_type',
            'type_of_record': 'computer_file',
            'undefined': 0,
        },
    }

    data = marcxml_v1.schema_class().dump(marcxml_v1.preprocess_record(
        pid=pid,
        record=record)).data
    assert_dict(expected, data)

    marcxml_v1.serialize(pid=pid, record=record)
Ejemplo n.º 40
0
def test_undelete_no_get(testapp, db):
    """Test undelete a record."""
    record = Record.create({'title': 'test'})
    db.session.commit()
    record.delete()
    db.session.commit()
    record.undelete()
    record.commit()
    db.session.commit()
    assert record == {'title': 'test'}
Ejemplo n.º 41
0
def test_record_replace_refs(app, db):
    """Test the replacement of JSON references using JSONResolver."""
    record = Record.create({"one": {"$ref": "http://nest.ed/A"}, "three": {"$ref": "http://nest.ed/ABC"}})
    app.extensions["invenio-records"].loader_cls = json_loader_factory(JSONResolver(plugins=["demo.json_resolver"]))
    out_json = record.replace_refs()
    expected_json = {
        "one": {"letter": "A", "next": "."},
        "three": {"letter": "A", "next": {"letter": "B", "next": {"letter": "C", "next": "."}}},
    }
    assert out_json == expected_json
def test_api(app, tmpdir):
    """Test view."""
    hello = tmpdir.join('hello.txt')
    hello.write('Hello world!')

    bye = tmpdir.join('bye.txt')
    bye.write('Bye bye!')

    with app.app_context():
        record = Record.create({'title': 'Greetings',
                                'document': hello.strpath})
        document = Document(record, '/document')

        assert document.open().read() == hello.read()

        # Change document uri
        document.uri = bye.strpath
        assert record['document'] == bye.strpath
        assert document.open().read() == bye.read()

        # Move bye.txt to done.txt
        done = tmpdir.join('done.txt')
        document.move(os.path.abspath(done.strpath))
        assert document.uri == done.strpath
        assert record['document'] == done.strpath
        assert 'Bye bye!' == document.open().read()

        # Copy done.txt to copy.txt
        copy = tmpdir.join('copy.txt')
        copy_patch = document.copy(copy.strpath)
        assert document.uri == done.strpath
        assert copy_patch[0]['value'] == copy.strpath
        assert done.read() == copy.read()

        # Set hello.txt to done.txt
        document.setcontents(hello)
        assert document.open().read() == hello.read()
        assert done.read() == hello.read()

        # Set copy.txt to done.txt via path
        document.setcontents(copy.strpath)
        assert document.open().read() == copy.read()
        assert done.read() == copy.read()

        # Remove done.txt from metadata
        document.remove()
        assert document.uri is None
        assert os.path.exists(done.strpath)

        # Remove copy.txt from filesystem
        assert os.path.exists(copy.strpath)
        document.uri = copy.strpath
        document.remove(force=True)
        assert document.uri is None
        assert not os.path.exists(copy.strpath)
Ejemplo n.º 43
0
def test_validate_partial(app, db):
    """Test partial validation."""
    schema = {
        'properties': {
            'a': {
                'type': 'string'
            },
            'b': {
                'type': 'string'
            },
        },
        'required': ['b']
    }
    data = {'a': 'hello', '$schema': schema}
    with app.app_context():
        # Test validation on create()

        # normal validation should fail because 'b' is required
        with pytest.raises(ValidationError) as exc_info:
            Record.create(data)
        assert "'b' is a required property" == exc_info.value.message
        # validate with a less restrictive validator
        record = Record.create(data, validator=PartialDraft4Validator)
        # set wrong data types should fails in any case
        data_incorrect = copy.deepcopy(data)
        data_incorrect['a'] = 1
        with pytest.raises(ValidationError) as exc_info:
            Record.create(data_incorrect, validator=PartialDraft4Validator)
        assert "1 is not of type 'string'" == exc_info.value.message

        # Test validation on commit()

        # validation not passing with normal validator
        with pytest.raises(ValidationError) as exc_info:
            record.commit()
        assert "'b' is a required property" == exc_info.value.message
        # validation passing with less restrictive validator
        assert data == record.commit(validator=PartialDraft4Validator)
        # set wrong data types should fails in any case
        record['a'] = 1
        with pytest.raises(ValidationError) as exc_info:
            record.commit(validator=PartialDraft4Validator)
Ejemplo n.º 44
0
def test_undelete_with_get(testapp, db):
    """Test undelete a record."""
    record = Record.create({'title': 'test'})
    db.session.commit()
    record.delete()
    db.session.commit()
    record = Record.get_record(record.id, with_deleted=True)
    record.undelete()
    record.commit()
    db.session.commit()
    assert record == {}
Ejemplo n.º 45
0
def published_record(app, db, schemas, mappings, prepare_es):
    # let's create a record
    record_uuid = uuid.uuid4()
    data = {'title': 'blah', '$schema': schemas['published']}
    recid_minter(record_uuid, data)
    rec = Record.create(data, id_=record_uuid)
    RecordIndexer().index(rec)
    current_search_client.indices.refresh()
    current_search_client.indices.flush()

    return rec
Ejemplo n.º 46
0
def create_record(app, item_dict, mint_oaiid=True):
    """Create test record."""
    indexer = RecordIndexer()
    with app.test_request_context():
        record_id = uuid.uuid4()
        recid_minter(record_id, item_dict)
        if mint_oaiid:
            oaiid_minter(record_id, item_dict)
        record = Record.create(item_dict, id_=record_id)
        indexer.index(record)
        return record
Ejemplo n.º 47
0
def test_record_dump(app, db):
    """Test record dump method."""
    with app.app_context():
        record = Record.create({
            'foo': {
                'bar': 'Bazz',
            },
        })
        record_dump = record.dumps()
        record_dump['foo']['bar'] = 'Spam'
        assert record_dump['foo']['bar'] != record['foo']['bar']
Ejemplo n.º 48
0
def create_record(app, item_dict, mint_oaiid=True):
    """Create test record."""
    indexer = RecordIndexer()
    with app.test_request_context():
        record_id = uuid.uuid4()
        recid_minter(record_id, item_dict)
        if mint_oaiid:
            oaiid_minter(record_id, item_dict)
        record = Record.create(item_dict, id_=record_id)
        indexer.index(record)
        return record
Ejemplo n.º 49
0
def test_validate_partial(app, db):
    """Test partial validation."""
    schema = {
        'properties': {
            'a': {'type': 'string'},
            'b': {'type': 'string'},
        },
        'required': ['b']
    }
    data = {
        'a': 'hello',
        '$schema': schema
    }
    with app.app_context():
        # Test validation on create()

        # normal validation should fail because 'b' is required
        with pytest.raises(ValidationError) as exc_info:
            Record.create(data)
        assert "'b' is a required property" == exc_info.value.message
        # validate with a less restrictive validator
        record = Record.create(data, validator=PartialDraft4Validator)
        # set wrong data types should fails in any case
        data_incorrect = copy.deepcopy(data)
        data_incorrect['a'] = 1
        with pytest.raises(ValidationError) as exc_info:
            Record.create(data_incorrect, validator=PartialDraft4Validator)
        assert "1 is not of type 'string'" == exc_info.value.message

        # Test validation on commit()

        # validation not passing with normal validator
        with pytest.raises(ValidationError) as exc_info:
            record.commit()
        assert "'b' is a required property" == exc_info.value.message
        # validation passing with less restrictive validator
        assert data == record.commit(validator=PartialDraft4Validator)
        # set wrong data types should fails in any case
        record['a'] = 1
        with pytest.raises(ValidationError) as exc_info:
            record.commit(validator=PartialDraft4Validator)
Ejemplo n.º 50
0
def datasets():
    """Load demo datasets records."""
    from invenio_db import db
    from invenio_records_files.api import Record
    from invenio_indexer.api import RecordIndexer
    from cernopendata.modules.records.minters.recid import \
        cernopendata_recid_minter
    from cernopendata.modules.records.minters.datasetid import \
        cernopendata_datasetid_minter

    from invenio_files_rest.models import \
        Bucket, FileInstance, ObjectVersion
    from invenio_records_files.models import RecordsBuckets

    indexer = RecordIndexer()
    schema = current_app.extensions['invenio-jsonschemas'].path_to_url(
        'records/datasets-v1.0.0.json')
    data = pkg_resources.resource_filename('cernopendata',
                                           'modules/fixtures/data/datasets')
    datasets_json = glob.glob(os.path.join(data, '*.json'))

    for filename in datasets_json:
        with open(filename, 'rb') as source:
            for data in json.load(source):
                files = data.pop('files', None)

                id = uuid.uuid4()
                # (TOFIX) Remove if statement in production
                # as every dataset record should have a doi
                if data.get('doi', None):
                    cernopendata_datasetid_minter(id, data)
                else:
                    cernopendata_recid_minter(id, data)
                record = Record.create(data, id_=id)
                record['$schema'] = schema
                bucket = Bucket.create()
                RecordsBuckets.create(record=record.model, bucket=bucket)

                for file in files:
                    assert 'uri' in file
                    assert 'size' in file
                    assert 'checksum' in file

                    f = FileInstance.create()
                    filename = file.get("uri").split('/')[-1:][0]
                    f.set_uri(file.get("uri"), file.get("size"),
                              file.get("checksum"))

                    ObjectVersion.create(bucket, filename, _file_id=f.id)
                db.session.commit()
                indexer.index(record)
                db.session.expunge_all()
Ejemplo n.º 51
0
def test_get_records(app, db):
    """Test bulk record fetching."""
    # Create test records
    test_records = [
        Record.create({"title": "test1"}),
        Record.create({"title": "to_be_deleted"}),
        Record.create({"title": "test3"}),
    ]
    db.session.commit()
    test_ids = [record.id for record in test_records]

    # Fetch test records
    assert len(Record.get_records(test_ids)) == 3

    test_records[1].delete()

    # should not show deleted
    db.session.commit()
    assert len(Record.get_records(test_ids)) == 2

    # should show deleted
    assert len(Record.get_records(test_ids, with_deleted=True)) == 3
Ejemplo n.º 52
0
def test_get_records(app, db):
    """Test bulk record fetching."""
    # Create test records
    test_records = [
        Record.create({'title': 'test1'}),
        Record.create({'title': 'to_be_deleted'}),
        Record.create({'title': 'test3'}),
    ]
    db.session.commit()
    test_ids = [record.id for record in test_records]

    # Fetch test records
    assert len(Record.get_records(test_ids)) == 3

    test_records[1].delete()

    # should not show deleted
    db.session.commit()
    assert len(Record.get_records(test_ids)) == 2

    # should show deleted
    assert len(Record.get_records(test_ids, with_deleted=True)) == 3
Ejemplo n.º 53
0
def test_validate_with_format(app, db):
    """Test that validation can accept custom format rules."""
    with app.app_context():
        checker = FormatChecker()
        checker.checks('foo')(lambda el: el.startswith('foo'))
        data = {
            'bar': 'foo',
            '$schema': {
                'properties': {
                    'bar': {
                        'format': 'foo'
                    }
                }
            }
        }

        # test record creation with valid data
        assert data == Record.create(data)
        record = Record.create(data, format_checker=checker)
        # test direct call to validate with valid data
        assert record.validate(format_checker=checker) is None
        # test commit with valid data
        record.commit(format_checker=checker)

        record['bar'] = 'bar'
        # test direct call to validate with invalid data
        with pytest.raises(ValidationError) as excinfo:
            record.validate(format_checker=checker)
        assert "'bar' is not a 'foo'" in str(excinfo.value)
        # test commit with invalid data
        with pytest.raises(ValidationError) as excinfo:
            record.commit(format_checker=checker)
        assert "'bar' is not a 'foo'" in str(excinfo.value)

        data['bar'] = 'bar'
        # test record creation with invalid data
        with pytest.raises(ValidationError) as excinfo:
            record = Record.create(data, format_checker=checker)
        assert "'bar' is not a 'foo'" in str(excinfo.value)
def create_record(collection):
    """Basic test view."""

    collection = Collection.query.filter(
        Collection.name == collection).first_or_404()

    schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'),
                     url_for('records.jsonschema',
                             collection=collection.name))

    data, pid, recid = construct_record(collection,
                                        json.loads(request.get_data()),
                                        current_user.id,
                                        schema)

    try:
        record = Record.create(data, id_=recid)
    except ValidationError as error:
        print("============================")
        print(error.message)
        print("============================")

        db.session.rollback()
        resp = jsonify(**{'message': error.message})
        resp.status_code = 400
        return resp

    # Invenio-Indexer is delegating the document inferring to
    # Invenio-Search which is analysing the string splitting by `/` and
    # using `.json` to be sure that it cans understand the mapping.
    record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

    indexer = RecordIndexer()
    indexer.index(record)

    # Creating permission needs for the record
    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    # Giving index, read, write permissions to user/creator
    db.session.add(ActionUsers.allow(action_edit_record, user=current_user))
    db.session.add(ActionUsers.allow(action_read_record, user=current_user))
    db.session.add(ActionUsers.allow(action_index_record, user=current_user))

    db.session.commit()

    resp = jsonify(**{'pid': pid})
    resp.status_code = 200
    return resp
Ejemplo n.º 55
0
def sample_record(app, test_db):
    record = Record.create(
        {
            "id": "1",
            "identifier": [
                {
                    "value": "oai:server:id",
                    "type": "originalOAI"
                }
            ]
        }
    )
    db_.session.commit()
    return record
def create_record(collection):
    """Basic test view."""

    collection = Collection.query.filter(
        Collection.name == collection).first_or_404()

    schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'),
                     url_for('records.jsonschema',
                             collection=collection.name))

    data, pid, recid = construct_record(collection,
                                        json.loads(request.get_data()),
                                        current_user.id,
                                        schema)

    try:
        record = Record.create(data, id_=recid)
    except ValidationError as error:
        print("============================")
        print(error.message)
        print("============================")

        db.session.rollback()
        resp = jsonify(**{'message': error.message})
        resp.status_code = 400
        return resp

    # Invenio-Indexer is delegating the document inferring to
    # Invenio-Search which is analysing the string splitting by `/` and
    # using `.json` to be sure that it cans understand the mapping.
    record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

    indexer = RecordIndexer()
    indexer.index(record)

    # Creating permission needs for the record
    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    # Giving index, read, write permissions to user/creator
    db.session.add(ActionUsers.allow(action_edit_record, user=current_user))
    db.session.add(ActionUsers.allow(action_read_record, user=current_user))
    db.session.add(ActionUsers.allow(action_index_record, user=current_user))

    db.session.commit()

    resp = jsonify(**{'pid': pid})
    resp.status_code = 200
    return resp
Ejemplo n.º 57
0
def draft_record(app, db, schemas, mappings, prepare_es):
    # let's create a record
    draft_uuid = uuid.uuid4()
    data = {'title': 'blah', '$schema': schemas['draft'], 'id': '1'}
    PersistentIdentifier.create(pid_type='drecid',
                                pid_value='1',
                                status=PIDStatus.REGISTERED,
                                object_type='rec',
                                object_uuid=draft_uuid)
    rec = Record.create(data, id_=draft_uuid)

    RecordIndexer().index(rec)
    current_search_client.indices.refresh()
    current_search_client.indices.flush()

    return rec
Ejemplo n.º 58
0
def assign_record_id(record_information, id=None):
    """
    :param record_information:
    :return:
    """
    if id:
        record_information['recid'] = id
    else:
        record_id = Record.create(record_information).id
        PersistentIdentifier.create('recid', record_id,
                                    object_type='rec',
                                    object_uuid=uuid.uuid4(),
                                    status=PIDStatus.REGISTERED)

    # bit redundant, but the recid is used in many places.
    record_information['control_number'] = record_information['recid']
Ejemplo n.º 59
0
def record_upsert(json):
    """Insert or update a record."""
    control_number = json.get('control_number', json.get('recid'))
    if control_number:
        control_number = int(control_number)
        pid_type = InspireRecordIdProvider.schema_to_pid_type(json['$schema'])
        try:
            pid = PersistentIdentifier.get(pid_type, control_number)
            record = Record.get_record(pid.object_uuid)
            record.update(json)
            record.commit()
        except PIDDoesNotExistError:
            record = Record.create(json, id_=None)
            # Create persistent identifier.
            inspire_recid_minter(str(record.id), json)

        return record
Ejemplo n.º 60
0
def store_record(obj, *args, **kwargs):
    """Create and index new record in main record space."""
    if '$schema' in obj.data:
        obj.data['$schema'] = url_for(
            'invenio_jsonschemas.get_schema',
            schema_path="records/{0}".format(obj.data['$schema'])
        )
    # Create record
    rec_uuid = str(Record.create(obj.data, id_=None).id)

    # Create persistent identifier.
    pid = inspire_recid_minter(rec_uuid, obj.data)
    db.session.commit()

    # Index record
    indexer = RecordIndexer()
    indexer.index_by_id(pid.object_uuid)