schemathesis 4.0.15__py3-none-any.whl → 4.0.16__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.
@@ -26,6 +26,7 @@ from schemathesis.engine import Status, events
26
26
  from schemathesis.engine.phases import PhaseName, PhaseSkipReason
27
27
  from schemathesis.engine.phases.probes import ProbeOutcome
28
28
  from schemathesis.engine.recorder import Interaction, ScenarioRecorder
29
+ from schemathesis.generation.meta import CoveragePhaseData
29
30
  from schemathesis.generation.modes import GenerationMode
30
31
  from schemathesis.schemas import ApiStatistic
31
32
 
@@ -1053,10 +1054,19 @@ class OutputHandler(EventHandler):
1053
1054
 
1054
1055
  warnings = self.config.warnings_for(operation=operation)
1055
1056
 
1057
+ def has_only_missing_auth_case() -> bool:
1058
+ case = list(event.recorder.cases.values())[0].value
1059
+ return bool(
1060
+ case.meta
1061
+ and isinstance(case.meta.phase.data, CoveragePhaseData)
1062
+ and case.meta.phase.data.description == "Missing `Authorization` at header"
1063
+ )
1064
+
1056
1065
  if SchemathesisWarning.MISSING_AUTH in warnings:
1057
- for status_code in (401, 403):
1058
- if statistic.ratio_for(status_code) >= AUTH_ERRORS_THRESHOLD:
1059
- self.warnings.missing_auth.setdefault(status_code, set()).add(event.recorder.label)
1066
+ if not (len(event.recorder.cases) == 1 and has_only_missing_auth_case()):
1067
+ for status_code in (401, 403):
1068
+ if statistic.ratio_for(status_code) >= AUTH_ERRORS_THRESHOLD:
1069
+ self.warnings.missing_auth.setdefault(status_code, set()).add(event.recorder.label)
1060
1070
 
1061
1071
  # Warn if all positive test cases got 4xx in return and no failure was found
1062
1072
  def all_positive_are_rejected(recorder: ScenarioRecorder) -> bool:
@@ -1220,10 +1230,10 @@ class OutputHandler(EventHandler):
1220
1230
  click.echo()
1221
1231
  if self.warnings.missing_auth:
1222
1232
  self._display_warning_block(
1223
- title="Missing authentication",
1233
+ title="Authentication failed",
1224
1234
  operations=self.warnings.missing_auth,
1225
1235
  operation_suffix=" returned authentication errors",
1226
- tips=["💡 Use --auth or -H to provide authentication credentials"],
1236
+ tips=["💡 Ensure valid authentication credentials are set via --auth or -H"],
1227
1237
  )
1228
1238
 
1229
1239
  if self.warnings.missing_test_data:
@@ -185,9 +185,11 @@ class APIStateMachine(RuleBasedStateMachine):
185
185
  if target is not None:
186
186
  super()._add_result_to_targets((target,), result)
187
187
 
188
- def _add_results_to_targets(self, targets: tuple[str, ...], results: list[StepOutput]) -> None:
188
+ def _add_results_to_targets(self, targets: tuple[str, ...], results: list[StepOutput | None]) -> None:
189
189
  # Hypothesis >6.131.15
190
190
  for result in results:
191
+ if result is None:
192
+ continue
191
193
  target = self._get_target_for_result(result)
192
194
  if target is not None:
193
195
  super()._add_results_to_targets((target,), [result])
@@ -80,6 +80,10 @@ class RequestsTransport(BaseTransport["requests.Session"]):
80
80
  if cookies is not None:
81
81
  merge_at(data, "cookies", cookies)
82
82
 
83
+ excluded_headers = get_exclude_headers(case)
84
+ for name in excluded_headers:
85
+ data["headers"].pop(name, None)
86
+
83
87
  return data
84
88
 
85
89
  def send(self, case: Case, *, session: requests.Session | None = None, **kwargs: Any) -> Response:
@@ -112,9 +116,6 @@ class RequestsTransport(BaseTransport["requests.Session"]):
112
116
  data.update({key: value for key, value in kwargs.items() if key not in data})
113
117
  data.setdefault("timeout", DEFAULT_RESPONSE_TIMEOUT)
114
118
 
115
- excluded_headers = get_exclude_headers(case)
116
- for name in excluded_headers:
117
- data["headers"].pop(name, None)
118
119
  current_session_headers: MutableMapping[str, Any] = {}
119
120
  current_session_auth = None
120
121
 
@@ -124,9 +125,11 @@ class RequestsTransport(BaseTransport["requests.Session"]):
124
125
  close_session = True
125
126
  else:
126
127
  current_session_headers = session.headers
127
- if isinstance(session.auth, tuple) and "Authorization" in excluded_headers:
128
- current_session_auth = session.auth
129
- session.auth = None
128
+ if isinstance(session.auth, tuple):
129
+ excluded_headers = get_exclude_headers(case)
130
+ if "Authorization" in excluded_headers:
131
+ current_session_auth = session.auth
132
+ session.auth = None
130
133
  close_session = False
131
134
  session.headers = {}
