Skip to content

Commit

Permalink
[#56] More robust date parsing with dateutil, expand tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amercader committed Jul 2, 2024
1 parent a8a3f25 commit c7b8c02
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 59 deletions.
138 changes: 85 additions & 53 deletions ckanext/dcat/tests/test_scheming_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,9 @@ def test_e2e_ckan_to_dcat(self):
# Resources: standard fields

assert self._triple(g, distribution_ref, DCT.rights, resource["rights"])
assert self._triple(g, distribution_ref, ADMS.status, URIRef(resource["status"]))
assert self._triple(
g, distribution_ref, ADMS.status, URIRef(resource["status"])
)
assert self._triple(
g,
distribution_ref,
Expand Down Expand Up @@ -566,6 +568,88 @@ def test_legacy_fields(self):
assert len(publisher) == 1
assert self._triple(g, publisher[0][2], FOAF.name, "Test Publisher")

def test_dcat_date(self):
dataset_dict = {
# Core fields
"name": "test-dataset",
"title": "Test DCAT dataset",
"notes": "Some notes",
"issued": "2024",
"modified": "2024-10",
"temporal_coverage": [
{"start": "1905-03-01T10:07:31.182680", "end": "2013-01-05"},
{"start": "2024-04-10T10:07:31", "end": "2024-05-29"},
],
}

dataset = call_action("package_create", **dataset_dict)

s = RDFSerializer()
g = s.g

dataset_ref = s.graph_from_dataset(dataset)

# Year
assert dataset["issued"] == dataset_dict["issued"]
assert self._triple(
g,
dataset_ref,
DCT.issued,
dataset_dict["issued"],
data_type=XSD.gYear,
)

# Year-month
assert dataset["modified"] == dataset_dict["modified"]
assert self._triple(
g,
dataset_ref,
DCT.modified,
dataset_dict["modified"],
data_type=XSD.gYearMonth,
)

temporal = [t for t in g.triples((dataset_ref, DCT.temporal, None))]

# Date
assert (
dataset["temporal_coverage"][0]["end"]
== dataset_dict["temporal_coverage"][0]["end"]
)

assert self._triple(
g,
temporal[0][2],
SCHEMA.endDate,
dataset_dict["temporal_coverage"][0]["end"],
data_type=XSD.date,
)

# Datetime
assert (
dataset["temporal_coverage"][0]["start"]
== dataset_dict["temporal_coverage"][0]["start"]
)
assert self._triple(
g,
temporal[0][2],
SCHEMA.startDate,
dataset_dict["temporal_coverage"][0]["start"],
data_type=XSD.dateTime,
)

assert (
dataset["temporal_coverage"][1]["start"]
== dataset_dict["temporal_coverage"][1]["start"]
)
assert self._triple(
g,
temporal[1][2],
SCHEMA.startDate,
dataset_dict["temporal_coverage"][1]["start"],
data_type=XSD.dateTime,
)


@pytest.mark.usefixtures("with_plugins", "clean_db")
@pytest.mark.ckan_config("ckan.plugins", "dcat scheming_datasets")
Expand Down Expand Up @@ -859,55 +943,3 @@ def test_spatial_field(self):
assert search_dict["spatial"] == json.dumps(
dataset_dict["spatial_coverage"][0]["centroid"]
)


@pytest.mark.usefixtures("with_plugins", "clean_db")
@pytest.mark.ckan_config("ckan.plugins", "dcat scheming_datasets")
@pytest.mark.ckan_config(
"scheming.dataset_schemas", "ckanext.dcat.schemas:dcat_ap_2.1_full.yaml"
)
@pytest.mark.ckan_config(
"scheming.presets",
"ckanext.scheming:presets.json ckanext.dcat.schemas:presets.yaml",
)
@pytest.mark.ckan_config(
"ckanext.dcat.rdf.profiles", "euro_dcat_ap_2 euro_dcat_ap_scheming"
)
class TestSchemingPresets:
def test_dcat_date(self):
dataset_dict = {
# Core fields
"name": "test-dataset",
"title": "Test DCAT dataset",
"notes": "Some notes",
"issued": "2024",
"modified": "2024-10",
"temporal_coverage": [
{"start": "1905-03-01T10:07:31.182680", "end": "2013-01-05"},
{"start": "2024-04-10T10:07:31", "end": "2024-05-29"},
],
}

dataset = call_action("package_create", **dataset_dict)

# Year
assert dataset["issued"] == dataset_dict["issued"]

# Year-month
assert dataset["modified"] == dataset_dict["modified"]

# Date
assert (
dataset["temporal_coverage"][0]["end"]
== dataset_dict["temporal_coverage"][0]["end"]
)

# Datetime
assert (
dataset["temporal_coverage"][0]["start"]
== dataset_dict["temporal_coverage"][0]["start"]
)
assert (
dataset["temporal_coverage"][1]["start"]
== dataset_dict["temporal_coverage"][1]["start"]
)
27 changes: 26 additions & 1 deletion ckanext/dcat/tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import datetime
import json

import pytest

from ckantoolkit import StopOnError
from ckanext.dcat.validators import scheming_multiple_number
from ckanext.dcat.validators import scheming_multiple_number, dcat_date


def test_scheming_multiple_number():
Expand Down Expand Up @@ -60,3 +62,26 @@ def test_scheming_multiple_number_wrong_value():
assert errors[key][0].startswith("invalid type for repeating number")

errors = {key: []}


@pytest.mark.usefixtures(
"with_plugins",
)
@pytest.mark.ckan_config("ckan.plugins", "dcat scheming_datasets")
def test_dcat_date_valid():

key = ("some_date",)
errors = {key: []}
valid_values = [
datetime.datetime.now(),
"2024",
"2024-07",
"2024-07-01",
"1905-03-01T10:07:31.182680",
"2024-04-10T10:07:31",
"2024-04-10T10:07:31.000Z",
]

for value in valid_values:
data = {key: value}
dcat_date(key, data, errors, {}), value
8 changes: 3 additions & 5 deletions ckanext/dcat/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import json
import re

from dateutil.parser import parse as parse_date
from ckantoolkit import (
missing,
StopOnError,
get_validator,
Invalid,
_,
)
Expand Down Expand Up @@ -41,17 +41,15 @@ def is_date(value):
def dcat_date(key, data, errors, context):
value = data[key]

scheming_isodatetime = get_validator("scheming_isodatetime")

if isinstance(value, datetime.datetime):
return

if is_year(value) or is_year_month(value) or is_date(value):
return

try:
scheming_isodatetime({}, {})(key, data, errors, context)
except Invalid:
parse_date(value)
except ValueError:
raise Invalid(
_(
"Date format incorrect. Supported formats are YYYY, YYYY-MM, YYYY-MM-DD and YYYY-MM-DDTHH:MM:SS"

This comment has been minimized.

Copy link
@EricSoroos

EricSoroos Jul 2, 2024

Maybe touch up the error message here.

Expand Down

0 comments on commit c7b8c02

Please sign in to comment.