|
8 | 8 | from slack_sdk.signature import SignatureVerifier |
9 | 9 | from slack_sdk.web.async_client import AsyncWebClient |
10 | 10 |
|
| 11 | +from slack_bolt import BoltResponse |
11 | 12 | from slack_bolt.app.async_app import AsyncApp |
12 | 13 | from slack_bolt.oauth.async_oauth_settings import AsyncOAuthSettings |
13 | 14 | from tests.mock_web_api_server import ( |
|
20 | 21 | pytestmark = pytest.mark.skipif(sys.version_info < (3, 9), reason="Quart requires Python 3.9+") |
21 | 22 |
|
22 | 23 | if sys.version_info >= (3, 9): |
23 | | - from slack_bolt.adapter.quart.async_handler import AsyncSlackRequestHandler |
| 24 | + from slack_bolt.adapter.quart.async_handler import AsyncSlackRequestHandler, to_quart_response |
24 | 25 | from quart import Quart, request |
25 | 26 |
|
26 | 27 |
|
@@ -275,6 +276,64 @@ async def test_url_verification(self): |
275 | 276 | assert json.loads(await response.get_data(as_text=True)) == {"challenge": input["challenge"]} |
276 | 277 | assert_auth_test_count(self, 0) |
277 | 278 |
|
| 279 | + @pytest.mark.asyncio |
| 280 | + async def test_to_quart_response_preserves_multi_value_headers_and_content_type(self): |
| 281 | + api = Quart(__name__) |
| 282 | + async with api.app_context(): |
| 283 | + response = await to_quart_response( |
| 284 | + BoltResponse( |
| 285 | + status=201, |
| 286 | + body="created", |
| 287 | + headers={ |
| 288 | + "content-type": "application/custom", |
| 289 | + "x-bolt-test": ["one", "two"], |
| 290 | + }, |
| 291 | + ) |
| 292 | + ) |
| 293 | + |
| 294 | + assert response.status_code == 201 |
| 295 | + assert await response.get_data(as_text=True) == "created" |
| 296 | + assert response.headers.get("content-type") == "application/custom" |
| 297 | + assert response.headers.getlist("x-bolt-test") == ["one", "two"] |
| 298 | + |
| 299 | + @pytest.mark.asyncio |
| 300 | + async def test_to_quart_response_preserves_cookie_attributes(self): |
| 301 | + api = Quart(__name__) |
| 302 | + async with api.app_context(): |
| 303 | + response = await to_quart_response( |
| 304 | + BoltResponse( |
| 305 | + status=200, |
| 306 | + body="", |
| 307 | + headers={ |
| 308 | + "set-cookie": [ |
| 309 | + "session=abc; Max-Age=60; Path=/install; Domain=example.com", |
| 310 | + "bare=xyz", |
| 311 | + ], |
| 312 | + }, |
| 313 | + ) |
| 314 | + ) |
| 315 | + |
| 316 | + set_cookie_headers = response.headers.getlist("set-cookie") |
| 317 | + assert len(set_cookie_headers) == 2 |
| 318 | + |
| 319 | + session_cookie = set_cookie_headers[0] |
| 320 | + assert "session=abc" in session_cookie |
| 321 | + assert "Domain=example.com" in session_cookie |
| 322 | + assert "Max-Age=60" in session_cookie |
| 323 | + assert "Path=/install" in session_cookie |
| 324 | + assert "Secure" in session_cookie |
| 325 | + assert "HttpOnly" in session_cookie |
| 326 | + assert "Expires=;" not in session_cookie |
| 327 | + |
| 328 | + bare_cookie = set_cookie_headers[1] |
| 329 | + assert "bare=xyz" in bare_cookie |
| 330 | + assert "Secure" in bare_cookie |
| 331 | + assert "HttpOnly" in bare_cookie |
| 332 | + assert "Domain=" not in bare_cookie |
| 333 | + assert "Expires=" not in bare_cookie |
| 334 | + assert "Max-Age=" not in bare_cookie |
| 335 | + assert "Path=" not in bare_cookie |
| 336 | + |
278 | 337 | @pytest.mark.asyncio |
279 | 338 | async def test_not_found(self): |
280 | 339 | app = self.build_app() |
|
0 commit comments