diff --git a/nomad/datamodel/datamodel.py b/nomad/datamodel/datamodel.py index 5470a5a3fd7fbf6a6a721e0fef242ee576f9c40e..03e6f115d16000fc6d8e0a468f520e143cdce079 100644 --- a/nomad/datamodel/datamodel.py +++ b/nomad/datamodel/datamodel.py @@ -325,6 +325,8 @@ def derive_authors(entry: 'EntryMetadata') -> List[User]: authors: List[User] = [] if entry.main_author is not None and entry.external_db is None: authors.append(entry.main_author) + if entry.coauthors: + authors.extend(entry.coauthors) if entry.entry_coauthors: authors.extend(entry.entry_coauthors) return authors @@ -387,6 +389,8 @@ class EntryMetadata(metainfo.MSection): origin: A short human readable description of the entries origin. Usually it is the handle of an external database/repository or the name of the main author. main_author: Id of the main author of this entry. + coauthors: A user provided list of co-authors for the whole upload. These can view + and edit the upload when in staging, and view it also if it is embargoed. entry_coauthors: Ids of all co-authors (excl. the main author and upload coauthors) specified on the entry level, rather than on the upload level. They are shown as authors of this entry alongside its main author and upload coauthors. @@ -561,6 +565,13 @@ class EntryMetadata(metainfo.MSection): description='The main author of the entry', a_elasticsearch=Elasticsearch(material_entry_type)) + coauthors = metainfo.Quantity( + type=author_reference, shape=['0..*'], default=[], categories=[MongoUploadMetadata, EditableUserMetadata], + description=''' + A user provided list of co-authors for the whole upload. These can view and edit the + upload when in staging, and view it also if it is embargoed. + ''') + entry_coauthors = metainfo.Quantity( type=author_reference, shape=['0..*'], default=[], categories=[MongoEntryMetadata, EditableUserMetadata], description=''' @@ -581,10 +592,16 @@ class EntryMetadata(metainfo.MSection): derived=derive_authors, a_elasticsearch=Elasticsearch(material_entry_type, metrics=dict(n_authors='cardinality'))) + writers = metainfo.Quantity( + type=user_reference, shape=['0..*'], + description='All viewers (main author, upload coauthors, and reviewers)', + derived=lambda entry: ([entry.main_author] if entry.main_author is not None else []) + entry.coauthors, + a_elasticsearch=Elasticsearch(material_entry_type)) + owners = metainfo.Quantity( type=user_reference, shape=['0..*'], description='All viewers (main author, upload coauthors, and reviewers)', - derived=lambda entry: ([entry.main_author] if entry.main_author is not None else []) + entry.reviewers, + derived=lambda entry: ([entry.main_author] if entry.main_author is not None else []) + entry.coauthors + entry.reviewers, a_elasticsearch=Elasticsearch(material_entry_type)) datasets = metainfo.Quantity( diff --git a/nomad/processing/data.py b/nomad/processing/data.py index a2cacddbf6c1ff146f3d3f7320c614fcaf2f0428..497329bf28ee61eab42d4cd38c94d385bf4185fe 100644 --- a/nomad/processing/data.py +++ b/nomad/processing/data.py @@ -810,6 +810,7 @@ class Upload(Proc): upload_name = StringField(default=None) upload_create_time = DateTimeField(required=True) main_author = StringField(required=True) + coauthors = ListField(StringField(), default=None) reviewers = ListField(StringField(), default=None) last_update = DateTimeField() publish_time = DateTimeField() @@ -1717,10 +1718,11 @@ class Upload(Proc): assert bundle_info['entries'], 'Upload published but no entries in bundle_info.json' # Check user references check_user_ids([upload_dict['main_author']], 'Invalid main_author: {id}') + check_user_ids(upload_dict.get('coauthors', []), 'Invalid coauthor reference: {id}') check_user_ids(upload_dict.get('reviewers', []), 'Invalid reviewers reference: {id}') # Define which keys we think okay to copy from the bundle upload_keys_to_copy = [ - 'upload_name', 'main_author', 'reviewers', 'embargo_length', 'license', + 'upload_name', 'main_author', 'coauthors', 'reviewers', 'embargo_length', 'license', 'from_oasis', 'oasis_deployment_id'] if settings.keep_original_timestamps: upload_keys_to_copy.extend(('upload_create_time', 'publish_time',)) diff --git a/tests/app/v1/conftest.py b/tests/app/v1/conftest.py index 97f32b7eb5cf284baca4fbdc5f098a5a36289df6..f109baa5656341f2afaa65aaf43093bc98b30820 100644 --- a/tests/app/v1/conftest.py +++ b/tests/app/v1/conftest.py @@ -37,61 +37,59 @@ def example_data(elastic_module, raw_files_module, mongo_module, test_user, othe Provides a couple of uploads and entries including metadata, raw-data, and archive files. - 23 entries, 6 materials published without embargo - 1 entry, 1 material unpublished - 1 entry, 1 material unpublished shared - 1 entry, 1 material published with embargo - 1 entry, 1 material published shared with embargo - - partial archive exists only for id_01 - raw files and archive file for id_02 are missing - id_10, id_11 reside in the same directory + id_embargo: + 1 entry, 1 material, published with embargo + id_embargo_w_coauthor: + 1 entry, 1 material, published with embargo and coauthor + id_embargo_w_reviewer: + 1 entry, 1 material, published with embargo and reviewer + id_unpublished: + 1 entry, 1 material, unpublished + id_unpublished_w_coauthor: + 1 entry, 1 material, unpublished with coauthor + id_unpublished_w_reviewer: + 1 entry, 1 material, unpublished with reviewer + id_published: + 23 entries, 6 materials published without embargo + partial archive exists only for id_01 + raw files and archive file for id_02 are missing + id_10, id_11 reside in the same directory + id_processing: + unpublished upload without any entries, in status processing + id_empty: + unpublished upload without any entries ''' data = ExampleData(main_author=test_user) - # one upload with two calc published with embargo, one shared - data.create_upload( - upload_id='id_embargo', - upload_name='name_embargo', - published=True, - embargo_length=12) - data.create_entry( - upload_id='id_embargo', - calc_id='id_embargo', - material_id='id_embargo', - mainfile='test_content/test_embargo_entry/mainfile.json') - data.create_upload( - upload_id='id_embargo_shared_upload', - upload_name='name_embargo_shared', - published=True, - reviewers=[other_test_user.user_id], - embargo_length=12) - data.create_entry( - upload_id='id_embargo_shared_upload', - calc_id='id_embargo_shared', - material_id='id_embargo_shared', - mainfile='test_content/test_embargo_entry_shared/mainfile.json') - - # one upload with two calc in staging, one shared - data.create_upload( - upload_id='id_unpublished', - published=False) - data.create_entry( - upload_id='id_unpublished', - calc_id='id_unpublished', - material_id='id_unpublished', - mainfile='test_content/test_entry/mainfile.json') - data.create_upload( - upload_id='id_unpublished_shared_upload', - published=False, - reviewers=[other_test_user.user_id]) - data.create_entry( - upload_id='id_unpublished_shared_upload', - calc_id='id_unpublished_shared', - material_id='id_unpublished_shared', - mainfile='test_content/test_entry_shared/mainfile.json') - - # one upload with 23 calcs published + # 6 uploads with different combinations of main_type and sub_type + for main_type in ('embargo', 'unpublished'): + for sub_type in ('', 'w_coauthor', 'w_reviewer'): + upload_id = 'id_' + main_type + ('_' if sub_type else '') + sub_type + if main_type == 'embargo': + published = True + embargo_length = 12 + upload_name = 'name_' + upload_id[3:] + else: + published = False + embargo_length = 0 + upload_name = None + calc_id = upload_id + '_1' + coauthors = [other_test_user.user_id] if sub_type == 'w_coauthor' else None + reviewers = [other_test_user.user_id] if sub_type == 'w_reviewer' else None + data.create_upload( + upload_id=upload_id, + upload_name=upload_name, + coauthors=coauthors, + reviewers=reviewers, + published=published, + embargo_length=embargo_length) + data.create_entry( + upload_id=upload_id, + calc_id=calc_id, + material_id=upload_id, + mainfile=f'test_content/{calc_id}/mainfile.json') + + # one upload with 23 calcs, published, no embargo data.create_upload( upload_id='id_published', upload_name='name_published', diff --git a/tests/app/v1/routers/common.py b/tests/app/v1/routers/common.py index 5f96e13bca1e103560b0c6011a7ff05b6f459d33..d14071f2edacdf7b51a8dfad3aca28ad40f60f4c 100644 --- a/tests/app/v1/routers/common.py +++ b/tests/app/v1/routers/common.py @@ -115,24 +115,24 @@ def owner_test_parameters(total: int): pytest.param('shared', None, 401, -1, id='shared-wo-auth'), pytest.param('public', None, 200, total, id='public-wo-auth'), - pytest.param('user', 'test_user', 200, total + 4, id='user-test-user'), - pytest.param('staging', 'test_user', 200, 2, id='staging-test-user'), - pytest.param('visible', 'test_user', 200, total + 4, id='visible-test-user'), + pytest.param('user', 'test_user', 200, total + 6, id='user-test-user'), + pytest.param('staging', 'test_user', 200, 3, id='staging-test-user'), + pytest.param('visible', 'test_user', 200, total + 6, id='visible-test-user'), pytest.param('admin', 'test_user', 401, -1, id='admin-test-user'), - pytest.param('shared', 'test_user', 200, total + 4, id='shared-test-user'), + pytest.param('shared', 'test_user', 200, total + 6, id='shared-test-user'), pytest.param('public', 'test_user', 200, total, id='public-test-user'), pytest.param('user', 'other_test_user', 200, 0, id='user-other-test-user'), - pytest.param('staging', 'other_test_user', 200, 1, id='staging-other-test-user'), - pytest.param('visible', 'other_test_user', 200, total + 2, id='visible-other-test-user'), - pytest.param('shared', 'other_test_user', 200, 2, id='shared-other-test-user'), + pytest.param('staging', 'other_test_user', 200, 2, id='staging-other-test-user'), + pytest.param('visible', 'other_test_user', 200, total + 4, id='visible-other-test-user'), + pytest.param('shared', 'other_test_user', 200, 4, id='shared-other-test-user'), pytest.param('public', 'other_test_user', 200, total, id='public-other-test-user'), - pytest.param('all', None, 200, total + 2, id='metadata-all-wo-auth'), - pytest.param('all', 'test_user', 200, total + 4, id='metadata-all-test-user'), - pytest.param('all', 'other_test_user', 200, total + 3, id='metadata-all-other-test-user'), + pytest.param('all', None, 200, total + 3, id='metadata-all-wo-auth'), + pytest.param('all', 'test_user', 200, total + 6, id='metadata-all-test-user'), + pytest.param('all', 'other_test_user', 200, total + 5, id='metadata-all-other-test-user'), - pytest.param('admin', 'admin_user', 200, total + 4, id='admin-admin-user'), + pytest.param('admin', 'admin_user', 200, total + 6, id='admin-admin-user'), pytest.param('all', 'bad_user', 401, -1, id='bad-credentials') ] @@ -180,7 +180,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref ), pytest.param( {'terms': {'quantity': f'{entry_prefix}upload_id'}}, - 5, 5, 200, 'test_user', id='default'), + 7, 7, 200, 'test_user', id='default'), pytest.param( { 'terms': { @@ -188,7 +188,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref 'pagination': {'order_by': f'{entry_prefix}main_author.user_id'} } }, - 5, 5, 200, 'test_user', id='order-str'), + 7, 7, 200, 'test_user', id='order-str'), pytest.param( { 'terms': { @@ -196,7 +196,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref 'pagination': {'order_by': upload_create_time} } }, - 5, 5, 200, 'test_user', id='order-date'), + 7, 7, 200, 'test_user', id='order-date'), pytest.param( { 'terms': { @@ -204,7 +204,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref 'pagination': {'order_by': f'{entry_prefix}results.properties.n_calculations'} } }, - 5, 5, 200, 'test_user', id='order-int'), + 7, 7, 200, 'test_user', id='order-int'), pytest.param( {'terms': {'quantity': f'{material_prefix}symmetry.structure_name'}}, 0, 0, 200, 'test_user', id='no-results'), @@ -215,7 +215,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref 'pagination': {'page_after_value': 'id_published'} } }, - 5, 2, 200, 'test_user', id='after'), + 7, 3, 200, 'test_user', id='after'), pytest.param( { 'terms': { @@ -226,13 +226,13 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref } } }, - 5, 2, 200, 'test_user', id='after-order'), + 7, 3, 200, 'test_user', id='after-order'), pytest.param( {'terms': {'quantity': f'{entry_prefix}upload_id', 'entries': {'size': 10}}}, - 5, 5, 200, 'test_user', id='entries'), + 7, 7, 200, 'test_user', id='entries'), pytest.param( {'terms': {'quantity': f'{entry_prefix}upload_id', 'entries': {'size': 1}}}, - 5, 5, 200, 'test_user', id='entries-size'), + 7, 7, 200, 'test_user', id='entries-size'), pytest.param( {'terms': {'quantity': f'{entry_prefix}upload_id', 'entries': {'size': 0}}}, -1, -1, 422, 'test_user', id='bad-entries'), @@ -248,7 +248,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref } } }, - 5, 5, 200, 'test_user', id='entries-include'), + 7, 7, 200, 'test_user', id='entries-include'), pytest.param( {'terms': {'quantity': program_name}}, n_code_names, n_code_names, 200, None, id='fixed-values'), @@ -280,7 +280,7 @@ def aggregation_test_parameters(entity_id: str, material_prefix: str, entry_pref 'pagination': {'order': 'asc'} } }, - 5, 5, 200, 'test_user', id='order-direction'), + 7, 7, 200, 'test_user', id='order-direction'), pytest.param( {'terms': {'quantity': 'does not exist'}}, -1, -1, 422, None, id='bad-quantity'), diff --git a/tests/app/v1/routers/test_entries.py b/tests/app/v1/routers/test_entries.py index a05751f2621823606abaf13e15eb7cf2af593240..1eedf3d2b554657ea873422ed3d26191fc37251b 100644 --- a/tests/app/v1/routers/test_entries.py +++ b/tests/app/v1/routers/test_entries.py @@ -339,7 +339,7 @@ def test_entries_all_metrics(client, data): } } }, - 5, 5, 200, 'test_user', id='entries-exclude'), + 7, 7, 200, 'test_user', id='entries-exclude'), pytest.param( {'terms': {'quantity': 'entry_id', 'value_filter': '_0'}}, 9, 9, 200, None, id='filter'), @@ -534,10 +534,11 @@ def example_data_with_compressed_files(elastic_module, raw_files_module, mongo_m pytest.param('with_compr_unpublished', 'mainfile.xz', {'decompress': True, 'user': 'test-user'}, 200, id='decompress-xz-unpublished'), pytest.param('with_compr_unpublished', 'mainfile.gz', {'decompress': True, 'user': 'test-user'}, 200, id='decompress-gz-unpublished'), pytest.param('id_unpublished', 'mainfile.json', {}, 404, id='404-unpublished'), - pytest.param('id_embargo', 'mainfile.json', {}, 404, id='404-embargo'), - pytest.param('id_embargo', 'mainfile.json', {'user': 'test-user'}, 200, id='embargo'), - pytest.param('id_embargo', 'mainfile.json', {'user': 'other-test-user'}, 404, id='404-embargo-shared'), - pytest.param('id_embargo_shared', 'mainfile.json', {'user': 'other-test-user'}, 200, id='embargo-shared') + pytest.param('id_embargo_1', 'mainfile.json', {}, 404, id='404-embargo-no-user'), + pytest.param('id_embargo_1', 'mainfile.json', {'user': 'other-test-user'}, 404, id='404-embargo-no-access'), + pytest.param('id_embargo_1', 'mainfile.json', {'user': 'test-user'}, 200, id='embargo-main_author'), + pytest.param('id_embargo_w_coauthor_1', 'mainfile.json', {'user': 'other-test-user'}, 200, id='embargo-coauthor'), + pytest.param('id_embargo_w_reviewer_1', 'mainfile.json', {'user': 'other-test-user'}, 200, id='embargo-reviewer') ]) def test_entry_raw_download_file( client, data, example_data_with_compressed_files, example_mainfile_contents, test_user_auth, other_test_user_auth, diff --git a/tests/app/v1/routers/test_uploads.py b/tests/app/v1/routers/test_uploads.py index d30f4fec9b56f820e28866f7c2cc7bf1bbaba285..cabc9f99f35e3ba756e28a0512f27c5e13d8f70d 100644 --- a/tests/app/v1/routers/test_uploads.py +++ b/tests/app/v1/routers/test_uploads.py @@ -324,10 +324,11 @@ def get_upload_entries_metadata(entries: List[Dict[str, Any]]) -> Iterable[Entry pytest.param( dict( expected_upload_ids=[ - 'id_embargo', 'id_embargo_shared_upload', 'id_unpublished', 'id_unpublished_shared_upload', + 'id_embargo', 'id_embargo_w_coauthor', 'id_embargo_w_reviewer', + 'id_unpublished', 'id_unpublished_w_coauthor', 'id_unpublished_w_reviewer', 'id_published', 'id_processing', 'id_empty'], expected_pagination={ - 'total': 7, 'page': 1, 'page_after_value': None, 'next_page_after_value': None, + 'total': 9, 'page': 1, 'page_after_value': None, 'next_page_after_value': None, 'page_url': Any, 'next_page_url': None, 'prev_page_url': None, 'first_page_url': Any} ), id='no-args'), pytest.param( @@ -354,18 +355,21 @@ def get_upload_entries_metadata(entries: List[Dict[str, Any]]) -> Iterable[Entry dict( query_params={'is_processing': False}, expected_upload_ids=[ - 'id_embargo', 'id_embargo_shared_upload', 'id_unpublished', 'id_unpublished_shared_upload', + 'id_embargo', 'id_embargo_w_coauthor', 'id_embargo_w_reviewer', + 'id_unpublished', 'id_unpublished_w_coauthor', 'id_unpublished_w_reviewer', 'id_published', 'id_empty'], ), id='filter-is_processing-False'), pytest.param( dict( query_params={'is_published': True}, - expected_upload_ids=['id_embargo', 'id_embargo_shared_upload', 'id_published'], + expected_upload_ids=['id_embargo', 'id_embargo_w_coauthor', 'id_embargo_w_reviewer', 'id_published'], ), id='filter-is_published-True'), pytest.param( dict( query_params={'is_published': False}, - expected_upload_ids=['id_unpublished', 'id_unpublished_shared_upload', 'id_processing', 'id_empty'], + expected_upload_ids=[ + 'id_unpublished', 'id_unpublished_w_coauthor', 'id_unpublished_w_reviewer', + 'id_processing', 'id_empty'], ), id='filter-is_published-False'), pytest.param( dict( @@ -390,30 +394,30 @@ def get_upload_entries_metadata(entries: List[Dict[str, Any]]) -> Iterable[Entry pytest.param( dict( query_params={'page_size': 2}, - expected_upload_ids=['id_embargo', 'id_embargo_shared_upload'], + expected_upload_ids=['id_embargo', 'id_embargo_w_coauthor'], expected_pagination={ - 'total': 7, 'page': 1, 'page_after_value': None, 'next_page_after_value': '1', + 'total': 9, 'page': 1, 'page_after_value': None, 'next_page_after_value': '1', 'page_url': Any, 'next_page_url': Any, 'prev_page_url': None, 'first_page_url': Any} ), id='pag-page-1'), pytest.param( dict( query_params={'page_size': 2, 'page': 2}, - expected_upload_ids=['id_unpublished', 'id_unpublished_shared_upload'], + expected_upload_ids=['id_embargo_w_reviewer', 'id_unpublished'], expected_pagination={ - 'total': 7, 'page': 2, 'page_after_value': '1', 'next_page_after_value': '3', + 'total': 9, 'page': 2, 'page_after_value': '1', 'next_page_after_value': '3', 'page_url': Any, 'next_page_url': Any, 'prev_page_url': Any, 'first_page_url': Any} ), id='pag-page-2'), pytest.param( dict( query_params={'page_size': 3, 'page': 3}, - expected_upload_ids=['id_empty'], + expected_upload_ids=['id_published', 'id_processing', 'id_empty'], expected_pagination={ - 'total': 7, 'page': 3, 'page_after_value': '5', 'next_page_after_value': None, + 'total': 9, 'page': 3, 'page_after_value': '5', 'next_page_after_value': None, 'page_url': Any, 'next_page_url': None, 'prev_page_url': Any, 'first_page_url': Any} ), id='pag-page-3'), pytest.param( dict( - query_params={'page_size': 2, 'page': 5}, + query_params={'page_size': 3, 'page': 4}, expected_status_code=400 ), id='pag-page-out-of-range'), pytest.param( @@ -421,7 +425,7 @@ def get_upload_entries_metadata(entries: List[Dict[str, Any]]) -> Iterable[Entry query_params={'page_size': 2, 'order': 'desc'}, expected_upload_ids=['id_empty', 'id_processing'], expected_pagination={ - 'total': 7, 'page': 1, 'page_after_value': None, 'next_page_after_value': '1', + 'total': 9, 'page': 1, 'page_after_value': None, 'next_page_after_value': '1', 'page_url': Any, 'next_page_url': Any, 'prev_page_url': None, 'first_page_url': Any} ), id='pag-page-order-desc'), pytest.param( @@ -625,12 +629,12 @@ def test_get_upload_entries( @pytest.mark.parametrize('upload_id, entry_id, user, expected_status_code', [ - pytest.param('id_embargo', 'id_embargo', 'test_user', 200, id='ok'), - pytest.param('id_embargo', 'id_embargo', None, 401, id='no-credentials'), - pytest.param('id_embargo', 'id_embargo', 'invalid', 401, id='invalid-credentials'), - pytest.param('id_embargo', 'id_embargo', 'other_test_user', 401, id='no-access'), - pytest.param('id_embargo', 'id_embargo', 'admin_user', 200, id='admin-access'), - pytest.param('silly_value', 'id_embargo', 'test_user', 404, id='invalid-upload_id'), + pytest.param('id_embargo', 'id_embargo_1', 'test_user', 200, id='ok'), + pytest.param('id_embargo', 'id_embargo_1', None, 401, id='no-credentials'), + pytest.param('id_embargo', 'id_embargo_1', 'invalid', 401, id='invalid-credentials'), + pytest.param('id_embargo', 'id_embargo_1', 'other_test_user', 401, id='no-access'), + pytest.param('id_embargo', 'id_embargo_1', 'admin_user', 200, id='admin-access'), + pytest.param('silly_value', 'id_embargo_1', 'test_user', 404, id='invalid-upload_id'), pytest.param('id_embargo', 'silly_value', 'test_user', 404, id='invalid-entry_id')]) def test_get_upload_entry( client, mongo_module, test_auth_dict, example_data, @@ -650,25 +654,25 @@ def test_get_upload_entry( @pytest.mark.parametrize('args, expected_status_code, expected_mime_type, expected_content', [ pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 200, 'text/plain; charset=utf-8', 'content', id='unpublished-file'), pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/', + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/', accept='application/json'), 200, 'application/json', ['1.aux', '2.aux', '3.aux', '4.aux', 'mainfile.json'], id='unpublished-dir-json'), pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/'), + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/'), 200, 'text/html; charset=utf-8', ['1.aux', '2.aux', '3.aux', '4.aux', 'mainfile.json'], id='unpublished-dir-html'), pytest.param(dict( user='test_user', upload_id='id_unpublished', path='', accept='application/json'), 200, 'application/json', ['test_content'], id='unpublished-dir-json-root'), pytest.param(dict( - user='other_test_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user='other_test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 401, None, None, id='unpublished-file-unauthorized'), pytest.param(dict( - user='admin_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user='admin_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 200, 'text/plain; charset=utf-8', 'content', id='unpublished-file-admin-auth'), pytest.param(dict( user='test_user', upload_id='id_published', path='test_content/subdir/test_entry_01/mainfile.json'), @@ -690,19 +694,19 @@ def test_get_upload_entry( user='admin_user', upload_id='id_published', path='test_content/subdir/test_entry_01/1.aux'), 200, 'text/plain; charset=utf-8', 'content', id='published-file-admin-auth'), pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux', + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux', compress=True), 200, 'application/zip', 'content', id='unpublished-file-compressed'), pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/', + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/', compress=True), 200, 'application/zip', ['1.aux', '2.aux', '3.aux', '4.aux', 'mainfile.json'], id='unpublished-dir-compressed'), pytest.param(dict( user='test_user', upload_id='id_unpublished', path='', compress=True), 200, 'application/zip', - ['test_content', 'test_content/test_entry/1.aux', 'test_content/test_entry/mainfile.json'], + ['test_content', 'test_content/id_unpublished_1/1.aux', 'test_content/id_unpublished_1/mainfile.json'], id='unpublished-dir-compressed-root'), pytest.param(dict( user='test_user', upload_id='id_published', path='test_content/subdir/test_entry_01/1.aux', @@ -725,11 +729,11 @@ def test_get_upload_entry( user='test_user', upload_id='id_published', path='test_content/silly_name', compress=True), 404, None, None, id='bad-path'), pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux', + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux', offset=2), 200, 'text/plain; charset=utf-8', 'ntent\n', id='unpublished-file-offset'), pytest.param(dict( - user='test_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux', + user='test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux', offset=2, length=4), 200, 'text/plain; charset=utf-8', 'nten', id='unpublished-file-offset-and-length'), pytest.param(dict( @@ -749,16 +753,16 @@ def test_get_upload_entry( offset=3, length=-3), 400, None, None, id='invalid-length'), pytest.param(dict( - user=None, upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user=None, upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 401, None, None, id='no-credentials'), pytest.param(dict( - user='invalid', upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user='invalid', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 401, None, None, id='invalid-credentials'), pytest.param(dict( - user='other_test_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user='other_test_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 401, None, None, id='no-access'), pytest.param(dict( - user='admin_user', upload_id='id_unpublished', path='test_content/test_entry/1.aux'), + user='admin_user', upload_id='id_unpublished', path='test_content/id_unpublished_1/1.aux'), 200, 'text/plain; charset=utf-8', 'content', id='admin-access')]) def test_get_upload_raw_path( client, example_data, test_auth_dict, diff --git a/tests/utils.py b/tests/utils.py index 1b7bb4d8c7d0e0b41b0bf6d5a1d195ffe96479cc..75d46380ba0146279aedc8902c9b4a7eeac34a45 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -30,6 +30,7 @@ from nomad import search, files from nomad.datamodel import EntryMetadata, EntryArchive, Results from nomad.datamodel.metainfo.simulation.run import Run, Program from nomad.datamodel.metainfo.simulation.system import System, Atoms +from nomad.processing.data import _mongo_upload_metadata from tests.normalizing.conftest import run_normalize @@ -265,11 +266,10 @@ class ExampleData: parser_name='parsers/vasp') entry_metadata.m_update(**self.entry_defaults) # Fetch data from Upload - upload_keys = ['upload_name', 'main_author', 'reviewers', 'upload_create_time', 'publish_time', 'license'] - upload_values = {k: upload_dict[k] for k in upload_keys if k in upload_dict} + upload_values = {k: upload_dict[k] for k in _mongo_upload_metadata if k in upload_dict} upload_values['with_embargo'] = upload_dict['embargo_length'] > 0 upload_values['published'] = upload_dict.get('publish_time') is not None - for k in upload_keys + ['with_embargo', 'published']: + for k in list(_mongo_upload_metadata) + ['with_embargo', 'published']: assert k not in kwargs, f'Upload level metadata specified on entry level: {k}' entry_metadata.m_update(**upload_values) entry_metadata.m_update(**kwargs)