From 1a941807d3b43a2938a4c4019518a1db8868b443 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Tue, 8 Apr 2025 13:58:37 +0300 Subject: [PATCH 1/9] Add new task to update node metadata with verified_links --- .../datacite/datacite_tree_walker.py | 18 ++++++++++++ website/identifiers/tasks.py | 29 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/osf/metadata/serializers/datacite/datacite_tree_walker.py b/osf/metadata/serializers/datacite/datacite_tree_walker.py index 640e00e76f0..aa02f8193fc 100644 --- a/osf/metadata/serializers/datacite/datacite_tree_walker.py +++ b/osf/metadata/serializers/datacite/datacite_tree_walker.py @@ -113,6 +113,7 @@ def walk(self, doi_override=None): self._visit_rights(self.root) self._visit_descriptions(self.root, self.basket.focus.iri) self._visit_funding_references(self.root) + self._visit_verified_links(self.root) self._visit_related(self.root) def _visit_identifier(self, parent_el, *, doi_override=None): @@ -432,3 +433,20 @@ def _get_resource_type_general(self, focus_iri): if isinstance(type_term, rdflib.URIRef) and type_term.startswith(DATACITE): return without_namespace(type_term, DATACITE) return 'Text' + + def _visit_verified_links(self, parent_el): + osf_item = self.basket.focus.dbmodel + verified_links = getattr(osf_item, 'verified_links', None) + resource_type = getattr(osf_item, 'link_resource_type', 'Text') + + if verified_links and isinstance(verified_links, list): + related_identifiers_el = self.visit(parent_el, 'relatedIdentifiers', is_list=True) + for link in verified_links: + if link and isinstance(link, str) and smells_like_iri(link): + self.visit(related_identifiers_el, 'relatedIdentifier', text=link, attrib={ + 'relatedIdentifierType': 'URL', + 'relationType': 'IsReferencedBy', + 'resourceTypeGeneral': resource_type + }) + else: + logger.warning('skipping non-URL verified link "%s"', link) diff --git a/website/identifiers/tasks.py b/website/identifiers/tasks.py index f940956d54b..5c10b59a733 100644 --- a/website/identifiers/tasks.py +++ b/website/identifiers/tasks.py @@ -17,3 +17,32 @@ def task__update_doi_metadata_on_change(self, target_guid): @celery_app.task(ignore_results=True) def update_doi_metadata_on_change(target_guid): task__update_doi_metadata_on_change(target_guid) + +@celery_app.task(bind=True, max_retries=5, acks_late=True) +def task__update_doi_metadata_with_verified_links(self, target_guid, verified_links=None, link_resource_type='Text'): + sentry.log_message('Updating DOI with verified links for guid', + extra_data={'guid': target_guid, 'verified_links': verified_links, 'link_resource_type': link_resource_type}, + level=logging.INFO) + + Guid = apps.get_model('osf.Guid') + target_object = Guid.load(target_guid).referent + try: + if verified_links is not None: + target_object.verified_links = verified_links + target_object.link_resource_type = link_resource_type + + target_object.request_identifier_update(category='doi') + + sentry.log_message('DOI metadata with verified links updated for guid', + extra_data={'guid': target_guid}, + level=logging.INFO) + except Exception as exc: + sentry.log_message('Failed to update DOI metadata with verified links', + extra_data={'guid': target_guid, 'error': str(exc)}, + level=logging.ERROR) + raise self.retry(exc=exc) + +@queued_task +@celery_app.task(ignore_results=True) +def update_doi_metadata_with_verified_links(target_guid, verified_links=None, resource_type='Text'): + task__update_doi_metadata_with_verified_links.apply_async((target_guid, verified_links, resource_type)) From 609bf29d16b902fc99c49ac49b32d96fe542770b Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Tue, 29 Apr 2025 17:14:32 +0300 Subject: [PATCH 2/9] Update task to change node metadata to use gv request to get verified links --- .../datacite/datacite_tree_walker.py | 43 ++++++++++--------- osf/models/node.py | 4 ++ website/identifiers/clients/datacite.py | 3 ++ website/identifiers/tasks.py | 11 ++--- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/osf/metadata/serializers/datacite/datacite_tree_walker.py b/osf/metadata/serializers/datacite/datacite_tree_walker.py index aa02f8193fc..4660ee7ba4f 100644 --- a/osf/metadata/serializers/datacite/datacite_tree_walker.py +++ b/osf/metadata/serializers/datacite/datacite_tree_walker.py @@ -113,8 +113,7 @@ def walk(self, doi_override=None): self._visit_rights(self.root) self._visit_descriptions(self.root, self.basket.focus.iri) self._visit_funding_references(self.root) - self._visit_verified_links(self.root) - self._visit_related(self.root) + self._visit_related_and_verified_links(self.root) def _visit_identifier(self, parent_el, *, doi_override=None): if doi_override is None: @@ -374,13 +373,16 @@ def _visit_related_identifier_and_item(self, identifier_parent_el, item_parent_e self._visit_publication_year(related_item_el, related_iri) self._visit_publisher(related_item_el, related_iri) - def _visit_related(self, parent_el): + def _visit_related_and_verified_links(self, parent_el): relation_pairs = set() for relation_iri, datacite_relation in RELATED_IDENTIFIER_TYPE_MAP.items(): for related_iri in self.basket[relation_iri]: relation_pairs.add((datacite_relation, related_iri)) + related_identifiers_el = self.visit(parent_el, 'relatedIdentifiers', is_list=True) related_items_el = self.visit(parent_el, 'relatedItems', is_list=True) + + # First add regular related identifiers for datacite_relation, related_iri in sorted(relation_pairs): self._visit_related_identifier_and_item( related_identifiers_el, @@ -389,6 +391,24 @@ def _visit_related(self, parent_el): datacite_relation, ) + # Then add verified links to same relatedIdentifiers element + osf_item = self.basket.focus.dbmodel + from osf.models import AbstractNode + + if isinstance(osf_item, AbstractNode): + gv_verified_link_list = osf_item.get_links() + for item in gv_verified_link_list: + verified_link, resource_type = item.get('target_url', None), item.get('resource_type', None) + if verified_link and resource_type: + if verified_link and isinstance(verified_link, str) and smells_like_iri(verified_link): + self.visit(related_identifiers_el, 'relatedIdentifier', text=verified_link, attrib={ + 'relatedIdentifierType': 'URL', + 'relationType': 'IsReferencedBy', + 'resourceTypeGeneral': resource_type.title() + }) + else: + logger.warning('skipping non-URL verified link "%s"', verified_link) + def _visit_name_identifiers(self, parent_el, agent_iri): for identifier in sorted(self.basket[agent_iri:DCTERMS.identifier]): identifier_type, identifier_value = self._identifier_type_and_value(identifier) @@ -433,20 +453,3 @@ def _get_resource_type_general(self, focus_iri): if isinstance(type_term, rdflib.URIRef) and type_term.startswith(DATACITE): return without_namespace(type_term, DATACITE) return 'Text' - - def _visit_verified_links(self, parent_el): - osf_item = self.basket.focus.dbmodel - verified_links = getattr(osf_item, 'verified_links', None) - resource_type = getattr(osf_item, 'link_resource_type', 'Text') - - if verified_links and isinstance(verified_links, list): - related_identifiers_el = self.visit(parent_el, 'relatedIdentifiers', is_list=True) - for link in verified_links: - if link and isinstance(link, str) and smells_like_iri(link): - self.visit(related_identifiers_el, 'relatedIdentifier', text=link, attrib={ - 'relatedIdentifierType': 'URL', - 'relationType': 'IsReferencedBy', - 'resourceTypeGeneral': resource_type - }) - else: - logger.warning('skipping non-URL verified link "%s"', link) diff --git a/osf/models/node.py b/osf/models/node.py index 47bf04d4f59..f20e72ff53b 100644 --- a/osf/models/node.py +++ b/osf/models/node.py @@ -1991,6 +1991,10 @@ def on_update(self, first_save, saved_fields): request_headers = string_type_request_headers(request) self.update_or_enqueue_on_node_updated(user_id, first_save, saved_fields) + from website.identifiers.tasks import update_doi_metadata_with_verified_links + if self.get_identifier('doi') and bool(self.IDENTIFIER_UPDATE_FIELDS.intersection(set(saved_fields))): + update_doi_metadata_with_verified_links(self._id) + user = User.load(user_id) if user: # Specifically call the super class save method to avoid recursion into model save method. diff --git a/website/identifiers/clients/datacite.py b/website/identifiers/clients/datacite.py index 64c9b0a075b..66bb2f924b6 100644 --- a/website/identifiers/clients/datacite.py +++ b/website/identifiers/clients/datacite.py @@ -57,6 +57,9 @@ def create_identifier(self, node, category, doi_value=None): doi_value = doi_value or self._get_doi_value(node) metadata_record_xml = self.build_metadata(node, doi_value, as_xml=True) if settings.DATACITE_ENABLED: + if isinstance(metadata_record_xml, bytes): + metadata_record_xml = metadata_record_xml.decode('utf-8') + resp = self._client.metadata_post(metadata_record_xml) # Typical response: 'OK (10.70102/FK2osf.io/cq695)' to doi 10.70102/FK2osf.io/cq695 doi = re.match(r'OK \((?P[a-zA-Z0-9 .\/]{0,})\)', resp).groupdict()['doi'] diff --git a/website/identifiers/tasks.py b/website/identifiers/tasks.py index 5c10b59a733..277df0c5b53 100644 --- a/website/identifiers/tasks.py +++ b/website/identifiers/tasks.py @@ -19,17 +19,14 @@ def update_doi_metadata_on_change(target_guid): task__update_doi_metadata_on_change(target_guid) @celery_app.task(bind=True, max_retries=5, acks_late=True) -def task__update_doi_metadata_with_verified_links(self, target_guid, verified_links=None, link_resource_type='Text'): +def task__update_doi_metadata_with_verified_links(self, target_guid): sentry.log_message('Updating DOI with verified links for guid', - extra_data={'guid': target_guid, 'verified_links': verified_links, 'link_resource_type': link_resource_type}, + extra_data={'guid': target_guid}, level=logging.INFO) Guid = apps.get_model('osf.Guid') target_object = Guid.load(target_guid).referent try: - if verified_links is not None: - target_object.verified_links = verified_links - target_object.link_resource_type = link_resource_type target_object.request_identifier_update(category='doi') @@ -44,5 +41,5 @@ def task__update_doi_metadata_with_verified_links(self, target_guid, verified_li @queued_task @celery_app.task(ignore_results=True) -def update_doi_metadata_with_verified_links(target_guid, verified_links=None, resource_type='Text'): - task__update_doi_metadata_with_verified_links.apply_async((target_guid, verified_links, resource_type)) +def update_doi_metadata_with_verified_links(target_guid): + task__update_doi_metadata_with_verified_links(target_guid) From 57f9639aacf14c0c1e0bd7991dd983d40e0c4f6e Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 1 May 2025 15:12:28 +0300 Subject: [PATCH 3/9] Add mock for gravy valet get_links to fix failed tests --- api_tests/identifiers/managment_commands/test_sync_dois.py | 2 +- conftest.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/api_tests/identifiers/managment_commands/test_sync_dois.py b/api_tests/identifiers/managment_commands/test_sync_dois.py index e72893dc7dd..c36e29080e0 100644 --- a/api_tests/identifiers/managment_commands/test_sync_dois.py +++ b/api_tests/identifiers/managment_commands/test_sync_dois.py @@ -58,7 +58,7 @@ def test_doi_synced_datacite(self, app, registration, registration_identifier, m assert registration_identifier.modified.date() < datetime.datetime.now().date() call_command('sync_doi_metadata', f'-m={datetime.datetime.now()}') - assert len(mock_datacite.calls) == 2 + assert len(mock_datacite.calls) == 3 update_metadata, update_doi = mock_datacite.calls assert update_metadata.request.url == f'{settings.DATACITE_URL}/metadata' assert update_doi.request.url == f'{settings.DATACITE_URL}/doi' diff --git a/conftest.py b/conftest.py index 6f870093ed4..c183b5faac0 100644 --- a/conftest.py +++ b/conftest.py @@ -357,3 +357,10 @@ def helpful_thing(self): ``` """ yield from rolledback_transaction('function_transaction') + +@pytest.fixture(autouse=True) +def mock_gravy_valet_get_links(): + + with mock.patch('osf.external.gravy_valet.translations.get_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links From 029c6dbda627bef0dd99821bc13cae22172947a0 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 1 May 2025 15:52:01 +0300 Subject: [PATCH 4/9] Fix test_doi_synced_datacite test --- api_tests/identifiers/managment_commands/test_sync_dois.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_tests/identifiers/managment_commands/test_sync_dois.py b/api_tests/identifiers/managment_commands/test_sync_dois.py index c36e29080e0..e72893dc7dd 100644 --- a/api_tests/identifiers/managment_commands/test_sync_dois.py +++ b/api_tests/identifiers/managment_commands/test_sync_dois.py @@ -58,7 +58,7 @@ def test_doi_synced_datacite(self, app, registration, registration_identifier, m assert registration_identifier.modified.date() < datetime.datetime.now().date() call_command('sync_doi_metadata', f'-m={datetime.datetime.now()}') - assert len(mock_datacite.calls) == 3 + assert len(mock_datacite.calls) == 2 update_metadata, update_doi = mock_datacite.calls assert update_metadata.request.url == f'{settings.DATACITE_URL}/metadata' assert update_doi.request.url == f'{settings.DATACITE_URL}/doi' From d05c9a264363f6a1775e64d89c95efeaca9080ef Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Mon, 5 May 2025 14:25:22 +0300 Subject: [PATCH 5/9] Update PR accordng to comments --- conftest.py | 2 +- .../datacite/datacite_tree_walker.py | 13 +++++++++---- osf/models/identifiers.py | 4 ++-- website/identifiers/clients/datacite.py | 2 -- website/identifiers/tasks.py | 19 ++++++++----------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/conftest.py b/conftest.py index c183b5faac0..a44c3c20739 100644 --- a/conftest.py +++ b/conftest.py @@ -361,6 +361,6 @@ def helpful_thing(self): @pytest.fixture(autouse=True) def mock_gravy_valet_get_links(): - with mock.patch('osf.external.gravy_valet.translations.get_links') as mock_get_links: + with mock.patch('osf.external.gravy_valet.translations.get_verified_links') as mock_get_links: mock_get_links.return_value = [] yield mock_get_links diff --git a/osf/metadata/serializers/datacite/datacite_tree_walker.py b/osf/metadata/serializers/datacite/datacite_tree_walker.py index 4660ee7ba4f..7e772b1666b 100644 --- a/osf/metadata/serializers/datacite/datacite_tree_walker.py +++ b/osf/metadata/serializers/datacite/datacite_tree_walker.py @@ -6,7 +6,9 @@ import rdflib +from framework import sentry from osf.exceptions import MetadataSerializationError +from osf.external.gravy_valet.request_helpers import get_verified_links from osf.metadata import gather from osf.metadata.rdfutils import ( RDF, @@ -396,18 +398,21 @@ def _visit_related_and_verified_links(self, parent_el): from osf.models import AbstractNode if isinstance(osf_item, AbstractNode): - gv_verified_link_list = osf_item.get_links() + gv_verified_link_list = get_verified_links(node_guid=osf_item._id) + non_url_verified_links = [] for item in gv_verified_link_list: - verified_link, resource_type = item.get('target_url', None), item.get('resource_type', None) + verified_link, resource_type = item.attributes.get('target_url', None), item.attributes.get('resource_type', None) if verified_link and resource_type: - if verified_link and isinstance(verified_link, str) and smells_like_iri(verified_link): + if smells_like_iri(verified_link): self.visit(related_identifiers_el, 'relatedIdentifier', text=verified_link, attrib={ 'relatedIdentifierType': 'URL', 'relationType': 'IsReferencedBy', 'resourceTypeGeneral': resource_type.title() }) else: - logger.warning('skipping non-URL verified link "%s"', verified_link) + non_url_verified_links.append(verified_link) + if non_url_verified_links: + sentry.log_message(f'Skipped - {','.join(non_url_verified_links)} for node {osf_item._id}') def _visit_name_identifiers(self, parent_el, agent_iri): for identifier in sorted(self.basket[agent_iri:DCTERMS.identifier]): diff --git a/osf/models/identifiers.py b/osf/models/identifiers.py index 49be9f9c45b..9383bc61484 100644 --- a/osf/models/identifiers.py +++ b/osf/models/identifiers.py @@ -86,8 +86,8 @@ def request_identifier(self, category): def request_identifier_update(self, category, create=False): '''Noop if no existing identifier value for the category.''' - if not self.get_identifier_value(category) and not create: - return + # if not self.get_identifier_value(category) and not create: + # return client = self.get_doi_client() if client: diff --git a/website/identifiers/clients/datacite.py b/website/identifiers/clients/datacite.py index 66bb2f924b6..be4e4197c7b 100644 --- a/website/identifiers/clients/datacite.py +++ b/website/identifiers/clients/datacite.py @@ -57,8 +57,6 @@ def create_identifier(self, node, category, doi_value=None): doi_value = doi_value or self._get_doi_value(node) metadata_record_xml = self.build_metadata(node, doi_value, as_xml=True) if settings.DATACITE_ENABLED: - if isinstance(metadata_record_xml, bytes): - metadata_record_xml = metadata_record_xml.decode('utf-8') resp = self._client.metadata_post(metadata_record_xml) # Typical response: 'OK (10.70102/FK2osf.io/cq695)' to doi 10.70102/FK2osf.io/cq695 diff --git a/website/identifiers/tasks.py b/website/identifiers/tasks.py index 277df0c5b53..c00a3629b2e 100644 --- a/website/identifiers/tasks.py +++ b/website/identifiers/tasks.py @@ -1,10 +1,13 @@ import logging from django.apps import apps +from osf.external.gravy_valet.exceptions import GVException from framework.celery_tasks import app as celery_app from framework.celery_tasks.handlers import queued_task from framework import sentry +logger = logging.getLogger(__name__) + @celery_app.task(bind=True, max_retries=5, acks_late=True) def task__update_doi_metadata_on_change(self, target_guid): sentry.log_message('Updating DOI for guid', extra_data={'guid': target_guid}, level=logging.INFO) @@ -20,9 +23,7 @@ def update_doi_metadata_on_change(target_guid): @celery_app.task(bind=True, max_retries=5, acks_late=True) def task__update_doi_metadata_with_verified_links(self, target_guid): - sentry.log_message('Updating DOI with verified links for guid', - extra_data={'guid': target_guid}, - level=logging.INFO) + logger.info(f'Updating DOI with verified links for guid - {target_guid}') Guid = apps.get_model('osf.Guid') target_object = Guid.load(target_guid).referent @@ -30,14 +31,10 @@ def task__update_doi_metadata_with_verified_links(self, target_guid): target_object.request_identifier_update(category='doi') - sentry.log_message('DOI metadata with verified links updated for guid', - extra_data={'guid': target_guid}, - level=logging.INFO) - except Exception as exc: - sentry.log_message('Failed to update DOI metadata with verified links', - extra_data={'guid': target_guid, 'error': str(exc)}, - level=logging.ERROR) - raise self.retry(exc=exc) + logger.info(f'DOI metadata with verified links updated for guid - {target_guid}') + except GVException as e: + logger.info(f'Failed to update DOI metadata with verified links for guid - {target_guid}') + raise self.retry(exc=e) @queued_task @celery_app.task(ignore_results=True) From fae9a54d59494a1a34cde1c678fe826156d85716 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 8 May 2025 14:00:48 +0300 Subject: [PATCH 6/9] Remove autouse=True for mock_gravy_valet_get_links --- conftest.py | 2 +- .../datacite/datacite_tree_walker.py | 32 +++++++++---------- osf/models/identifiers.py | 4 +-- osf/models/node.py | 4 --- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/conftest.py b/conftest.py index a44c3c20739..38189455580 100644 --- a/conftest.py +++ b/conftest.py @@ -358,7 +358,7 @@ def helpful_thing(self): """ yield from rolledback_transaction('function_transaction') -@pytest.fixture(autouse=True) +@pytest.fixture def mock_gravy_valet_get_links(): with mock.patch('osf.external.gravy_valet.translations.get_verified_links') as mock_get_links: diff --git a/osf/metadata/serializers/datacite/datacite_tree_walker.py b/osf/metadata/serializers/datacite/datacite_tree_walker.py index 7e772b1666b..0946cc940a3 100644 --- a/osf/metadata/serializers/datacite/datacite_tree_walker.py +++ b/osf/metadata/serializers/datacite/datacite_tree_walker.py @@ -8,7 +8,6 @@ from framework import sentry from osf.exceptions import MetadataSerializationError -from osf.external.gravy_valet.request_helpers import get_verified_links from osf.metadata import gather from osf.metadata.rdfutils import ( RDF, @@ -398,21 +397,22 @@ def _visit_related_and_verified_links(self, parent_el): from osf.models import AbstractNode if isinstance(osf_item, AbstractNode): - gv_verified_link_list = get_verified_links(node_guid=osf_item._id) - non_url_verified_links = [] - for item in gv_verified_link_list: - verified_link, resource_type = item.attributes.get('target_url', None), item.attributes.get('resource_type', None) - if verified_link and resource_type: - if smells_like_iri(verified_link): - self.visit(related_identifiers_el, 'relatedIdentifier', text=verified_link, attrib={ - 'relatedIdentifierType': 'URL', - 'relationType': 'IsReferencedBy', - 'resourceTypeGeneral': resource_type.title() - }) - else: - non_url_verified_links.append(verified_link) - if non_url_verified_links: - sentry.log_message(f'Skipped - {','.join(non_url_verified_links)} for node {osf_item._id}') + gv_verified_link_list = osf_item.get_verified_links() + if gv_verified_link_list: + non_url_verified_links = [] + for item in gv_verified_link_list: + verified_link, resource_type = item.get('target_url', None), item.get('resource_type', None) + if verified_link and resource_type: + if smells_like_iri(verified_link): + self.visit(related_identifiers_el, 'relatedIdentifier', text=verified_link, attrib={ + 'relatedIdentifierType': 'URL', + 'relationType': 'IsReferencedBy', + 'resourceTypeGeneral': resource_type.title() + }) + else: + non_url_verified_links.append(verified_link) + if non_url_verified_links: + sentry.log_message(f'Skipped - {','.join(non_url_verified_links)} for node {osf_item._id}') def _visit_name_identifiers(self, parent_el, agent_iri): for identifier in sorted(self.basket[agent_iri:DCTERMS.identifier]): diff --git a/osf/models/identifiers.py b/osf/models/identifiers.py index 9383bc61484..49be9f9c45b 100644 --- a/osf/models/identifiers.py +++ b/osf/models/identifiers.py @@ -86,8 +86,8 @@ def request_identifier(self, category): def request_identifier_update(self, category, create=False): '''Noop if no existing identifier value for the category.''' - # if not self.get_identifier_value(category) and not create: - # return + if not self.get_identifier_value(category) and not create: + return client = self.get_doi_client() if client: diff --git a/osf/models/node.py b/osf/models/node.py index f20e72ff53b..47bf04d4f59 100644 --- a/osf/models/node.py +++ b/osf/models/node.py @@ -1991,10 +1991,6 @@ def on_update(self, first_save, saved_fields): request_headers = string_type_request_headers(request) self.update_or_enqueue_on_node_updated(user_id, first_save, saved_fields) - from website.identifiers.tasks import update_doi_metadata_with_verified_links - if self.get_identifier('doi') and bool(self.IDENTIFIER_UPDATE_FIELDS.intersection(set(saved_fields))): - update_doi_metadata_with_verified_links(self._id) - user = User.load(user_id) if user: # Specifically call the super class save method to avoid recursion into model save method. From ab27f65b5d546f759267639ed065ee98aa90212a Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 8 May 2025 16:24:22 +0300 Subject: [PATCH 7/9] Add mock_gravy_valet_get_links where it is needed --- admin_tests/nodes/test_views.py | 7 ++++- .../registrations/test_registrations.py | 20 +++++++++---- .../managment_commands/test_sync_dois.py | 7 +++++ .../views/test_registration_detail.py | 29 ++++++++++++++---- .../test_registrations_childrens_list.py | 18 ++++++++++- .../views/test_withdrawn_registrations.py | 8 +++++ .../registries_moderation/test_submissions.py | 8 +++++ .../search/serializers/test_serializers.py | 9 +++++- api_tests/search/views/test_views.py | 10 ++++++- osf_tests/embargoes/test_embargoes.py | 8 ++++- osf_tests/metadata/test_osf_gathering.py | 9 +++++- osf_tests/test_archiver.py | 16 ++++++---- osf_tests/test_node.py | 8 ++++- osf_tests/test_notable_domains.py | 8 ++++- osf_tests/test_pigeon.py | 8 ++++- osf_tests/test_registrations.py | 13 +++++++- osf_tests/test_sanctions.py | 6 ++++ tests/identifiers/test_datacite.py | 7 +++++ tests/test_registrations/test_embargoes.py | 30 +++++++++++++++---- .../test_registration_approvals.py | 14 ++++++--- tests/test_registrations/test_retractions.py | 6 ++++ tests/test_registrations/test_review_flows.py | 8 +++++ website/identifiers/clients/datacite.py | 1 - 23 files changed, 221 insertions(+), 37 deletions(-) diff --git a/admin_tests/nodes/test_views.py b/admin_tests/nodes/test_views.py index c80eeb27e47..ce822ddfec7 100644 --- a/admin_tests/nodes/test_views.py +++ b/admin_tests/nodes/test_views.py @@ -504,8 +504,13 @@ def setUp(self): super().setUp() self.user = AuthUserFactory() self.node = ProjectFactory(creator=self.user) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links - def test_request_approval_is_approved(self): + def test_request_approval_is_approved(self, mock_gravy_valet_get_links): now = timezone.now() self.approval = RegistrationApprovalFactory( initiation_date=now - timezone.timedelta(days=1), diff --git a/admin_tests/registrations/test_registrations.py b/admin_tests/registrations/test_registrations.py index 5a7431c5977..36236058477 100644 --- a/admin_tests/registrations/test_registrations.py +++ b/admin_tests/registrations/test_registrations.py @@ -1,3 +1,5 @@ +from unittest import mock + from scripts.approve_registrations import main as approve_registrations_runner from datetime import timedelta import pytest @@ -68,6 +70,12 @@ def embargoed_registration_from_changed_to_public_project(self, superuser, publi def embargoed_registration_from_changed_to_private_project(self, superuser, private_project_from_public): return RegistrationFactory(project=private_project_from_public, creator=superuser, is_embargoed=True) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_embargoed_registration_from_public_project_spam_ham(self, embargoed_registration_from_public_project): embargoed_registration_from_public_project.confirm_spam(save=True) assert not embargoed_registration_from_public_project.is_public @@ -92,13 +100,13 @@ def test_embargoed_registration_from_changed_to_private_project_spam_ham(self, e embargoed_registration_from_changed_to_private_project.confirm_ham(save=True) assert not embargoed_registration_from_changed_to_private_project.is_public - def test_public_registration_from_public_project_spam_ham(self, superuser, public_registration_from_public_project): + def test_public_registration_from_public_project_spam_ham(self, superuser, public_registration_from_public_project, mock_gravy_valet_get_links): public_registration_from_public_project.confirm_spam(save=True) assert not public_registration_from_public_project.is_public public_registration_from_public_project.confirm_ham(save=True) assert public_registration_from_public_project.is_public - def test_public_registration_from_private_project_spam_ham(self, superuser, public_registration_from_private_project): + def test_public_registration_from_private_project_spam_ham(self, superuser, public_registration_from_private_project, mock_gravy_valet_get_links): public_registration_from_private_project.confirm_spam(save=True) assert not public_registration_from_private_project.is_public public_registration_from_private_project.confirm_ham(save=True) @@ -110,13 +118,13 @@ def test_private_registration_from_private_project_spam_ham(self, superuser, pri private_registration_from_public_project.confirm_ham(save=True) assert not private_registration_from_public_project.is_public - def test_public_registration_from_changed_to_public_project_spam_ham(self, superuser, public_registration_from_changed_to_public_project): + def test_public_registration_from_changed_to_public_project_spam_ham(self, superuser, public_registration_from_changed_to_public_project, mock_gravy_valet_get_links): public_registration_from_changed_to_public_project.confirm_spam(save=True) assert not public_registration_from_changed_to_public_project.is_public public_registration_from_changed_to_public_project.confirm_ham(save=True) assert public_registration_from_changed_to_public_project.is_public - def test_public_registration_from_changed_to_private_project_spam_ham(self, superuser, public_registration_from_changed_to_private_project): + def test_public_registration_from_changed_to_private_project_spam_ham(self, superuser, public_registration_from_changed_to_private_project, mock_gravy_valet_get_links): public_registration_from_changed_to_private_project.confirm_spam(save=True) assert not public_registration_from_changed_to_private_project.is_public public_registration_from_changed_to_private_project.confirm_ham(save=True) @@ -131,7 +139,7 @@ def test_unapproved_registration_task(self, embargoed_registration_from_changed_ embargoed_registration_from_changed_to_public_project.registration_approval.refresh_from_db() assert embargoed_registration_from_changed_to_public_project.registration_approval.state == 'approved' - def test_unapproved_registration_task_after_spam(self, embargoed_registration_from_changed_to_public_project): + def test_unapproved_registration_task_after_spam(self, embargoed_registration_from_changed_to_public_project, mock_gravy_valet_get_links): embargoed_registration_from_changed_to_public_project.registration_approval.state = 'unapproved' embargoed_registration_from_changed_to_public_project.registration_approval.initiation_date -= timedelta(3) embargoed_registration_from_changed_to_public_project.registration_approval.save() @@ -141,7 +149,7 @@ def test_unapproved_registration_task_after_spam(self, embargoed_registration_fr embargoed_registration_from_changed_to_public_project.registration_approval.refresh_from_db() assert embargoed_registration_from_changed_to_public_project.registration_approval.state == 'unapproved' - def test_unapproved_registration_task_after_spam_ham(self, embargoed_registration_from_changed_to_public_project): + def test_unapproved_registration_task_after_spam_ham(self, embargoed_registration_from_changed_to_public_project, mock_gravy_valet_get_links): embargoed_registration_from_changed_to_public_project.registration_approval.state = 'unapproved' embargoed_registration_from_changed_to_public_project.registration_approval.initiation_date -= timedelta(3) embargoed_registration_from_changed_to_public_project.registration_approval.save() diff --git a/api_tests/identifiers/managment_commands/test_sync_dois.py b/api_tests/identifiers/managment_commands/test_sync_dois.py index e72893dc7dd..ad0652ac529 100644 --- a/api_tests/identifiers/managment_commands/test_sync_dois.py +++ b/api_tests/identifiers/managment_commands/test_sync_dois.py @@ -1,5 +1,6 @@ import datetime +from unittest import mock import pytest from django.core.management import call_command from django.utils import timezone @@ -53,6 +54,12 @@ def preprint_identifier(self, preprint): identifier.save(update_modified=False) return identifier + @pytest.fixture(autouse=True) + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.mark.enable_enqueue_task def test_doi_synced_datacite(self, app, registration, registration_identifier, mock_datacite): assert registration_identifier.modified.date() < datetime.datetime.now().date() diff --git a/api_tests/registrations/views/test_registration_detail.py b/api_tests/registrations/views/test_registration_detail.py index 808ddc6b98d..e4af11b7a15 100644 --- a/api_tests/registrations/views/test_registration_detail.py +++ b/api_tests/registrations/views/test_registration_detail.py @@ -335,10 +335,17 @@ def license_cc0(self): @pytest.mark.django_db @pytest.mark.enable_implicit_clean class TestRegistrationUpdate(TestRegistrationUpdateTestCase): + + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_update_registration( self, app, user, read_only_contributor, read_write_contributor, public_registration, - public_url, private_url, make_payload, public_project): + public_url, private_url, make_payload, public_project, mock_gravy_valet_get_links): private_registration_payload = make_payload() non_contributor = AuthUserFactory() @@ -418,7 +425,7 @@ def test_update_registration( def test_fields( self, app, user, public_registration, private_registration, public_url, institution_one, - private_url, make_payload, license_cc0): + private_url, make_payload, license_cc0, mock_gravy_valet_get_links): # test_field_has_invalid_value invalid_public_payload = make_payload( @@ -562,7 +569,7 @@ def test_fields( assert res.status_code == 400 def test_turning_private_registrations_public( - self, app, user, make_payload): + self, app, user, make_payload, mock_gravy_valet_get_links): private_project = ProjectFactory(creator=user, is_public=False) private_registration = RegistrationFactory( project=private_project, creator=user, is_public=False) @@ -710,6 +717,12 @@ def test_read_write_contributor_can_edit_writeable_fields( @pytest.mark.django_db class TestRegistrationWithdrawal(TestRegistrationUpdateTestCase): + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.fixture def public_payload(self, public_registration, make_payload): return make_payload( @@ -777,7 +790,7 @@ def test_initiate_withdrawal_success(self, mock_send_mail, app, user, public_reg assert mock_send_mail.called def test_initiate_withdrawal_with_embargo_ends_embargo( - self, app, user, public_project, public_registration, public_url, public_payload): + self, app, user, public_project, public_registration, public_url, public_payload, mock_gravy_valet_get_links): public_registration.embargo_registration( user, (timezone.now() + datetime.timedelta(days=10)), @@ -934,11 +947,17 @@ def new_tag_payload_withdrawn(self, registration_withdrawn): } } + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_registration_tags( self, app, registration_public, registration_private, url_registration_public, url_registration_private, new_tag_payload_public, new_tag_payload_private, - user_admin, user_non_contrib, read_write_contrib): + user_admin, user_non_contrib, read_write_contrib, mock_gravy_valet_get_links): # test_registration_starts_with_no_tags res = app.get(url_registration_public) assert res.status_code == 200 diff --git a/api_tests/registrations/views/test_registrations_childrens_list.py b/api_tests/registrations/views/test_registrations_childrens_list.py index 67ff993fa2a..77b8811ebd8 100644 --- a/api_tests/registrations/views/test_registrations_childrens_list.py +++ b/api_tests/registrations/views/test_registrations_childrens_list.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest from api.base.settings.defaults import API_BASE @@ -57,6 +59,12 @@ def registration_with_children_approved_url(registration_with_children_approved) @pytest.mark.django_db class TestRegistrationsChildrenList: + @pytest.fixture() + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_registrations_children_list(self, user, app, registration_with_children, registration_with_children_url): component_one, component_two, component_three, component_four = registration_with_children.nodes @@ -68,7 +76,15 @@ def test_registrations_children_list(self, user, app, registration_with_children assert component_one._id in ids assert component_two._id in ids - def test_return_registrations_list_no_auth_approved(self, user, app, registration_with_children_approved, registration_with_children_approved_url): + def test_return_registrations_list_no_auth_approved( + self, + user, + app, + registration_with_children_approved, + registration_with_children_approved_url, + mock_gravy_valet_get_links + ): + component_one, component_two, component_three, component_four = registration_with_children_approved.nodes res = app.get(registration_with_children_approved_url) diff --git a/api_tests/registrations/views/test_withdrawn_registrations.py b/api_tests/registrations/views/test_withdrawn_registrations.py index 9cf582e7889..a72b5a11a33 100644 --- a/api_tests/registrations/views/test_withdrawn_registrations.py +++ b/api_tests/registrations/views/test_withdrawn_registrations.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest from urllib.parse import urlparse @@ -64,6 +66,12 @@ def url_withdrawn(self, registration): return '/{}registrations/{}/?version=2.2'.format( API_BASE, registration._id) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_can_access_withdrawn_contributors( self, app, user, registration, withdrawn_registration): url = '/{}registrations/{}/contributors/'.format( diff --git a/api_tests/registries_moderation/test_submissions.py b/api_tests/registries_moderation/test_submissions.py index feaf3141768..0d5901d1f1e 100644 --- a/api_tests/registries_moderation/test_submissions.py +++ b/api_tests/registries_moderation/test_submissions.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest import datetime @@ -164,6 +166,12 @@ def actions_payload_base(self): } return payload + @pytest.fixture(autouse=True) + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_get_provider_requests(self, app, provider_requests_url, registration_with_withdraw_request, access_request, moderator, moderator_wrong_provider): resp = app.get(provider_requests_url, expect_errors=True) assert resp.status_code == 401 diff --git a/api_tests/search/serializers/test_serializers.py b/api_tests/search/serializers/test_serializers.py index 6fb9d0b8adf..0e284cf54d4 100644 --- a/api_tests/search/serializers/test_serializers.py +++ b/api_tests/search/serializers/test_serializers.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest from api.search.serializers import SearchSerializer @@ -15,8 +17,13 @@ @pytest.mark.django_db class TestSearchSerializer: + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links - def test_search_serializer_mixed_model(self): + def test_search_serializer_mixed_model(self, mock_gravy_valet_get_links): user = AuthUserFactory() project = ProjectFactory(creator=user, is_public=True) diff --git a/api_tests/search/views/test_views.py b/api_tests/search/views/test_views.py index 675381668dc..4074e486f8a 100644 --- a/api_tests/search/views/test_views.py +++ b/api_tests/search/views/test_views.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest import uuid @@ -566,9 +568,15 @@ def registration_private(self, project_private, schema): registration_private.update_search() return registration_private + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_search_registrations( self, app, url_registration_search, user, user_one, user_two, - registration, registration_public, registration_private): + registration, registration_public, registration_private, mock_gravy_valet_get_links): # test_search_public_registration_no_auth res = app.get(url_registration_search) diff --git a/osf_tests/embargoes/test_embargoes.py b/osf_tests/embargoes/test_embargoes.py index 18df621d15f..c7197fccd8a 100644 --- a/osf_tests/embargoes/test_embargoes.py +++ b/osf_tests/embargoes/test_embargoes.py @@ -29,7 +29,13 @@ def registration(self, user): embargo.save() return embargo.registrations.last() - def test_request_early_termination_too_late(self, registration, user): + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + + def test_request_early_termination_too_late(self, registration, user, mock_gravy_valet_get_links): """ This is for an edge case test for where embargos are frozen and never expire when the user requests they be terminated with embargo with less then 48 hours before it would expire anyway. diff --git a/osf_tests/metadata/test_osf_gathering.py b/osf_tests/metadata/test_osf_gathering.py index 98de761a836..8b8d33341c3 100644 --- a/osf_tests/metadata/test_osf_gathering.py +++ b/osf_tests/metadata/test_osf_gathering.py @@ -1,6 +1,7 @@ import datetime from unittest import mock +import pytest from django.test import TestCase import rdflib from rdflib import Literal, URIRef @@ -117,6 +118,12 @@ def setUpTestData(cls): cls.userfocus__readwrite = osf_gathering.OsfFocus(cls.user__readwrite) cls.userfocus__readonly = osf_gathering.OsfFocus(cls.user__readonly) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_setupdata(self): assert self.projectfocus.iri == OSFIO[self.project._id] assert self.projectfocus.rdftype == OSF.Project @@ -703,7 +710,7 @@ def test_gather_collection_membership(self): (_collection_ref, DCTERMS.title, Literal(_collection_provider.name)), }) - def test_gather_registration_withdrawal(self): + def test_gather_registration_withdrawal(self, mock_gravy_valet_get_links): # focus: registration assert_triples(osf_gathering.gather_registration_withdrawal(self.registrationfocus), set()) _retraction = factories.WithdrawnRegistrationFactory( diff --git a/osf_tests/test_archiver.py b/osf_tests/test_archiver.py index 3855d169acb..d9a212dfd5b 100644 --- a/osf_tests/test_archiver.py +++ b/osf_tests/test_archiver.py @@ -436,6 +436,12 @@ def test_addons(self): class TestArchiverTasks(ArchiverTestCase): + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @mock.patch('framework.celery_tasks.handlers.enqueue_task') @mock.patch('celery.chain') def test_archive(self, mock_chain, mock_enqueue): @@ -566,7 +572,7 @@ def test_archive_success(self): assert registration_files == set(selected_files.keys()) - def test_archive_success_escaped_file_names(self): + def test_archive_success_escaped_file_names(self, mock_gravy_valet_get_links): file_tree = file_tree_factory(0, 0, 0) fake_file = file_factory(name='>and&and<') fake_file_name = normalize_unicode_filenames(fake_file['name'])[0] @@ -594,7 +600,7 @@ def test_archive_success_escaped_file_names(self): updated_response = registration.schema_responses.get().all_responses[qid] assert updated_response[0]['file_name'] == fake_file_name - def test_archive_success_with_components(self): + def test_archive_success_with_components(self, mock_gravy_valet_get_links): node = factories.NodeFactory(creator=self.user) comp1 = factories.NodeFactory(parent=node, creator=self.user) factories.NodeFactory(parent=comp1, creator=self.user) @@ -633,7 +639,7 @@ def mock_get_file_tree(self, *args, **kwargs): assert parent_registration._id in file_response['file_urls']['html'] registration_files.add(file_sha) - def test_archive_success_different_name_same_sha(self): + def test_archive_success_different_name_same_sha(self, mock_gravy_valet_get_links): file_tree = file_tree_factory(0, 0, 0) fake_file = file_factory() fake_file2 = file_factory(sha256=fake_file['extra']['hashes']['sha256']) @@ -659,7 +665,7 @@ def test_archive_success_different_name_same_sha(self): for key, question in registration.registered_meta[schema._id].items(): assert question['extra'][0]['selectedFileName'] == fake_file['name'] - def test_archive_failure_different_name_same_sha(self): + def test_archive_failure_different_name_same_sha(self, mock_gravy_valet_get_links): file_tree = file_tree_factory(0, 0, 0) fake_file = file_factory() fake_file2 = file_factory(sha256=fake_file['extra']['hashes']['sha256']) @@ -684,7 +690,7 @@ def test_archive_failure_different_name_same_sha(self): with pytest.raises(ArchivedFileNotFound): archive_success(registration._id, job._id) - def test_archive_success_same_file_in_component(self): + def test_archive_success_same_file_in_component(self, mock_gravy_valet_get_links): file_tree = file_tree_factory(3, 3, 3) selected = list(select_files_from_tree(file_tree).values())[0] diff --git a/osf_tests/test_node.py b/osf_tests/test_node.py index 4fcd6e542cf..84a2b1adcde 100644 --- a/osf_tests/test_node.py +++ b/osf_tests/test_node.py @@ -3640,6 +3640,12 @@ def test_validate_categories(self, model, resource): @pytest.mark.enable_implicit_clean class TestNodeUpdate: + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_update_description(self, fake, node, auth): new_title = fake.bs() @@ -3707,7 +3713,7 @@ def test_update_is_public(self, node, user, auth): last_log = node.logs.latest() assert last_log.action == NodeLog.MADE_PRIVATE - def test_update_can_make_registration_public(self): + def test_update_can_make_registration_public(self, mock_gravy_valet_get_links): reg = RegistrationFactory(is_public=False) reg.update({'is_public': True}) diff --git a/osf_tests/test_notable_domains.py b/osf_tests/test_notable_domains.py index 68e39912a65..d5a3c7c1fcf 100644 --- a/osf_tests/test_notable_domains.py +++ b/osf_tests/test_notable_domains.py @@ -148,6 +148,12 @@ def marked_as_spam_domain(self): note=NotableDomain.Note.EXCLUDE_FROM_ACCOUNT_CREATION_AND_CONTENT, ) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.mark.parametrize('factory', [NodeFactory, CommentFactory, PreprintFactory, RegistrationFactory]) def test_check_resource_for_domains_moderation_queue(self, spam_domain, factory): obj = factory() @@ -190,7 +196,7 @@ def test_check_resource_for_domains_spam(self, spam_domain, marked_as_spam_domai @pytest.mark.enable_enqueue_task @pytest.mark.parametrize('factory', [NodeFactory, RegistrationFactory, PreprintFactory]) - def test_spam_check(self, app, factory, spam_domain, marked_as_spam_domain, request_context): + def test_spam_check(self, app, factory, spam_domain, marked_as_spam_domain, request_context, mock_gravy_valet_get_links): obj = factory() obj.is_public = True obj.is_published = True diff --git a/osf_tests/test_pigeon.py b/osf_tests/test_pigeon.py index a1905c41ba8..3b2748b4c18 100644 --- a/osf_tests/test_pigeon.py +++ b/osf_tests/test_pigeon.py @@ -30,6 +30,12 @@ def embargo(self): embargo.accept() return embargo + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.mark.enable_enqueue_task @pytest.mark.enable_implicit_clean def test_pigeon_sync_metadata(self, mock_pigeon, registration, mock_celery): @@ -61,7 +67,7 @@ def test_pigeon_archive_immediately(self, registration, mock_pigeon, mock_celery @pytest.mark.enable_enqueue_task @pytest.mark.enable_implicit_clean - def test_pigeon_archive_embargo(self, embargo, mock_pigeon, mock_celery): + def test_pigeon_archive_embargo(self, embargo, mock_pigeon, mock_celery, mock_gravy_valet_get_links): embargo._get_registration().terminate_embargo() guid = embargo._get_registration()._id diff --git a/osf_tests/test_registrations.py b/osf_tests/test_registrations.py index 970b3670a3e..eedcb2e8e6c 100644 --- a/osf_tests/test_registrations.py +++ b/osf_tests/test_registrations.py @@ -51,6 +51,11 @@ def project(user, auth, fake): def auth(user): return Auth(user) +@pytest.fixture(autouse=True) +def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links # copied from tests/test_models.py def test_factory(user, project): @@ -404,7 +409,13 @@ def registration(self, project_two, component, contributor_unregistered, contrib with mock_archive(project_two, autoapprove=True) as registration: return registration - def test_unregistered_contributors_unclaimed_records_get_copied(self, user, project, component, registration, contributor_unregistered, contributor_unregistered_no_email): + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + + def test_unregistered_contributors_unclaimed_records_get_copied(self, user, project, component, registration, contributor_unregistered, contributor_unregistered_no_email, mock_gravy_valet_get_links): contributor_unregistered.refresh_from_db() contributor_unregistered_no_email.refresh_from_db() assert registration.contributors.filter(id=contributor_unregistered.id).exists() diff --git a/osf_tests/test_sanctions.py b/osf_tests/test_sanctions.py index 244ce7f7628..2f1d01718b1 100644 --- a/osf_tests/test_sanctions.py +++ b/osf_tests/test_sanctions.py @@ -12,6 +12,12 @@ from osf_tests.utils import mock_archive from osf.utils import permissions +@pytest.fixture(autouse=True) +def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.mark.django_db class TestRegistrationApprovalHooks: diff --git a/tests/identifiers/test_datacite.py b/tests/identifiers/test_datacite.py index bff0542297a..1e448e04e0f 100644 --- a/tests/identifiers/test_datacite.py +++ b/tests/identifiers/test_datacite.py @@ -1,6 +1,7 @@ import lxml import pytest import responses +from unittest import mock from datacite import schema40 from django.utils import timezone @@ -41,6 +42,12 @@ def user(self): def registration(self, user): return RegistrationFactory(is_public=True, creator=user) + @pytest.fixture(autouse=True) + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_datacite_create_identifiers(self, registration, datacite_client, mock_datacite): identifiers = datacite_client.create_identifier(node=registration, category='doi') assert identifiers['doi'] == settings.DOI_FORMAT.format(prefix=settings.DATACITE_PREFIX, guid=registration._id) diff --git a/tests/test_registrations/test_embargoes.py b/tests/test_registrations/test_embargoes.py index 8b87cf4e252..5edd53e7504 100644 --- a/tests/test_registrations/test_embargoes.py +++ b/tests/test_registrations/test_embargoes.py @@ -45,6 +45,12 @@ def setUp(self): self.embargo = EmbargoFactory(user=self.user) self.valid_embargo_end_date = timezone.now() + datetime.timedelta(days=3) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + # Node#_initiate_embargo tests def test__initiate_embargo_saves_embargo(self): initial_count = Embargo.objects.all().count() @@ -150,7 +156,7 @@ def test_embargo_with_valid_end_date_starts_pending_embargo(self): self.registration.save() assert self.registration.is_pending_embargo - def test_embargo_public_project_makes_private_pending_embargo(self): + def test_embargo_public_project_makes_private_pending_embargo(self, mock_gravy_valet_get_links): self.registration.is_public = True assert self.registration.is_public self.registration.embargo_registration( @@ -427,7 +433,7 @@ def test_on_complete_raises_error_if_registration_is_spam(self): assert mock_notify.call_count == 0 # Regression for OSF-8840 - def test_public_embargo_cannot_be_deleted_with_initial_token(self): + def test_public_embargo_cannot_be_deleted_with_initial_token(self, mock_gravy_valet_get_links): embargo_termination_approval = EmbargoTerminationApprovalFactory() registration = Registration.objects.get(embargo_termination_approval=embargo_termination_approval) user = registration.contributors.first() @@ -534,6 +540,12 @@ def setUp(self): self.project = ProjectFactory(creator=self.user) self.registration = RegistrationFactory(creator=self.user, project=self.project) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_GET_approve_registration_without_embargo_raises_HTTPBad_Request(self): assert not self.registration.is_pending_embargo res = self.app.get( @@ -697,7 +709,7 @@ def test_GET_disapprove_for_existing_registration_returns_200(self): assert res.status_code == 200 assert res.request.path == self.registration.web_url_for('view_project') - def test_GET_from_unauthorized_user_with_registration_token(self): + def test_GET_from_unauthorized_user_with_registration_token(self, mock_gravy_valet_get_links): unauthorized_user = AuthUserFactory() self.registration.require_approval(self.user) @@ -747,7 +759,7 @@ def test_GET_from_unauthorized_user_with_registration_token(self): ) assert res.status_code == 200 - def test_GET_from_authorized_user_with_registration_app_token(self): + def test_GET_from_authorized_user_with_registration_app_token(self, mock_gravy_valet_get_links): self.registration.require_approval(self.user) self.registration.save() app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token'] @@ -797,6 +809,12 @@ def setUp(self): self.project = ProjectFactory(creator=self.user) self.registration = RegistrationFactory(creator=self.user, project=self.project) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test_GET_approve_registration_without_embargo_raises_HTTPBad_Request(self): assert not self.registration.is_pending_embargo res = self.app.get( @@ -960,7 +978,7 @@ def test_GET_disapprove_for_existing_registration_returns_200(self): assert res.status_code == 302 assert res.request.path == self.registration.web_url_for('token_action') - def test_GET_from_unauthorized_user_with_registration_token(self): + def test_GET_from_unauthorized_user_with_registration_token(self, mock_gravy_valet_get_links): unauthorized_user = AuthUserFactory() self.registration.require_approval(self.user) @@ -1010,7 +1028,7 @@ def test_GET_from_unauthorized_user_with_registration_token(self): ) assert res.status_code == 302 - def test_GET_from_authorized_user_with_registration_app_token(self): + def test_GET_from_authorized_user_with_registration_app_token(self, mock_gravy_valet_get_links): self.registration.require_approval(self.user) self.registration.save() app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token'] diff --git a/tests/test_registrations/test_registration_approvals.py b/tests/test_registrations/test_registration_approvals.py index 965b48c4e96..ad76a625319 100644 --- a/tests/test_registrations/test_registration_approvals.py +++ b/tests/test_registrations/test_registration_approvals.py @@ -38,6 +38,12 @@ def setUp(self): self.project = ProjectFactory(creator=self.user) self.registration = RegistrationFactory(project=self.project) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + def test__require_approval_saves_approval(self): initial_count = RegistrationApproval.objects.all().count() self.registration._initiate_approval( @@ -114,7 +120,7 @@ def test_non_admin_approval_token_raises_PermissionsError(self): self.registration.registration_approval.approve(user=non_admin, token=approval_token) assert self.registration.is_pending_registration - def test_approval_adds_to_parent_projects_log(self): + def test_approval_adds_to_parent_projects_log(self, mock_gravy_valet_get_links): initial_project_logs = self.registration.registered_from.logs.count() self.registration.require_approval( self.user @@ -126,7 +132,7 @@ def test_approval_adds_to_parent_projects_log(self): # adds initiated, approved, and registered logs assert self.registration.registered_from.logs.count() == initial_project_logs + 3 - def test_one_approval_with_two_admins_stays_pending(self): + def test_one_approval_with_two_admins_stays_pending(self, mock_gravy_valet_get_links): admin2 = UserFactory() Contributor.objects.create(node=self.registration, user=admin2) self.registration.add_permission(admin2, ADMIN, save=True) @@ -251,7 +257,7 @@ def test_new_registration_is_pending_registration(self): self.registration.save() assert self.registration.is_pending_registration - def test_should_suppress_emails(self): + def test_should_suppress_emails(self, mock_gravy_valet_get_links): self.registration = RegistrationFactory(project=self.project) self.registration.external_registration = True self.registration.save() @@ -280,7 +286,7 @@ def test_should_suppress_emails(self): self.registration.sanction.ask(contributors) assert mock_notify_non_authorizer.call_count == 0 - def test_on_complete_notify_initiator(self): + def test_on_complete_notify_initiator(self, mock_gravy_valet_get_links): self.registration.require_approval( self.user, notify_initiator_on_complete=True diff --git a/tests/test_registrations/test_retractions.py b/tests/test_registrations/test_retractions.py index 67f0b0fb497..e46ea876175 100644 --- a/tests/test_registrations/test_retractions.py +++ b/tests/test_registrations/test_retractions.py @@ -25,6 +25,12 @@ from osf.models import Contributor, Retraction from osf.utils import permissions +@pytest.fixture(autouse=True) +def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.mark.enable_bookmark_creation class RegistrationRetractionModelsTestCase(OsfTestCase): diff --git a/tests/test_registrations/test_review_flows.py b/tests/test_registrations/test_review_flows.py index 7aeaa241c13..d0b1188906e 100644 --- a/tests/test_registrations/test_review_flows.py +++ b/tests/test_registrations/test_review_flows.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest from api.providers.workflows import Workflows @@ -58,6 +60,12 @@ def retraction(provider=None): registration.save() return sanction +@pytest.fixture(autouse=True) +def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @pytest.mark.enable_bookmark_creation @pytest.mark.django_db diff --git a/website/identifiers/clients/datacite.py b/website/identifiers/clients/datacite.py index be4e4197c7b..64c9b0a075b 100644 --- a/website/identifiers/clients/datacite.py +++ b/website/identifiers/clients/datacite.py @@ -57,7 +57,6 @@ def create_identifier(self, node, category, doi_value=None): doi_value = doi_value or self._get_doi_value(node) metadata_record_xml = self.build_metadata(node, doi_value, as_xml=True) if settings.DATACITE_ENABLED: - resp = self._client.metadata_post(metadata_record_xml) # Typical response: 'OK (10.70102/FK2osf.io/cq695)' to doi 10.70102/FK2osf.io/cq695 doi = re.match(r'OK \((?P[a-zA-Z0-9 .\/]{0,})\)', resp).groupdict()['doi'] From a591f6d36494109f05bcca71f266991472e518a8 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 8 May 2025 17:18:05 +0300 Subject: [PATCH 8/9] Update using fixture for some tests --- admin_tests/nodes/test_views.py | 3 ++- .../registrations/test_registrations.py | 1 + .../identifiers/views/test_identifier_list.py | 9 +++++++++ .../views/test_registrations_childrens_list.py | 4 ++-- .../views/test_withdrawn_registrations.py | 1 + api_tests/search/views/test_views.py | 3 ++- osf_tests/metadata/test_osf_gathering.py | 3 ++- osf_tests/metadata/test_serialized_metadata.py | 8 ++++++++ osf_tests/test_archiver.py | 15 ++++++++++----- osf_tests/test_registrations.py | 2 +- osf_tests/test_sanctions.py | 2 +- tests/identifiers/test_datacite.py | 7 +++++++ tests/test_registrations/test_embargoes.py | 18 ++++++++++++------ .../test_registration_approvals.py | 12 ++++++++---- tests/test_registrations/test_retractions.py | 2 +- tests/test_registrations/test_review_flows.py | 2 +- tests/test_tokens.py | 7 +++++++ 17 files changed, 75 insertions(+), 24 deletions(-) diff --git a/admin_tests/nodes/test_views.py b/admin_tests/nodes/test_views.py index ce822ddfec7..5d8e6871ed1 100644 --- a/admin_tests/nodes/test_views.py +++ b/admin_tests/nodes/test_views.py @@ -510,7 +510,8 @@ def mock_gravy_valet_get_links(self): mock_get_links.return_value = [] yield mock_get_links - def test_request_approval_is_approved(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_request_approval_is_approved(self): now = timezone.now() self.approval = RegistrationApprovalFactory( initiation_date=now - timezone.timedelta(days=1), diff --git a/admin_tests/registrations/test_registrations.py b/admin_tests/registrations/test_registrations.py index 36236058477..ce9d88684e3 100644 --- a/admin_tests/registrations/test_registrations.py +++ b/admin_tests/registrations/test_registrations.py @@ -130,6 +130,7 @@ def test_public_registration_from_changed_to_private_project_spam_ham(self, supe public_registration_from_changed_to_private_project.confirm_ham(save=True) assert public_registration_from_changed_to_private_project.is_public + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_unapproved_registration_task(self, embargoed_registration_from_changed_to_public_project): embargoed_registration_from_changed_to_public_project.registration_approval.state = 'unapproved' embargoed_registration_from_changed_to_public_project.registration_approval.initiation_date -= timedelta(3) diff --git a/api_tests/identifiers/views/test_identifier_list.py b/api_tests/identifiers/views/test_identifier_list.py index 88d98fa27ce..c528b3e14bb 100644 --- a/api_tests/identifiers/views/test_identifier_list.py +++ b/api_tests/identifiers/views/test_identifier_list.py @@ -1,3 +1,5 @@ +from unittest import mock + import pytest from urllib.parse import urlparse @@ -475,6 +477,13 @@ def ark_payload(self): def client(self, resource): return DataCiteClient(resource) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + + @pytest.mark.usefixtures('mock_gravy_valet_get_links') @responses.activate def test_create_identifier(self, app, resource, client, identifier_url, identifier_payload, user, write_contributor, read_contributor, ark_payload): diff --git a/api_tests/registrations/views/test_registrations_childrens_list.py b/api_tests/registrations/views/test_registrations_childrens_list.py index 77b8811ebd8..18f372e93c3 100644 --- a/api_tests/registrations/views/test_registrations_childrens_list.py +++ b/api_tests/registrations/views/test_registrations_childrens_list.py @@ -76,13 +76,13 @@ def test_registrations_children_list(self, user, app, registration_with_children assert component_one._id in ids assert component_two._id in ids + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_return_registrations_list_no_auth_approved( self, user, app, registration_with_children_approved, - registration_with_children_approved_url, - mock_gravy_valet_get_links + registration_with_children_approved_url ): component_one, component_two, component_three, component_four = registration_with_children_approved.nodes diff --git a/api_tests/registrations/views/test_withdrawn_registrations.py b/api_tests/registrations/views/test_withdrawn_registrations.py index a72b5a11a33..53e24383bff 100644 --- a/api_tests/registrations/views/test_withdrawn_registrations.py +++ b/api_tests/registrations/views/test_withdrawn_registrations.py @@ -232,6 +232,7 @@ def test_field_specific_related_counts_retrieved_if_visible_field_on_withdrawn_r assert res.status_code == 200 assert res.json['data']['relationships']['contributors']['links']['related']['meta']['count'] == 1 + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_child_inherits_withdrawal_justification_and_date_withdrawn( self, app, user, withdrawn_registration_with_child, registration_with_child): diff --git a/api_tests/search/views/test_views.py b/api_tests/search/views/test_views.py index 4074e486f8a..caf2457e64f 100644 --- a/api_tests/search/views/test_views.py +++ b/api_tests/search/views/test_views.py @@ -574,9 +574,10 @@ def mock_gravy_valet_get_links(self): mock_get_links.return_value = [] yield mock_get_links + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_search_registrations( self, app, url_registration_search, user, user_one, user_two, - registration, registration_public, registration_private, mock_gravy_valet_get_links): + registration, registration_public, registration_private): # test_search_public_registration_no_auth res = app.get(url_registration_search) diff --git a/osf_tests/metadata/test_osf_gathering.py b/osf_tests/metadata/test_osf_gathering.py index 8b8d33341c3..a88e2648485 100644 --- a/osf_tests/metadata/test_osf_gathering.py +++ b/osf_tests/metadata/test_osf_gathering.py @@ -710,7 +710,8 @@ def test_gather_collection_membership(self): (_collection_ref, DCTERMS.title, Literal(_collection_provider.name)), }) - def test_gather_registration_withdrawal(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_gather_registration_withdrawal(self): # focus: registration assert_triples(osf_gathering.gather_registration_withdrawal(self.registrationfocus), set()) _retraction = factories.WithdrawnRegistrationFactory( diff --git a/osf_tests/metadata/test_serialized_metadata.py b/osf_tests/metadata/test_serialized_metadata.py index d591ab9d6ca..5bef77670d7 100644 --- a/osf_tests/metadata/test_serialized_metadata.py +++ b/osf_tests/metadata/test_serialized_metadata.py @@ -2,6 +2,7 @@ import pathlib from unittest import mock +import pytest import rdflib from osf import models as osfdb @@ -329,6 +330,13 @@ def _setUp_full(self): self.project.node_license.year = '2250-2254' self.project.node_license.save() + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + + pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_serialized_metadata(self): self._assert_scenario(BASIC_METADATA_SCENARIO) self._setUp_full() diff --git a/osf_tests/test_archiver.py b/osf_tests/test_archiver.py index d9a212dfd5b..bae439896ba 100644 --- a/osf_tests/test_archiver.py +++ b/osf_tests/test_archiver.py @@ -572,7 +572,8 @@ def test_archive_success(self): assert registration_files == set(selected_files.keys()) - def test_archive_success_escaped_file_names(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_archive_success_escaped_file_names(self): file_tree = file_tree_factory(0, 0, 0) fake_file = file_factory(name='>and&and<') fake_file_name = normalize_unicode_filenames(fake_file['name'])[0] @@ -600,7 +601,8 @@ def test_archive_success_escaped_file_names(self, mock_gravy_valet_get_links): updated_response = registration.schema_responses.get().all_responses[qid] assert updated_response[0]['file_name'] == fake_file_name - def test_archive_success_with_components(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_archive_success_with_components(self): node = factories.NodeFactory(creator=self.user) comp1 = factories.NodeFactory(parent=node, creator=self.user) factories.NodeFactory(parent=comp1, creator=self.user) @@ -639,7 +641,8 @@ def mock_get_file_tree(self, *args, **kwargs): assert parent_registration._id in file_response['file_urls']['html'] registration_files.add(file_sha) - def test_archive_success_different_name_same_sha(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_archive_success_different_name_same_sha(self): file_tree = file_tree_factory(0, 0, 0) fake_file = file_factory() fake_file2 = file_factory(sha256=fake_file['extra']['hashes']['sha256']) @@ -665,7 +668,8 @@ def test_archive_success_different_name_same_sha(self, mock_gravy_valet_get_link for key, question in registration.registered_meta[schema._id].items(): assert question['extra'][0]['selectedFileName'] == fake_file['name'] - def test_archive_failure_different_name_same_sha(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_archive_failure_different_name_same_sha(self): file_tree = file_tree_factory(0, 0, 0) fake_file = file_factory() fake_file2 = file_factory(sha256=fake_file['extra']['hashes']['sha256']) @@ -690,7 +694,8 @@ def test_archive_failure_different_name_same_sha(self, mock_gravy_valet_get_link with pytest.raises(ArchivedFileNotFound): archive_success(registration._id, job._id) - def test_archive_success_same_file_in_component(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_archive_success_same_file_in_component(self): file_tree = file_tree_factory(3, 3, 3) selected = list(select_files_from_tree(file_tree).values())[0] diff --git a/osf_tests/test_registrations.py b/osf_tests/test_registrations.py index eedcb2e8e6c..4a9678c6983 100644 --- a/osf_tests/test_registrations.py +++ b/osf_tests/test_registrations.py @@ -52,7 +52,7 @@ def auth(user): return Auth(user) @pytest.fixture(autouse=True) -def mock_gravy_valet_get_links(self): +def mock_gravy_valet_get_links(): with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: mock_get_links.return_value = [] yield mock_get_links diff --git a/osf_tests/test_sanctions.py b/osf_tests/test_sanctions.py index 2f1d01718b1..5c5a1969f34 100644 --- a/osf_tests/test_sanctions.py +++ b/osf_tests/test_sanctions.py @@ -13,7 +13,7 @@ from osf.utils import permissions @pytest.fixture(autouse=True) -def mock_gravy_valet_get_links(self): +def mock_gravy_valet_get_links(): with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: mock_get_links.return_value = [] yield mock_get_links diff --git a/tests/identifiers/test_datacite.py b/tests/identifiers/test_datacite.py index 1e448e04e0f..59855119604 100644 --- a/tests/identifiers/test_datacite.py +++ b/tests/identifiers/test_datacite.py @@ -266,7 +266,14 @@ def setUp(self): self.node = RegistrationFactory(creator=self.user, is_public=True) self.client = DataCiteClient(self.node) + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + @responses.activate + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_datacite_create_identifiers_not_exists(self): responses.add( responses.Response( diff --git a/tests/test_registrations/test_embargoes.py b/tests/test_registrations/test_embargoes.py index 5edd53e7504..05bbc9649e5 100644 --- a/tests/test_registrations/test_embargoes.py +++ b/tests/test_registrations/test_embargoes.py @@ -156,7 +156,8 @@ def test_embargo_with_valid_end_date_starts_pending_embargo(self): self.registration.save() assert self.registration.is_pending_embargo - def test_embargo_public_project_makes_private_pending_embargo(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_embargo_public_project_makes_private_pending_embargo(self): self.registration.is_public = True assert self.registration.is_public self.registration.embargo_registration( @@ -433,7 +434,8 @@ def test_on_complete_raises_error_if_registration_is_spam(self): assert mock_notify.call_count == 0 # Regression for OSF-8840 - def test_public_embargo_cannot_be_deleted_with_initial_token(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_public_embargo_cannot_be_deleted_with_initial_token(self): embargo_termination_approval = EmbargoTerminationApprovalFactory() registration = Registration.objects.get(embargo_termination_approval=embargo_termination_approval) user = registration.contributors.first() @@ -709,7 +711,8 @@ def test_GET_disapprove_for_existing_registration_returns_200(self): assert res.status_code == 200 assert res.request.path == self.registration.web_url_for('view_project') - def test_GET_from_unauthorized_user_with_registration_token(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_GET_from_unauthorized_user_with_registration_token(self): unauthorized_user = AuthUserFactory() self.registration.require_approval(self.user) @@ -759,7 +762,8 @@ def test_GET_from_unauthorized_user_with_registration_token(self, mock_gravy_val ) assert res.status_code == 200 - def test_GET_from_authorized_user_with_registration_app_token(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_GET_from_authorized_user_with_registration_app_token(self): self.registration.require_approval(self.user) self.registration.save() app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token'] @@ -978,7 +982,8 @@ def test_GET_disapprove_for_existing_registration_returns_200(self): assert res.status_code == 302 assert res.request.path == self.registration.web_url_for('token_action') - def test_GET_from_unauthorized_user_with_registration_token(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_GET_from_unauthorized_user_with_registration_token(self): unauthorized_user = AuthUserFactory() self.registration.require_approval(self.user) @@ -1028,7 +1033,8 @@ def test_GET_from_unauthorized_user_with_registration_token(self, mock_gravy_val ) assert res.status_code == 302 - def test_GET_from_authorized_user_with_registration_app_token(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_GET_from_authorized_user_with_registration_app_token(self): self.registration.require_approval(self.user) self.registration.save() app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token'] diff --git a/tests/test_registrations/test_registration_approvals.py b/tests/test_registrations/test_registration_approvals.py index ad76a625319..94dfa4891b5 100644 --- a/tests/test_registrations/test_registration_approvals.py +++ b/tests/test_registrations/test_registration_approvals.py @@ -120,7 +120,8 @@ def test_non_admin_approval_token_raises_PermissionsError(self): self.registration.registration_approval.approve(user=non_admin, token=approval_token) assert self.registration.is_pending_registration - def test_approval_adds_to_parent_projects_log(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_approval_adds_to_parent_projects_log(self): initial_project_logs = self.registration.registered_from.logs.count() self.registration.require_approval( self.user @@ -132,7 +133,8 @@ def test_approval_adds_to_parent_projects_log(self, mock_gravy_valet_get_links): # adds initiated, approved, and registered logs assert self.registration.registered_from.logs.count() == initial_project_logs + 3 - def test_one_approval_with_two_admins_stays_pending(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_one_approval_with_two_admins_stays_pending(self): admin2 = UserFactory() Contributor.objects.create(node=self.registration, user=admin2) self.registration.add_permission(admin2, ADMIN, save=True) @@ -257,7 +259,8 @@ def test_new_registration_is_pending_registration(self): self.registration.save() assert self.registration.is_pending_registration - def test_should_suppress_emails(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_should_suppress_emails(self): self.registration = RegistrationFactory(project=self.project) self.registration.external_registration = True self.registration.save() @@ -286,7 +289,8 @@ def test_should_suppress_emails(self, mock_gravy_valet_get_links): self.registration.sanction.ask(contributors) assert mock_notify_non_authorizer.call_count == 0 - def test_on_complete_notify_initiator(self, mock_gravy_valet_get_links): + @pytest.mark.usefixtures('mock_gravy_valet_get_links') + def test_on_complete_notify_initiator(self): self.registration.require_approval( self.user, notify_initiator_on_complete=True diff --git a/tests/test_registrations/test_retractions.py b/tests/test_registrations/test_retractions.py index e46ea876175..aaf6acc273e 100644 --- a/tests/test_registrations/test_retractions.py +++ b/tests/test_registrations/test_retractions.py @@ -26,7 +26,7 @@ from osf.utils import permissions @pytest.fixture(autouse=True) -def mock_gravy_valet_get_links(self): +def mock_gravy_valet_get_links(): with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: mock_get_links.return_value = [] yield mock_get_links diff --git a/tests/test_registrations/test_review_flows.py b/tests/test_registrations/test_review_flows.py index d0b1188906e..422807472b7 100644 --- a/tests/test_registrations/test_review_flows.py +++ b/tests/test_registrations/test_review_flows.py @@ -61,7 +61,7 @@ def retraction(provider=None): return sanction @pytest.fixture(autouse=True) -def mock_gravy_valet_get_links(self): +def mock_gravy_valet_get_links(): with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: mock_get_links.return_value = [] yield mock_get_links diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 3afafa2363a..29ad7c1c8f1 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -88,6 +88,13 @@ def setUp(self, *args, **kwargs): self.reg = AbstractNode.objects.get(Q(**{self.Model.SHORT_NAME: self.sanction})) self.user = self.reg.creator + @pytest.fixture + def mock_gravy_valet_get_links(self): + with mock.patch('osf.models.node.AbstractNode.get_verified_links') as mock_get_links: + mock_get_links.return_value = [] + yield mock_get_links + + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_sanction_handler(self): if not self.kind: return From 07f409e17bf20cbe437f575b46e55a466c2784e1 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 8 May 2025 17:48:28 +0300 Subject: [PATCH 9/9] Update expected metadata files --- .../expected_metadata_files/file_basic.turtle | 13 ++- .../expected_metadata_files/file_full.turtle | 35 +++--- .../file_monthly_supplement.turtle | 1 + .../file_supplement.turtle | 2 +- .../preprint_basic.turtle | 27 ++--- .../preprint_full.turtle | 41 +++---- .../preprint_monthly_supplement.turtle | 1 + .../preprint_supplement.turtle | 2 + .../project_basic.datacite.json | 6 + .../project_basic.datacite.xml | 1 + .../project_basic.turtle | 77 ++++++------- .../project_full.datacite.json | 6 + .../project_full.datacite.xml | 1 + .../project_full.turtle | 103 +++++++++--------- .../project_monthly_supplement.turtle | 1 + .../project_supplement.turtle | 4 +- .../registration_basic.turtle | 59 +++++----- .../registration_full.turtle | 95 ++++++++-------- .../registration_monthly_supplement.turtle | 1 + .../registration_supplement.turtle | 2 + .../expected_metadata_files/user_basic.turtle | 3 +- .../expected_metadata_files/user_full.turtle | 3 +- .../user_monthly_supplement.turtle | 2 +- .../user_supplement.turtle | 2 +- .../metadata/test_serialized_metadata.py | 2 +- osf_tests/test_archiver.py | 1 + 26 files changed, 263 insertions(+), 228 deletions(-) diff --git a/osf_tests/metadata/expected_metadata_files/file_basic.turtle b/osf_tests/metadata/expected_metadata_files/file_basic.turtle index 3f430b22521..63c362903c4 100644 --- a/osf_tests/metadata/expected_metadata_files/file_basic.turtle +++ b/osf_tests/metadata/expected_metadata_files/file_basic.turtle @@ -6,10 +6,10 @@ @prefix skos: . a osf:File ; - dcat:accessService ; dcterms:created "2123-05-04" ; dcterms:identifier "http://localhost:5000/w3ibb" ; dcterms:modified "2123-05-04" ; + dcat:accessService ; osf:fileName "my-file.blarg" ; osf:filePath "/my-file.blarg" ; osf:hasFileVersion ; @@ -38,14 +38,15 @@ osf:storageRegion ; osf:versionNumber "1" . - a dcterms:Agent, - foaf:Person ; - dcterms:identifier "http://localhost:5000/w1ibb" ; - foaf:name "Person McNamington" . + skos:prefLabel "United States"@en . a dcterms:Agent, foaf:Organization ; dcterms:identifier "http://localhost:5000" ; foaf:name "OSF" . - skos:prefLabel "United States"@en . + a dcterms:Agent, + foaf:Person ; + dcterms:identifier "http://localhost:5000/w1ibb" ; + foaf:name "Person McNamington" . + diff --git a/osf_tests/metadata/expected_metadata_files/file_full.turtle b/osf_tests/metadata/expected_metadata_files/file_full.turtle index 175ccfb042f..7ef342cc3bd 100644 --- a/osf_tests/metadata/expected_metadata_files/file_full.turtle +++ b/osf_tests/metadata/expected_metadata_files/file_full.turtle @@ -7,10 +7,10 @@ @prefix skos: . a osf:File ; - dcat:accessService ; dcterms:created "2123-05-04" ; dcterms:identifier "http://localhost:5000/w3ibb" ; dcterms:modified "2123-05-04" ; + dcat:accessService ; osf:fileName "my-file.blarg" ; osf:filePath "/my-file.blarg" ; osf:hasFileVersion ; @@ -44,6 +44,15 @@ osf:storageRegion ; osf:versionNumber "1" . + skos:prefLabel "United States"@en . + + dcterms:identifier "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ; + foaf:name "CC-By Attribution-NonCommercial-NoDerivatives 4.0 International" . + + a dcterms:Agent ; + dcterms:identifier "https://doi.org/10.$" ; + foaf:name "Caring Fan" . + a osf:FundingAward ; dcterms:contributor ; dcterms:identifier "https://moneypockets.example/millions" ; @@ -56,27 +65,19 @@ dcterms:title "because reasons!" ; osf:awardNumber "2000000" . - dcterms:identifier "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ; - foaf:name "CC-By Attribution-NonCommercial-NoDerivatives 4.0 International" . - - a dcterms:Agent ; - dcterms:identifier "https://doi.org/10.$$$$" ; - foaf:name "Mx. Moneypockets" . + rdfs:label "Dataset"@en . - a dcterms:Agent ; - dcterms:identifier "https://doi.org/10.$" ; - foaf:name "Caring Fan" . + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000" ; + foaf:name "OSF" . a dcterms:Agent, foaf:Person ; dcterms:identifier "http://localhost:5000/w1ibb" ; foaf:name "Person McNamington" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000" ; - foaf:name "OSF" . - - rdfs:label "Dataset"@en . + a dcterms:Agent ; + dcterms:identifier "https://doi.org/10.$$$$" ; + foaf:name "Mx. Moneypockets" . - skos:prefLabel "United States"@en . diff --git a/osf_tests/metadata/expected_metadata_files/file_monthly_supplement.turtle b/osf_tests/metadata/expected_metadata_files/file_monthly_supplement.turtle index 845bd149f37..3724c914858 100644 --- a/osf_tests/metadata/expected_metadata_files/file_monthly_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/file_monthly_supplement.turtle @@ -11,3 +11,4 @@ osf:downloadSessionCount 2 ; osf:viewCount 7 ; osf:viewSessionCount 5 ] . + diff --git a/osf_tests/metadata/expected_metadata_files/file_supplement.turtle b/osf_tests/metadata/expected_metadata_files/file_supplement.turtle index 662c197699d..8b137891791 100644 --- a/osf_tests/metadata/expected_metadata_files/file_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/file_supplement.turtle @@ -1 +1 @@ -# correctly empty (for now) + diff --git a/osf_tests/metadata/expected_metadata_files/preprint_basic.turtle b/osf_tests/metadata/expected_metadata_files/preprint_basic.turtle index 4d3627b928f..cd16d315275 100644 --- a/osf_tests/metadata/expected_metadata_files/preprint_basic.turtle +++ b/osf_tests/metadata/expected_metadata_files/preprint_basic.turtle @@ -25,17 +25,12 @@ dcterms:type ; owl:sameAs ; dcat:accessService ; - osf:hostingInstitution ; - osf:isSupplementedBy ; - osf:statedConflictOfInterest osf:no-conflict-of-interest ; prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; prov:agent ; - osf:order 0 ] . - - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000" ; - foaf:name "OSF" . + osf:order 0 ] ; + osf:hostingInstitution ; + osf:isSupplementedBy ; + osf:statedConflictOfInterest osf:no-conflict-of-interest . a dcterms:Agent, foaf:Organization ; @@ -72,10 +67,10 @@ rdfs:label "Preprint"@en . - a dcterms:Agent, - foaf:Person ; - dcterms:identifier "http://localhost:5000/w1ibb" ; - foaf:name "Person McNamington" . + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000" ; + foaf:name "OSF" . a skos:ConceptScheme ; dcterms:title "preprovi" . @@ -93,6 +88,12 @@ a skos:ConceptScheme ; dcterms:title "bepress Digital Commons Three-Tiered Taxonomy" . + a dcterms:Agent, + foaf:Person ; + dcterms:identifier "http://localhost:5000/w1ibb" ; + foaf:name "Person McNamington" . + a skos:Concept ; skos:inScheme ; skos:prefLabel "wibbble" . + diff --git a/osf_tests/metadata/expected_metadata_files/preprint_full.turtle b/osf_tests/metadata/expected_metadata_files/preprint_full.turtle index 448c04ab644..3649b6282f3 100644 --- a/osf_tests/metadata/expected_metadata_files/preprint_full.turtle +++ b/osf_tests/metadata/expected_metadata_files/preprint_full.turtle @@ -25,17 +25,12 @@ dcterms:type ; owl:sameAs ; dcat:accessService ; - osf:hostingInstitution ; - osf:isSupplementedBy ; - osf:statedConflictOfInterest osf:no-conflict-of-interest ; prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; prov:agent ; - osf:order 0 ] . - - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000" ; - foaf:name "OSF" . + osf:order 0 ] ; + osf:hostingInstitution ; + osf:isSupplementedBy ; + osf:statedConflictOfInterest osf:no-conflict-of-interest . a dcterms:Agent, foaf:Organization ; @@ -76,6 +71,10 @@ dcterms:identifier "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ; foaf:name "CC-By Attribution-NonCommercial-NoDerivatives 4.0 International" . + a dcterms:Agent ; + dcterms:identifier "https://doi.org/10.$" ; + foaf:name "Caring Fan" . + dcterms:identifier "https://doi.org/11.111/something-or-other" . a osf:FundingAward ; @@ -94,10 +93,10 @@ rdfs:label "Preprint"@en . - a dcterms:Agent, - foaf:Person ; - dcterms:identifier "http://localhost:5000/w1ibb" ; - foaf:name "Person McNamington" . + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000" ; + foaf:name "OSF" . a skos:ConceptScheme ; dcterms:title "preprovi" . @@ -115,14 +114,16 @@ a skos:ConceptScheme ; dcterms:title "bepress Digital Commons Three-Tiered Taxonomy" . - a dcterms:Agent ; - dcterms:identifier "https://doi.org/10.$$$$" ; - foaf:name "Mx. Moneypockets" . - - a dcterms:Agent ; - dcterms:identifier "https://doi.org/10.$" ; - foaf:name "Caring Fan" . + a dcterms:Agent, + foaf:Person ; + dcterms:identifier "http://localhost:5000/w1ibb" ; + foaf:name "Person McNamington" . a skos:Concept ; skos:inScheme ; skos:prefLabel "wibbble" . + + a dcterms:Agent ; + dcterms:identifier "https://doi.org/10.$$$$" ; + foaf:name "Mx. Moneypockets" . + diff --git a/osf_tests/metadata/expected_metadata_files/preprint_monthly_supplement.turtle b/osf_tests/metadata/expected_metadata_files/preprint_monthly_supplement.turtle index 8e6d6fb9331..9e0ef035f18 100644 --- a/osf_tests/metadata/expected_metadata_files/preprint_monthly_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/preprint_monthly_supplement.turtle @@ -11,3 +11,4 @@ osf:downloadSessionCount 2 ; osf:viewCount 7 ; osf:viewSessionCount 5 ] . + diff --git a/osf_tests/metadata/expected_metadata_files/preprint_supplement.turtle b/osf_tests/metadata/expected_metadata_files/preprint_supplement.turtle index 9ff0732a509..968336cbaef 100644 --- a/osf_tests/metadata/expected_metadata_files/preprint_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/preprint_supplement.turtle @@ -1,7 +1,9 @@ @prefix osf: . @prefix skos: . +@prefix xsd: . osf:storageByteCount 1337 ; osf:storageRegion . skos:prefLabel "United States"@en . + diff --git a/osf_tests/metadata/expected_metadata_files/project_basic.datacite.json b/osf_tests/metadata/expected_metadata_files/project_basic.datacite.json index 1f85e773f2f..d866a786a89 100644 --- a/osf_tests/metadata/expected_metadata_files/project_basic.datacite.json +++ b/osf_tests/metadata/expected_metadata_files/project_basic.datacite.json @@ -63,6 +63,12 @@ "relatedIdentifier": "11.pp/FK2osf.io/w4ibb_v1", "relatedIdentifierType": "DOI", "relationType": "IsSupplementTo" + }, + { + "relatedIdentifier": "https://foo.bar", + "relatedIdentifierType": "URL", + "relationType": "IsReferencedBy", + "resourceTypeGeneral": "Other" } ], "relatedItems": [ diff --git a/osf_tests/metadata/expected_metadata_files/project_basic.datacite.xml b/osf_tests/metadata/expected_metadata_files/project_basic.datacite.xml index 8b4abfb5d87..d395415a708 100644 --- a/osf_tests/metadata/expected_metadata_files/project_basic.datacite.xml +++ b/osf_tests/metadata/expected_metadata_files/project_basic.datacite.xml @@ -38,6 +38,7 @@ http://localhost:5000/w5ibb 11.pp/FK2osf.io/w4ibb_v1 + https://foo.bar diff --git a/osf_tests/metadata/expected_metadata_files/project_basic.turtle b/osf_tests/metadata/expected_metadata_files/project_basic.turtle index c5208ec295e..95f758da594 100644 --- a/osf_tests/metadata/expected_metadata_files/project_basic.turtle +++ b/osf_tests/metadata/expected_metadata_files/project_basic.turtle @@ -8,6 +8,16 @@ @prefix skos: . @prefix xsd: . + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000/preprints/preprovi" ; + foaf:name "PP the Preprint Provider" . + + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000/registries/regiprovi" ; + foaf:name "RegiProvi the Registration Provider" . + a osf:Project ; dcterms:created "2123-05-04" ; dcterms:creator ; @@ -24,15 +34,34 @@ dcterms:title "this is a project title!" ; owl:sameAs ; dcat:accessService ; - osf:contains ; - osf:hostingInstitution ; - osf:supplements ; prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; prov:agent ; osf:order 0 ] ; + osf:contains ; + osf:hostingInstitution ; + osf:supplements ; osf:verifiedLink [ dcterms:type ; dcat:accessURL "https://foo.bar" ] . + a osf:File ; + dcterms:created "2123-05-04" ; + dcterms:identifier "http://localhost:5000/w3ibb" ; + dcterms:modified "2123-05-04" ; + osf:fileName "my-file.blarg" ; + osf:filePath "/my-file.blarg" ; + osf:hasFileVersion ; + osf:isContainedBy . + + a osf:FileVersion ; + dcterms:created "2123-05-04" ; + dcterms:creator ; + dcterms:extent "0.000007 MB" ; + dcterms:format "img/png" ; + dcterms:modified "2123-05-04" ; + dcterms:requires ; + osf:storageRegion ; + osf:versionNumber "1" . + a osf:Preprint ; dcterms:created "2123-05-04" ; dcterms:creator ; @@ -55,24 +84,7 @@ dcterms:title "this is a project title!" ; dcterms:type . - a osf:File ; - dcterms:created "2123-05-04" ; - dcterms:identifier "http://localhost:5000/w3ibb" ; - dcterms:modified "2123-05-04" ; - osf:fileName "my-file.blarg" ; - osf:filePath "/my-file.blarg" ; - osf:hasFileVersion ; - osf:isContainedBy . - - a osf:FileVersion ; - dcterms:created "2123-05-04" ; - dcterms:creator ; - dcterms:extent "0.000007 MB" ; - dcterms:format "img/png" ; - dcterms:modified "2123-05-04" ; - dcterms:requires ; - osf:storageRegion ; - osf:versionNumber "1" . + skos:prefLabel "United States"@en . a dcterms:Agent, foaf:Organization ; @@ -81,28 +93,17 @@ owl:sameAs ; foaf:name "Center for Open Science" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000/registries/regiprovi" ; - foaf:name "RegiProvi the Registration Provider" . - - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000/preprints/preprovi" ; - foaf:name "PP the Preprint Provider" . + rdfs:label "Preprint"@en . - a dcterms:Agent, - foaf:Person ; - dcterms:identifier "http://localhost:5000/w1ibb" ; - foaf:name "Person McNamington" . + rdfs:label "StudyRegistration"@en . a dcterms:Agent, foaf:Organization ; dcterms:identifier "http://localhost:5000" ; foaf:name "OSF" . - rdfs:label "Preprint"@en . - - rdfs:label "StudyRegistration"@en . + a dcterms:Agent, + foaf:Person ; + dcterms:identifier "http://localhost:5000/w1ibb" ; + foaf:name "Person McNamington" . - skos:prefLabel "United States"@en . diff --git a/osf_tests/metadata/expected_metadata_files/project_full.datacite.json b/osf_tests/metadata/expected_metadata_files/project_full.datacite.json index 4ead1090105..f4a43d07bd6 100644 --- a/osf_tests/metadata/expected_metadata_files/project_full.datacite.json +++ b/osf_tests/metadata/expected_metadata_files/project_full.datacite.json @@ -97,6 +97,12 @@ "relatedIdentifier": "11.pp/FK2osf.io/w4ibb_v1", "relatedIdentifierType": "DOI", "relationType": "IsSupplementTo" + }, + { + "relatedIdentifier": "https://foo.bar", + "relatedIdentifierType": "URL", + "relationType": "IsReferencedBy", + "resourceTypeGeneral": "Other" } ], "relatedItems": [ diff --git a/osf_tests/metadata/expected_metadata_files/project_full.datacite.xml b/osf_tests/metadata/expected_metadata_files/project_full.datacite.xml index e8649704d02..f707bb2e077 100644 --- a/osf_tests/metadata/expected_metadata_files/project_full.datacite.xml +++ b/osf_tests/metadata/expected_metadata_files/project_full.datacite.xml @@ -56,6 +56,7 @@ http://localhost:5000/w5ibb 11.pp/FK2osf.io/w4ibb_v1 + https://foo.bar diff --git a/osf_tests/metadata/expected_metadata_files/project_full.turtle b/osf_tests/metadata/expected_metadata_files/project_full.turtle index 6856faa651f..09925966657 100644 --- a/osf_tests/metadata/expected_metadata_files/project_full.turtle +++ b/osf_tests/metadata/expected_metadata_files/project_full.turtle @@ -8,6 +8,16 @@ @prefix skos: . @prefix xsd: . + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000/preprints/preprovi" ; + foaf:name "PP the Preprint Provider" . + + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000/registries/regiprovi" ; + foaf:name "RegiProvi the Registration Provider" . + a osf:Project ; dcterms:created "2123-05-04" ; dcterms:creator ; @@ -26,6 +36,9 @@ dcterms:type ; owl:sameAs ; dcat:accessService ; + prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; + prov:agent ; + osf:order 0 ] ; osf:contains ; osf:funder , ; @@ -33,12 +46,28 @@ ; osf:hostingInstitution ; osf:supplements ; - prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; - prov:agent ; - osf:order 0 ] ; osf:verifiedLink [ dcterms:type ; dcat:accessURL "https://foo.bar" ] . + a osf:File ; + dcterms:created "2123-05-04" ; + dcterms:identifier "http://localhost:5000/w3ibb" ; + dcterms:modified "2123-05-04" ; + osf:fileName "my-file.blarg" ; + osf:filePath "/my-file.blarg" ; + osf:hasFileVersion ; + osf:isContainedBy . + + a osf:FileVersion ; + dcterms:created "2123-05-04" ; + dcterms:creator ; + dcterms:extent "0.000007 MB" ; + dcterms:format "img/png" ; + dcterms:modified "2123-05-04" ; + dcterms:requires ; + osf:storageRegion ; + osf:versionNumber "1" . + a osf:Preprint ; dcterms:created "2123-05-04" ; dcterms:creator ; @@ -61,24 +90,18 @@ dcterms:title "this is a project title!" ; dcterms:type . - a osf:File ; - dcterms:created "2123-05-04" ; - dcterms:identifier "http://localhost:5000/w3ibb" ; - dcterms:modified "2123-05-04" ; - osf:fileName "my-file.blarg" ; - osf:filePath "/my-file.blarg" ; - osf:hasFileVersion ; - osf:isContainedBy . + skos:prefLabel "United States"@en . - a osf:FileVersion ; - dcterms:created "2123-05-04" ; - dcterms:creator ; - dcterms:extent "0.000007 MB" ; - dcterms:format "img/png" ; - dcterms:modified "2123-05-04" ; - dcterms:requires ; - osf:storageRegion ; - osf:versionNumber "1" . + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "https://cos.io/", + "https://ror.org/05d5mza29" ; + owl:sameAs ; + foaf:name "Center for Open Science" . + + a dcterms:Agent ; + dcterms:identifier "https://doi.org/10.$" ; + foaf:name "Caring Fan" . a osf:FundingAward ; dcterms:contributor ; @@ -92,48 +115,26 @@ dcterms:title "because reasons!" ; osf:awardNumber "2000000" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "https://cos.io/", - "https://ror.org/05d5mza29" ; - owl:sameAs ; - foaf:name "Center for Open Science" . + rdfs:label "Dataset"@en . - dcterms:identifier "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ; - foaf:name "CC-By Attribution-NonCommercial-NoDerivatives 4.0 International" . + rdfs:label "Preprint"@en . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000/registries/regiprovi" ; - foaf:name "RegiProvi the Registration Provider" . + rdfs:label "StudyRegistration"@en . - a dcterms:Agent, + a dcterms:Agent, foaf:Organization ; - dcterms:identifier "http://localhost:5000/preprints/preprovi" ; - foaf:name "PP the Preprint Provider" . + dcterms:identifier "http://localhost:5000" ; + foaf:name "OSF" . + + dcterms:identifier "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ; + foaf:name "CC-By Attribution-NonCommercial-NoDerivatives 4.0 International" . a dcterms:Agent ; dcterms:identifier "https://doi.org/10.$$$$" ; foaf:name "Mx. Moneypockets" . - a dcterms:Agent ; - dcterms:identifier "https://doi.org/10.$" ; - foaf:name "Caring Fan" . - a dcterms:Agent, foaf:Person ; dcterms:identifier "http://localhost:5000/w1ibb" ; foaf:name "Person McNamington" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000" ; - foaf:name "OSF" . - - rdfs:label "Preprint"@en . - - rdfs:label "Dataset"@en . - - rdfs:label "StudyRegistration"@en . - - skos:prefLabel "United States"@en . diff --git a/osf_tests/metadata/expected_metadata_files/project_monthly_supplement.turtle b/osf_tests/metadata/expected_metadata_files/project_monthly_supplement.turtle index dd9c54b1f93..ac6021a334c 100644 --- a/osf_tests/metadata/expected_metadata_files/project_monthly_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/project_monthly_supplement.turtle @@ -11,3 +11,4 @@ osf:downloadSessionCount 2 ; osf:viewCount 7 ; osf:viewSessionCount 5 ] . + diff --git a/osf_tests/metadata/expected_metadata_files/project_supplement.turtle b/osf_tests/metadata/expected_metadata_files/project_supplement.turtle index d055e97554f..84986b4635a 100644 --- a/osf_tests/metadata/expected_metadata_files/project_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/project_supplement.turtle @@ -1,13 +1,15 @@ @prefix dcterms: . @prefix osf: . @prefix skos: . +@prefix xsd: . osf:hasOsfAddon ; osf:storageByteCount 7 ; osf:storageRegion . + skos:prefLabel "United States"@en . + a osf:AddonImplementation ; dcterms:identifier "gitlab" ; skos:prefLabel "GitLab" . - skos:prefLabel "United States"@en . diff --git a/osf_tests/metadata/expected_metadata_files/registration_basic.turtle b/osf_tests/metadata/expected_metadata_files/registration_basic.turtle index 562ded6c88a..56bc461acf7 100644 --- a/osf_tests/metadata/expected_metadata_files/registration_basic.turtle +++ b/osf_tests/metadata/expected_metadata_files/registration_basic.turtle @@ -8,6 +8,26 @@ @prefix skos: . @prefix xsd: . + dcterms:title "Open-Ended Registration" . + + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000/registries/regiprovi" ; + foaf:name "RegiProvi the Registration Provider" . + + a osf:Project ; + dcterms:created "2123-05-04" ; + dcterms:creator ; + dcterms:dateCopyrighted "2252" ; + dcterms:identifier "http://localhost:5000/w2ibb", + "https://doi.org/10.70102/FK2osf.io/w2ibb" ; + dcterms:publisher ; + dcterms:rights [ foaf:name "No license" ] ; + dcterms:rightsHolder "Me", + "You" ; + dcterms:title "this is a project title!" ; + owl:sameAs . + a osf:Registration ; dcterms:conformsTo ; dcterms:created "2123-05-04" ; @@ -24,24 +44,11 @@ dcterms:title "this is a project title!" ; dcterms:type ; dcat:accessService ; - osf:contains ; - osf:hostingInstitution ; prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; prov:agent ; - osf:order 0 ] . - - a osf:Project ; - dcterms:created "2123-05-04" ; - dcterms:creator ; - dcterms:dateCopyrighted "2252" ; - dcterms:identifier "http://localhost:5000/w2ibb", - "https://doi.org/10.70102/FK2osf.io/w2ibb" ; - dcterms:publisher ; - dcterms:rights [ foaf:name "No license" ] ; - dcterms:rightsHolder "Me", - "You" ; - dcterms:title "this is a project title!" ; - owl:sameAs . + osf:order 0 ] ; + osf:contains ; + osf:hostingInstitution . a osf:File ; dcterms:created "2123-05-04" ; @@ -62,6 +69,8 @@ osf:storageRegion ; osf:versionNumber "1" . + skos:prefLabel "United States"@en . + a dcterms:Agent, foaf:Organization ; dcterms:identifier "https://cos.io/", @@ -69,23 +78,15 @@ owl:sameAs ; foaf:name "Center for Open Science" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000/registries/regiprovi" ; - foaf:name "RegiProvi the Registration Provider" . - - a dcterms:Agent, - foaf:Person ; - dcterms:identifier "http://localhost:5000/w1ibb" ; - foaf:name "Person McNamington" . + rdfs:label "StudyRegistration"@en . a dcterms:Agent, foaf:Organization ; dcterms:identifier "http://localhost:5000" ; foaf:name "OSF" . - dcterms:title "Open-Ended Registration" . - - rdfs:label "StudyRegistration"@en . + a dcterms:Agent, + foaf:Person ; + dcterms:identifier "http://localhost:5000/w1ibb" ; + foaf:name "Person McNamington" . - skos:prefLabel "United States"@en . diff --git a/osf_tests/metadata/expected_metadata_files/registration_full.turtle b/osf_tests/metadata/expected_metadata_files/registration_full.turtle index 03d711b8f79..0751b6ac4ad 100644 --- a/osf_tests/metadata/expected_metadata_files/registration_full.turtle +++ b/osf_tests/metadata/expected_metadata_files/registration_full.turtle @@ -8,27 +8,12 @@ @prefix skos: . @prefix xsd: . - a osf:Registration ; - dcterms:conformsTo ; - dcterms:created "2123-05-04" ; - dcterms:creator ; - dcterms:dateCopyrighted "2250-2254" ; - dcterms:description "this is a project description!" ; - dcterms:identifier "http://localhost:5000/w5ibb" ; - dcterms:isVersionOf ; - dcterms:modified "2123-05-04" ; - dcterms:publisher ; - dcterms:rights ; - dcterms:rightsHolder "Me", - "You" ; - dcterms:title "this is a project title!" ; - dcterms:type ; - dcat:accessService ; - osf:contains ; - osf:hostingInstitution ; - prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; - prov:agent ; - osf:order 0 ] . + dcterms:title "Open-Ended Registration" . + + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "http://localhost:5000/registries/regiprovi" ; + foaf:name "RegiProvi the Registration Provider" . a osf:Project ; dcterms:created "2123-05-04" ; @@ -48,6 +33,28 @@ osf:hasFunding , . + a osf:Registration ; + dcterms:conformsTo ; + dcterms:created "2123-05-04" ; + dcterms:creator ; + dcterms:dateCopyrighted "2250-2254" ; + dcterms:description "this is a project description!" ; + dcterms:identifier "http://localhost:5000/w5ibb" ; + dcterms:isVersionOf ; + dcterms:modified "2123-05-04" ; + dcterms:publisher ; + dcterms:rights ; + dcterms:rightsHolder "Me", + "You" ; + dcterms:title "this is a project title!" ; + dcterms:type ; + dcat:accessService ; + prov:qualifiedAttribution [ dcat:hadRole osf:admin-contributor ; + prov:agent ; + osf:order 0 ] ; + osf:contains ; + osf:hostingInstitution . + a osf:File ; dcterms:created "2123-05-04" ; dcterms:identifier "http://localhost:5000/w6ibb" ; @@ -67,6 +74,19 @@ osf:storageRegion ; osf:versionNumber "1" . + skos:prefLabel "United States"@en . + + a dcterms:Agent, + foaf:Organization ; + dcterms:identifier "https://cos.io/", + "https://ror.org/05d5mza29" ; + owl:sameAs ; + foaf:name "Center for Open Science" . + + a dcterms:Agent ; + dcterms:identifier "https://doi.org/10.$" ; + foaf:name "Caring Fan" . + a osf:FundingAward ; dcterms:contributor ; dcterms:identifier "https://moneypockets.example/millions" ; @@ -79,43 +99,24 @@ dcterms:title "because reasons!" ; osf:awardNumber "2000000" . - a dcterms:Agent, + rdfs:label "Dataset"@en . + + rdfs:label "StudyRegistration"@en . + + a dcterms:Agent, foaf:Organization ; - dcterms:identifier "https://cos.io/", - "https://ror.org/05d5mza29" ; - owl:sameAs ; - foaf:name "Center for Open Science" . + dcterms:identifier "http://localhost:5000" ; + foaf:name "OSF" . dcterms:identifier "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ; foaf:name "CC-By Attribution-NonCommercial-NoDerivatives 4.0 International" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000/registries/regiprovi" ; - foaf:name "RegiProvi the Registration Provider" . - a dcterms:Agent ; dcterms:identifier "https://doi.org/10.$$$$" ; foaf:name "Mx. Moneypockets" . - a dcterms:Agent ; - dcterms:identifier "https://doi.org/10.$" ; - foaf:name "Caring Fan" . - a dcterms:Agent, foaf:Person ; dcterms:identifier "http://localhost:5000/w1ibb" ; foaf:name "Person McNamington" . - a dcterms:Agent, - foaf:Organization ; - dcterms:identifier "http://localhost:5000" ; - foaf:name "OSF" . - - rdfs:label "Dataset"@en . - - dcterms:title "Open-Ended Registration" . - - rdfs:label "StudyRegistration"@en . - - skos:prefLabel "United States"@en . diff --git a/osf_tests/metadata/expected_metadata_files/registration_monthly_supplement.turtle b/osf_tests/metadata/expected_metadata_files/registration_monthly_supplement.turtle index 435f7f4f921..81abd9d231d 100644 --- a/osf_tests/metadata/expected_metadata_files/registration_monthly_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/registration_monthly_supplement.turtle @@ -11,3 +11,4 @@ osf:downloadSessionCount 2 ; osf:viewCount 7 ; osf:viewSessionCount 5 ] . + diff --git a/osf_tests/metadata/expected_metadata_files/registration_supplement.turtle b/osf_tests/metadata/expected_metadata_files/registration_supplement.turtle index 9e8201b7915..942b38de61d 100644 --- a/osf_tests/metadata/expected_metadata_files/registration_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/registration_supplement.turtle @@ -1,7 +1,9 @@ @prefix osf: . @prefix skos: . +@prefix xsd: . osf:storageByteCount 17 ; osf:storageRegion . skos:prefLabel "United States"@en . + diff --git a/osf_tests/metadata/expected_metadata_files/user_basic.turtle b/osf_tests/metadata/expected_metadata_files/user_basic.turtle index 8ebcc616171..e570163d03d 100644 --- a/osf_tests/metadata/expected_metadata_files/user_basic.turtle +++ b/osf_tests/metadata/expected_metadata_files/user_basic.turtle @@ -4,6 +4,7 @@ a dcterms:Agent, foaf:Person ; - dcat:accessService ; dcterms:identifier "http://localhost:5000/w1ibb" ; + dcat:accessService ; foaf:name "Person McNamington" . + diff --git a/osf_tests/metadata/expected_metadata_files/user_full.turtle b/osf_tests/metadata/expected_metadata_files/user_full.turtle index 8ebcc616171..e570163d03d 100644 --- a/osf_tests/metadata/expected_metadata_files/user_full.turtle +++ b/osf_tests/metadata/expected_metadata_files/user_full.turtle @@ -4,6 +4,7 @@ a dcterms:Agent, foaf:Person ; - dcat:accessService ; dcterms:identifier "http://localhost:5000/w1ibb" ; + dcat:accessService ; foaf:name "Person McNamington" . + diff --git a/osf_tests/metadata/expected_metadata_files/user_monthly_supplement.turtle b/osf_tests/metadata/expected_metadata_files/user_monthly_supplement.turtle index 662c197699d..8b137891791 100644 --- a/osf_tests/metadata/expected_metadata_files/user_monthly_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/user_monthly_supplement.turtle @@ -1 +1 @@ -# correctly empty (for now) + diff --git a/osf_tests/metadata/expected_metadata_files/user_supplement.turtle b/osf_tests/metadata/expected_metadata_files/user_supplement.turtle index 662c197699d..8b137891791 100644 --- a/osf_tests/metadata/expected_metadata_files/user_supplement.turtle +++ b/osf_tests/metadata/expected_metadata_files/user_supplement.turtle @@ -1 +1 @@ -# correctly empty (for now) + diff --git a/osf_tests/metadata/test_serialized_metadata.py b/osf_tests/metadata/test_serialized_metadata.py index 5bef77670d7..f122e33e84e 100644 --- a/osf_tests/metadata/test_serialized_metadata.py +++ b/osf_tests/metadata/test_serialized_metadata.py @@ -336,7 +336,7 @@ def mock_gravy_valet_get_links(self): mock_get_links.return_value = [] yield mock_get_links - pytest.mark.usefixtures('mock_gravy_valet_get_links') + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_serialized_metadata(self): self._assert_scenario(BASIC_METADATA_SCENARIO) self._setUp_full() diff --git a/osf_tests/test_archiver.py b/osf_tests/test_archiver.py index bae439896ba..a38cd70bef2 100644 --- a/osf_tests/test_archiver.py +++ b/osf_tests/test_archiver.py @@ -540,6 +540,7 @@ def test_archive_addon(self, mock_make_copy_request): } ) + @pytest.mark.usefixtures('mock_gravy_valet_get_links') def test_archive_success(self): node = factories.NodeFactory(creator=self.user) file_trees, selected_files, node_index = generate_file_tree([node])