Skip to main content
Glama

MCP Atlassian

by ArconixForge
test_client_oauth.py16.3 kB
"""Tests for the JiraClient with OAuth authentication.""" import os from unittest.mock import MagicMock, PropertyMock, patch import pytest from mcp_atlassian.exceptions import MCPAtlassianAuthenticationError from mcp_atlassian.jira.client import JiraClient from mcp_atlassian.jira.config import JiraConfig from mcp_atlassian.utils.oauth import BYOAccessTokenOAuthConfig, OAuthConfig class TestJiraClientOAuth: """Tests for JiraClient with OAuth authentication.""" def test_init_with_oauth_config(self): """Test initializing the client with OAuth configuration.""" # Create a mock OAuth config with both access and refresh tokens oauth_config = OAuthConfig( client_id="test-client-id", client_secret="test-client-secret", redirect_uri="https://example.com/callback", scope="read:jira-work write:jira-work", cloud_id="test-cloud-id", access_token="test-access-token", refresh_token="test-refresh-token", expires_at=9999999999.0, # Set a future expiry time ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=oauth_config, ) # Mock dependencies with ( patch("mcp_atlassian.jira.client.Jira") as mock_jira, patch( "mcp_atlassian.jira.client.configure_oauth_session" ) as mock_configure_oauth, patch( "mcp_atlassian.jira.client.configure_ssl_verification" ) as mock_configure_ssl, patch.object( OAuthConfig, "is_token_expired", new_callable=PropertyMock, return_value=False, ) as mock_is_expired, patch.object( oauth_config, "ensure_valid_token", return_value=True ) as mock_ensure_valid, ): # Configure the mock to return success for OAuth configuration mock_configure_oauth.return_value = True # Initialize client client = JiraClient(config=config) # Verify OAuth session configuration was called mock_configure_oauth.assert_called_once() # Verify Jira was initialized with the expected parameters mock_jira.assert_called_once() jira_kwargs = mock_jira.call_args[1] assert ( jira_kwargs["url"] == f"https://api.atlassian.com/ex/jira/{oauth_config.cloud_id}" ) assert "session" in jira_kwargs assert jira_kwargs["cloud"] is True # Verify SSL verification was configured mock_configure_ssl.assert_called_once() def test_init_with_oauth_missing_cloud_id(self): """Test initializing the client with OAuth but missing cloud_id.""" # Create a mock OAuth config without cloud_id oauth_config = OAuthConfig( client_id="test-client-id", client_secret="test-client-secret", redirect_uri="https://example.com/callback", scope="read:jira-work write:jira-work", # No cloud_id access_token="test-access-token", ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=oauth_config, ) # Verify error is raised with pytest.raises( ValueError, match="OAuth authentication requires a valid cloud_id" ): JiraClient(config=config) def test_init_with_oauth_failed_session_config(self): """Test initializing the client with OAuth but failed session configuration.""" # Create a mock OAuth config oauth_config = OAuthConfig( client_id="test-client-id", client_secret="test-client-secret", redirect_uri="https://example.com/callback", scope="read:jira-work write:jira-work", cloud_id="test-cloud-id", access_token="test-access-token", refresh_token="test-refresh-token", ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=oauth_config, ) # Mock dependencies with OAuth configuration failure with ( patch("mcp_atlassian.jira.client.Jira") as mock_jira, # Patch where the function is imported, not where it's defined patch( "mcp_atlassian.jira.client.configure_oauth_session" ) as mock_configure_oauth, patch( "mcp_atlassian.jira.client.configure_ssl_verification" ) as mock_configure_ssl, patch( "mcp_atlassian.preprocessing.jira.JiraPreprocessor" ) as mock_preprocessor, patch.object( OAuthConfig, "is_token_expired", new_callable=PropertyMock, return_value=False, ) as mock_is_expired, patch.object( oauth_config, "ensure_valid_token", return_value=True ) as mock_ensure_valid, ): # Configure the mock to return failure for OAuth configuration mock_configure_oauth.return_value = False # Verify error is raised with pytest.raises( MCPAtlassianAuthenticationError, match="Failed to configure OAuth session", ): JiraClient(config=config) def test_init_with_byo_access_token_oauth_config(self): """Test initializing the client with BYO Access Token OAuth configuration.""" # Create a mock BYO OAuth config byo_oauth_config = BYOAccessTokenOAuthConfig( cloud_id="test-cloud-id", access_token="my-byo-token" ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=byo_oauth_config, ) # Mock dependencies with ( patch("mcp_atlassian.jira.client.Jira") as mock_jira, patch( "mcp_atlassian.jira.client.configure_oauth_session" ) as mock_configure_oauth, patch( "mcp_atlassian.jira.client.configure_ssl_verification" ) as mock_configure_ssl, ): # Configure the mock to return success for OAuth configuration mock_configure_oauth.return_value = True # Initialize client client = JiraClient(config=config) # Verify OAuth session configuration was called mock_configure_oauth.assert_called_once() # Verify Jira was initialized with the expected parameters mock_jira.assert_called_once() jira_kwargs = mock_jira.call_args[1] assert ( jira_kwargs["url"] == f"https://api.atlassian.com/ex/jira/{byo_oauth_config.cloud_id}" ) assert "session" in jira_kwargs assert jira_kwargs["cloud"] is True # Verify SSL verification was configured mock_configure_ssl.assert_called_once() def test_init_with_byo_oauth_missing_cloud_id(self): """Test initializing with BYO OAuth but missing cloud_id.""" # Create a mock BYO OAuth config with an empty cloud_id byo_oauth_config = BYOAccessTokenOAuthConfig( cloud_id="", access_token="my-byo-token" ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=byo_oauth_config, ) # Verify error is raised with pytest.raises( ValueError, match="OAuth authentication requires a valid cloud_id" ): JiraClient(config=config) def test_init_with_byo_oauth_failed_session_config(self): """Test init with BYO OAuth but failed session configuration.""" # Create a mock BYO OAuth config byo_oauth_config = BYOAccessTokenOAuthConfig( cloud_id="test-cloud-id", access_token="my_byo_token" ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=byo_oauth_config, ) # Mock dependencies with OAuth configuration failure with ( patch("mcp_atlassian.jira.client.Jira"), # No need to assert mock_jira patch( "mcp_atlassian.jira.client.configure_oauth_session" ) as mock_configure_oauth, patch("mcp_atlassian.jira.client.configure_ssl_verification"), ): # Configure the mock to return failure for OAuth configuration mock_configure_oauth.return_value = False # Verify error is raised with pytest.raises( MCPAtlassianAuthenticationError, match="Failed to configure OAuth session", ): JiraClient(config=config) def test_init_with_byo_oauth_empty_token_failed_session_config(self): """Test init with BYO OAuth, empty token, so session config fails.""" # Create a mock BYO OAuth config with an empty token byo_oauth_config_empty_token = BYOAccessTokenOAuthConfig( cloud_id="test-cloud-id", access_token="", # Empty token ) # Create a Jira config with OAuth config = JiraConfig( url="https://test.atlassian.net", auth_type="oauth", oauth_config=byo_oauth_config_empty_token, ) # Mock dependencies - configure_oauth_session will be called with real logic with ( patch("mcp_atlassian.jira.client.Jira"), patch("mcp_atlassian.jira.client.configure_ssl_verification"), # We want to test the actual behavior of configure_oauth_session here for empty token ): # Verify error is raised with pytest.raises( MCPAtlassianAuthenticationError, match="Failed to configure OAuth session", ): JiraClient(config=config) def test_from_env_with_oauth(self): # Mock environment variables env_vars = { "JIRA_URL": "https://test.atlassian.net", "JIRA_AUTH_TYPE": "oauth", # Add auth_type to env vars "ATLASSIAN_OAUTH_CLIENT_ID": "env-client-id", "ATLASSIAN_OAUTH_CLIENT_SECRET": "env-client-secret", "ATLASSIAN_OAUTH_REDIRECT_URI": "https://example.com/callback", "ATLASSIAN_OAUTH_SCOPE": "read:jira-work", "ATLASSIAN_OAUTH_CLOUD_ID": "env-cloud-id", } # Mock OAuth config and token loading mock_oauth_config = MagicMock() mock_oauth_config.cloud_id = "env-cloud-id" mock_oauth_config.access_token = "env-access-token" mock_oauth_config.refresh_token = "env-refresh-token" mock_oauth_config.expires_at = 9999999999.0 with ( patch.dict(os.environ, env_vars), patch( "mcp_atlassian.jira.config.get_oauth_config_from_env", return_value=mock_oauth_config, ), patch.object( OAuthConfig, "is_token_expired", new_callable=PropertyMock, return_value=False, ) as mock_is_expired_env, patch.object( mock_oauth_config, "ensure_valid_token", return_value=True ) as mock_ensure_valid_env, patch("mcp_atlassian.jira.client.Jira") as mock_jira, patch( "mcp_atlassian.jira.client.configure_oauth_session", return_value=True ) as mock_configure_oauth, patch( "mcp_atlassian.jira.client.configure_ssl_verification" ) as mock_configure_ssl, ): # Initialize client from environment client = JiraClient() # Verify client was initialized with OAuth assert client.config.auth_type == "oauth" assert client.config.oauth_config is mock_oauth_config # Verify Jira was initialized correctly mock_jira.assert_called_once() jira_kwargs = mock_jira.call_args[1] assert ( jira_kwargs["url"] == f"https://api.atlassian.com/ex/jira/{mock_oauth_config.cloud_id}" ) assert "session" in jira_kwargs assert jira_kwargs["cloud"] is True # Verify OAuth session was configured mock_configure_oauth.assert_called_once() def test_from_env_with_byo_token_oauth(self): """Test JiraClient.from_env() when BYO token OAuth config is found.""" env_vars = { "JIRA_URL": "https://test.atlassian.net", "JIRA_AUTH_TYPE": "oauth", "ATLASSIAN_OAUTH_ACCESS_TOKEN": "env-byo-access-token", "ATLASSIAN_OAUTH_CLOUD_ID": "env-byo-cloud-id", # Ensure other standard OAuth env vars are not set or are ignored "ATLASSIAN_OAUTH_CLIENT_ID": "", "ATLASSIAN_OAUTH_CLIENT_SECRET": "", } # Mock BYO OAuth config mock_byo_oauth_config = MagicMock(spec=BYOAccessTokenOAuthConfig) mock_byo_oauth_config.cloud_id = "env-byo-cloud-id" mock_byo_oauth_config.access_token = "env-byo-access-token" # BYO config does not have refresh_token or expires_at in the same way # and does not have is_token_expired or ensure_valid_token methods with ( patch.dict(os.environ, env_vars), patch( "mcp_atlassian.jira.config.get_oauth_config_from_env", return_value=mock_byo_oauth_config, ), patch("mcp_atlassian.jira.client.Jira") as mock_jira, patch( "mcp_atlassian.jira.client.configure_oauth_session", return_value=True ) as mock_configure_oauth, patch( "mcp_atlassian.jira.client.configure_ssl_verification" ) as mock_configure_ssl, ): client = JiraClient() # Initializes from env via JiraConfig.from_env() assert client.config.auth_type == "oauth" assert client.config.oauth_config is mock_byo_oauth_config # Verify OAuth session configuration was called mock_configure_oauth.assert_called_once() mock_jira.assert_called_once() jira_kwargs = mock_jira.call_args[1] assert ( jira_kwargs["url"] == f"https://api.atlassian.com/ex/jira/{mock_byo_oauth_config.cloud_id}" ) mock_configure_ssl.assert_called_once() def test_from_env_with_no_oauth_config_found(self): """Test JiraClient.from_env() when no OAuth config is found.""" env_vars = { "JIRA_URL": "https://test.atlassian.net", "JIRA_AUTH_TYPE": "oauth", # No OAuth specific variables set "ATLASSIAN_OAUTH_CLIENT_ID": "", "ATLASSIAN_OAUTH_ACCESS_TOKEN": "", # Explicitly clear basic auth credentials "JIRA_USERNAME": "", "JIRA_API_TOKEN": "", } with ( patch.dict(os.environ, env_vars, clear=True), patch( "mcp_atlassian.jira.config.get_oauth_config_from_env", return_value=None, # Simulate no config found ), ): with pytest.raises( ValueError, # Adjusted to actual error raised by JiraConfig.from_env match=r"Cloud authentication requires JIRA_USERNAME and JIRA_API_TOKEN, or OAuth configuration.*", ): JiraClient()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ArconixForge/mcp-atlassian'

If you have feedback or need assistance with the MCP directory API, please join our Discord server