Skip to content

Commit

Permalink
Calculate additional codelist values for schema using anyOf, like OCD…
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmckinney authored and odscjames committed Nov 8, 2023
1 parent b2c6851 commit 79d70fd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Restore jsonschema's type validator, as its performance has improved in recent Python versions https://github.com/OpenDataServices/lib-cove/pull/127
- Allow `SchemaJsonMixin` classes to define a `validator` method, that accepts lib-cove's JSON Schema draft 4 validator class and its format checker, and returns a validator instance. https://github.com/OpenDataServices/lib-cove/pull/128

### Fixed

- Calculate additional codelist values for schema using `anyOf`, like OCDS record packages https://github.com/open-contracting/lib-cove-ocds/issues/106

## [0.31.0] - 2023-07-06

### Changed
Expand Down
29 changes: 19 additions & 10 deletions libcove/lib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,17 +456,26 @@ def get_schema_codelist_paths(
if "codelist" in value and path not in codelist_paths:
codelist_paths[path] = (value["codelist"], value.get("openCodelist", False))

if value.get("type") == "object":
get_schema_codelist_paths(None, value, path, codelist_paths)
elif value.get("type") == "array" and isinstance(value.get("items"), dict):
if value.get("items").get("type") == "string":
if "codelist" in value["items"] and path not in codelist_paths:
codelist_paths[path] = (
value["items"]["codelist"],
value["items"].get("openCodelist", False),
descendants = []
if "oneOf" in value and isinstance(value["oneOf"], list):
descendants = value["oneOf"]
else:
descendants = [value]

for value in descendants:
if value.get("type") == "object":
get_schema_codelist_paths(None, value, path, codelist_paths)
elif value.get("type") == "array" and isinstance(value.get("items"), dict):
if value.get("items").get("type") == "string":
if "codelist" in value["items"] and path not in codelist_paths:
codelist_paths[path] = (
value["items"]["codelist"],
value["items"].get("openCodelist", False),
)
elif value.get("items").get("properties"):
get_schema_codelist_paths(
None, value["items"], path, codelist_paths
)
elif value.get("items").get("properties"):
get_schema_codelist_paths(None, value["items"], path, codelist_paths)

return codelist_paths

Expand Down
42 changes: 42 additions & 0 deletions tests/lib/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
_get_schema_deprecated_paths,
add_field_coverage,
add_field_coverage_percentages,
common_checks_context,
fields_present_generator,
get_additional_codelist_values,
get_additional_fields_info,
Expand All @@ -28,6 +29,18 @@
)


def get_schema_obj(fixture):
schema_obj = SchemaJsonMixin()
schema_obj.schema_host = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "fixtures", "common/"
)
schema_obj.release_pkg_schema_name = f"{fixture}.json"
schema_obj.pkg_schema_url = os.path.join(
schema_obj.schema_host, schema_obj.release_pkg_schema_name
)
return schema_obj


def test_unique_ids_False():
ui = False
schema = {"uniqueItems": ui}
Expand Down Expand Up @@ -1347,3 +1360,32 @@ def test_get_additional_codelist_values():
"extension_codelist": False,
},
}


def test_get_additional_codelist_values_anyOf():
json_data = {
"version": "1.1",
"records": [
{
"releases": [
{"parties": [{"id": "1", "name": "Name", "roles": ["additional"]}]}
]
}
],
}
schema_obj = get_schema_obj("record-package-schema")
schema_obj.codelists = "https://raw.githubusercontent.com/open-contracting/standard/1.1/schema/codelists/"
additional_codelist_values = get_additional_codelist_values(schema_obj, json_data)

assert additional_codelist_values == {
"records/releases/parties/roles": {
"codelist": "partyRole.csv",
"codelist_amend_urls": [],
"codelist_url": "https://raw.githubusercontent.com/open-contracting/standard/1.1/schema/codelists/partyRole.csv",
"extension_codelist": False,
"field": "roles",
"isopen": True,
"path": "records/releases/parties",
"values": ["additional"],
},
}

0 comments on commit 79d70fd

Please sign in to comment.