diff --git a/swh/deposit/api/checks.py b/swh/deposit/api/checks.py --- a/swh/deposit/api/checks.py +++ b/swh/deposit/api/checks.py @@ -13,14 +13,19 @@ from typing import Dict, Optional, Tuple +import iso8601 + +from swh.deposit.utils import normalize_date + MANDATORY_FIELDS_MISSING = "Mandatory fields are missing" +INVALID_DATE_FORMAT = "Invalid date format" def check_metadata(metadata: Dict) -> Tuple[bool, Optional[Dict]]: - """Check metadata for mandatory field presence. + """Check metadata for mandatory field presence and date format. Args: - metadata: Metadata dictionary to check for mandatory fields + metadata: Metadata dictionary to check Returns: tuple (status, error_detail): True, None if metadata are @@ -41,7 +46,29 @@ mandatory_result = [" or ".join(k) for k, v in alternate_fields.items() if not v] - if mandatory_result == []: - return True, None - detail = [{"summary": MANDATORY_FIELDS_MISSING, "fields": mandatory_result}] - return False, {"metadata": detail} + if mandatory_result: + detail = [{"summary": MANDATORY_FIELDS_MISSING, "fields": mandatory_result}] + return False, {"metadata": detail} + + fields = [] + + commit_date = metadata.get("codemeta:datePublished") + author_date = metadata.get("codemeta:dateCreated") + + if commit_date: + try: + normalize_date(commit_date) + except iso8601.iso8601.ParseError: + fields.append("codemeta:datePublished") + + if author_date: + try: + normalize_date(author_date) + except iso8601.iso8601.ParseError: + fields.append("codemeta:dateCreated") + + if fields: + detail = [{"summary": INVALID_DATE_FORMAT, "fields": fields}] + return False, {"metadata": detail} + + return True, None diff --git a/swh/deposit/tests/api/test_checks.py b/swh/deposit/tests/api/test_checks.py --- a/swh/deposit/tests/api/test_checks.py +++ b/swh/deposit/tests/api/test_checks.py @@ -24,6 +24,14 @@ "atom:author": "no one", }, {"atom:url": "some url", "codemeta:name": "bar", "codemeta:author": "no one",}, + { + "atom:url": "some url", + "atom:external_identifier": "some id", + "atom:title": "bar", + "atom:author": "no one", + "codemeta:datePublished": "2020-12-21", + "codemeta:dateCreated": "2020-12-21", + }, ], ) def test_api_checks_check_metadata_ok(metadata_ok, swh_checks_deposit): @@ -93,14 +101,25 @@ "fields": ["atom:author or codemeta:author"], }, ), + ( + { + "atom:url": "some url", + "atom:external_identifier": "some id", + "atom:title": "bar", + "atom:author": "no one", + "codemeta:datePublished": "2020-aa-21", + "codemeta:dateCreated": "2020-12-bb", + }, + { + "summary": "Invalid date format", + "fields": ["codemeta:datePublished", "codemeta:dateCreated"], + }, + ), ], ) def test_api_checks_check_metadata_ko( metadata_ko, expected_summary, swh_checks_deposit ): - """Missing optional field should be caught - - """ actual_check, error_detail = check_metadata(metadata_ko) assert actual_check is False assert error_detail == {"metadata": [expected_summary]}