Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reference parameter/response with MarshmallowPlugin #414

Merged
merged 2 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/apispec/ext/marshmallow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ def init_spec(self, spec):
def resolve_parameters(self, parameters):
resolved = []
for parameter in parameters:
if not isinstance(parameter.get("schema", {}), dict):
if isinstance(parameter, dict) and not isinstance(
parameter.get("schema", {}), dict
):
schema_instance = resolve_schema_instance(parameter["schema"])
if "in" in parameter:
del parameter["schema"]
Expand All @@ -109,8 +111,12 @@ def resolve_schema(self, data):
corresponding dict to convert Marshmallow Schema object or class into dict

:param APISpec spec: `APISpec` containing refs.
:param dict data: the parameter or response dictionary that may contain a schema
:param dict|str data: either a parameter or response dictionary that may
contain a schema, or a reference provided as string
"""
if not isinstance(data, dict):
return

# OAS 2 component or OAS 3 header
if "schema" in data:
data["schema"] = self.openapi.resolve_schema_dict(data["schema"])
Expand Down
39 changes: 33 additions & 6 deletions tests/test_ext_marshmallow.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ def test_schema_array_uses_ref_if_available_v2(self, spec_fixture):
},
)
get = get_paths(spec_fixture.spec)["/pet"]["get"]
len(get["parameters"]) == 1
assert len(get["parameters"]) == 1
resolved_schema = {
"type": "array",
"items": {"$ref": ref_path(spec_fixture.spec) + "Pet"},
Expand Down Expand Up @@ -608,16 +608,15 @@ def test_schema_array_uses_ref_if_available_v3(self, spec_fixture):
}
},
)
p = get_paths(spec_fixture.spec)["/pet"]
assert "get" in p
op = p["get"]
get = get_paths(spec_fixture.spec)["/pet"]["get"]
assert len(get["parameters"]) == 1
resolved_schema = {
"type": "array",
"items": {"$ref": ref_path(spec_fixture.spec) + "Pet"},
}
request_schema = op["parameters"][0]["content"]["application/json"]["schema"]
request_schema = get["parameters"][0]["content"]["application/json"]["schema"]
assert request_schema == resolved_schema
response_schema = op["responses"][200]["content"]["application/json"]["schema"]
response_schema = get["responses"][200]["content"]["application/json"]["schema"]
assert response_schema == resolved_schema

@pytest.mark.parametrize("spec_fixture", ("2.0",), indirect=True)
Expand Down Expand Up @@ -684,6 +683,34 @@ def test_schema_partially_v3(self, spec_fixture):
},
}

def test_parameter_reference(self, spec_fixture):
if spec_fixture.spec.openapi_version.major < 3:
param = {"schema": PetSchema}
reference = "#/parameters/Pet"
else:
param = {"content": {"application/json": {"schema": PetSchema}}}
reference = "#/components/parameters/Pet"
spec_fixture.spec.components.parameter("Pet", "body", param)
spec_fixture.spec.path(
path="/parents", operations={"get": {"parameters": ["Pet"]}}
)
get = get_paths(spec_fixture.spec)["/parents"]["get"]
assert get["parameters"] == [{"$ref": reference}]

def test_response_reference(self, spec_fixture):
if spec_fixture.spec.openapi_version.major < 3:
resp = {"schema": PetSchema}
reference = "#/responses/Pet"
else:
resp = {"content": {"application/json": {"schema": PetSchema}}}
reference = "#/components/responses/Pet"
spec_fixture.spec.components.response("Pet", resp)
spec_fixture.spec.path(
path="/parents", operations={"get": {"responses": {"200": "Pet"}}}
)
get = get_paths(spec_fixture.spec)["/parents"]["get"]
assert get["responses"] == {"200": {"$ref": reference}}

def test_schema_global_state_untouched_2json(self, spec_fixture):
assert RunSchema._declared_fields["sample"]._Nested__schema is None
data = spec_fixture.openapi.schema2jsonschema(RunSchema)
Expand Down