Skip to content

Commit

Permalink
feat: Support for testing of examples in Parameter & Media Type objec…
Browse files Browse the repository at this point in the history
…ts in Open API 3.0.
  • Loading branch information
Stranger6667 committed Feb 7, 2020
1 parent df07a14 commit c352fdf
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 2 deletions.
6 changes: 6 additions & 0 deletions docs/changelog.rst
Expand Up @@ -6,6 +6,11 @@ Changelog
`Unreleased`_
-------------

Added
~~~~~

- Support for testing of examples in Parameter & Media Type objects in Open API 3.0. `#394`_

Changed
~~~~~~~

Expand Down Expand Up @@ -667,6 +672,7 @@ Fixed
.. _0.3.0: https://github.com/kiwicom/schemathesis/compare/v0.2.0...v0.3.0
.. _0.2.0: https://github.com/kiwicom/schemathesis/compare/v0.1.0...v0.2.0

.. _#394: https://github.com/kiwicom/schemathesis/issues/394
.. _#386: https://github.com/kiwicom/schemathesis/issues/386
.. _#383: https://github.com/kiwicom/schemathesis/issues/383
.. _#381: https://github.com/kiwicom/schemathesis/issues/381
Expand Down
10 changes: 10 additions & 0 deletions src/schemathesis/schemas.py
Expand Up @@ -318,6 +318,11 @@ def process_by_type(self, endpoint: Endpoint, parameter: Dict[str, Any]) -> None

def add_parameter(self, container: Optional[Dict[str, Any]], parameter: Dict[str, Any]) -> Dict[str, Any]:
container = super().add_parameter(container, parameter)
if "example" in parameter["schema"]:
container["example"] = {parameter["name"]: parameter["schema"]["example"]}
# https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameter-object
# > Furthermore, if referencing a schema which contains an example,
# > the example value SHALL override the example provided by the schema
if "example" in parameter:
container["example"] = {parameter["name"]: parameter["example"]}
return container
Expand All @@ -329,6 +334,11 @@ def process_body(self, endpoint: Endpoint, parameter: Dict[str, Any]) -> None:
# Take the first media type object
options = iter(parameter["content"].values())
parameter = next(options)
# https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#media-type-object
# > Furthermore, if referencing a schema which contains an example,
# > the example value SHALL override the example provided by the schema
if "example" in parameter:
parameter["schema"]["example"] = parameter["example"]
super().process_body(endpoint, parameter)

def parameter_to_json_schema(self, data: Dict[str, Any]) -> Dict[str, Any]:
Expand Down
87 changes: 85 additions & 2 deletions test/test_parametrization.py
Expand Up @@ -182,7 +182,46 @@ def test(request, case):


def test_specified_example_query(testdir):
# When the given query parameter contains an example
# When the given query parameter contains an example in the "schema" field
testdir.make_test(
"""
from hypothesis import Phase
@schema.parametrize()
@settings(max_examples=1, phases=[Phase.explicit])
def test(request, case):
request.config.HYPOTHESIS_CASES += 1
assert case.query == {"id": "test"}
""",
schema={
"openapi": "3.0.2",
"info": {"title": "Test", "description": "Test", "version": "0.1.0"},
"paths": {
"/query": {
"get": {
"parameters": [
{
"name": "id",
"in": "query",
"required": True,
"schema": {"type": "string", "example": "test"},
}
],
"responses": {"200": {"description": "OK"}},
}
}
},
},
)

result = testdir.runpytest("-v", "-s")
# Then this example should be used in tests
result.assert_outcomes(passed=1)
result.stdout.re_match_lines([r"Hypothesis calls: 1$"])


def test_specified_example_parameter_override(testdir):
# When the given parameter contains an example
testdir.make_test(
"""
from hypothesis import Phase
Expand All @@ -205,7 +244,7 @@ def test(request, case):
"in": "query",
"required": True,
"example": "test",
"schema": {"type": "string"},
"schema": {"type": "string", "example": "NOT test"},
}
],
"responses": {"200": {"description": "OK"}},
Expand All @@ -221,6 +260,50 @@ def test(request, case):
result.stdout.re_match_lines([r"Hypothesis calls: 1$"])


def test_specified_example_body_media_type_override(testdir):
# When the given requestBody parameter contains an example specified in Media Type Object (not in Schema Object)
testdir.make_test(
"""
from hypothesis import Phase
@schema.parametrize()
@settings(max_examples=1, phases=[Phase.explicit])
def test(request, case):
request.config.HYPOTHESIS_CASES += 1
assert case.body == {"name": "John"}
""",
schema={
"openapi": "3.0.2",
"info": {"title": "Test", "description": "Test", "version": "0.1.0"},
"paths": {
"/body": {
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {"name": {"type": "string"}},
"required": ["name"],
"example": {"name": "NOT John"},
},
"example": {"name": "John"},
}
}
},
"responses": {"200": {"description": "OK"}},
}
}
},
},
)

result = testdir.runpytest("-v", "-s")
# Then this example should be used in tests, not the example from the schema
result.assert_outcomes(passed=1)
result.stdout.re_match_lines([r"Hypothesis calls: 1$"])


def test_deselecting(testdir):
# When pytest selecting is applied via "-k" option
testdir.make_test(
Expand Down

0 comments on commit c352fdf

Please sign in to comment.