Example #1
0
def test_invalid_content_type(httpserver, without_content_type):
    # When the user tries to load an HTML as a schema
    content = """
<html>
<style>
  html {
    margin: 0;
    background: #fafafa;
  }
</style>
<html>
    """
    response = Response(response=content)
    if without_content_type:
        del response.headers["Content-Type"]
    path = "/openapi/"
    handler = httpserver.expect_request(path)
    handler.respond_with_response(response)
    schema_url = httpserver.url_for(path)
    # And loading cause an error
    # Then it should be suggested to the user that they should provide JSON or YAML
    with pytest.raises(ValueError, match=YAML_LOADING_ERROR) as exc:
        schemathesis.from_uri(schema_url)
    if not without_content_type:
        # And list the actual response content type
        assert "The actual response has `text/html; charset=utf-8` Content-Type" in exc.value.args[
            0]
Example #2
0
def test_add_link_behind_a_reference(schema_url):
    # See GH-824
    schema = schemathesis.from_uri(schema_url)
    # When all methods for an API operation are behind a reference
    schema.raw_schema["components"]["methods"] = {
        "users": schema.raw_schema["paths"]["/users/"],
        "user-details": schema.raw_schema["paths"]["/users/{user_id}"],
    }
    schema.raw_schema["paths"]["/users/"] = {
        "$ref": "#/components/methods/users"
    }
    schema.raw_schema["paths"]["/users/{user_id}"] = {
        "$ref": "#/components/methods/user-details"
    }
    assert not hasattr(schema, "_operations")
    # And a link is added
    add_link(schema,
             schema["/users/{user_id}"]["GET"],
             parameters={"userId": "$response.body#/id"})
    # Then the source API operation should have the new link
    operation = schema["/users/"]["POST"]
    links = operation.definition.resolved["responses"]["201"]["links"]
    assert len(links) == 3
    assert links["GET /users/{user_id}"] == {
        "parameters": {
            "userId": "$response.body#/id"
        },
        "operationId": "getUser"
    }
Example #3
0
def test_call_and_validate(openapi3_schema_url):
    api_schema = schemathesis.from_uri(openapi3_schema_url)

    @given(case=api_schema["/success"]["GET"].as_strategy())
    @settings(max_examples=1)
    def test(case):
        case.call_and_validate()
Example #4
0
def test_get_operation_via_remote_reference(openapi_version, schema_url):
    schema = schemathesis.from_uri(schema_url)
    resolved = schema.get_operation_by_reference(
        f"{schema_url}#/paths/~1users~1{{user_id}}/patch")
    assert isinstance(resolved, APIOperation)
    assert resolved.path == "/users/{user_id}"
    assert resolved.method.upper() == "PATCH"
    # Via common parameters for all methods
    if openapi_version.is_openapi_2:
        assert resolved.query == ParameterSet([
            OpenAPI20Parameter({
                "in": "query",
                "name": "common",
                "required": True,
                "type": "integer"
            })
        ])
    if openapi_version.is_openapi_3:
        assert resolved.query == ParameterSet([
            OpenAPI30Parameter({
                "in": "query",
                "name": "common",
                "required": True,
                "schema": {
                    "type": "integer"
                }
            })
        ])
def test_serialize_interrupted(mocker, schema_url):
    mocker.patch(
        "schemathesis.runner.impl.solo.SingleThreadRunner._execute_impl",
        side_effect=KeyboardInterrupt)
    schema = schemathesis.from_uri(schema_url)
    events = from_schema(schema).execute()
    next(events)
    assert serialize_event(next(events)) == {"Interrupted": None}
Example #6
0
def test_get_links(openapi3_base_url, schema_url, url, expected):
    schema = schemathesis.from_uri(schema_url)
    response = requests.post(f"{openapi3_base_url}{url}", json={"first_name": "TEST", "last_name": "TEST"})
    tests = schema["/users/"]["POST"].get_stateful_tests(response, Stateful.links)
    assert len(tests) == len(expected)
    for test, value in zip(tests, expected):
        assert test.name == value.name
        assert test.parameters == value.parameters
Example #7
0
def test_add_link_by_reference(schema_url):
    schema = schemathesis.from_uri(schema_url)
    links = add_link(schema,
                     "#/paths/~1users~1{user_id}/get",
                     parameters={"userId": "$response.body#/id"})
    assert links["#/paths/~1users~1{user_id}/get"] == {
        "operationRef": "#/paths/~1users~1{user_id}/get",
        **EXPECTED_LINK_PARAMETERS,
    }
Example #8
0
def test_get_links(openapi3_base_url, schema_url, url, expected):
    schema = schemathesis.from_uri(schema_url)
    response = requests.post(f"{openapi3_base_url}{url}",
                             json={
                                 "first_name": "TEST",
                                 "last_name": "TEST"
                             })
    assert schema["/users/"]["POST"].get_stateful_tests(
        response, Stateful.links) == expected
