Skip to content

Commit d5f9c38

Browse files
committed
Support subdomains when testing
Subdomains are supported in the Flask API and required if a user wants to test routes that have a defined subdomain.
1 parent 527f29d commit d5f9c38

4 files changed

Lines changed: 30 additions & 10 deletions

File tree

src/quart/app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,7 @@ def test_request_context(
14851485
http_version: str = "1.1",
14861486
scope_base: Optional[dict] = None,
14871487
auth: Optional[Union[Authorization, Tuple[str, str]]] = None,
1488+
subdomain: Optional[str] = None,
14881489
) -> RequestContext:
14891490
"""Create a request context for testing purposes.
14901491
@@ -1511,6 +1512,7 @@ def test_request_context(
15111512
headers,
15121513
query_string,
15131514
auth,
1515+
subdomain,
15141516
)
15151517
request_body, body_headers = make_test_body_with_headers(data=data, form=form, json=json)
15161518
headers.update(**body_headers)

src/quart/testing/client.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ async def open(
9393
http_version: str = "1.1",
9494
scope_base: Optional[dict] = None,
9595
auth: Optional[Union[Authorization, Tuple[str, str]]] = None,
96+
subdomain: Optional[str] = None,
9697
) -> Response:
9798
self.push_promises = []
9899
response = await self._make_request(
@@ -109,6 +110,7 @@ async def open(
109110
http_version,
110111
scope_base,
111112
auth,
113+
subdomain,
112114
)
113115
if follow_redirects:
114116
while response.status_code >= 300 and response.status_code <= 399:
@@ -131,6 +133,7 @@ async def open(
131133
http_version,
132134
scope_base,
133135
auth,
136+
subdomain,
134137
)
135138
if self.preserve_context:
136139
_cv_request.set(self.app._preserved_context) # type: ignore
@@ -148,13 +151,15 @@ def request(
148151
http_version: str = "1.1",
149152
scope_base: Optional[dict] = None,
150153
auth: Optional[Union[Authorization, Tuple[str, str]]] = None,
154+
subdomain: Optional[str] = None,
151155
) -> TestHTTPConnectionProtocol:
152156
headers, path, query_string_bytes = make_test_headers_path_and_query_string(
153157
self.app,
154158
path,
155159
headers,
156160
query_string,
157161
auth,
162+
subdomain,
158163
)
159164
if self.cookie_jar is not None:
160165
for cookie in self.cookie_jar:
@@ -185,13 +190,15 @@ def websocket(
185190
http_version: str = "1.1",
186191
scope_base: Optional[dict] = None,
187192
auth: Optional[Union[Authorization, Tuple[str, str]]] = None,
193+
subdomain: Optional[str] = None,
188194
) -> TestWebsocketConnectionProtocol:
189195
headers, path, query_string_bytes = make_test_headers_path_and_query_string(
190196
self.app,
191197
path,
192198
headers,
193199
query_string,
194200
auth,
201+
subdomain,
195202
)
196203
if self.cookie_jar is not None:
197204
for cookie in self.cookie_jar:
@@ -409,9 +416,10 @@ async def _make_request(
409416
http_version: str,
410417
scope_base: Optional[dict],
411418
auth: Optional[Union[Authorization, Tuple[str, str]]] = None,
419+
subdomain: Optional[str] = None,
412420
) -> Response:
413421
headers, path, query_string_bytes = make_test_headers_path_and_query_string(
414-
self.app, path, headers, query_string, auth
422+
self.app, path, headers, query_string, auth, subdomain
415423
)
416424
request_data, body_headers = make_test_body_with_headers(
417425
data=data, form=form, files=files, json=json, app=self.app

src/quart/testing/utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def make_test_headers_path_and_query_string(
2929
headers: Optional[Union[dict, Headers]] = None,
3030
query_string: Optional[dict] = None,
3131
auth: Optional[Union[Authorization, Tuple[str, str]]] = None,
32+
subdomain: Optional[str] = None,
3233
) -> Tuple[Headers, str, bytes]:
3334
"""Make the headers and path with defaults for testing.
3435
@@ -54,7 +55,10 @@ def make_test_headers_path_and_query_string(
5455
headers.setdefault("Authorization", auth.to_header())
5556

5657
headers.setdefault("User-Agent", "Quart")
57-
headers.setdefault("host", app.config["SERVER_NAME"] or "localhost")
58+
host = app.config["SERVER_NAME"] or "localhost"
59+
if subdomain is not None:
60+
host = f"{subdomain}.{host}"
61+
headers.setdefault("host", host)
5862
if "?" in path and query_string is not None:
5963
raise ValueError("Query string is defined in the path and as an argument")
6064
if query_string is None:

tests/test_testing.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,29 @@ async def echo() -> str:
3636

3737

3838
@pytest.mark.parametrize(
39-
"path, query_string, expected_path, expected_query_string",
39+
"path, query_string, subdomain, expected_path, expected_query_string, expected_host",
4040
[
41-
("/path", {"a": "b"}, "/path", b"a=b"),
42-
("/path", {"a": ["b", "c"]}, "/path", b"a=b&a=c"),
43-
("/path?b=c", None, "/path", b"b=c"),
44-
("/path%20", None, "/path ", b""),
41+
("/path", {"a": "b"}, None, "/path", b"a=b", "localhost"),
42+
("/path", {"a": ["b", "c"]}, None, "/path", b"a=b&a=c", "localhost"),
43+
("/path?b=c", None, None, "/path", b"b=c", "localhost"),
44+
("/path%20", None, None, "/path ", b"", "localhost"),
45+
("/path", None, "api", "/path", b"", "api.localhost"),
4546
],
4647
)
4748
def test_build_headers_path_and_query_string(
48-
path: str, query_string: Optional[dict], expected_path: str, expected_query_string: bytes
49+
path: str,
50+
query_string: Optional[dict],
51+
subdomain: Optional[str],
52+
expected_path: str,
53+
expected_query_string: bytes,
54+
expected_host: str,
4955
) -> None:
5056
headers, result_path, result_qs = make_test_headers_path_and_query_string(
51-
Quart(__name__), path, None, query_string
57+
Quart(__name__), path, None, query_string, None, subdomain
5258
)
5359
assert result_path == expected_path
5460
assert headers["User-Agent"] == "Quart"
55-
assert headers["host"] == "localhost"
61+
assert headers["host"] == expected_host
5662
assert result_qs == expected_query_string
5763

5864

0 commit comments

Comments
 (0)