Skip to content

Commit

Permalink
Merge pull request #272 from crim-ca/minmax-occurs-rep
Browse files Browse the repository at this point in the history
 Fixed  representation according to ogcapi (fixes #263)
  • Loading branch information
fmigneault authored Jul 7, 2021
2 parents 569c133 + ee8a697 commit 65490d1
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 62 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Changes:

Fixes:
------
- No change.
- Fix ``minOccurs`` and ``maxOccurs`` representation according to `OGC-API`
(fixes `#263 <https://github.com/crim-ca/weaver/issues/263>`_).

`3.2.1 <https://github.com/crim-ca/weaver/tree/3.2.1>`_ (2021-06-08)
========================================================================
Expand Down
118 changes: 60 additions & 58 deletions tests/functional/test_wps_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ def test_literal_io_from_package(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 1
assert desc["process"]["inputs"][0]["id"] == "url"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert "format" not in desc["process"]["inputs"][0]
assert isinstance(desc["process"]["outputs"], list)
assert len(desc["process"]["outputs"]) == 1
Expand Down Expand Up @@ -232,11 +232,11 @@ def test_literal_io_from_package_and_offering(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 2
assert desc["process"]["inputs"][0]["id"] == "literal_input_only_cwl_minimal"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert desc["process"]["inputs"][1]["id"] == "literal_input_both_cwl_and_wps"
assert desc["process"]["inputs"][1]["minOccurs"] == "1"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 1
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert desc["process"]["inputs"][1]["title"] == "Extra detail for I/O both in CWL and WPS", \
"Additional details defined only in WPS matching CWL I/O by ID should be preserved"
assert isinstance(desc["process"]["outputs"], list)
Expand Down Expand Up @@ -558,32 +558,32 @@ def test_complex_io_with_multiple_formats_and_defaults(self):

# process description input validation
assert desc["process"]["inputs"][0]["id"] == "single_value_single_format"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][0]["formats"]) == 1
assert desc["process"]["inputs"][0]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][0]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][1]["id"] == "multi_value_single_format"
assert desc["process"]["inputs"][1]["minOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 1
assert desc["process"]["inputs"][1]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][1]["formats"]) == 1
assert desc["process"]["inputs"][1]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
assert desc["process"]["inputs"][1]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][2]["id"] == "single_value_single_format_default"
assert desc["process"]["inputs"][2]["minOccurs"] == "0"
assert desc["process"]["inputs"][2]["maxOccurs"] == "1"
assert desc["process"]["inputs"][2]["minOccurs"] == 0
assert desc["process"]["inputs"][2]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][2]["formats"]) == 1
assert desc["process"]["inputs"][2]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][2]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][3]["id"] == "multi_value_single_format_default"
assert desc["process"]["inputs"][3]["minOccurs"] == "0"
assert desc["process"]["inputs"][3]["minOccurs"] == 0
assert desc["process"]["inputs"][3]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][3]["formats"]) == 1
assert desc["process"]["inputs"][3]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
assert desc["process"]["inputs"][3]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][4]["id"] == "single_value_multi_format"
assert desc["process"]["inputs"][4]["minOccurs"] == "1"
assert desc["process"]["inputs"][4]["maxOccurs"] == "1"
assert desc["process"]["inputs"][4]["minOccurs"] == 1
assert desc["process"]["inputs"][4]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][4]["formats"]) == 3
assert desc["process"]["inputs"][4]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][4]["formats"][0]["default"] is True # no explicit default, uses first
Expand All @@ -592,7 +592,7 @@ def test_complex_io_with_multiple_formats_and_defaults(self):
assert desc["process"]["inputs"][4]["formats"][2]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][4]["formats"][2]["default"] is False
assert desc["process"]["inputs"][5]["id"] == "multi_value_multi_format"
assert desc["process"]["inputs"][5]["minOccurs"] == "1"
assert desc["process"]["inputs"][5]["minOccurs"] == 1
assert desc["process"]["inputs"][5]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][5]["formats"]) == 3
assert desc["process"]["inputs"][5]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_NETCDF
Expand All @@ -602,8 +602,8 @@ def test_complex_io_with_multiple_formats_and_defaults(self):
assert desc["process"]["inputs"][5]["formats"][2]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][5]["formats"][2]["default"] is False
assert desc["process"]["inputs"][6]["id"] == "single_value_multi_format_default"
assert desc["process"]["inputs"][6]["minOccurs"] == "0"
assert desc["process"]["inputs"][6]["maxOccurs"] == "1"
assert desc["process"]["inputs"][6]["minOccurs"] == 0
assert desc["process"]["inputs"][6]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][6]["formats"]) == 3
assert desc["process"]["inputs"][6]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][6]["formats"][0]["default"] is True # no explicit default, uses first
Expand All @@ -612,7 +612,7 @@ def test_complex_io_with_multiple_formats_and_defaults(self):
assert desc["process"]["inputs"][6]["formats"][2]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][6]["formats"][2]["default"] is False
assert desc["process"]["inputs"][7]["id"] == "multi_value_multi_format_default"
assert desc["process"]["inputs"][7]["minOccurs"] == "0"
assert desc["process"]["inputs"][7]["minOccurs"] == 0
assert desc["process"]["inputs"][7]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][7]["formats"]) == 3
assert desc["process"]["inputs"][7]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
Expand Down Expand Up @@ -789,51 +789,51 @@ def test_resolution_io_min_max_occurs(self):
desc, pkg = self.deploy_process(body)

