1
+ import importlib
1
2
import json
2
3
import threading
3
4
from unittest import mock
13
14
from sentry_sdk .integrations .logging import LoggingIntegration
14
15
import sentry_sdk .integrations .quart as quart_sentry
15
16
16
- from quart import Quart , Response , abort , stream_with_context
17
- from quart .views import View
18
17
19
- from quart_auth import AuthUser , login_user
20
-
21
- try :
22
- from quart_auth import QuartAuth
18
+ def quart_app_factory ():
19
+ # These imports are inlined because the `test_quart_flask_patch` testcase
20
+ # tests behavior that is triggered by importing a package before any Quart
21
+ # imports happen, so we can't have these on the module level
22
+ from quart import Quart
23
23
24
- auth_manager = QuartAuth ()
25
- except ImportError :
26
- from quart_auth import AuthManager
24
+ try :
25
+ from quart_auth import QuartAuth
27
26
28
- auth_manager = AuthManager ()
27
+ auth_manager = QuartAuth ()
28
+ except ImportError :
29
+ from quart_auth import AuthManager
29
30
31
+ auth_manager = AuthManager ()
30
32
31
- def quart_app_factory ():
32
33
app = Quart (__name__ )
33
34
app .debug = False
34
35
app .config ["TESTING" ] = False
@@ -71,6 +72,42 @@ def integration_enabled_params(request):
71
72
raise ValueError (request .param )
72
73
73
74
75
+ @pytest .mark .asyncio
76
+ @pytest .mark .forked
77
+ @pytest .mark .skipif (
78
+ not importlib .util .find_spec ("quart_flask_patch" ),
79
+ reason = "requires quart_flask_patch" ,
80
+ )
81
+ async def test_quart_flask_patch (sentry_init , capture_events , reset_integrations ):
82
+ # This testcase is forked because `import quart_flask_patch` needs to run
83
+ # before anything else Quart-related is imported (since it monkeypatches
84
+ # some things) and we don't want this to affect other testcases.
85
+ #
86
+ # It's also important this testcase be run before any other testcase
87
+ # that uses `quart_app_factory`.
88
+ import quart_flask_patch # noqa: F401
89
+
90
+ app = quart_app_factory ()
91
+ sentry_init (
92
+ integrations = [quart_sentry .QuartIntegration ()],
93
+ )
94
+
95
+ @app .route ("/" )
96
+ async def index ():
97
+ 1 / 0
98
+
99
+ events = capture_events ()
100
+
101
+ client = app .test_client ()
102
+ try :
103
+ await client .get ("/" )
104
+ except ZeroDivisionError :
105
+ pass
106
+
107
+ (event ,) = events
108
+ assert event ["exception" ]["values" ][0 ]["mechanism" ]["type" ] == "quart"
109
+
110
+
74
111
@pytest .mark .asyncio
75
112
async def test_has_context (sentry_init , capture_events ):
76
113
sentry_init (integrations = [quart_sentry .QuartIntegration ()])
@@ -213,6 +250,8 @@ async def test_quart_auth_configured(
213
250
monkeypatch ,
214
251
integration_enabled_params ,
215
252
):
253
+ from quart_auth import AuthUser , login_user
254
+
216
255
sentry_init (send_default_pii = send_default_pii , ** integration_enabled_params )
217
256
app = quart_app_factory ()
218
257
@@ -368,6 +407,8 @@ async def error_handler(err):
368
407
369
408
@pytest .mark .asyncio
370
409
async def test_bad_request_not_captured (sentry_init , capture_events ):
410
+ from quart import abort
411
+
371
412
sentry_init (integrations = [quart_sentry .QuartIntegration ()])
372
413
app = quart_app_factory ()
373
414
events = capture_events ()
@@ -385,6 +426,8 @@ async def index():
385
426
386
427
@pytest .mark .asyncio
387
428
async def test_does_not_leak_scope (sentry_init , capture_events ):
429
+ from quart import Response , stream_with_context
430
+
388
431
sentry_init (integrations = [quart_sentry .QuartIntegration ()])
389
432
app = quart_app_factory ()
390
433
events = capture_events ()
@@ -514,6 +557,8 @@ async def error():
514
557
515
558
@pytest .mark .asyncio
516
559
async def test_class_based_views (sentry_init , capture_events ):
560
+ from quart .views import View
561
+
517
562
sentry_init (integrations = [quart_sentry .QuartIntegration ()])
518
563
app = quart_app_factory ()
519
564
events = capture_events ()
0 commit comments