def test_many_redirections_to_the_same_pid(inspire_app): pid_1 = PersistentIdentifier.create( pid_type="a", pid_value="1", status=PIDStatus.REGISTERED, object_uuid=uuid.uuid4(), ) pid_2 = PersistentIdentifier.create( pid_type="a", pid_value="2", status=PIDStatus.REGISTERED, object_uuid=uuid.uuid4(), ) pid_3 = PersistentIdentifier.create( pid_type="a", pid_value="3", status=PIDStatus.REGISTERED, object_uuid=uuid.uuid4(), ) InspireRedirect.redirect(pid_1, pid_2) InspireRedirect.redirect(pid_3, pid_2) assert pid_1.status == PIDStatus.REDIRECTED assert pid_3.status == PIDStatus.REDIRECTED assert len(pid_2.redirected_pids) == 2
def test_get_redirected_pid(inspire_app): pid_1 = PersistentIdentifier.create(pid_type="a", pid_value="1", status=PIDStatus.REGISTERED) pid_2 = PersistentIdentifier.create(pid_type="a", pid_value="2", status=PIDStatus.REGISTERED) InspireRedirect.redirect(pid_1, pid_2) assert InspireRedirect.get_redirect(pid_1) == pid_2
def test_delete_redirected_record_is_not_deleting_redirected_pid(inspire_app): redirected_record = create_record("lit") new_record = create_record("lit") redirected_pid = redirected_record.control_number_pid new_pid = new_record.control_number_pid InspireRedirect.redirect(redirected_pid, new_pid) redirected_record.delete() record_from_redirection = LiteratureRecord.get_record_by_pid_value( redirected_record.control_number) assert record_from_redirection.id == new_record.id
def test_redirect_pid_to_many_pids_overwrites_previous_redirection( inspire_app): pid_1 = PersistentIdentifier.create(pid_type="a", pid_value="1", status=PIDStatus.REGISTERED) pid_2 = PersistentIdentifier.create(pid_type="a", pid_value="2", status=PIDStatus.REGISTERED) pid_3 = PersistentIdentifier.create(pid_type="a", pid_value="3", status=PIDStatus.REGISTERED) InspireRedirect.redirect(pid_1, pid_2) InspireRedirect.redirect(pid_1, pid_3) assert InspireRedirect.get_redirect(pid_1) == pid_3
def resolve(self, pid_value): """Override the `pid.is_deleted` case Now if user is cataloger or superuser, PIDDeletedError is not raised """ pid = PersistentIdentifier.get(self.pid_type, pid_value) if pid.is_new() or pid.is_reserved(): raise PIDUnregistered(pid) if pid.is_deleted() and not is_superuser_or_cataloger_logged_in(): obj_id = pid.get_assigned_object(object_type=self.object_type) try: obj = self.object_getter(obj_id) if obj_id else None except NoResultFound: obj = None raise PIDDeletedError(pid, obj) if pid.is_redirected(): if request.method != "PUT": raise PIDRedirectedError(pid, InspireRedirect.get_redirect(pid)) obj_id = pid.get_assigned_object(object_type=self.object_type) if not obj_id: raise PIDMissingObjectError(self.pid_type, pid_value) return pid, self.object_getter(obj_id)
def redirected_record_ref(self): """Returns redirected PID if PID was redirected, otherwise returns None""" pid = self.control_number_pid if self.get("deleted") and pid.status == PIDStatus.REDIRECTED: redirection = InspireRedirect.get_redirect(pid) return get_ref_from_pid(redirection.pid_type, redirection.pid_value)
def test_get_redirection_object(inspire_app): pid_1 = PersistentIdentifier.create(pid_type="a", pid_value="1", status=PIDStatus.REGISTERED) pid_2 = PersistentIdentifier.create(pid_type="a", pid_value="2", status=PIDStatus.REGISTERED) InspireRedirect.redirect(pid_1, pid_2) redirection = InspireRedirect.get(pid_1) assert redirection.original_pid.pid_type == pid_1.pid_type assert redirection.original_pid.pid_value == pid_1.pid_value assert redirection.new_pid.pid_type == pid_2.pid_type assert redirection.new_pid.pid_value == pid_2.pid_value with pytest.raises(PidRedirectionMissing): InspireRedirect.get(pid_2)
def test_deleting_redirection_object(inspire_app): pid_1 = PersistentIdentifier.create(pid_type="a", pid_value="1", status=PIDStatus.REGISTERED) pid_2 = PersistentIdentifier.create(pid_type="a", pid_value="2", status=PIDStatus.REGISTERED) InspireRedirect.redirect(pid_1, pid_2) assert pid_1.status == PIDStatus.REDIRECTED redirection = InspireRedirect.get(pid_1) redirection.delete() assert pid_1.status == PIDStatus.DELETED with pytest.raises(PidRedirectionMissing): InspireRedirect.get(pid_1)
def get_literature_recids_for_orcid(orcid): """Return the Literature recids that were claimed by an ORCiD. We record the fact that the Author record X has claimed the Literature record Y by storing in Y an author object with a ``$ref`` pointing to X and the key ``curated_relation`` set to ``True``. Therefore this method first searches the DB for the Author records for the one containing the given ORCiD, and then uses its recid to search in ES for the Literature records that satisfy the above property. Args: orcid (str): the ORCiD. Return: list(int): the recids of the Literature records that were claimed by that ORCiD. """ orcid_object = f'[{{"schema": "ORCID", "value": "{orcid}"}}]' # this first query is written in a way that can use the index on (json -> ids) author_rec_uuid = ( db.session.query(RecordMetadata.id) .filter(type_coerce(RecordMetadata.json, JSONB)["ids"].contains(orcid_object)) .one() .id ) author_record = ( db.session.query(PersistentIdentifier) .filter( PersistentIdentifier.object_type == "rec", PersistentIdentifier.object_uuid == author_rec_uuid, PersistentIdentifier.pid_type == "aut", ) .one() ) author_recid = ( author_record.pid_value if not author_record.is_redirected() else InspireRedirect.get_redirect(author_record).pid_value ) query = Q("match", authors__curated_relation=True) & Q( "match", **{"authors.record.$ref": author_recid} ) search_by_curated_author = ( LiteratureSearch() .query("nested", path="authors", query=query) .params(_source=["control_number"], size=9999) ) return [el["control_number"] for el in search_by_curated_author]
def redirect_pid(self, pid_type, pid_value): try: old_pid = PersistentIdentifier.get(pid_type, pid_value) except PIDDoesNotExistError: LOGGER.warning( "Cannot redirect non existent PID", pid_to_redirect=pid_value, redirecting_pid=self.control_number, pid_type=self.pid_type, ) return old_pid_object_uuid = str(old_pid.object_uuid) new_pid = self.control_number_pid InspireRedirect.redirect(old_pid, new_pid) old_record = self.get_record(old_pid_object_uuid, with_deleted=True) old_record["new_record"] = get_ref_from_pid(self.pid_type, self.control_number) if not old_record.get("deleted"): old_record.delete() else: old_record.update(dict(old_record))
def test_redirection_invalidates_correctly_pid_objects(inspire_app): pid_1 = PersistentIdentifier.create( pid_type="a", pid_value="1", status=PIDStatus.REGISTERED, object_uuid=uuid.uuid4(), ) pid_2 = PersistentIdentifier.create( pid_type="a", pid_value="2", status=PIDStatus.REGISTERED, object_uuid=uuid.uuid4(), ) pid_3 = PersistentIdentifier.create( pid_type="a", pid_value="3", status=PIDStatus.REGISTERED, object_uuid=uuid.uuid4(), ) InspireRedirect.redirect(pid_1, pid_2) redirection = InspireRedirect.get(pid_1) assert redirection.original_pid == pid_1 assert redirection.new_pid == pid_2 assert pid_1.status == PIDStatus.REDIRECTED assert pid_1.redirection == redirection assert pid_2.redirected_pids == [redirection] assert pid_3.redirected_pids == [] pid_2.status = PIDStatus.DELETED InspireRedirect.redirect(pid_1, pid_3) assert redirection.original_pid == pid_1 assert redirection.new_pid == pid_3 assert pid_1.status == PIDStatus.REDIRECTED assert pid_1.redirection == redirection assert pid_2.redirected_pids == [] assert pid_3.redirected_pids == [redirection] assert pid_2.status == PIDStatus.DELETED redirection.delete() assert pid_1.status == PIDStatus.DELETED assert pid_1.redirection is None assert len(pid_2.redirected_pids) == 0 with pytest.raises(PidRedirectionMissing): InspireRedirect.get(pid_1)
def get_uuid_from_pid_value(cls, pid_value, pid_type=None, original_record=False): """Get uuid for provided PID value. Args: pid_value(str): pid value to query pid_type(str): pid_type to query original_record(bool): if record was redirected this flag determines whether this method should return redirected record uuid (if False) or original record uuid (if True) Returns: requested record uuid """ if not pid_type: pid_type = cls.pid_type pid = PersistentIdentifier.get(pid_type, pid_value) if pid.is_redirected() and not original_record: pid = InspireRedirect.get_redirect(pid) return pid.object_uuid