Exemple #1
0
def test_loose_urlencoded_form_open_api_3(assert_parameters,
                                          make_openapi_3_schema,
                                          make_user_schema, user_jsonschema):
    # The schema doesn't define "type": "object"
    loose_schema = {
        "schema":
        make_user_schema(is_loose=True,
                         middle_name={
                             "type": "string",
                             "nullable": True
                         })
    }
    schema = make_openapi_3_schema({
        "required": True,
        "content": {
            "application/x-www-form-urlencoded": loose_schema
        },
    })
    assert_parameters(
        schema,
        PayloadAlternatives([
            OpenAPI30Body(definition=loose_schema,
                          media_type="application/x-www-form-urlencoded",
                          required=True)
        ]),
        # But when it is converted to JSON Schema, Schemathesis sets `type` to `object`
        # Therefore it corresponds to the default JSON Schema defined for a User
        [user_jsonschema],
    )
Exemple #2
0
def test_invalid_body_in_get_disable_validation(simple_schema):
    schema = schemathesis.from_dict(simple_schema, validate_schema=False)
    endpoint = Endpoint(
        path="/foo",
        method="GET",
        definition=EndpointDefinition({}, {}, "foo", []),
        schema=schema,
        body=PayloadAlternatives(
            [
                OpenAPI20Body(
                    {
                        "name": "attributes",
                        "in": "body",
                        "required": True,
                        "schema": {"required": ["foo"], "type": "object", "properties": {"foo": {"type": "string"}}},
                    },
                    media_type="application/json",
                )
            ]
        ),
    )
    strategy = get_case_strategy(endpoint)

    @given(strategy)
    @settings(max_examples=1)
    def test(case):
        assert case.body is not None

    test()
Exemple #3
0
def test_invalid_body_in_get(swagger_20):
    operation = APIOperation(
        path="/foo",
        method="GET",
        definition=OperationDefinition({}, {}, "foo", []),
        schema=swagger_20,
        body=PayloadAlternatives([
            OpenAPI20Body(
                {
                    "name": "attributes",
                    "in": "body",
                    "required": True,
                    "schema": {
                        "required": ["foo"],
                        "type": "object",
                        "properties": {
                            "foo": {
                                "type": "string"
                            }
                        }
                    },
                },
                media_type="application/json",
            )
        ]),
    )
    with pytest.raises(
            InvalidSchema,
            match=r"^Body parameters are defined for GET request.$"):
        get_case_strategy(operation).example()
def test_empty_content():
    # When the "content" value is empty in "requestBody"
    raw_schema = {
        "openapi": "3.0.2",
        "info": {"title": "Test", "description": "Test", "version": "0.1.0"},
        "paths": {"/body": {"post": {"requestBody": {"content": {}}, "responses": {"200": {"description": "OK"}}}}},
    }
    schema = schemathesis.from_dict(raw_schema)
    # Then the body processing should be no-op
    operation = schema["/body"]["POST"]
    assert operation.body == PayloadAlternatives([])
def test_resolving_multiple_files():
    raw_schema = {
        "swagger": "2.0",
        "info": {"title": "Example API", "description": "An API to test Schemathesis", "version": "1.0.0"},
        "host": "127.0.0.1:8888",
        "basePath": "/api",
        "schemes": ["http"],
        "produces": ["application/json"],
        "paths": {
            "/teapot": {
                "post": {
                    "parameters": [
                        {
                            "schema": {"$ref": "test/data/petstore_v2.yaml#/definitions/User"},
                            "in": "body",
                            "name": "user",
                            "required": True,
                        }
                    ],
                    "responses": {"200": {"description": "OK"}},
                }
            }
        },
    }
    schema = schemathesis.from_dict(raw_schema)
    assert schema["/teapot"]["post"].body == PayloadAlternatives(
        [
            OpenAPI20Body(
                {
                    "schema": {
                        "type": "object",
                        "properties": {
                            "id": {"type": "integer", "format": "int64"},
                            "username": {"type": "string"},
                            "firstName": {"type": "string"},
                            "lastName": {"type": "string"},
                            "email": {"type": "string"},
                            "password": {"type": "string"},
                            "phone": {"type": "string"},
                            "userStatus": {"type": "integer", "format": "int32", "description": "User Status"},
                        },
                        "xml": {"name": "User"},
                    },
                    "in": "body",
                    "name": "user",
                    "required": True,
                },
                media_type="application/json",
            )
        ]
    )
