def test_locationsdumper_with_polygon_and_no_shapely(app, db, minimal_record): dumper = ElasticsearchDumper(extensions=[LocationsDumper()]) minimal_record['metadata']['locations'] = { 'features': [{ 'geometry': { 'type': 'Polygon', 'coordinates': [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], ]] } }], } record = RDMRecord.create(minimal_record) with pytest.warns(UserWarning): dump = record.dumps(dumper=dumper) assert 'centroid' not in dump['metadata']['locations']['features'][0]
def test_esdumper_with_edtfext(app, db, minimal_record, location, date, expected_start, expected_end): """Test edft extension implementation.""" # Create a simple extension that adds a computed field. dumper = ElasticsearchDumper(extensions=[ EDTFDumperExt("metadata.publication_date"), EDTFListDumperExt("metadata.dates", "date"), ]) minimal_record["metadata"]["publication_date"] = date minimal_record["metadata"]["dates"] = [{"date": date}] # Create the record record = RDMRecord.create(minimal_record, parent=RDMParent.create({})) db.session.commit() # Dump it dump = record.dumps(dumper=dumper) assert dump["metadata"]["publication_date_range"]["gte"] == expected_start assert dump["metadata"]["publication_date_range"]["lte"] == expected_end assert dump["metadata"]["publication_date"] == date assert dump["metadata"]["dates"][0]["date_range"]["gte"] == expected_start assert dump["metadata"]["dates"][0]["date_range"]["lte"] == expected_end assert dump["metadata"]["dates"][0]["date"] == date # Load it new_record = RDMRecord.loads(dump, loader=dumper) assert "publication_date_range" not in new_record["metadata"] assert "publication_date" in new_record["metadata"] assert "date_range" not in new_record["metadata"]["dates"][0] assert "date" in new_record["metadata"]["dates"][0]
def test_access_component_valid(minimal_record, parent, identity_simple, users): record = RDMRecord.create(minimal_record, parent=parent) component = AccessComponent(current_rdm_records.records_service) component.create(identity_simple, minimal_record, record) assert len(record.parent.access.owners) > 0
def test_locationsdumper_with_polygon_and_mock_shapely(app, db, minimal_record): with unittest.mock.patch( 'invenio_rdm_records.records.dumpers.locations.shapely' ) as shapely: dumper = ElasticsearchDumper(extensions=[LocationsDumper()]) minimal_record['metadata']['locations'] = { 'features': [{ 'geometry': { 'type': 'Polygon', 'coordinates': [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], ]] } }], } record = RDMRecord.create(minimal_record) shape = unittest.mock.Mock() shape.centroid.x, shape.centroid.y = 100.5, 0.5 shapely.geometry.shape.return_value = shape dump = record.dumps(dumper=dumper) shapely.geometry.shape.assert_called_once_with( minimal_record['metadata']['locations']['features'][0]['geometry']) assert dump['metadata']['locations']['features'][0]['centroid'] == \ [100.5, 0.5]
def test_locationsdumper_with_point_geometry(app, db, minimal_record): dumper = ElasticsearchDumper(extensions=[LocationsDumper()]) minimal_record['metadata']['locations'] = { 'features': [{ 'geometry': { 'type': 'Point', 'coordinates': [6.052778, 46.234167] } }] } record = RDMRecord.create(minimal_record) # Dump it dump = record.dumps(dumper=dumper) # Centroid has been inferred dumped_feature = dump['metadata']['locations']['features'][0] expected_feature = minimal_record['metadata']['locations']['features'][0] assert (dumped_feature['centroid'] == expected_feature['geometry'] ['coordinates']) # And it round-trips assert (record.loads(dump, loader=dumper)['metadata']['locations'] == minimal_record['metadata']['locations'])
def test_locationsdumper_with_no_featurecollection(app, db, minimal_record): dumper = ElasticsearchDumper(extensions=[LocationsDumper()]) record = RDMRecord.create(minimal_record) # Dump it dump = record.dumps(dumper=dumper)
def test_locationsdumper_with_polygon_and_shapely(app, db, minimal_record): pytest.importorskip('shapely') dumper = ElasticsearchDumper(extensions=[LocationsDumper()]) # This also tests shapes with elevations minimal_record['locations'] = { 'features': [{ 'geometry': { 'type': 'Polygon', 'coordinates': [[ [100.0, 0.0, 10], [101.0, 0.0, 10], [101.0, 1.0, 30], [100.0, 1.0, 30], [100.0, 0.0, 10], ]] } }], } record = RDMRecord.create(minimal_record) dump = record.dumps(dumper=dumper) # 3D geometries still lead to 2D centroids assert dump['locations']['features'][0]['centroid'] == [100.5, 0.5]
def test_eslistdumper_with_edtfext_parse_error(app, db, minimal_record): """Test edft extension implementation.""" dumper = ElasticsearchDumper( extensions=[ EDTFListDumperExt("metadata.creators", "family_name"), ] ) # Create the record record = RDMRecord.create(minimal_record, parent=RDMParent.create({})) db.session.commit() # Dump it dump = record.dumps(dumper=dumper) person_or_org = dump["metadata"]["creators"][0]["person_or_org"] assert "family_name_range" not in person_or_org assert "family_name" in person_or_org # Load it new_record = RDMRecord.loads(dump, loader=dumper) person_or_org = dump["metadata"]["creators"][0]["person_or_org"] assert 'family_name_range' not in person_or_org assert 'family_name' in person_or_org assert 'type_start' not in new_record['metadata']['resource_type'] assert 'type_end' not in new_record['metadata']['resource_type'] assert 'type' in new_record['metadata']['resource_type']
def test_permission_policy_generators(app, anyuser_identity, authenticated_identity, superuser_identity, system_process_identity): """Test permission policies with given Identities.""" policy = TestRDMPermissionPolicy # TODO: add to fixture rest_record = RDMRecord.create({}, access={}, parent=RDMParent.create({})) rest_record.access.protection.set("restricted", "restricted") rest_record.parent.access.owners.add({'user': 1}) # TODO: add to fixture pub_record = RDMRecord.create({}, access={}, parent=RDMParent.create({})) pub_record.access.protection.set("public", "public") pub_record.parent.access.owners.add({'user': 21}) assert policy(action='search').allows(anyuser_identity) assert policy(action='search').allows(system_process_identity) assert policy(action='create').allows(authenticated_identity) assert policy(action='create').allows(system_process_identity) assert isinstance(policy(action='update').generators[0], Disable) assert isinstance(policy(action='delete').generators[0], Disable) assert policy(action='read').generators[0].needs(record=rest_record) == { UserNeed(1) } assert policy(action='read').generators[0].needs(record=pub_record) == { system_process, any_user } assert policy(action='read_files').generators[0].needs( record=rest_record) == {UserNeed(1)} assert isinstance(policy(action='update_files').generators[0], Disable) assert policy(action='read_draft').generators[0].needs( record=rest_record) == [UserNeed(1)] assert policy(action='update_draft').generators[0].needs( record=rest_record) == [UserNeed(1)] assert policy(action='delete_draft').generators[0].needs( record=rest_record) == [UserNeed(1)] assert policy(action='read_draft_files').generators[0].needs( record=rest_record) == [UserNeed(1)] assert policy(action='read_update_files').generators[0].needs( record=rest_record) == [UserNeed(1)] assert policy(action='publish').generators[0].needs( record=rest_record) == [UserNeed(1)] assert policy(action='manage').generators[0].needs(record=rest_record) == [ UserNeed(1) ]
def test_access_component_unknown_owner(minimal_record, parent, identity_simple, users): record = RDMRecord.create(minimal_record, parent=parent) record.parent["access"]["owned_by"] = [{"user": -1337}] component = AccessComponent(RDMRecordService()) # both should work, since 'access.owned_by' is ignored for anybody # other than system processes component.create(identity_simple, minimal_record, record) component.update_draft(identity_simple, minimal_record, record)
def test_access_field_clear_embargo(minimal_record, parent): next_year = arrow.utcnow().datetime + timedelta(days=+365) minimal_record["access"]["embargo"] = { "until": next_year.strftime("%Y-%m-%d"), "active": True, "reason": "nothing in particular", } rec = RDMRecord.create(minimal_record, parent=parent) rec.access.embargo.clear() assert not rec.access.embargo
def test_access_component_unknown_owner_with_system_process( minimal_record, parent, users): record = RDMRecord.create(minimal_record, parent=parent) record.parent["access"]["owned_by"] = [{"user": -1337}] component = AccessComponent(current_rdm_records.records_service) with pytest.raises(ValidationError): component.create(system_identity, minimal_record, record) with pytest.raises(ValidationError): component.update_draft(system_identity, minimal_record, record)
def test_access_component_set_owner(minimal_record, parent, users): user = users[0] identity = Identity(user.id) identity.provides.add(UserNeed(user.id)) record = RDMRecord.create(minimal_record, parent=parent) record.parent["access"]["owned_by"] = [] component = AccessComponent(current_rdm_records.records_service) component.create(identity, minimal_record, record) assert len(record.access.owners) == 1 assert list(record.access.owners)[0].resolve() == user
def _owned_record(): data = { "access": { "owned_by": [ {"user": 16}, {"user": 17}, ] } } record = RDMRecord.create({}, access={}) record.parent = RDMParent(data) return record
def test_access_field_update_protection(minimal_record, parent, users): minimal_record["access"]["record"] = "restricted" minimal_record["access"]["files"] = "restricted" rec = RDMRecord.create(minimal_record, parent=parent) assert rec.access.protection.record == "restricted" assert rec.access.protection.files == "restricted" rec.access.protection.set("public", "public") rec.commit() assert rec["access"]["record"] == "public" assert rec["access"]["files"] == "public"
def test_access_field_on_record(running_app, minimal_record, parent, users): next_year = arrow.utcnow().datetime + timedelta(days=+365) minimal_record["access"]["embargo"] = { "until": next_year.strftime("%Y-%m-%d"), "active": True, "reason": "nothing in particular", } rec = RDMRecord.create(minimal_record, parent=parent) assert isinstance(rec.access, RecordAccess) assert isinstance(rec.access.protection, Protection) assert rec.access.protection.record == minimal_record["access"]["record"] assert rec.access.protection.files == minimal_record["access"]["files"] assert isinstance(rec.access.embargo, Embargo)
def test_access_component_unknown_grant_subject(minimal_record, parent, identity_simple, users): record = RDMRecord.create(minimal_record, parent=parent) record.parent["access"]["grants"] = [{ "subject": "user", "id": "-1337", "level": "view" }] component = AccessComponent(current_rdm_records.records_service) with pytest.raises(ValidationError): component.create(identity_simple, minimal_record, record) with pytest.raises(ValidationError): component.update_draft(identity_simple, minimal_record, record)
def test_access_field_update_embargo(minimal_record, parent, users): next_year = arrow.utcnow().datetime + timedelta(days=+365) minimal_record["access"]["embargo"] = { "until": next_year.strftime("%Y-%m-%d"), "active": True, "reason": "nothing in particular", } rec = RDMRecord.create(minimal_record.copy(), parent=parent) assert rec.access.embargo rec.access.embargo.active = False rec.access.embargo.reason = "can't remember" rec.commit() minimal_record["access"]["embargo"]["active"] = False minimal_record["access"]["embargo"]["reason"] = "can't remember"
def test_metadata_component(minimal_record, parent, identity_simple, location): """Test the metadata component.""" record = RDMRecord.create(minimal_record, parent=parent) draft = RDMDraft.new_version(record) assert 'publication_date' in record.metadata assert 'title' in record.metadata component = MetadataComponent(RDMRecordService()) component.new_version(identity_simple, draft=draft, record=record) # Make sure publication_date was NOT copied, but that title WAS copied assert 'publication_date' not in draft.metadata assert 'title' in draft.metadata # make sure the reference management is correct assert 'publication_date' in record.metadata
def test_access_field_update_owners(minimal_record, parent, users): rec = RDMRecord.create(minimal_record.copy(), parent=parent) parent = rec.parent new_owner = {"user": 1337} parent.access.owners.add(users[0]) parent.access.owners.add(new_owner) parent.commit() num_owners = len(parent.access.owners) assert num_owners == len(parent["access"]["owned_by"]) assert num_owners == 2 assert new_owner in parent["access"]["owned_by"] parent.access.owners.remove(new_owner) parent.commit() num_owners = len(parent.access.owners) assert num_owners == len(parent["access"]["owned_by"]) assert num_owners == 1 assert new_owner not in parent["access"]["owned_by"]
def test_access_component_update_access_via_json(minimal_record, parent, users, identity_simple): next_year = arrow.utcnow().datetime + timedelta(days=+365) restricted_access = { "record": "restricted", "files": "restricted", "embargo": { "until": next_year.strftime("%Y-%m-%d"), "active": True, "reason": "nothing in particular", }, } minimal_record["access"] = restricted_access # create an initially restricted-access record record = RDMRecord.create(minimal_record, parent=parent) component = AccessComponent(current_rdm_records.records_service) component.create(identity_simple, minimal_record, record) prot = record.access.protection assert record.access.embargo is not None assert "embargo" in record["access"] assert prot.record == record["access"]["record"] == "restricted" assert prot.files == record["access"]["files"] == "restricted" # update the record's access via new json data # (instead of via the record's access object) new_data = minimal_record.copy() public_access = { "grants": [], "record": "public", "files": "public", } new_data["access"] = public_access component.create(identity_simple, new_data, record) prot = record.access.protection assert not record.access.embargo assert "embargo" not in record["access"] assert prot.record == record["access"]["record"] == "public" assert prot.files == record["access"]["files"] == "public"
def test_eslistdumper_with_edtfext_not_defined(app, db, minimal_record): """Test edft extension implementation.""" # Create a simple extension that adds a computed field. dumper = ElasticsearchDumper(extensions=[ EDTFListDumperExt("metadata.non_existing_array_field", "date"), ]) # Create the record record = RDMRecord.create(minimal_record, parent=RDMParent.create({})) db.session.commit() # Dump it dump = record.dumps(dumper=dumper) assert "non_existing_array_field_range" not in dump["metadata"] assert "non_existing_array_field" not in dump["metadata"] # Load it new_record = RDMRecord.loads(dump, loader=dumper) assert "non_existing_array_field_range" not in new_record["metadata"] assert "non_existing_array_field" not in new_record["metadata"]
def test_esdumper_with_edtfext_parse_error(app, db, location, minimal_record): """Test edft extension implementation.""" # NOTE: We cannot trigger this on publication_date because it is checked # by marshmallow on record creation. We can simply give a non date field. dumper = ElasticsearchDumper(extensions=[ EDTFDumperExt("metadata.resource_type.type"), ]) # Create the record record = RDMRecord.create(minimal_record, parent=RDMParent.create({})) db.session.commit() # Dump it dump = record.dumps(dumper=dumper) assert "type_range" not in dump["metadata"]["resource_type"] assert "type" in dump["metadata"]["resource_type"] # Load it new_record = RDMRecord.loads(dump, loader=dumper) assert "type_range" not in new_record["metadata"]["resource_type"] assert "type" in new_record["metadata"]["resource_type"]
def test_esdumper_with_externalpidsext(app, db, minimal_record, location): # Create a simple extension that adds a computed field. dumper = ElasticsearchDumper( extensions=[PIDsDumperExt()] ) minimal_record["pids"] = { "doi": { "identifier": "10.5281/zenodo.1234", "provider": "datacite", "client": "zenodo" }, "handle": { "identifier": "9.12314", "provider": "cern-handle", "client": "zenodo" } } # Create the record record = RDMRecord.create(minimal_record, parent=RDMParent.create({})) db.session.commit() # Dump it dump = record.dumps(dumper=dumper) dumped_pids = dump["pids"] for dumped_pid in dumped_pids: pid_attrs = dumped_pid.keys() assert "scheme" in pid_attrs assert "identifier" in pid_attrs assert "provider" in pid_attrs assert "client" in pid_attrs # Load it new_record = RDMRecord.loads(dump, loader=dumper) assert minimal_record["pids"] == new_record["pids"]
def _owned_record(): parent = RDMParent.create({}) parent.access.owners.add({"user": 16}) parent.access.owners.add({"user": 17}) record = RDMRecord.create({}, parent=parent) return record