Skip to content

Commit

Permalink
Merge pull request #40 from DACCS-Climate/schema-service
Browse files Browse the repository at this point in the history
update service schema definitions
  • Loading branch information
mishaschwartz authored Apr 9, 2024
2 parents 7fc410a + 58554fa commit 16fde27
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 75 deletions.
165 changes: 90 additions & 75 deletions node_registry.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,88 +54,17 @@
}
},
{
"contains": {
"type": "object",
"properties": {
"rel": {
"type": "string",
"const": "version"
}
}
}
"$ref": "#/$defs/link-version"
},
{
"contains": {
"type": "object",
"properties": {
"rel": {
"type": "string",
"const": "service"
}
}
}
"$ref": "#/$defs/link-service"
}
]
},
"services": {
"type": "array",
"items": {
"$anchor": "service",
"type": "object",
"required": [
"name",
"keywords",
"description",
"links"
],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"keywords": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"pattern": "^catalog|data|jupyterhub|other|service-(wps|wms|wfs|wcs|ogcapi_processes)$"
}
},
"description": {
"type": "string",
"minLength": 1
},
"links": {
"type": "array",
"items": {
"$ref": "https://json-schema.org/draft/2020-12/links"
},
"allOf": [
{
"contains": {
"type": "object",
"properties": {
"rel": {
"type": "string",
"const": "service"
}
}
}
},
{
"contains": {
"type": "object",
"properties": {
"rel": {
"type": "string",
"const": "service-doc"
}
}
}
}
]
}
}
"$ref": "#/$defs/service"
}
},
"last_updated": {
Expand Down Expand Up @@ -176,5 +105,91 @@
"additionalProperties": false
}
},
"additionalProperties": false
"additionalProperties": false,
"$defs": {
"link-service": {
"contains": {
"type": "object",
"required": ["rel"],
"properties": {
"rel": {
"type": "string",
"const": "service"
}
}
}
},
"link-service-doc": {
"contains": {
"type": "object",
"required": ["rel"],
"properties": {
"rel": {
"type": "string",
"const": "service-doc"
}
}
}
},
"link-version": {
"contains": {
"type": "object",
"required": ["rel"],
"properties": {
"rel": {
"type": "string",
"const": "version"
}
}
}
},
"service": {
"$anchor": "service",
"type": "object",
"required": [
"name",
"keywords",
"description",
"links"
],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"keywords": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"pattern": "^catalog|data|jupyterhub|other|service-(wps|wms|wfs|wcs|ogcapi_processes)$"
}
},
"description": {
"type": "string",
"minLength": 1
},
"version": {
"type": "string",
"$comment": "Pattern from 'https://semver.org/'.",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
},
"links": {
"$comment": "Links for individual services does not enforce 'rel: version' for backward compatibility.",
"type": "array",
"items": {
"$ref": "https://json-schema.org/draft/2020-12/links"
},
"allOf": [
{
"$ref": "#/$defs/link-service"
},
{
"$ref": "#/$defs/link-service-doc"
}
]
}
}
}
}
}
68 changes: 68 additions & 0 deletions tests/test_registry.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import copy
import os

import json
Expand Down Expand Up @@ -26,6 +27,33 @@ def registry_content(request):
return content


@pytest.fixture
def registry_content_with_services(registry_content):
any_svc_key = list(registry_content)[0]
registry_content["test"] = copy.deepcopy(registry_content[any_svc_key])
registry_content["test"]["services"] = [
{
"name": "test-service",
"keywords": ["other"],
"description": "test service",
"version": "1.2.3",
"links": [
{
"rel": "service",
"href": "https://example.com/test",
"type": "application/json"
},
{
"rel": "service-doc",
"href": "https://readthedocs.com/example",
"type": "text/html"
}
]
}
]
return registry_content


@pytest.fixture
def schema_content(request):
"""Return the content contained in node_registry.schema.json"""
Expand All @@ -38,3 +66,43 @@ def schema_content(request):

def test_valid_registry(registry_content, schema_content):
jsonschema.validate(registry_content, schema_content)


def test_services_good_version(registry_content_with_services, schema_content):
jsonschema.validate(registry_content_with_services, schema_content)


def test_services_bad_version(registry_content_with_services, schema_content):
registry_content_with_services["test"]["services"][0]["version"] = "bad_version"
with pytest.raises(jsonschema.exceptions.ValidationError) as exc:
jsonschema.validate(registry_content_with_services, schema_content)
assert "bad_version" in exc.value.message
assert list(exc.value.path) == ["test", "services", 0, "version"]
assert list(exc.value.schema_path)[-6:] == ["properties", "services", "items", "properties", "version", "pattern"]


def test_services_bad_links(registry_content_with_services, schema_content):
registry_content_with_services["test"]["services"][0].pop("links")
with pytest.raises(jsonschema.exceptions.ValidationError) as exc:
jsonschema.validate(registry_content_with_services, schema_content)
assert exc.value.message == "'links' is a required property"
assert list(exc.value.path) == ["test", "services", 0]
assert list(exc.value.schema_path)[-4:] == ["properties", "services", "items", "required"]


@pytest.mark.parametrize(
["required_link_rel", "expected_link_pos"],
[
("service", 0),
("service-doc", 1),
]
)
def test_services_missing_link(registry_content_with_services, schema_content, required_link_rel, expected_link_pos):
links = registry_content_with_services["test"]["services"][0]["links"]
links = [link for link in links if link["rel"] != required_link_rel]
registry_content_with_services["test"]["services"][0]["links"] = links
with pytest.raises(jsonschema.exceptions.ValidationError) as exc:
jsonschema.validate(registry_content_with_services, schema_content)
assert "does not contain" in exc.value.message
assert list(exc.value.path) == ["test", "services", 0, "links"]
assert list(exc.value.schema_path)[-4:] == ["links", "allOf", expected_link_pos, "contains"]

0 comments on commit 16fde27

Please sign in to comment.