Skip to content

Commit

Permalink
fix: Internal error when YAML payload definition contains nested bina…
Browse files Browse the repository at this point in the history
…ry format

Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
  • Loading branch information
Stranger6667 committed Feb 29, 2024
1 parent 327393f commit 084de7d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Changelog

- Not respecting ``allow_x00`` and ``codec`` configs options during filling gaps in explicit examples.
- Internal error when sending ``multipart/form-data`` requests when the schema defines the ``*/*`` content type.
- Internal error when YAML payload definition contains nested ``binary`` format.

.. _v3.25.5:

Expand Down
12 changes: 10 additions & 2 deletions src/schemathesis/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import annotations

import binascii
import os
from dataclasses import dataclass
Expand All @@ -10,13 +11,14 @@
Collection,
Dict,
Generator,
cast,
Protocol,
cast,
runtime_checkable,
)

from .internal.copy import fast_deepcopy
from ._xml import _to_xml
from .internal.copy import fast_deepcopy
from .internal.jsonschema import traverse_schema
from .transports.content_types import (
is_json_media_type,
is_plain_text_media_type,
Expand Down Expand Up @@ -150,6 +152,10 @@ def as_werkzeug(self, context: SerializerContext, value: Any) -> dict[str, Any]:
return _to_json(value)


def _replace_binary(value: dict) -> dict:
return {key: value.data if isinstance(value, Binary) else value for key, value in value.items()}


def _to_yaml(value: Any) -> dict[str, Any]:
import yaml

Expand All @@ -162,6 +168,8 @@ def _to_yaml(value: Any) -> dict[str, Any]:
return {"data": value}
if isinstance(value, Binary):
return {"data": value.data}
if isinstance(value, (list, dict)):
value = traverse_schema(value, _replace_binary)
return {"data": yaml.dump(value, Dumper=SafeDumper)}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Exit code: 0
---
Stdout:
======================= Schemathesis test session starts =======================
Schema location: file:///tmp/schema.json
Base URL: http://127.0.0.1/api
Specification version: Open API 3.0.2
Random seed: 42
Workers: 1
Collected API operations: 1
Collected API links: 0

POST /api/property . [100%]

=================================== SUMMARY ====================================

Performed checks:
not_a_server_error 10 / 10 passed PASSED

WARNING: All API responses have a 404 status code. Did you specify the proper API location?

Tip: Use the `--report` CLI option to visualize test results via Schemathesis.io.
We run additional conformance checks on reports from public repos.

============================== 1 passed in 1.00s ===============================
26 changes: 26 additions & 0 deletions test/cli/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,32 @@ def decode(idx):
# NOTE, that the actual API operation is not checked in this test


def test_nested_binary_in_yaml(testdir, openapi3_base_url, cli, snapshot_cli, empty_open_api_3_schema):
empty_open_api_3_schema["paths"] = {
"/property": {
"post": {
"requestBody": {
"required": True,
"content": {
"*/*": {
"schema": {
"type": "object",
"properties": {"file": {"type": "string", "format": "binary"}},
"required": ["file"],
}
}
},
},
"responses": {
"200": {"description": "OK", "content": {"application/json": {"schema": {"type": "object"}}}}
},
}
},
}
schema_file = testdir.make_openapi_schema_file(empty_open_api_3_schema)
assert cli.run(str(schema_file), f"--base-url={openapi3_base_url}", "--hypothesis-max-examples=10") == snapshot_cli


@pytest.mark.operations("form")
def test_urlencoded_form(cli, cli_args):
# When the API operation accepts application/x-www-form-urlencoded
Expand Down

0 comments on commit 084de7d

Please sign in to comment.