def generate_curl_example(endpoint: str,
                          method: str,
                          api_url: str,
                          auth_email: str = DEFAULT_AUTH_EMAIL,
                          auth_api_key: str = DEFAULT_AUTH_API_KEY,
                          exclude: Optional[List[str]] = None,
                          include: Optional[List[str]] = None) -> List[str]:
    if exclude is not None and include is not None:
        raise AssertionError(
            "exclude and include cannot be set at the same time.")

    lines = ["```curl"]
    operation = endpoint + ":" + method.lower()
    operation_entry = openapi_spec.spec()['paths'][endpoint][method.lower()]
    global_security = openapi_spec.spec()['security']

    operation_params = operation_entry.get("parameters", [])
    operation_request_body = operation_entry.get("requestBody", None)
    operation_security = operation_entry.get("security", None)

    if settings.RUNNING_OPENAPI_CURL_TEST:  # nocoverage
        from zerver.openapi.curl_param_value_generators import patch_openapi_example_values
        operation_params, operation_request_body = patch_openapi_example_values(
            operation, operation_params, operation_request_body)

    format_dict = {}
    for param in operation_params:
        if param["in"] != "path":
            continue
        example_value = get_openapi_param_example_value_as_string(
            endpoint, method, param)
        format_dict[param["name"]] = example_value
    example_endpoint = endpoint.format_map(format_dict)

    curl_first_line_parts = ["curl"] + curl_method_arguments(
        example_endpoint, method, api_url)
    lines.append(" ".join(curl_first_line_parts))

    insecure_operations = ['/dev_fetch_api_key:post']
    if operation_security is None:
        if global_security == [{'basicAuth': []}]:
            authentication_required = True
        else:
            raise AssertionError(
                "Unhandled global securityScheme." +
                " Please update the code to handle this scheme.")
    elif operation_security == []:
        if operation in insecure_operations:
            authentication_required = False
        else:
            raise AssertionError(
                "Unknown operation without a securityScheme. " +
                "Please update insecure_operations.")
    else:
        raise AssertionError(
            "Unhandled securityScheme. Please update the code to handle this scheme."
        )

    if authentication_required:
        lines.append(f"    -u {auth_email}:{auth_api_key}")

    for param in operation_params:
        if param["in"] == "path":
            continue
        param_name = param["name"]

        if include is not None and param_name not in include:
            continue

        if exclude is not None and param_name in exclude:
            continue

        example_value = get_openapi_param_example_value_as_string(
            endpoint, method, param, curl_argument=True)
        lines.append(example_value)

    if "requestBody" in operation_entry:
        properties = operation_entry["requestBody"]["content"][
            "multipart/form-data"]["schema"]["properties"]
        for key, property in properties.items():
            lines.append('    -F "{}=@{}"'.format(key, property["example"]))

    for i in range(1, len(lines) - 1):
        lines[i] = lines[i] + " \\"

    lines.append("```")

    return lines
Пример #2
0
    def test_validate_against_openapi_schema(self) -> None:
        with self.assertRaises(ValidationError,
                               msg=("Additional properties are not" +
                                    " allowed ('foo' was unexpected)")):
            bad_content: Dict[str, object] = {
                'msg': '',
                'result': 'success',
                'foo': 'bar',
            }
            validate_against_openapi_schema(bad_content, TEST_ENDPOINT,
                                            TEST_METHOD, TEST_RESPONSE_SUCCESS)

        with self.assertRaises(ValidationError,
                               msg=("42 is not of type string")):
            bad_content = {
                'msg': 42,
                'result': 'success',
            }
            validate_against_openapi_schema(bad_content, TEST_ENDPOINT,
                                            TEST_METHOD, TEST_RESPONSE_SUCCESS)

        with self.assertRaises(ValidationError,
                               msg='Expected to find the "msg" required key'):
            bad_content = {
                'result': 'success',
            }
            validate_against_openapi_schema(bad_content, TEST_ENDPOINT,
                                            TEST_METHOD, TEST_RESPONSE_SUCCESS)

        # No exceptions should be raised here.
        good_content = {
            'msg': '',
            'result': 'success',
        }
        validate_against_openapi_schema(good_content, TEST_ENDPOINT,
                                        TEST_METHOD, TEST_RESPONSE_SUCCESS)

        # Overwrite the exception list with a mocked one
        test_dict: Dict[str, Any] = {}

        # Check that validate_against_openapi_schema correctly
        # descends into 'deep' objects and arrays.  Test 1 should
        # pass, Test 2 has a 'deep' extraneous key and Test 3 has a
        # 'deep' opaque object. Also the parameters are a heterogenous
        # mix of arrays and objects to verify that our descent logic
        # correctly gets to the the deeply nested objects.
        with open(
                os.path.join(os.path.dirname(OPENAPI_SPEC_PATH),
                             "testing.yaml")) as test_file:
            test_dict = yaml.safe_load(test_file)
        openapi_spec.spec()['paths']['testing'] = test_dict
        try:
            validate_against_openapi_schema(
                (test_dict['test1']['responses']['200']['content']
                 ['application/json']['example']), 'testing', 'test1', '200')
            with self.assertRaises(
                    ValidationError,
                    msg='Extraneous key "str4" in response\'s content'):
                validate_against_openapi_schema(
                    (test_dict['test2']['responses']['200']['content']
                     ['application/json']['example']), 'testing', 'test2',
                    '200')
            with self.assertRaises(SchemaError, msg='Opaque object "obj"'):
                # Checks for opaque objects
                validate_schema((test_dict['test3']['responses']['200']
                                 ['content']['application/json']['schema']))
        finally:
            openapi_spec.spec()['paths'].pop('testing', None)