assert desc["process"]["inputs"][0]["id"] == "required_literal"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert desc["process"]["inputs"][1]["id"] == "required_literal_default"
assert desc["process"]["inputs"][1]["minOccurs"] == "0"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 0
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert desc["process"]["inputs"][2]["id"] == "optional_literal_shortcut"
assert desc["process"]["inputs"][2]["minOccurs"] == "0"
assert desc["process"]["inputs"][2]["maxOccurs"] == "1"
assert desc["process"]["inputs"][2]["minOccurs"] == 0
assert desc["process"]["inputs"][2]["maxOccurs"] == 1
assert desc["process"]["inputs"][3]["id"] == "optional_literal_explicit"
assert desc["process"]["inputs"][3]["minOccurs"] == "0"
assert desc["process"]["inputs"][3]["maxOccurs"] == "1"
assert desc["process"]["inputs"][3]["minOccurs"] == 0
assert desc["process"]["inputs"][3]["maxOccurs"] == 1
assert desc["process"]["inputs"][4]["id"] == "required_array_shortcut"
assert desc["process"]["inputs"][4]["minOccurs"] == "1"
assert desc["process"]["inputs"][4]["minOccurs"] == 1
assert desc["process"]["inputs"][4]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][5]["id"] == "required_array_explicit"
assert desc["process"]["inputs"][5]["minOccurs"] == "1"
assert desc["process"]["inputs"][5]["minOccurs"] == 1
assert desc["process"]["inputs"][5]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][6]["id"] == "optional_array_shortcut"
assert desc["process"]["inputs"][6]["minOccurs"] == "0"
assert desc["process"]["inputs"][6]["minOccurs"] == 0
assert desc["process"]["inputs"][6]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][7]["id"] == "optional_array_explicit"
assert desc["process"]["inputs"][7]["minOccurs"] == "0"
assert desc["process"]["inputs"][7]["minOccurs"] == 0
assert desc["process"]["inputs"][7]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][8]["id"] == "required_literal_min_fixed_by_wps"
assert desc["process"]["inputs"][8]["minOccurs"] == "1"
assert desc["process"]["inputs"][8]["maxOccurs"] == "1"
assert desc["process"]["inputs"][8]["minOccurs"] == 1
assert desc["process"]["inputs"][8]["maxOccurs"] == 1
assert desc["process"]["inputs"][9]["id"] == "optional_literal_min_fixed_by_wps"
assert desc["process"]["inputs"][9]["minOccurs"] == "0"
assert desc["process"]["inputs"][9]["maxOccurs"] == "1"
assert desc["process"]["inputs"][9]["minOccurs"] == 0
assert desc["process"]["inputs"][9]["maxOccurs"] == 1
assert desc["process"]["inputs"][10]["id"] == "required_array_min_fixed_by_wps"
# FIXME: https://github.com/crim-ca/weaver/issues/50
# `maxOccurs=1` not updated to `maxOccurs="unbounded"` as it is evaluated as a single value,
# but it should be considered an array since `minOccurs>1`
# (see: https://github.com/crim-ca/weaver/issues/17)
assert desc["process"]["inputs"][10]["minOccurs"] == "2"
assert desc["process"]["inputs"][10]["minOccurs"] == 2
# assert desc["process"]["inputs"][10]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][11]["id"] == "required_array_min_optional_fixed_by_wps"
assert desc["process"]["inputs"][11]["minOccurs"] == "2"
assert desc["process"]["inputs"][11]["minOccurs"] == 2
# assert desc["process"]["inputs"][11]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][12]["id"] == "required_array_max_fixed_by_wps"
assert desc["process"]["inputs"][12]["minOccurs"] == "1"
assert desc["process"]["inputs"][12]["maxOccurs"] == "10"
assert desc["process"]["inputs"][12]["minOccurs"] == 1
assert desc["process"]["inputs"][12]["maxOccurs"] == 10
assert desc["process"]["inputs"][13]["id"] == "optional_array_max_fixed_by_wps"
assert desc["process"]["inputs"][13]["minOccurs"] == "0"
assert desc["process"]["inputs"][13]["maxOccurs"] == "10"
assert desc["process"]["inputs"][13]["minOccurs"] == 0
assert desc["process"]["inputs"][13]["maxOccurs"] == 10