Example #9
0
def test_add_link_no_operation_id(schema_url):
    schema = schemathesis.from_uri(schema_url)
    target = schema["/users/{user_id}"]["GET"]
    del target.definition.resolved["operationId"]
    links = add_link(schema,
                     target,
                     parameters={"userId": "$response.body#/id"})
    assert links[f"{target.method.upper()} {target.path}"] == {
        "operationRef": "#/paths/~1users~1{user_id}/get",
        **EXPECTED_LINK_PARAMETERS,
    }
Example #10
0
def test_add_link_nothing_is_provided(schema_url):
    schema = schemathesis.from_uri(schema_url)
    # When the user doesn't provide parameters or request_body
    with pytest.raises(
            ValueError,
            match="You need to provide `parameters` or `request_body`."):
        # Then there should be an error
        schema.add_link(
            source=schema["/users/"]["POST"],
            target="#/paths/~1users~1{user_id}/get",
            status_code="201",
        )
def test_serialize_event(schema_url):
    schema = schemathesis.from_uri(schema_url)
    events = from_schema(schema).execute()
    next(events)
    next(events)
    event = serialize_event(next(events))
    assert "interactions" not in event["AfterExecution"]["result"]
    assert "logs" not in event["AfterExecution"]["result"]
    assert event["AfterExecution"]["result"]["checks"][0]["example"][
        "query"] == {
            "id": ["0"]
        }
Example #12
0
def test_port_override_with_ipv6(openapi3_schema_url, simple_openapi, mocker):
    resp = Response()
    resp.status_code = 200
    resp._content = json.dumps(simple_openapi).encode("utf-8")
    mocker.patch("requests.get", return_value=resp)

    url = URL(openapi3_schema_url)
    parts = list(map(int, url.host.split(".")))
    ipv6_host = "2002:{:02x}{:02x}:{:02x}{:02x}::".format(*parts)
    ipv6 = url.with_host("[%s]" % ipv6_host)
    schema = schemathesis.from_uri(str(ipv6), validate_schema=False, port=8081)
    operation = next(schema.get_all_operations()).ok()
    assert operation.base_url == "http://[2002:7f00:1::]:8081/schema.yaml"
Example #13
0
def test_read_only(schema_url):
    # When API operation has `readOnly` properties
    schema = schemathesis.from_uri(schema_url)

    @given(case=schema["/read_only"]["GET"].as_strategy())
    @settings(max_examples=1, deadline=None)
    def test(case):
        # Then `writeOnly` should not affect the response schema
        response = case.call()
        assert "write" not in response.json()
        case.validate_response(response)

    test()
Example #14
0
def test_add_link_default(schema_url):
    schema = schemathesis.from_uri(schema_url)
    # When we add a link to the target API operation
    # And it is an `APIOperation` instance
    # And it has the `operationId` key
    links = add_link(schema,
                     schema["/users/{user_id}"]["GET"],
                     parameters={"userId": "$response.body#/id"})
    # Then it should be added without errors
    assert links[schema["/users/{user_id}"]["GET"].verbose_name] == {
        "operationId": "getUser",
        **EXPECTED_LINK_PARAMETERS,
    }
Example #15
0
def test_misspelled_parameter(schema_url, parameter, message):
    schema = schemathesis.from_uri(schema_url)
    # When the user supplies a parameter definition, that points to location which has no parameters defined in the
    # schema
    add_link(schema,
             "#/paths/~1users~1{user_id}/get",
             parameters={f"header.{parameter}": "$response.body#/id"})
    case = schema["/users/{user_id}"]["GET"].make_case()
    link = schema["/users/"]["POST"].links["201"][
        "#/paths/~1users~1{user_id}/get"]
    with pytest.raises(ValueError, match=re.escape(message)):
        link.set_data(case,
                      context=expressions.ExpressionContext(case=case,
                                                            response=None))
Example #16
0
def test_add_link_unknown_operation(schema_url, change, message):
    schema = schemathesis.from_uri(schema_url)
    # When the source API operation is modified and can't be found
    source = schema["/users/"]["POST"]
    change(schema, source)
    with pytest.raises(
            ValueError,
            match=re.escape(
                f"{message} Check if the requested API operation passes the filters in the schema."
            )):
        # Then there should be an error about it.
        schema.add_link(source=source,
                        target="#/paths/~1users~1{user_id}/get",
                        status_code="201",
                        request_body="#/foo")
def test_optional_form_parameters(schema_url):
    # When form parameters are optional
    schema = schemathesis.from_uri(schema_url)
    strategy = schema["/multipart"]["POST"].as_strategy()

    @given(case=strategy)
    @settings(max_examples=3, deadline=None, suppress_health_check=[HealthCheck.too_slow, HealthCheck.filter_too_much])
    def test(case):
        assume("maybe" in case.body)
        response = case.call()
        assert response.status_code == 200
        # Then they still should be possible to generate
        assert response.json()["maybe"] == str(case.body["maybe"])

    test()
