diff --git a/ckanext/dataset_series/actions.py b/ckanext/dataset_series/actions.py index 1a0e930..19df339 100644 --- a/ckanext/dataset_series/actions.py +++ b/ckanext/dataset_series/actions.py @@ -108,7 +108,6 @@ def _add_series_navigation(series_dict: dict) -> dict: if not series_dict.get("series_order_field"): return series_dict - first, last = _get_series_first_and_last( series_dict["id"], series_dict["series_order_field"] ) diff --git a/ckanext/dataset_series/schemas/dataset_in_series.yaml b/ckanext/dataset_series/schemas/dataset_in_series.yaml new file mode 100644 index 0000000..31f32c7 --- /dev/null +++ b/ckanext/dataset_series/schemas/dataset_in_series.yaml @@ -0,0 +1,97 @@ +scheming_version: 2 +dataset_type: dataset +about: A standard CKAN dataset schema with the in_series field +about_url: http://github.com/ckan/ckanext-dataset-series + + +dataset_fields: + +- field_name: title + label: Title + preset: title + form_placeholder: eg. A descriptive title + +- field_name: name + label: URL + preset: dataset_slug + form_placeholder: eg. my-dataset + +- field_name: notes + label: Description + form_snippet: markdown.html + form_placeholder: eg. Some useful notes about the data + +- field_name: tag_string + label: Tags + preset: tag_string_autocomplete + form_placeholder: eg. economy, mental health, government + +- field_name: license_id + label: License + form_snippet: license.html + help_text: License definitions and additional information can be found at http://opendefinition.org/ + +- field_name: owner_org + label: Organization + preset: dataset_organization + +- field_name: url + label: Source + form_placeholder: http://example.com/dataset.json + display_property: foaf:homepage + display_snippet: link.html + +- field_name: version + label: Version + validators: ignore_missing unicode_safe package_version_validator + form_placeholder: '1.0' + +- field_name: author + label: Author + form_placeholder: Joe Bloggs + display_property: dc:creator + +- field_name: author_email + label: Author Email + form_placeholder: joe@example.com + display_property: dc:creator + display_snippet: email.html + display_email_name_field: author + +- field_name: maintainer + label: Maintainer + form_placeholder: Joe Bloggs + display_property: dc:contributor + +- field_name: maintainer_email + label: Maintainer Email + form_placeholder: joe@example.com + display_property: dc:contributor + display_snippet: email.html + display_email_name_field: maintainer + +# Series fields + +- field_name: in_series + label: In Series + preset: multiple_text + # TODO: snippet + +resource_fields: + +- field_name: url + label: URL + preset: resource_url_upload + +- field_name: name + label: Name + form_placeholder: eg. January 2011 Gold Prices + +- field_name: description + label: Description + form_snippet: markdown.html + form_placeholder: Some useful notes about the data + +- field_name: format + label: Format + preset: resource_format_autocomplete diff --git a/ckanext/dataset_series/tests/test_action.py b/ckanext/dataset_series/tests/test_action.py new file mode 100644 index 0000000..7f0fee1 --- /dev/null +++ b/ckanext/dataset_series/tests/test_action.py @@ -0,0 +1,159 @@ +import pytest + +from ckan.tests import factories +from ckan.tests.helpers import call_action, reset_db + + +@pytest.fixture +def series_fixtures(): + dataset_series = factories.Dataset(type="dataset-series", series_order_field="name") + + dataset1 = factories.Dataset( + name="test-series-member-1", in_series=dataset_series["id"] + ) + dataset2 = factories.Dataset( + name="test-series-member-2", in_series=dataset_series["id"] + ) + dataset3 = factories.Dataset( + name="test-series-member-3", in_series=dataset_series["id"] + ) + + return { + "dataset_series": dataset_series, + "dataset1": dataset1, + "dataset2": dataset2, + "dataset3": dataset3, + } + + +@pytest.mark.usefixtures("with_plugins", "clean_db") +@pytest.mark.ckan_config("ckan.plugins", "dataset_series scheming_datasets") +@pytest.mark.ckan_config( + "scheming.dataset_schemas", + "ckanext.dataset_series.schemas:dataset_series.yaml " + "ckanext.dataset_series.schemas:dataset_in_series.yaml", +) +def test_series_navigation(series_fixtures): + + series_dict = call_action( + "package_show", id=series_fixtures["dataset_series"]["id"] + ) + + assert "series_navigation" in series_dict + + fields = ("id", "name", "title") + for item, dataset in [("first", "dataset1"), ("last", "dataset3")]: + for field in fields: + assert ( + series_dict["series_navigation"][item][field] + == series_fixtures[dataset][field] + ), (item, dataset, field) + + +@pytest.mark.usefixtures("with_plugins", "clean_db") +@pytest.mark.ckan_config("ckan.plugins", "dataset_series scheming_datasets") +@pytest.mark.ckan_config( + "scheming.dataset_schemas", + "ckanext.dataset_series.schemas:dataset_series.yaml " + "ckanext.dataset_series.schemas:dataset_in_series.yaml", +) +def test_series_first_dataset(series_fixtures): + + dataset_dict = call_action("package_show", id=series_fixtures["dataset1"]["id"]) + + assert len(dataset_dict["series_navigation"]) == 1 + + for field in ("id", "name", "title"): + assert ( + dataset_dict["series_navigation"][0][field] + == series_fixtures["dataset_series"][field] + ), field + + assert ( + dataset_dict["series_navigation"][0]["next"][field] + == series_fixtures["dataset2"][field] + ), field + + assert dataset_dict["series_navigation"][0]["previous"] is None + + +@pytest.mark.usefixtures("with_plugins", "clean_db") +@pytest.mark.ckan_config("ckan.plugins", "dataset_series scheming_datasets") +@pytest.mark.ckan_config( + "scheming.dataset_schemas", + "ckanext.dataset_series.schemas:dataset_series.yaml " + "ckanext.dataset_series.schemas:dataset_in_series.yaml", +) +def test_series_middle_dataset(series_fixtures): + + dataset_dict = call_action("package_show", id=series_fixtures["dataset2"]["id"]) + + assert len(dataset_dict["series_navigation"]) == 1 + + for field in ("id", "name", "title"): + assert ( + dataset_dict["series_navigation"][0][field] + == series_fixtures["dataset_series"][field] + ), field + + assert ( + dataset_dict["series_navigation"][0]["previous"][field] + == series_fixtures["dataset1"][field] + ), field + + assert ( + dataset_dict["series_navigation"][0]["next"][field] + == series_fixtures["dataset3"][field] + ), field + + +@pytest.mark.usefixtures("with_plugins", "clean_db") +@pytest.mark.ckan_config("ckan.plugins", "dataset_series scheming_datasets") +@pytest.mark.ckan_config( + "scheming.dataset_schemas", + "ckanext.dataset_series.schemas:dataset_series.yaml " + "ckanext.dataset_series.schemas:dataset_in_series.yaml", +) +def test_series_last_dataset(series_fixtures): + + dataset_dict = call_action("package_show", id=series_fixtures["dataset3"]["id"]) + + assert len(dataset_dict["series_navigation"]) == 1 + + for field in ("id", "name", "title"): + assert ( + dataset_dict["series_navigation"][0][field] + == series_fixtures["dataset_series"][field] + ), field + + assert ( + dataset_dict["series_navigation"][0]["previous"][field] + == series_fixtures["dataset2"][field] + ), field + + assert dataset_dict["series_navigation"][0]["next"] is None + + +@pytest.mark.usefixtures("with_plugins", "clean_db") +@pytest.mark.ckan_config("ckan.plugins", "dataset_series scheming_datasets") +@pytest.mark.ckan_config( + "scheming.dataset_schemas", + "ckanext.dataset_series.schemas:dataset_series.yaml " + "ckanext.dataset_series.schemas:dataset_in_series.yaml", +) +def test_series_only_dataset(): + + dataset_series = factories.Dataset(type="dataset-series", series_order_field="name") + + dataset_only = factories.Dataset( + name="test-series-only-member", in_series=dataset_series["id"] + ) + + dataset_dict = call_action("package_show", id=dataset_only["id"]) + + assert len(dataset_dict["series_navigation"]) == 1 + + assert dataset_dict["series_navigation"][0]["id"] == dataset_series["id"] + + assert dataset_dict["series_navigation"][0]["previous"] is None + assert dataset_dict["series_navigation"][0]["next"] is None