Exemple #1
0
    def test_live_reload(self) -> None:
        # Force the reload by making the last update date < the file's last
        # modified date
        openapi_spec.mtime = 0
        get_openapi_fixture(TEST_ENDPOINT, TEST_METHOD)

        # Check that the file has been reloaded by verifying that the last
        # update date isn't zero anymore
        self.assertNotEqual(openapi_spec.mtime, 0)

        # Now verify calling it again doesn't call reload
        old_openapi = openapi_spec.openapi()
        get_openapi_fixture(TEST_ENDPOINT, TEST_METHOD)
        new_openapi = openapi_spec.openapi()
        self.assertIs(old_openapi, new_openapi)
Exemple #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 heterogeneous
        # 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.openapi()["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.openapi()["paths"].pop("testing", None)
Exemple #3
0
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]:

    lines = ["```curl"]
    operation = endpoint + ":" + method.lower()
    operation_entry = openapi_spec.openapi()["paths"][endpoint][method.lower()]
    global_security = openapi_spec.openapi()["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(map(shlex.quote, curl_first_line_parts)))

    insecure_operations = ["/dev_fetch_api_key:post", "/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("    -u " + shlex.quote(f"{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 " +
                shlex.quote("{}=@{}".format(key, property["example"])))

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

    lines.append("```")

    return lines