assert pkg["inputs"][0]["id"] == "required_literal"
assert pkg["inputs"][0]["type"] == "string"
Expand Down Expand Up @@ -929,8 +929,10 @@ def test_valid_io_min_max_occurs_as_str_or_int(self):
assert desc["process"]["inputs"][i]["id"] == process_input["id"]
for field in ["minOccurs", "maxOccurs"]:
proc_in_res = desc["process"]["inputs"][i][field]
proc_in_exp = process_input[field]
assert proc_in_res in (proc_in_exp, str(proc_in_exp)), \
proc_in_exp = (
int(process_input[field]) if str(process_input[field]).isnumeric() else process_input[field]
)
assert proc_in_res == proc_in_exp, \
"Field '{}' of input '{}'({}) is expected to be '{}' but was '{}'" \
.format(field, process_input, i, proc_in_exp, proc_in_res)

Expand Down Expand Up @@ -1190,8 +1192,8 @@ def test_complex_io_from_package(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 1
assert desc["process"]["inputs"][0]["id"] == "url"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert isinstance(desc["process"]["inputs"][0]["formats"], list)
assert len(desc["process"]["inputs"][0]["formats"]) == 1
assert isinstance(desc["process"]["inputs"][0]["formats"][0], dict)
Expand Down Expand Up @@ -1285,15 +1287,15 @@ def test_complex_io_from_package_and_offering(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 2
assert desc["process"]["inputs"][0]["id"] == "complex_input_only_cwl_minimal"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][0]["formats"]) == 1, \
"Default format should be added to process definition when omitted from both CWL and WPS"
assert desc["process"]["inputs"][0]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
assert desc["process"]["inputs"][0]["formats"][0]["default"] is True
assert desc["process"]["inputs"][1]["id"] == "complex_input_both_cwl_and_wps"
assert desc["process"]["inputs"][1]["minOccurs"] == "1"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 1
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][1]["formats"]) == 1, \
"Default format should be added to process definition when omitted from both CWL and WPS"
assert desc["process"]["inputs"][1]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
Expand Down Expand Up @@ -1391,17 +1393,17 @@ def test_literal_and_complex_io_from_wps_xml_reference(self):
assert desc["process"]["inputs"][0]["id"] == "tasmax"
assert desc["process"]["inputs"][0]["title"] == "Resource"
assert desc["process"]["inputs"][0]["abstract"] == "NetCDF Files or archive (tar/zip) containing netCDF files."
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1000"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1000
assert len(desc["process"]["inputs"][0]["formats"]) == 1
assert desc["process"]["inputs"][0]["formats"][0]["default"] is True
assert desc["process"]["inputs"][0]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][0]["formats"][0]["encoding"] == "base64"
assert desc["process"]["inputs"][1]["id"] == "freq"
assert desc["process"]["inputs"][1]["title"] == "Frequency"
assert desc["process"]["inputs"][1]["abstract"] == "Resampling frequency"
assert desc["process"]["inputs"][1]["minOccurs"] == "0"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 0
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert "formats" not in desc["process"]["inputs"][1]
assert len(desc["process"]["outputs"]) == 2
assert desc["process"]["outputs"][0]["id"] == "output_netcdf"
Expand Down Expand Up @@ -1488,21 +1490,21 @@ def test_enum_array_and_multi_format_inputs_from_wps_xml_reference(self):
assert desc["process"]["inputs"][0]["id"] == "region"
assert desc["process"]["inputs"][0]["title"] == "Region"
assert desc["process"]["inputs"][0]["abstract"] == "Country code, see ISO-3166-3"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "220"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 220
assert "formats" not in desc["process"]["inputs"][0]
assert desc["process"]["inputs"][1]["id"] == "mosaic"
assert desc["process"]["inputs"][1]["title"] == "Union of multiple regions"
assert desc["process"]["inputs"][1]["abstract"] == \
"If True, selected regions will be merged into a single geometry." # noqa
assert desc["process"]["inputs"][1]["minOccurs"] == "0"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 0
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert "formats" not in desc["process"]["inputs"][1]
assert desc["process"]["inputs"][2]["id"] == "resource"
assert desc["process"]["inputs"][2]["title"] == "Resource"
assert desc["process"]["inputs"][2]["abstract"] == "NetCDF Files or archive (tar/zip) containing NetCDF files."
assert desc["process"]["inputs"][2]["minOccurs"] == "1"
assert desc["process"]["inputs"][2]["maxOccurs"] == "1000"
assert desc["process"]["inputs"][2]["minOccurs"] == 1
assert desc["process"]["inputs"][2]["maxOccurs"] == 1000
# note: TAR should remain as literal format in the WPS context (not mapped/added as GZIP when resolved for CWL)
assert len(desc["process"]["inputs"][2]["formats"]) == 3
assert desc["process"]["inputs"][2]["formats"][0]["default"] is True
Expand Down
4 changes: 2 additions & 2 deletions tests/wps_restapi/test_processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ def assert_deployed_wps3(response_json, expected_process_id):
assert expected_process_id in response_json["process"]["id"]
assert len(response_json["process"]["inputs"]) == 1
assert response_json["process"]["inputs"][0]["id"] == "input-1"
assert response_json["process"]["inputs"][0]["minOccurs"] == "1"
assert response_json["process"]["inputs"][0]["maxOccurs"] == "1"
assert response_json["process"]["inputs"][0]["minOccurs"] == 1
assert response_json["process"]["inputs"][0]["maxOccurs"] == 1
assert "formats" not in response_json["process"]["inputs"][0] # literal data doesn't have "formats"
assert len(response_json["process"]["outputs"]) == 1
assert response_json["process"]["outputs"][0]["id"] == "output"
Expand Down
Loading

0 comments on commit 65490d1

Please sign in to comment.