132
135
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: schemathesis
3
- Version: 4.0.15
3
+ Version: 4.0.16
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://github.com/schemathesis/schemathesis/blob/master/CHANGELOG.md
@@ -23,7 +23,7 @@ schemathesis/cli/commands/run/handlers/__init__.py,sha256=TPZ3KdGi8m0fjlN0GjA31M
23
23
  schemathesis/cli/commands/run/handlers/base.py,sha256=yDsTtCiztLksfk7cRzg8JlaAVOfS-zwK3tsJMOXAFyc,530
24
24
  schemathesis/cli/commands/run/handlers/cassettes.py,sha256=rRD4byjp4HXCkJS-zx3jSIFOJsPq77ejPpYeyCtsEZs,19461
25
25
  schemathesis/cli/commands/run/handlers/junitxml.py,sha256=ydk6Ofj-Uti6H8EucT4Snp85cmTA5W7uVpKkoHrIDKE,2586
26
- schemathesis/cli/commands/run/handlers/output.py,sha256=zlI0M5PuzduzluzONv3eyuoWWnigPkErPpUtjgHWESE,62476
26
+ schemathesis/cli/commands/run/handlers/output.py,sha256=oS3HP4idz99IxpZcjsqADtEOkuu8wruTcri5c1YIph0,62986
27
27
  schemathesis/cli/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  schemathesis/cli/ext/fs.py,sha256=3lvoAsEDDdih75ITJJNxemd3nwxX55gGWrI7uDxm0cM,447
29
29
  schemathesis/cli/ext/groups.py,sha256=kQ37t6qeArcKaY2y5VxyK3_KwAkBKCVm58IYV8gewds,2720
@@ -97,7 +97,7 @@ schemathesis/generation/hypothesis/given.py,sha256=sTZR1of6XaHAPWtHx2_WLlZ50M8D5
97
97
  schemathesis/generation/hypothesis/reporting.py,sha256=uDVow6Ya8YFkqQuOqRsjbzsbyP4KKfr3jA7ZaY4FuKY,279
98
98
  schemathesis/generation/hypothesis/strategies.py,sha256=RurE81E06d99YKG48dizy9346ayfNswYTt38zewmGgw,483
99
99
  schemathesis/generation/stateful/__init__.py,sha256=s7jiJEnguIj44IsRyMi8afs-8yjIUuBbzW58bH5CHjs,1042
100
- schemathesis/generation/stateful/state_machine.py,sha256=1cY3AH-f_AbUGfvfK8WMMKkUxAJT9Iw8eZGyRE2Sd44,8740
100
+ schemathesis/generation/stateful/state_machine.py,sha256=3oAGpn46adNJx3sp5ym9e30SyYOjJGiEqenDZ5gWtBY,8803
101
101
  schemathesis/graphql/__init__.py,sha256=_eO6MAPHGgiADVGRntnwtPxmuvk666sAh-FAU4cG9-0,326
102
102
  schemathesis/graphql/checks.py,sha256=IADbxiZjgkBWrC5yzHDtohRABX6zKXk5w_zpWNwdzYo,3186
103
103
  schemathesis/graphql/loaders.py,sha256=2tgG4HIvFmjHLr_KexVXnT8hSBM-dKG_fuXTZgE97So,9445
@@ -154,11 +154,11 @@ schemathesis/specs/openapi/stateful/links.py,sha256=h5q40jUbcIk5DS_Tih1cvFJxS_Qx
154
154
  schemathesis/transport/__init__.py,sha256=6yg_RfV_9L0cpA6qpbH-SL9_3ggtHQji9CZrpIkbA6s,5321
155
155
  schemathesis/transport/asgi.py,sha256=qTClt6oT_xUEWnRHokACN_uqCNNUZrRPT6YG0PjbElY,926
156
156
  schemathesis/transport/prepare.py,sha256=erYXRaxpQokIDzaIuvt_csHcw72iHfCyNq8VNEzXd0o,4743
157
- schemathesis/transport/requests.py,sha256=rziZTrZCVMAqgy6ldB8iTwhkpAsnjKSgK8hj5Sq3ThE,10656
157
+ schemathesis/transport/requests.py,sha256=46aplzhSmBupegPNMawma-iJWCegWkEd6mzdWLTpgM4,10742
158
158
  schemathesis/transport/serialization.py,sha256=igUXKZ_VJ9gV7P0TUc5PDQBJXl_s0kK9T3ljGWWvo6E,10339
159
159
  schemathesis/transport/wsgi.py,sha256=KoAfvu6RJtzyj24VGB8e-Iaa9smpgXJ3VsM8EgAz2tc,6152
160
- schemathesis-4.0.15.dist-info/METADATA,sha256=nQbpPuX0uQ1CRaGdgF7Sor6E9pqtPKFYNHraxONfRdM,8472
161
- schemathesis-4.0.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
- schemathesis-4.0.15.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
- schemathesis-4.0.15.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
- schemathesis-4.0.15.dist-info/RECORD,,
160
+ schemathesis-4.0.16.dist-info/METADATA,sha256=Cy4KK06pQyWGPssr3PsSFtofmnMdsSgSNNjy3LHoxuw,8472
161
+ schemathesis-4.0.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
+ schemathesis-4.0.16.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
+ schemathesis-4.0.16.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
+ schemathesis-4.0.16.dist-info/RECORD,,