Exemple #6
0
def test_default_strategies_bytes(swagger_20):
    endpoint = make_endpoint(
        swagger_20,
        body=PayloadAlternatives(
            [
                OpenAPI20Body(
                    {"in": "body", "name": "byte", "required": True, "schema": {"type": "string", "format": "byte"}},
                    media_type="text/plain",
                )
            ]
        ),
    )
    result = get_case_strategy(endpoint).example()
    assert isinstance(result.body, str)
    b64decode(result.body)
Exemple #7
0
def test_default_strategies_binary(swagger_20):
    operation = make_operation(
        swagger_20,
        body=PayloadAlternatives([
            OpenAPI20CompositeBody.from_parameters(
                {
                    "name": "upfile",
                    "in": "formData",
                    "type": "file",
                    "required": True,
                },
                media_type="multipart/form-data",
            )
        ]),
    )
    result = get_case_strategy(operation).example()
    assert isinstance(result.body["upfile"], bytes)
Exemple #8
0
def test_forms_open_api_2(consumes, assert_parameters, make_openapi_2_schema,
                          user_jsonschema, open_api_2_user_form_parameters):
    # In Open API 2.0, forms are separate "formData" parameters
    schema = make_openapi_2_schema(consumes, open_api_2_user_form_parameters)
    assert_parameters(
        schema,
        PayloadAlternatives([
            # They are represented as a single "composite" body for each media type
            OpenAPI20CompositeBody(
                definition=[
                    OpenAPI20Parameter(parameter)
                    for parameter in open_api_2_user_form_parameters
                ],
                media_type=value,
            ) for value in consumes
        ]),
        # Each converted schema should correspond to the default User schema.
        [user_jsonschema] * len(consumes),
    )
Exemple #9
0
def test_payload_open_api_2(
    consumes,
    assert_parameters,
    make_openapi_2_schema,
    open_api_2_user_form_with_file_parameters,
    open_api_2_user_in_body,
    user_jsonschema,
):
    # A single "body" parameter is used for all payload variants
    schema = make_openapi_2_schema(consumes, [open_api_2_user_in_body])
    assert_parameters(
        schema,
        PayloadAlternatives([
            OpenAPI20Body(definition=open_api_2_user_in_body, media_type=value)
            for value in consumes
        ]),
        # For each one the schema is extracted from the parameter definition and transformed to the proper JSON Schema
        [user_jsonschema] * len(consumes),
    )
Exemple #10
0
def test_multipart_form_open_api_3(assert_parameters, make_openapi_3_schema,
                                   user_jsonschema_with_file,
                                   open_api_3_user_with_file):
    # A regular multipart for with a file upload in Open API 3
    schema = make_openapi_3_schema({
        "required": True,
        "content": {
            "multipart/form-data": {
                "schema": open_api_3_user_with_file
            }
        },
    })
    assert_parameters(
        schema,
        PayloadAlternatives([
            OpenAPI30Body(definition={"schema": open_api_3_user_with_file},
                          media_type="multipart/form-data",
                          required=True)
        ]),
        # When converted, the schema corresponds the default schema defined for a User object with a file
        [user_jsonschema_with_file],
    )
Exemple #11
0
def test_urlencoded_form_open_api_3(assert_parameters, make_openapi_3_schema,
                                    open_api_3_user, user_jsonschema):
    # A regular urlencoded form in Open API 3
    schema = make_openapi_3_schema({
        "required": True,
        "content": {
            "application/x-www-form-urlencoded": {
                "schema": open_api_3_user
            }
        },
    })
    assert_parameters(
        schema,
        PayloadAlternatives([
            OpenAPI30Body(
                definition={"schema": open_api_3_user},
                media_type="application/x-www-form-urlencoded",
                required=True,
            )
        ]),
        # It should correspond to the default User schema
        [user_jsonschema],
    )
