From eeaa8088a1a97422b9c95d2ca463b6ef40c798c8 Mon Sep 17 00:00:00 2001 From: Tal Rostoker Date: Wed, 2 Sep 2026 15:45:52 +0300 Subject: [PATCH 1/3] dd proxy authentication mode with mock token --- src/fabric_cli/commands/auth/fab_auth.py | 26 +++ src/fabric_cli/core/fab_auth.py | 31 ++++ src/fabric_cli/errors/auth.py | 14 ++ tests/conftest.py | 1 + tests/test_commands/test_auth.py | 76 +++++++++ tests/test_core/test_fab_api_client.py | 45 +++++ tests/test_core/test_fab_auth.py | 161 ++++++++++++++++++ .../test_fab_msal_bridge_azure_cli.py | 13 ++ 8 files changed, 367 insertions(+) diff --git a/src/fabric_cli/commands/auth/fab_auth.py b/src/fabric_cli/commands/auth/fab_auth.py index ca0a2be8..2fb73320 100644 --- a/src/fabric_cli/commands/auth/fab_auth.py +++ b/src/fabric_cli/commands/auth/fab_auth.py @@ -14,6 +14,17 @@ def init(args: Namespace) -> Any: + if FabAuth().is_proxy_auth_mode(): + fab_ui.print_output_error( + FabricCLIError( + ErrorMessages.Auth.login_not_available_in_proxy_mode(), + fab_constant.ERROR_AUTHENTICATION_FAILED, + ), + command=args.command, + output_format_type=args.output_format, + ) + return + auth_options = [ "Interactive with a web browser", "Azure CLI (existing 'az login' session)", @@ -209,6 +220,17 @@ def init(args: Namespace) -> Any: def logout(args: Namespace) -> None: + if FabAuth().is_proxy_auth_mode(): + fab_ui.print_output_error( + FabricCLIError( + ErrorMessages.Auth.logout_not_available_in_proxy_mode(), + fab_constant.ERROR_AUTHENTICATION_FAILED, + ), + command=args.command, + output_format_type=args.output_format, + ) + return + FabAuth().logout() # Clear cache and context including current and stale context files @@ -220,6 +242,10 @@ def logout(args: Namespace) -> None: def status(args: Namespace) -> None: auth = FabAuth() + if auth.is_proxy_auth_mode(): + fab_ui.print_output_format(args, data="proxy authentication mode") + return + identity_type = auth.get_identity_type() tenant_id = auth.get_tenant_id() diff --git a/src/fabric_cli/core/fab_auth.py b/src/fabric_cli/core/fab_auth.py index bf8ee275..ae5701d4 100644 --- a/src/fabric_cli/core/fab_auth.py +++ b/src/fabric_cli/core/fab_auth.py @@ -28,6 +28,17 @@ from fabric_cli.errors import ErrorMessages from fabric_cli.utils import fab_ui as utils_ui +_PROXY_AUTH_ENVIRONMENT_VARIABLE = "FAB_PROXY_AUTH_ENABLED" +_PROXY_AUTH_PLACEHOLDER_TOKEN = "mockToken" +_PROXY_AUTH_EXPIRES_ON = 9999999999 + + +def _is_proxy_auth_placeholder(token: Any) -> bool: + return token in ( + _PROXY_AUTH_PLACEHOLDER_TOKEN, + _PROXY_AUTH_PLACEHOLDER_TOKEN.encode(), + ) + def singleton(class_): instances = {} @@ -128,6 +139,9 @@ def _validate_environment_variables(self): ) def _load_env(self): + if self.is_proxy_auth_mode(): + return + # Validate the environment variables self._validate_environment_variables() @@ -328,6 +342,14 @@ def get_tenant_id(self): def get_identity_type(self): return self._get_auth_property(con.IDENTITY_TYPE) + @staticmethod + def is_proxy_auth_mode() -> bool: + """Return whether proxy authentication mode is enabled.""" + return os.environ.get(_PROXY_AUTH_ENVIRONMENT_VARIABLE, "").lower() in ( + "true", + "1", + ) + def set_access_mode(self, mode, tenant_id=None): if mode not in con.AUTH_KEYS[con.IDENTITY_TYPE]: raise FabricCLIError( @@ -525,6 +547,12 @@ def acquire_token(self, scope: list[str], interactive_renew=True) -> dict: from fabric_cli.utils.fab_secure_io import restrict_existing_file try: + if self.is_proxy_auth_mode(): + return { + "access_token": _PROXY_AUTH_PLACEHOLDER_TOKEN, + "expires_on": _PROXY_AUTH_EXPIRES_ON, + } + token = None env_var_token = self._get_access_token_from_env_vars_if_exist(scope) identity_type = self.get_identity_type() @@ -677,6 +705,9 @@ def _fetch_public_key_from_aad(self, token): return key def _decode_jwt_token(self, token, expected_audience=None): + if self.is_proxy_auth_mode() and _is_proxy_auth_placeholder(token): + return {} + decode_options = {"verify_aud": expected_audience is not None} # Try using the cached public key if available if self.aad_public_key is not None: diff --git a/src/fabric_cli/errors/auth.py b/src/fabric_cli/errors/auth.py index 52640f6a..c910c14c 100644 --- a/src/fabric_cli/errors/auth.py +++ b/src/fabric_cli/errors/auth.py @@ -120,6 +120,20 @@ def cert_read_failed(error: str) -> str: def only_supported_with_user_authentication() -> str: return "This operation is only supported with user authentication" + @staticmethod + def login_not_available_in_proxy_mode() -> str: + return ( + "Authentication login is not available in proxy authentication mode. " + "Unset FAB_PROXY_AUTH_ENABLED to manage CLI authentication" + ) + + @staticmethod + def logout_not_available_in_proxy_mode() -> str: + return ( + "Authentication logout is not available in proxy authentication mode. " + "Unset FAB_PROXY_AUTH_ENABLED to manage CLI authentication" + ) + @staticmethod def azure_cli_not_available() -> str: return ( diff --git a/tests/conftest.py b/tests/conftest.py index 176b8035..54b49958 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -101,6 +101,7 @@ def azure_cli_auth_fixture(monkeypatch, tmp_path): "fabric_cli.core.fab_state_config.config_location", lambda: str(tmp_path) ) for variable in ( + "FAB_PROXY_AUTH_ENABLED", "FAB_TOKEN", "FAB_TOKEN_ONELAKE", "FAB_TOKEN_AZURE", diff --git a/tests/test_commands/test_auth.py b/tests/test_commands/test_auth.py index f4208cc3..fcaae771 100644 --- a/tests/test_commands/test_auth.py +++ b/tests/test_commands/test_auth.py @@ -912,6 +912,68 @@ def test_auth_logout( mock_print_done.assert_called_once() + def test_auth_login_proxy_auth_mode_has_no_side_effects(self, mock_fab_auth): + args = prepare_auth_args() + auth = mock_fab_auth["instance"] + auth.is_proxy_auth_mode.return_value = True + + with ( + patch( + "fabric_cli.commands.auth.fab_auth.utils_mem_store.clear_caches" + ) as clear_caches, + patch( + "fabric_cli.commands.auth.fab_auth.fab_ui.prompt_select_item" + ) as prompt_select_item, + patch( + "fabric_cli.commands.auth.fab_auth.fab_ui.print_output_error" + ) as print_error, + ): + result = fab_auth.init(args) + + assert result is None + error = print_error.call_args.args[0] + assert error.status_code == fab_constant.ERROR_AUTHENTICATION_FAILED + assert error.message == ErrorMessages.Auth.login_not_available_in_proxy_mode() + print_error.assert_called_once_with( + error, + command=args.command, + output_format_type=args.output_format, + ) + assert_fab_auth_not_called(mock_fab_auth) + clear_caches.assert_not_called() + prompt_select_item.assert_not_called() + + def test_auth_logout_proxy_auth_mode_has_no_side_effects( + self, mock_fab_auth, mock_fab_context + ): + args = argparse.Namespace(command="auth", output_format="text") + auth = mock_fab_auth["instance"] + auth.is_proxy_auth_mode.return_value = True + context = mock_fab_context["instance"] + + with ( + patch( + "fabric_cli.commands.auth.fab_auth.utils_mem_store.clear_caches" + ) as clear_caches, + patch( + "fabric_cli.commands.auth.fab_auth.fab_ui.print_output_error" + ) as print_error, + ): + result = fab_auth.logout(args) + + assert result is None + error = print_error.call_args.args[0] + assert error.status_code == fab_constant.ERROR_AUTHENTICATION_FAILED + assert error.message == ErrorMessages.Auth.logout_not_available_in_proxy_mode() + print_error.assert_called_once_with( + error, + command="auth", + output_format_type="text", + ) + auth.logout.assert_not_called() + clear_caches.assert_not_called() + context.reset_context.assert_not_called() + def test_auth_status(self, mock_fab_auth, capsys): # Arrange args = argparse.Namespace( @@ -945,6 +1007,19 @@ def test_auth_status(self, mock_fab_auth, capsys): assert "Token Storage: mock************************************" in captured.out assert "Token Azure: mock************************************" in captured.out + def test_auth_status_proxy_auth_mode(self, monkeypatch, capsys): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + args = argparse.Namespace( + command="auth", + auth_subcommand="status", + output_format="text", + ) + fab_auth.status(args) + + captured = capsys.readouterr() + assert captured.out.strip() == "proxy authentication mode" + assert captured.err == "" + def test_auth_status_azure_cli_session_available(self, mock_fab_auth, capsys): args = argparse.Namespace( command="auth", @@ -1217,6 +1292,7 @@ def mock_fab_auth(): set_spn=MagicMock(), set_managed_identity=MagicMock(), logout=MagicMock(), + is_proxy_auth_mode=MagicMock(return_value=False), # add more methods if needed ) as mocks: # mocks is a dictionary containing the mock objects for each method diff --git a/tests/test_core/test_fab_api_client.py b/tests/test_core/test_fab_api_client.py index 2b16c07f..caca524d 100644 --- a/tests/test_core/test_fab_api_client.py +++ b/tests/test_core/test_fab_api_client.py @@ -345,6 +345,51 @@ def __init__(self, status_code, headers=None, text=""): mock_sleep.assert_called_once_with(10) +@pytest.mark.parametrize("audience", [None, "storage", "azure"]) +def test_do_request_proxy_auth_mode_sends_placeholder_header(monkeypatch, audience): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + monkeypatch.delenv("FAB_TOKEN", raising=False) + monkeypatch.delenv("FAB_TOKEN_ONELAKE", raising=False) + monkeypatch.delenv("FAB_TOKEN_AZURE", raising=False) + + auth = FabAuth() + auth._auth_info = {} + monkeypatch.setattr( + auth, + "_get_app", + lambda: pytest.fail("Proxy authentication must not initialize MSAL"), + ) + monkeypatch.setattr( + auth, + "_decode_jwt_token", + lambda token, expected_audience=None: pytest.fail( + "Proxy authentication must not decode the placeholder token" + ), + ) + + class DummyResponse: + status_code = 200 + text = "{}" + content = b"{}" + headers = {} + + dummy_args = Namespace( + uri="items", + method="get", + audience=audience, + headers=None, + wait=False, + raw_response=True, + request_params={}, + json_file=None, + ) + + with patch("requests.Session.request", return_value=DummyResponse()) as request: + do_request(dummy_args) + + assert request.call_args.kwargs["headers"]["Authorization"] == "Bearer mockToken" + + @pytest.mark.parametrize( "host_app_env, host_app_version_env, expected_suffix", [ diff --git a/tests/test_core/test_fab_auth.py b/tests/test_core/test_fab_auth.py index b4f0bc73..83cf4b8f 100644 --- a/tests/test_core/test_fab_auth.py +++ b/tests/test_core/test_fab_auth.py @@ -30,6 +30,13 @@ def temp_dir_fixture(monkeypatch, tmp_path): monkeypatch.setattr( "fabric_cli.core.fab_state_config.config_location", lambda: str(tmp_path) ) + auth = FabAuth() + monkeypatch.setattr(auth, "auth_file", str(tmp_path / "auth.json")) + monkeypatch.setattr(auth, "cache_file", str(tmp_path / "cache.bin")) + monkeypatch.setattr(auth, "_auth_info", {}) + monkeypatch.setattr(auth, "app", None) + monkeypatch.setattr(auth, "_azure_cli_credential", None) + monkeypatch.setattr(auth, "aad_public_key", None) return str(tmp_path) @@ -40,6 +47,7 @@ def temp_dir_fixture(monkeypatch, tmp_path): def _clear_environment_variables(monkeypatch): + monkeypatch.delenv("FAB_PROXY_AUTH_ENABLED", raising=False) monkeypatch.delenv("FAB_TENANT_ID", raising=False) monkeypatch.delenv("FAB_SPN_CLIENT_ID", raising=False) monkeypatch.delenv("FAB_SPN_CLIENT_SECRET", raising=False) @@ -488,6 +496,68 @@ def test_validate_jwt_token_empty(): assert e.value.message == "Invalid JWT token" +@pytest.mark.parametrize("value", ["true", "TRUE", "1"]) +def test_proxy_auth_mode_enabled(monkeypatch, value): + auth = FabAuth() + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", value) + + assert auth.is_proxy_auth_mode() is True + + +@pytest.mark.parametrize("value", ["", "false", "0", "yes"]) +def test_proxy_auth_mode_disabled(monkeypatch, value): + auth = FabAuth() + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", value) + + assert auth.is_proxy_auth_mode() is False + + +def test_proxy_auth_mode_not_enabled_by_placeholder_tokens(monkeypatch): + auth = FabAuth() + monkeypatch.setenv("FAB_TOKEN", "mockToken") + monkeypatch.setenv("FAB_TOKEN_ONELAKE", "mockToken") + monkeypatch.setenv("FAB_TOKEN_AZURE", "mockToken") + + assert auth.is_proxy_auth_mode() is False + + +def test_proxy_auth_mode_skips_other_auth_environment(monkeypatch): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + monkeypatch.setenv("FAB_SPN_CLIENT_ID", "not-a-guid") + auth = FabAuth() + monkeypatch.setattr( + auth, + "_validate_environment_variables", + lambda: pytest.fail("Other authentication variables must be ignored"), + ) + + auth._load_env() + + +@pytest.mark.parametrize("token", ["mockToken", b"mockToken"]) +def test_decode_jwt_token_proxy_auth_mode(monkeypatch, token): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + auth = FabAuth() + + monkeypatch.setattr( + auth, + "_fetch_public_key_from_aad", + lambda token: pytest.fail("Proxy authentication must not fetch a public key"), + ) + + assert auth._decode_jwt_token(token) == {} + + +def test_get_claims_from_token_proxy_auth_mode(monkeypatch): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + auth = FabAuth() + + assert ( + auth._get_claims_from_token(b"mockToken", ["upn", "oid", "tid", "appid"]) + is None + ) + + def test_decode_jwt_token_with_cached_key_success(monkeypatch): auth = FabAuth() # Set a valid cached key @@ -815,6 +885,97 @@ def test_get_access_token_env_var(monkeypatch): assert token == "env_token" +@pytest.mark.parametrize( + "scope", + [ + con.SCOPE_FABRIC_DEFAULT, + con.SCOPE_ONELAKE_DEFAULT, + con.SCOPE_AZURE_DEFAULT, + ["https://example.com/.default"], + ], +) +def test_get_access_token_proxy_auth_mode(monkeypatch, scope): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + auth = FabAuth() + auth._auth_info = {} + + assert auth.get_access_token(scope) == "mockToken" + + +def test_acquire_token_proxy_auth_mode_includes_expiry(monkeypatch): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + auth = FabAuth() + + result = auth.acquire_token(con.SCOPE_FABRIC_DEFAULT) + + assert result["access_token"] == "mockToken" + assert result["expires_on"] == 9999999999 + + +@pytest.mark.parametrize( + "identity_type", + ["user", "service_principal", "managed_identity", "azure_cli"], +) +@pytest.mark.parametrize( + "scope", + [ + con.SCOPE_FABRIC_DEFAULT, + con.SCOPE_ONELAKE_DEFAULT, + con.SCOPE_AZURE_DEFAULT, + ], +) +def test_proxy_auth_mode_overrides_configured_auth_method( + monkeypatch, identity_type, scope +): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + auth = FabAuth() + auth._auth_info = {con.IDENTITY_TYPE: identity_type} + monkeypatch.setattr( + auth, + "_get_app", + lambda: pytest.fail("Proxy authentication must not initialize MSAL"), + ) + monkeypatch.setattr( + auth, + "_acquire_token_from_azure_cli", + lambda requested_scope: pytest.fail( + "Proxy authentication must not use Azure CLI credentials" + ), + ) + + result = auth.acquire_token(scope) + + assert result == {"access_token": "mockToken", "expires_on": 9999999999} + + +@pytest.mark.parametrize( + "scope", + [ + con.SCOPE_FABRIC_DEFAULT, + con.SCOPE_ONELAKE_DEFAULT, + con.SCOPE_AZURE_DEFAULT, + ], +) +def test_proxy_auth_mode_overrides_token_environment_variables(monkeypatch, scope): + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + monkeypatch.setenv("FAB_TOKEN", "fabric-access-token") + monkeypatch.setenv("FAB_TOKEN_ONELAKE", "onelake-access-token") + monkeypatch.setenv("FAB_TOKEN_AZURE", "azure-access-token") + auth = FabAuth() + auth._auth_info = {} + monkeypatch.setattr( + auth, + "_decode_jwt_token", + lambda token, expected_audience=None: pytest.fail( + "Proxy authentication must not validate token environment variables" + ), + ) + + result = auth.acquire_token(scope) + + assert result == {"access_token": "mockToken", "expires_on": 9999999999} + + # ----------------------------- # User Mode Tests # ----------------------------- diff --git a/tests/test_core/test_fab_msal_bridge_azure_cli.py b/tests/test_core/test_fab_msal_bridge_azure_cli.py index 6133b720..ea2ddc76 100644 --- a/tests/test_core/test_fab_msal_bridge_azure_cli.py +++ b/tests/test_core/test_fab_msal_bridge_azure_cli.py @@ -52,3 +52,16 @@ def test_bridge_rejects_invalid_scope( credential = MsalTokenCredential(auth) with pytest.raises(ClientAuthenticationError): credential.get_token("https://evil.example.com/.default") + + def test_bridge_returns_access_token_in_proxy_auth_mode( + self, monkeypatch, azure_cli_auth_fixture + ): + """Proxy auth placeholders should satisfy the TokenCredential contract.""" + monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") + auth = FabAuth() + + credential = MsalTokenCredential(auth) + result = credential.get_token(con.SCOPE_FABRIC_DEFAULT[0]) + + assert result.token == "mockToken" + assert result.expires_on == 9999999999 From 408360f1c32ced2471a63aace3a97b41f4ec9bf3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Sep 2026 06:38:43 +0000 Subject: [PATCH 2/3] test: suffix proxy auth test outcomes Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com> --- tests/test_commands/test_auth.py | 8 +++---- tests/test_core/test_fab_api_client.py | 4 +++- tests/test_core/test_fab_auth.py | 22 ++++++++++--------- .../test_fab_msal_bridge_azure_cli.py | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tests/test_commands/test_auth.py b/tests/test_commands/test_auth.py index fcaae771..4ebb02d3 100644 --- a/tests/test_commands/test_auth.py +++ b/tests/test_commands/test_auth.py @@ -912,7 +912,7 @@ def test_auth_logout( mock_print_done.assert_called_once() - def test_auth_login_proxy_auth_mode_has_no_side_effects(self, mock_fab_auth): + def test_auth_login_proxy_auth_mode_failure(self, mock_fab_auth): args = prepare_auth_args() auth = mock_fab_auth["instance"] auth.is_proxy_auth_mode.return_value = True @@ -943,9 +943,7 @@ def test_auth_login_proxy_auth_mode_has_no_side_effects(self, mock_fab_auth): clear_caches.assert_not_called() prompt_select_item.assert_not_called() - def test_auth_logout_proxy_auth_mode_has_no_side_effects( - self, mock_fab_auth, mock_fab_context - ): + def test_auth_logout_proxy_auth_mode_failure(self, mock_fab_auth, mock_fab_context): args = argparse.Namespace(command="auth", output_format="text") auth = mock_fab_auth["instance"] auth.is_proxy_auth_mode.return_value = True @@ -1007,7 +1005,7 @@ def test_auth_status(self, mock_fab_auth, capsys): assert "Token Storage: mock************************************" in captured.out assert "Token Azure: mock************************************" in captured.out - def test_auth_status_proxy_auth_mode(self, monkeypatch, capsys): + def test_auth_status_proxy_auth_mode_success(self, monkeypatch, capsys): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") args = argparse.Namespace( command="auth", diff --git a/tests/test_core/test_fab_api_client.py b/tests/test_core/test_fab_api_client.py index caca524d..bdd6a7b1 100644 --- a/tests/test_core/test_fab_api_client.py +++ b/tests/test_core/test_fab_api_client.py @@ -346,7 +346,9 @@ def __init__(self, status_code, headers=None, text=""): @pytest.mark.parametrize("audience", [None, "storage", "azure"]) -def test_do_request_proxy_auth_mode_sends_placeholder_header(monkeypatch, audience): +def test_do_request_proxy_auth_mode_sends_placeholder_header_success( + monkeypatch, audience +): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") monkeypatch.delenv("FAB_TOKEN", raising=False) monkeypatch.delenv("FAB_TOKEN_ONELAKE", raising=False) diff --git a/tests/test_core/test_fab_auth.py b/tests/test_core/test_fab_auth.py index 83cf4b8f..a4da8653 100644 --- a/tests/test_core/test_fab_auth.py +++ b/tests/test_core/test_fab_auth.py @@ -497,7 +497,7 @@ def test_validate_jwt_token_empty(): @pytest.mark.parametrize("value", ["true", "TRUE", "1"]) -def test_proxy_auth_mode_enabled(monkeypatch, value): +def test_proxy_auth_mode_enabled_success(monkeypatch, value): auth = FabAuth() monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", value) @@ -505,14 +505,14 @@ def test_proxy_auth_mode_enabled(monkeypatch, value): @pytest.mark.parametrize("value", ["", "false", "0", "yes"]) -def test_proxy_auth_mode_disabled(monkeypatch, value): +def test_proxy_auth_mode_disabled_success(monkeypatch, value): auth = FabAuth() monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", value) assert auth.is_proxy_auth_mode() is False -def test_proxy_auth_mode_not_enabled_by_placeholder_tokens(monkeypatch): +def test_proxy_auth_mode_not_enabled_by_placeholder_tokens_success(monkeypatch): auth = FabAuth() monkeypatch.setenv("FAB_TOKEN", "mockToken") monkeypatch.setenv("FAB_TOKEN_ONELAKE", "mockToken") @@ -521,7 +521,7 @@ def test_proxy_auth_mode_not_enabled_by_placeholder_tokens(monkeypatch): assert auth.is_proxy_auth_mode() is False -def test_proxy_auth_mode_skips_other_auth_environment(monkeypatch): +def test_proxy_auth_mode_skips_other_auth_environment_success(monkeypatch): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") monkeypatch.setenv("FAB_SPN_CLIENT_ID", "not-a-guid") auth = FabAuth() @@ -535,7 +535,7 @@ def test_proxy_auth_mode_skips_other_auth_environment(monkeypatch): @pytest.mark.parametrize("token", ["mockToken", b"mockToken"]) -def test_decode_jwt_token_proxy_auth_mode(monkeypatch, token): +def test_decode_jwt_token_proxy_auth_mode_success(monkeypatch, token): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") auth = FabAuth() @@ -548,7 +548,7 @@ def test_decode_jwt_token_proxy_auth_mode(monkeypatch, token): assert auth._decode_jwt_token(token) == {} -def test_get_claims_from_token_proxy_auth_mode(monkeypatch): +def test_get_claims_from_token_proxy_auth_mode_success(monkeypatch): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") auth = FabAuth() @@ -894,7 +894,7 @@ def test_get_access_token_env_var(monkeypatch): ["https://example.com/.default"], ], ) -def test_get_access_token_proxy_auth_mode(monkeypatch, scope): +def test_get_access_token_proxy_auth_mode_success(monkeypatch, scope): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") auth = FabAuth() auth._auth_info = {} @@ -902,7 +902,7 @@ def test_get_access_token_proxy_auth_mode(monkeypatch, scope): assert auth.get_access_token(scope) == "mockToken" -def test_acquire_token_proxy_auth_mode_includes_expiry(monkeypatch): +def test_acquire_token_proxy_auth_mode_includes_expiry_success(monkeypatch): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") auth = FabAuth() @@ -924,7 +924,7 @@ def test_acquire_token_proxy_auth_mode_includes_expiry(monkeypatch): con.SCOPE_AZURE_DEFAULT, ], ) -def test_proxy_auth_mode_overrides_configured_auth_method( +def test_proxy_auth_mode_overrides_configured_auth_method_success( monkeypatch, identity_type, scope ): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") @@ -956,7 +956,9 @@ def test_proxy_auth_mode_overrides_configured_auth_method( con.SCOPE_AZURE_DEFAULT, ], ) -def test_proxy_auth_mode_overrides_token_environment_variables(monkeypatch, scope): +def test_proxy_auth_mode_overrides_token_environment_variables_success( + monkeypatch, scope +): monkeypatch.setenv("FAB_PROXY_AUTH_ENABLED", "true") monkeypatch.setenv("FAB_TOKEN", "fabric-access-token") monkeypatch.setenv("FAB_TOKEN_ONELAKE", "onelake-access-token") diff --git a/tests/test_core/test_fab_msal_bridge_azure_cli.py b/tests/test_core/test_fab_msal_bridge_azure_cli.py index ea2ddc76..74e80ddd 100644 --- a/tests/test_core/test_fab_msal_bridge_azure_cli.py +++ b/tests/test_core/test_fab_msal_bridge_azure_cli.py @@ -53,7 +53,7 @@ def test_bridge_rejects_invalid_scope( with pytest.raises(ClientAuthenticationError): credential.get_token("https://evil.example.com/.default") - def test_bridge_returns_access_token_in_proxy_auth_mode( + def test_bridge_returns_access_token_in_proxy_auth_mode_success( self, monkeypatch, azure_cli_auth_fixture ): """Proxy auth placeholders should satisfy the TokenCredential contract.""" From 4cf34e3a9cbb41c2784c685375c6f33192158936 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Sep 2026 06:39:20 +0000 Subject: [PATCH 3/3] test: clarify proxy auth outcomes Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com> --- tests/test_commands/test_auth.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_commands/test_auth.py b/tests/test_commands/test_auth.py index 4ebb02d3..725de44e 100644 --- a/tests/test_commands/test_auth.py +++ b/tests/test_commands/test_auth.py @@ -912,7 +912,7 @@ def test_auth_logout( mock_print_done.assert_called_once() - def test_auth_login_proxy_auth_mode_failure(self, mock_fab_auth): + def test_auth_login_proxy_auth_mode_no_side_effects_success(self, mock_fab_auth): args = prepare_auth_args() auth = mock_fab_auth["instance"] auth.is_proxy_auth_mode.return_value = True @@ -943,7 +943,9 @@ def test_auth_login_proxy_auth_mode_failure(self, mock_fab_auth): clear_caches.assert_not_called() prompt_select_item.assert_not_called() - def test_auth_logout_proxy_auth_mode_failure(self, mock_fab_auth, mock_fab_context): + def test_auth_logout_proxy_auth_mode_no_side_effects_success( + self, mock_fab_auth, mock_fab_context + ): args = argparse.Namespace(command="auth", output_format="text") auth = mock_fab_auth["instance"] auth.is_proxy_auth_mode.return_value = True