This is an automated email from the ASF dual-hosted git repository.

aminghadersohi pushed a commit to branch work-pr-39604
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 9e4bf60cb459f31171a314eea90686de338931e9
Author: Amin Ghadersohi <[email protected]>
AuthorDate: Wed May 13 19:57:41 2026 +0000

    refactor(mcp): extract duplicated app context + sm setup into helper
    
    Add _mock_sm_ctx() context manager to eliminate repeated boilerplate
    (g.user = None / app.appbuilder = MagicMock() / appbuilder.sm = mock_sm)
    across seven API key auth unit tests.
---
 tests/unit_tests/mcp_service/test_auth_api_key.py | 59 ++++++++---------------
 1 file changed, 19 insertions(+), 40 deletions(-)

diff --git a/tests/unit_tests/mcp_service/test_auth_api_key.py 
b/tests/unit_tests/mcp_service/test_auth_api_key.py
index 546f789d498..ab74cb2236b 100644
--- a/tests/unit_tests/mcp_service/test_auth_api_key.py
+++ b/tests/unit_tests/mcp_service/test_auth_api_key.py
@@ -24,6 +24,7 @@ The streamable-http transport does not push a Flask request 
context, so
 """
 
 from collections.abc import Generator
+from contextlib import contextmanager
 from unittest.mock import MagicMock, patch
 
 import pytest
@@ -82,6 +83,16 @@ def _disable_api_keys(app: SupersetApp) -> Generator[None, 
None, None]:
         app.config["MCP_DEV_USERNAME"] = old_dev
 
 
+@contextmanager
+def _mock_sm_ctx(app: SupersetApp, mock_sm: MagicMock):
+    """Push an app context with g.user cleared and appbuilder.sm mocked."""
+    with app.app_context():
+        g.user = None
+        app.appbuilder = MagicMock()
+        app.appbuilder.sm = mock_sm
+        yield
+
+
 # -- Valid API key -> user loaded --
 
 
@@ -91,11 +102,7 @@ def test_valid_api_key_returns_user(app: SupersetApp, 
mock_user: MagicMock) -> N
     mock_sm = MagicMock()
     mock_sm.validate_api_key.return_value = mock_user
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with (
             _patch_access_token(_passthrough_access_token("sst_abc123")),
             patch(
@@ -124,11 +131,7 @@ def test_invalid_api_key_raises(app: SupersetApp) -> None:
     # mask the rejection.
     app.config["MCP_DEV_USERNAME"] = "admin"
     try:
-        with app.app_context():
-            g.user = None
-            app.appbuilder = MagicMock()
-            app.appbuilder.sm = mock_sm
-
+        with _mock_sm_ctx(app, mock_sm):
             with _patch_access_token(_passthrough_access_token("sst_bad_key")):
                 with pytest.raises(PermissionError, match="Invalid or expired 
API key"):
                     get_user_from_request()
@@ -145,11 +148,7 @@ def test_api_key_disabled_skips_auth(app: SupersetApp) -> 
None:
     even if an AccessToken is present."""
     mock_sm = MagicMock()
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with _patch_access_token(_passthrough_access_token("sst_abc123")):
             with pytest.raises(ValueError, match="No authenticated user 
found"):
                 get_user_from_request()
@@ -166,11 +165,7 @@ def test_no_access_token_skips_api_key_auth(app: 
SupersetApp) -> None:
     auth provider installed), API key auth is skipped."""
     mock_sm = MagicMock()
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with _patch_access_token(None):
             with pytest.raises(ValueError, match="No authenticated user 
found"):
                 get_user_from_request()
@@ -204,11 +199,7 @@ def test_fab_without_validate_method_raises(app: 
SupersetApp) -> None:
     PermissionError about unavailable validation."""
     mock_sm = MagicMock(spec=[])  # empty spec = no attributes
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with _patch_access_token(_passthrough_access_token("sst_abc123")):
             with pytest.raises(
                 PermissionError, match="API key validation is not available"
@@ -228,11 +219,7 @@ def test_relationship_reload_failure_returns_original_user(
     mock_sm = MagicMock()
     mock_sm.validate_api_key.return_value = mock_user
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with (
             _patch_access_token(_passthrough_access_token("sst_abc123")),
             patch(
@@ -259,11 +246,7 @@ def test_jwt_access_token_skips_api_key_auth(app: 
SupersetApp) -> None:
     jwt_access_token.token = "eyJhbGciOiJIUzI1NiJ9.not-an-api-key"  # noqa: 
S105
     jwt_access_token.claims = {"sub": "alice"}
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with _patch_access_token(jwt_access_token):
             # _resolve_user_from_jwt_context will try to resolve the user
             # from the JWT claims and (in this isolated unit-test setup)
@@ -313,11 +296,7 @@ def 
test_unnamespaced_passthrough_claim_does_not_trigger_api_key_path(
     rogue_token.token = "eyJhbGciOiJSUzI1NiJ9.rogue_jwt"  # noqa: S105
     rogue_token.claims = {"_api_key_passthrough": True, "sub": "alice"}
 
-    with app.app_context():
-        g.user = None
-        app.appbuilder = MagicMock()
-        app.appbuilder.sm = mock_sm
-
+    with _mock_sm_ctx(app, mock_sm):
         with _patch_access_token(rogue_token):
             # JWT path tries to resolve user "alice" from DB and (in this
             # isolated unit-test setup) raises ValueError. The assertion

Reply via email to