Exemple #12
0
def test_payload_open_api_3(media_types, assert_parameters,
                            make_openapi_3_schema, open_api_3_user,
                            user_jsonschema):
    schema = make_openapi_3_schema({
        "required": True,
        "content": {
            media_type: {
                "schema": open_api_3_user
            }
            for media_type in media_types
        },
    })
    assert_parameters(
        schema,
        PayloadAlternatives([
            OpenAPI30Body(definition={"schema": open_api_3_user},
                          media_type=media_type,
                          required=True) for media_type in media_types
        ]),
        # The converted schema should correspond the schema in the relevant "requestBody" part
        # In this case they are the same
        [user_jsonschema] * len(media_types),
    )
Exemple #13
0
def test_multipart_form_open_api_2(
    consumes,
    assert_parameters,
    make_openapi_2_schema,
    user_jsonschema_with_file,
    open_api_2_user_form_with_file_parameters,
):
    # Multipart forms are represented as a list of "formData" parameters
    schema = make_openapi_2_schema(consumes,
                                   open_api_2_user_form_with_file_parameters)
    assert_parameters(
        schema,
        PayloadAlternatives([
            # Is represented with a "composite" body
            OpenAPI20CompositeBody(
                definition=[
                    OpenAPI20Parameter(parameter)
                    for parameter in open_api_2_user_form_with_file_parameters
                ],
                media_type="multipart/form-data",
            )
        ]),
        [user_jsonschema_with_file],
    )
Exemple #14
0
def test_make_operation_body(body):
    # See GH-1069
    # When `requestBody` is present in the link definition
    # And in the target operation
    operation = APIOperation(
        path="/users/",
        method="post",
        verbose_name="GET /users/{user_id}",
        definition=ANY,
        schema=ANY,
        base_url=ANY,
        body=PayloadAlternatives([body]),
    )
    body = {"foo": "bar"}  # Literal value
    link = Link(
        name="Link",
        operation=operation,
        parameters={},
        request_body={"requestBody": body},
    )
    # Then it should be taken into account during creation a modified version of that operation
    new_operation = link.make_operation([ParsedData(
        {}, body=body)])  # Actual parsed data will contain the literal
    assert new_operation.body[0].definition["schema"] == {"enum": [body]}
def test_complex_dereference(testdir, complex_schema):
    schema = schemathesis.from_path(complex_schema)
    path = Path(str(testdir))
    body = OpenAPI30Body(
        {
            "schema": {
                "additionalProperties": False,
                "description": "Test",
                "properties": {
                    "profile": {
                        "additionalProperties": False,
                        "description": "Test",
                        "properties": {"id": {"type": "integer"}},
                        "required": ["id"],
                        "type": "object",
                    },
                    "username": {"type": "string"},
                },
                "required": ["username", "profile"],
                "type": "object",
            }
        },
        required=True,
        media_type="application/json",
    )
    assert schema.endpoints["/teapot"]["POST"] == Endpoint(
        base_url="file:///",
        path="/teapot",
        method="post",
        definition=EndpointDefinition(
            {
                "requestBody": {
                    "content": {
                        "application/json": {"schema": {"$ref": "../schemas/teapot/create.yaml#/TeapotCreateRequest"}}
                    },
                    "description": "Test.",
                    "required": True,
                },
                "responses": {"default": {"$ref": "../../common/responses.yaml#/DefaultError"}},
                "summary": "Test",
                "tags": ["ancillaries"],
            },
            {
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "additionalProperties": False,
                                "description": "Test",
                                "properties": {
                                    "profile": {
                                        "additionalProperties": False,
                                        "description": "Test",
                                        "properties": {"id": {"type": "integer"}},
                                        "required": ["id"],
                                        "type": "object",
                                    },
                                    "username": {"type": "string"},
                                },
                                "required": ["username", "profile"],
                                "type": "object",
                            }
                        }
                    },
                    "description": "Test.",
                    "required": True,
                },
                "responses": {
                    "default": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "additionalProperties": False,
                                    "properties": {
                                        "key": {"anyOf": [{"type": "string"}, {"type": "null"}]},
                                        "referenced": {"anyOf": [{"type": "string"}, {"type": "null"}]},
                                    },
                                    "required": ["key", "referenced"],
                                    "type": "object",
                                }
                            }
                        },
                        "description": "Probably an error",
                    }
                },
                "summary": "Test",
                "tags": ["ancillaries"],
            },
            scope=f"{path.as_uri()}/root/paths/teapot.yaml#/TeapotCreatePath",
            parameters=[body],
        ),
        body=PayloadAlternatives([body]),
        schema=schema,
    )