Example #18
0
def test_write_only(schema_url):
    # When API operation has `writeOnly` properties
    schema = schemathesis.from_uri(schema_url)

    @given(case=schema["/write_only"]["POST"].as_strategy())
    @settings(max_examples=1)
    def test(case):
        # Then `writeOnly` should be used only in requests
        assert "write" in case.body
        assert "read" not in case.body
        # And `readOnly` should only occur in responses
        response = case.call()
        assert "write" not in response.json()
        case.validate_response(response)

    test()
Example #19
0
def test_add_link_no_operations_cache(schema_url, status_code):
    schema = schemathesis.from_uri(schema_url)
    # When we add a link to the target API operation
    source = schema["/users/"]["POST"]
    target = schema["/users/{user_id}"]["GET"]
    # And the operations are not cached
    delattr(schema, "_operations")
    schema.add_link(
        source=source,
        target=target,
        status_code=status_code,
        parameters={"userId": "$response.body#/id"},
    )
    # Then it should be added without errors
    # And the cache cleanup should be no-op
    links = schema["/users/"]["POST"].definition.resolved["responses"]["201"][
        "links"]
    assert links[f"{target.method.upper()} {target.path}"] == {
        "operationId": "getUser",
        **EXPECTED_LINK_PARAMETERS,
    }
Example #20
0
def test_uri_loader_custom_kwargs(app, schema_url):
    # All custom kwargs are passed to `requests.get`
    schemathesis.from_uri(schema_url, verify=False, headers={"X-Test": "foo"})
    request = app["schema_requests"][0]
    assert request.headers["X-Test"] == "foo"
    assert request.headers["User-Agent"] == USER_AGENT
Example #21
0
import schemathesis
from hypothesis import settings
from schemathesis.checks import not_a_server_error

schema = schemathesis.from_uri("https://petstore.swagger.io/v2/swagger.json")


@schema.parametrize(method="GET", endpoint="/pet")
@settings(max_examples=25)
def test_get_booking(case):
    response = case.call()
    # assert response.status_code < 500
    case.validate_response(response, checks=(not_a_server_error,))
Example #22
0
API_PATH = os.getenv("API_URL")
BASE_URL = os.getenv("BASE_URL")


def handler(event, context):
    import pytest
    return pytest.main(['-o', 'cache_dir=/tmp/.testcache'])


# will only be run if called from cli
if __name__ == "__main__":
    test_event = {
        'openapi_uri': 'tests/openapi_example.yaml',
        'base_url': 'https://cloudstash.io'
    }
    test_context = {'env': {}}
    test_res = handler(test_event, test_context)
    print(test_res)

schema = schemathesis.from_uri(API_PATH)


@schema.parametrize()
@settings(deadline=2000,
          print_blob=True,
          max_examples=10,
          verbosity=Verbosity.verbose)
def test_api(case):
    response = case.call_and_validate()
    return response
Example #23
0
def test_port_override(openapi3_schema_url):
    schema = schemathesis.from_uri(openapi3_schema_url, port=8081)
    operation = next(schema.get_all_operations()).ok()
    assert operation.base_url == "http://127.0.0.1:8081/schema.yaml"
Example #24
0
def test_base_url(base_url, schema_url):
    schema = schemathesis.from_uri(schema_url)
    assert schema.base_url == base_url
Example #25
0
def api_schema(request, openapi_version):
    if request.param == "aiohttp":
        schema_url = request.getfixturevalue("schema_url")
        return schemathesis.from_uri(schema_url)
    app = request.getfixturevalue("flask_app")
    return schemathesis.from_wsgi("/schema.yaml", app=app)
Example #26
0
def test_base_url(openapi3_schema_url):
    schema = schemathesis.from_uri(openapi3_schema_url)
    assert schema.base_url is None
Example #27
0
def test_uri_loader(app_schema, app, schema_url):
    # Each loader method should read the specified schema correctly
    assert schemathesis.from_uri(schema_url).raw_schema == app_schema
Example #28
0
def test_base_url_override(openapi3_schema_url, url):
    schema = schemathesis.from_uri(openapi3_schema_url, base_url=url)
    operation = next(schema.get_all_operations()).ok()
    assert operation.base_url == "http://example.com"
Example #29
0
def test_base_url_override(schema_url, url):
    schema = schemathesis.from_uri(schema_url, base_url=url)
    endpoint = next(schema.get_all_endpoints())
    assert endpoint.base_url == "http://example.com"
Example #30
0
def test_links_access(schema_url):
    schema = schemathesis.from_uri(schema_url)
    links = schema["/users/"]["POST"].links["201"]
    assert len(links) == 2
    assert links["GetUserByUserId"].name == "GetUserByUserId"