Skip to content

Commit

Permalink
fix: Set default User-Agent header in Case.call
Browse files Browse the repository at this point in the history
  • Loading branch information
hebertjulio authored and Stranger6667 committed Oct 2, 2020
1 parent 7847d28 commit edb99f0
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 6 deletions.
5 changes: 5 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Changelog
- New hook to pre-commit, rstcheck, as well as updates to documentation based on rstcheck `#734`_
- New check for maximum response time and corresponding CLI option ``--max-response-time`` `#716`_

**Fixed**

- Default ``User-Agent`` header in ``Case.call``. `#717`_

`2.5.1`_ - 2020-09-30
---------------------

Expand Down Expand Up @@ -1371,6 +1375,7 @@ Deprecated
.. _#734: https://github.com/schemathesis/schemathesis/issues/734
.. _#721: https://github.com/schemathesis/schemathesis/issues/721
.. _#719: https://github.com/schemathesis/schemathesis/issues/719
.. _#717: https://github.com/schemathesis/schemathesis/issues/717
.. _#718: https://github.com/schemathesis/schemathesis/issues/718
.. _#716: https://github.com/schemathesis/schemathesis/issues/716
.. _#708: https://github.com/schemathesis/schemathesis/issues/708
Expand Down
10 changes: 8 additions & 2 deletions src/schemathesis/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from hypothesis.strategies import SearchStrategy
from starlette.testclient import TestClient as ASGIClient

from .constants import USER_AGENT
from .exceptions import InvalidSchema
from .types import Body, Cookies, FormData, Headers, PathParameters, Query
from .utils import GenericResponse, WSGIResponse
Expand Down Expand Up @@ -176,10 +177,13 @@ def call(
close_session = True
else:
close_session = False

data = self.as_requests_kwargs(base_url)
data["headers"] = data["headers"] or {}
data["headers"] = data["headers"].copy()
if headers is not None:
data["headers"] = {**(data["headers"] or {}), **headers}
data["headers"].update(headers)
if "User-Agent" not in data["headers"]:
data["headers"]["User-Agent"] = USER_AGENT
data.update(kwargs)
response = session.request(**data) # type: ignore
if close_session:
Expand Down Expand Up @@ -224,6 +228,8 @@ def call_wsgi(self, app: Any = None, headers: Optional[Dict[str, str]] = None, *
"Please, set `app` argument in the schema constructor or pass it to `call_wsgi`"
)
data = self.as_werkzeug_kwargs(headers)
if "User-Agent" not in data["headers"]:
data["headers"]["User-Agent"] = USER_AGENT
client = werkzeug.Client(application, WSGIResponse)
with cookie_handler(client, self.cookies):
response = client.open(**data, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion src/schemathesis/specs/graphql/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
class GraphQLCase(Case):
def as_requests_kwargs(self, base_url: Optional[str] = None) -> Dict[str, Any]:
base_url = self._get_base_url(base_url)
return {"method": self.method, "url": base_url, "json": {"query": self.body}}
return {"method": self.method, "url": base_url, "json": {"query": self.body}, "headers": self.headers}

def as_werkzeug_kwargs(self, headers: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
final_headers = self.headers.copy() if self.headers is not None else {}
Expand Down
5 changes: 4 additions & 1 deletion test/cli/test_cassettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from urllib3._collections import HTTPHeaderDict

from schemathesis.cli.cassettes import filter_cassette, get_command_representation, get_prepared_request
from schemathesis.constants import USER_AGENT
from schemathesis.models import Request


Expand Down Expand Up @@ -153,14 +154,16 @@ async def test_replay(openapi_version, cli, schema_url, app, reset_app, cassette


def test_multiple_cookies(base_url):
response = requests.get(f"{base_url}/success", cookies={"foo": "bar", "baz": "spam"})
headers = {"User-Agent": USER_AGENT}
response = requests.get(f"{base_url}/success", cookies={"foo": "bar", "baz": "spam"}, headers=headers)
request = Request.from_prepared_request(response.request)
serialized = {
"uri": request.uri,
"method": request.method,
"headers": request.headers,
"body": {"encoding": "utf-8", "base64_string": request.body},
}
assert USER_AGENT in serialized["headers"]["User-Agent"]
prepared = get_prepared_request(serialized)
compare_headers(prepared, serialized["headers"])

Expand Down
4 changes: 2 additions & 2 deletions test/runner/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,10 @@ def test_custom_loader(swagger_20, openapi2_base_url):
@pytest.mark.endpoints("failure")
def test_reproduce_code_with_overridden_headers(args, openapi3_base_url):
app, kwargs = args
headers = {"User-Agent": USER_AGENT, "X-Token": "test"}

*_, after, finished = prepare(**kwargs, headers={"X-Token": "test"}, hypothesis_max_examples=1)
*_, after, finished = prepare(**kwargs, headers=headers, hypothesis_max_examples=1)
assert finished.has_failures
headers = {"X-Token": "test", "User-Agent": USER_AGENT}
if isinstance(app, Flask):
expected = f"requests.get('http://localhost/api/failure', headers={headers})"
else:
Expand Down

0 comments on commit edb99f0

Please sign in to comment.