schemathesis 3.39.3__py3-none-any.whl → 3.39.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- schemathesis/_hypothesis.py +3 -4
- schemathesis/cli/__init__.py +4 -0
- schemathesis/specs/openapi/checks.py +21 -3
- schemathesis/specs/openapi/examples.py +4 -1
- {schemathesis-3.39.3.dist-info → schemathesis-3.39.5.dist-info}/METADATA +1 -1
- {schemathesis-3.39.3.dist-info → schemathesis-3.39.5.dist-info}/RECORD +9 -9
- {schemathesis-3.39.3.dist-info → schemathesis-3.39.5.dist-info}/WHEEL +0 -0
- {schemathesis-3.39.3.dist-info → schemathesis-3.39.5.dist-info}/entry_points.txt +0 -0
- {schemathesis-3.39.3.dist-info → schemathesis-3.39.5.dist-info}/licenses/LICENSE +0 -0
schemathesis/_hypothesis.py
CHANGED
|
@@ -320,10 +320,9 @@ def _iter_coverage_cases(
|
|
|
320
320
|
yield case
|
|
321
321
|
if DataGenerationMethod.negative in data_generation_methods:
|
|
322
322
|
# Generate HTTP methods that are not specified in the spec
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
)
|
|
326
|
-
for method in methods:
|
|
323
|
+
# NOTE: The HEAD method is excluded
|
|
324
|
+
methods = {"get", "put", "post", "delete", "options", "patch", "trace"} - set(operation.schema[operation.path])
|
|
325
|
+
for method in sorted(methods):
|
|
327
326
|
case = operation.make_case(**template)
|
|
328
327
|
case._explicit_method = method
|
|
329
328
|
case.data_generation_method = DataGenerationMethod.negative
|
schemathesis/cli/__init__.py
CHANGED
|
@@ -1199,6 +1199,10 @@ def run(
|
|
|
1199
1199
|
checks_config.missing_required_header.allowed_statuses = missing_required_header_allowed_statuses
|
|
1200
1200
|
if negative_data_rejection_allowed_statuses:
|
|
1201
1201
|
checks_config.negative_data_rejection.allowed_statuses = negative_data_rejection_allowed_statuses
|
|
1202
|
+
if experimental.COVERAGE_PHASE.is_enabled:
|
|
1203
|
+
from ..specs.openapi.checks import unsupported_method
|
|
1204
|
+
|
|
1205
|
+
selected_checks += (unsupported_method,)
|
|
1202
1206
|
|
|
1203
1207
|
selected_checks = tuple(check for check in selected_checks if check.__name__ not in exclude_checks)
|
|
1204
1208
|
|
|
@@ -273,13 +273,31 @@ def missing_required_header(ctx: CheckContext, response: GenericResponse, case:
|
|
|
273
273
|
if (
|
|
274
274
|
case.meta
|
|
275
275
|
and case.meta.parameter_location == "header"
|
|
276
|
+
and case.meta.parameter
|
|
276
277
|
and case.meta.description
|
|
277
278
|
and case.meta.description.startswith("Missing ")
|
|
278
279
|
):
|
|
279
|
-
|
|
280
|
-
|
|
280
|
+
if case.meta.parameter.lower() == "authorization":
|
|
281
|
+
allowed_statuses = {401}
|
|
282
|
+
else:
|
|
283
|
+
config = ctx.config.missing_required_header
|
|
284
|
+
allowed_statuses = expand_status_codes(config.allowed_statuses or [])
|
|
281
285
|
if response.status_code not in allowed_statuses:
|
|
282
|
-
|
|
286
|
+
allowed = f"Allowed statuses: {', '.join(map(str,allowed_statuses))}"
|
|
287
|
+
raise AssertionError(f"Unexpected response status for a missing header: {response.status_code}\n{allowed}")
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def unsupported_method(ctx: CheckContext, response: GenericResponse, case: Case) -> bool | None:
|
|
292
|
+
if case.meta and case.meta.description and case.meta.description.startswith("Unspecified HTTP method:"):
|
|
293
|
+
if response.status_code != 405:
|
|
294
|
+
raise AssertionError(
|
|
295
|
+
f"Unexpected response status for unspecified HTTP method: {response.status_code}\nExpected: 405"
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
allow_header = response.headers.get("Allow")
|
|
299
|
+
if not allow_header:
|
|
300
|
+
raise AssertionError("Missing 'Allow' header in 405 Method Not Allowed response")
|
|
283
301
|
return None
|
|
284
302
|
|
|
285
303
|
|
|
@@ -408,7 +408,8 @@ def find_matching_in_responses(examples: dict[str, list], param: str) -> Iterato
|
|
|
408
408
|
if found is not NOT_FOUND:
|
|
409
409
|
yield found
|
|
410
410
|
continue
|
|
411
|
-
|
|
411
|
+
if isinstance(inner, dict):
|
|
412
|
+
example = inner
|
|
412
413
|
found = _find_matching_in_responses(example, schema_name, param, normalized, is_id_param)
|
|
413
414
|
if found is not NOT_FOUND:
|
|
414
415
|
yield found
|
|
@@ -420,6 +421,8 @@ def _find_matching_in_responses(
|
|
|
420
421
|
# Check for exact match
|
|
421
422
|
if param in example:
|
|
422
423
|
return example[param]
|
|
424
|
+
if is_id_param and param[:-2] in example:
|
|
425
|
+
return example[param[:-2]]
|
|
423
426
|
|
|
424
427
|
# Check for case-insensitive match
|
|
425
428
|
for key in example:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: schemathesis
|
|
3
|
-
Version: 3.39.
|
|
3
|
+
Version: 3.39.5
|
|
4
4
|
Summary: Property-based testing framework for Open API and GraphQL based apps
|
|
5
5
|
Project-URL: Documentation, https://schemathesis.readthedocs.io/en/stable/
|
|
6
6
|
Project-URL: Changelog, https://schemathesis.readthedocs.io/en/stable/changelog.html
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
schemathesis/__init__.py,sha256=UW2Bq8hDDkcBeAAA7PzpBFXkOOxkmHox-mfQwzHDjL0,1914
|
|
2
2
|
schemathesis/_compat.py,sha256=y4RZd59i2NCnZ91VQhnKeMn_8t3SgvLOk2Xm8nymUHY,1837
|
|
3
3
|
schemathesis/_dependency_versions.py,sha256=pjEkkGAfOQJYNb-9UOo84V8nj_lKHr_TGDVdFwY2UU0,816
|
|
4
|
-
schemathesis/_hypothesis.py,sha256=
|
|
4
|
+
schemathesis/_hypothesis.py,sha256=SIacOZAi1phnTNFtPf7dHSuZQ3r5hDyOH8UOzEdk6AE,24423
|
|
5
5
|
schemathesis/_lazy_import.py,sha256=aMhWYgbU2JOltyWBb32vnWBb6kykOghucEzI_F70yVE,470
|
|
6
6
|
schemathesis/_override.py,sha256=TAjYB3eJQmlw9K_xiR9ptt9Wj7if4U7UFlUhGjpBAoM,1625
|
|
7
7
|
schemathesis/_patches.py,sha256=Hsbpn4UVeXUQD2Kllrbq01CSWsTYENWa0VJTyhX5C2k,895
|
|
@@ -28,7 +28,7 @@ schemathesis/targets.py,sha256=XIGRghvEzbmEJjse9aZgNEj67L3jAbiazm2rxURWgDE,2351
|
|
|
28
28
|
schemathesis/throttling.py,sha256=aisUc4MJDGIOGUAs9L2DlWWpdd4KyAFuNVKhYoaUC9M,1719
|
|
29
29
|
schemathesis/types.py,sha256=Tem2Q_zyMCd0Clp5iGKv6Fu13wdcbxVE8tCVH9WWt7A,1065
|
|
30
30
|
schemathesis/utils.py,sha256=LwqxqoAKmRiAdj-qUbNmgQgsamc49V5lc5TnOIDuuMA,4904
|
|
31
|
-
schemathesis/cli/__init__.py,sha256=
|
|
31
|
+
schemathesis/cli/__init__.py,sha256=IxJnRTCp0bl1B044jjD9GFJ2pisckw3-PBnNHcABBy4,75795
|
|
32
32
|
schemathesis/cli/__main__.py,sha256=MWaenjaUTZIfNPFzKmnkTiawUri7DVldtg3mirLwzU8,92
|
|
33
33
|
schemathesis/cli/callbacks.py,sha256=-VA_I_mVma9WxFNtUR8d2KNICKJD5ScayfSdKKPEP5Y,16321
|
|
34
34
|
schemathesis/cli/cassettes.py,sha256=zji-B-uuwyr0Z0BzQX-DLMV6lWb58JtLExcUE1v3m4Y,20153
|
|
@@ -107,11 +107,11 @@ schemathesis/specs/graphql/validation.py,sha256=uINIOt-2E7ZuQV2CxKzwez-7L9tDtqzM
|
|
|
107
107
|
schemathesis/specs/openapi/__init__.py,sha256=HDcx3bqpa6qWPpyMrxAbM3uTo0Lqpg-BUNZhDJSJKnw,279
|
|
108
108
|
schemathesis/specs/openapi/_cache.py,sha256=PAiAu4X_a2PQgD2lG5H3iisXdyg4SaHpU46bRZvfNkM,4320
|
|
109
109
|
schemathesis/specs/openapi/_hypothesis.py,sha256=nU8UDn1PzGCre4IVmwIuO9-CZv1KJe1fYY0d2BojhSo,22981
|
|
110
|
-
schemathesis/specs/openapi/checks.py,sha256=
|
|
110
|
+
schemathesis/specs/openapi/checks.py,sha256=q6BbsrNFs9lx7WNJQg-ZnlGN8B5kW7wTq5btqisWF7w,26194
|
|
111
111
|
schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
|
|
112
112
|
schemathesis/specs/openapi/converter.py,sha256=Yxw9lS_JKEyi-oJuACT07fm04bqQDlAu-iHwzkeDvE4,3546
|
|
113
113
|
schemathesis/specs/openapi/definitions.py,sha256=WTkWwCgTc3OMxfKsqh6YDoGfZMTThSYrHGp8h0vLAK0,93935
|
|
114
|
-
schemathesis/specs/openapi/examples.py,sha256=
|
|
114
|
+
schemathesis/specs/openapi/examples.py,sha256=hdeq7et8AexYGY2iU6SfMZWJ7G0PbOfapUtc4upNs_4,20483
|
|
115
115
|
schemathesis/specs/openapi/formats.py,sha256=3KtEC-8nQRwMErS-WpMadXsr8R0O-NzYwFisZqMuc-8,2761
|
|
116
116
|
schemathesis/specs/openapi/links.py,sha256=C4Uir2P_EcpqME8ee_a1vdUM8Tm3ZcKNn2YsGjZiMUQ,17935
|
|
117
117
|
schemathesis/specs/openapi/loaders.py,sha256=5B1cgYEBj3h2psPQxzrQ5Xq5owLVGw-u9HsCQIx7yFE,25705
|
|
@@ -153,8 +153,8 @@ schemathesis/transports/auth.py,sha256=urSTO9zgFO1qU69xvnKHPFQV0SlJL3d7_Ojl0tLnZ
|
|
|
153
153
|
schemathesis/transports/content_types.py,sha256=MiKOm-Hy5i75hrROPdpiBZPOTDzOwlCdnthJD12AJzI,2187
|
|
154
154
|
schemathesis/transports/headers.py,sha256=hr_AIDOfUxsJxpHfemIZ_uNG3_vzS_ZeMEKmZjbYiBE,990
|
|
155
155
|
schemathesis/transports/responses.py,sha256=OFD4ZLqwEFpo7F9vaP_SVgjhxAqatxIj38FS4XVq8Qs,1680
|
|
156
|
-
schemathesis-3.39.
|
|
157
|
-
schemathesis-3.39.
|
|
158
|
-
schemathesis-3.39.
|
|
159
|
-
schemathesis-3.39.
|
|
160
|
-
schemathesis-3.39.
|
|
156
|
+
schemathesis-3.39.5.dist-info/METADATA,sha256=nj2LiILtzKXgnfw87so8GJiPTfiG78DszX3qKZ2T4-0,12956
|
|
157
|
+
schemathesis-3.39.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
158
|
+
schemathesis-3.39.5.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
|
|
159
|
+
schemathesis-3.39.5.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
|
|
160
|
+
schemathesis-3.39.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|