From c0712431df6317e629b577efc5a1c95fe3ecda6d Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Mon, 27 Jan 2020 22:28:22 -0800 Subject: [PATCH] openapi: Add hacky support for oneOf parameter types. This is required for the upcoming type behavior of the "anchor" parameter. This change is the minimal work required to have our OpenAPI code not fail when checking a union-type value of this form. We'll likely want to, in the future, do something nicer, but it'd require more extensive infrastructure for parsing of OpenAPI data that it's worth with our current approach (we may want to switch to using a library). --- zerver/lib/bugdown/api_code_examples.py | 11 +++++++++-- zerver/tests/test_openapi.py | 10 ++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/zerver/lib/bugdown/api_code_examples.py b/zerver/lib/bugdown/api_code_examples.py index 8df2ed4e1d..19232e22c6 100644 --- a/zerver/lib/bugdown/api_code_examples.py +++ b/zerver/lib/bugdown/api_code_examples.py @@ -124,7 +124,14 @@ def curl_method_arguments(endpoint: str, method: str, def get_openapi_param_example_value_as_string(endpoint: str, method: str, param: Dict[str, Any], curl_argument: bool=False) -> str: - param_type = param["schema"]["type"] + if "type" in param["schema"]: + param_type = param["schema"]["type"] + else: + # Hack: Ideally, we'd extract a common function for handling + # oneOf values in types and do something with the resulting + # union type. But for this logic's purpose, it's good enough + # to just check the first parameter. + param_type = param["schema"]["oneOf"][0]["type"] param_name = param["name"] if param_type in ["object", "array"]: example_value = param.get("example", None) @@ -139,7 +146,7 @@ cURL example.""".format(endpoint, method, param_name) return " --data-urlencode {}='{}'".format(param_name, ordered_ex_val_str) return ordered_ex_val_str # nocoverage else: - example_value = param.get("example", DEFAULT_EXAMPLE[param["schema"]["type"]]) + example_value = param.get("example", DEFAULT_EXAMPLE[param_type]) if type(example_value) == bool: example_value = str(example_value).lower() if param["schema"].get("format", "") == "json": diff --git a/zerver/tests/test_openapi.py b/zerver/tests/test_openapi.py index 1656ad3802..91c37d10a1 100644 --- a/zerver/tests/test_openapi.py +++ b/zerver/tests/test_openapi.py @@ -377,9 +377,15 @@ do not match the types declared in the implementation of {}.\n""".format(functio openapi_params = set() # type: Set[Tuple[str, Union[type, Tuple[type, object]]]] for element in openapi_parameters: name = element["name"] # type: str - _type = VARMAP[element["schema"]["type"]] + schema = element["schema"] + if 'oneOf' in schema: + # Hack: Just use the type of the first value + # Ideally, we'd turn this into a Union type. + _type = VARMAP[schema['oneOf'][0]['type']] + else: + _type = VARMAP[schema["type"]] if _type == list: - items = element["schema"]["items"] + items = schema["items"] if "anyOf" in items.keys(): subtypes = [] for st in items["anyOf"]: