diff --git a/site/cds_rdm/inspire_harvester/update/config.py b/site/cds_rdm/inspire_harvester/update/config.py index 2abf4da1..f681ae93 100644 --- a/site/cds_rdm/inspire_harvester/update/config.py +++ b/site/cds_rdm/inspire_harvester/update/config.py @@ -18,7 +18,10 @@ IdentifiersFieldUpdate, RelatedIdentifiersUpdate, ) -from cds_rdm.inspire_harvester.update.fields.metadata import PublicationDateUpdate +from cds_rdm.inspire_harvester.update.fields.metadata import ( + PublicationDateUpdate, + ThesisPublicationDateUpdate, +) UPDATE_STRATEGY_CONFIG = { # fields not included in the strategy raise error on update attempt @@ -29,7 +32,7 @@ "metadata.contributors": CreatibutorsFieldUpdate(strict=False), "metadata.identifiers": IdentifiersFieldUpdate(), "metadata.related_identifiers": RelatedIdentifiersUpdate(), - "metadata.publication_date": OverwriteFieldUpdate(), + "metadata.publication_date": ThesisPublicationDateUpdate(), "metadata.subjects": ListOfDictAppendUniqueUpdate(key_field="subject"), "metadata.languages": ListOfDictAppendUniqueUpdate(key_field="id"), "metadata.description": OverwriteFieldUpdate(), diff --git a/site/cds_rdm/inspire_harvester/update/fields/metadata.py b/site/cds_rdm/inspire_harvester/update/fields/metadata.py index e78c8a9e..d6050be2 100644 --- a/site/cds_rdm/inspire_harvester/update/fields/metadata.py +++ b/site/cds_rdm/inspire_harvester/update/fields/metadata.py @@ -11,11 +11,42 @@ import dateparser +from cds_rdm.inspire_harvester.transform.resource_types import ResourceType from cds_rdm.inspire_harvester.update.engine import UpdateConflict, UpdateResult from cds_rdm.inspire_harvester.update.field import FieldUpdateBase +from cds_rdm.inspire_harvester.update.fields.base import OverwriteFieldUpdate from cds_rdm.inspire_harvester.utils import get_path, set_path +class ThesisPublicationDateUpdate(OverwriteFieldUpdate): + """Conflict if a thesis publication_date changed; otherwise overwrite.""" + + def update(self, current, incoming, path, ctx): + """Return a conflict when a thesis date differs; otherwise overwrite.""" + current_date = get_path(current, path) + incoming_date = get_path(incoming, path) + resource_type = get_path(current, "metadata.resource_type.id") + + if resource_type != ResourceType.THESIS: + return super().update(current, incoming, path, ctx) + + if current_date and incoming_date and current_date != incoming_date: + return UpdateResult( + updated=current, + conflicts=[ + UpdateConflict( + path=path, + kind="date_mismatch", + message="Incoming thesis publication_date differs", + current=current_date, + incoming=incoming_date, + ) + ], + ) + + return super().update(current, incoming, path, ctx) + + class PublicationDateUpdate(FieldUpdateBase): """ Update publication_date only if incoming value is more accurate. diff --git a/site/tests/inspire_harvester/test_writer.py b/site/tests/inspire_harvester/test_writer.py index b4d342bb..44082a23 100644 --- a/site/tests/inspire_harvester/test_writer.py +++ b/site/tests/inspire_harvester/test_writer.py @@ -452,7 +452,7 @@ def test_writer_1_existing_found_files_not_changed_metadata_changed( def test_writer_updates_publication_date_from_inspire_without_cds_doi( running_app, location, transformed_record_1_file, scientific_community ): - """Test INSPIRE publication-date mismatches update non-CDS DOI records.""" + """Test a different incoming thesis date is a conflict, even without a CDS DOI.""" writer = InspireWriter() transformed_record = deepcopy(transformed_record_1_file) @@ -469,8 +469,8 @@ def test_writer_updates_publication_date_from_inspire_without_cds_doi( RDMRecord.index.refresh() updated = current_rdm_records_service.read(system_identity, created["id"]) - assert updated["metadata"]["publication_date"] == "2014" - assert not update_entry.errors + assert updated["metadata"]["publication_date"] == "2020" + assert any("[date_mismatch]" in error for error in update_entry.errors) _cleanup_record(created["id"])