We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/amruthabesto28/JIRA-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Tests for the Jira client module."""
import os
from copy import deepcopy
from typing import Literal
from unittest.mock import MagicMock, call, patch
import pytest
from mcp_atlassian.jira.client import JiraClient
from mcp_atlassian.jira.config import JiraConfig
class DeepcopyMock(MagicMock):
"""A Mock that creates a deep copy of its arguments before storing them."""
def __call__(self, /, *args, **kwargs):
args = deepcopy(args)
kwargs = deepcopy(kwargs)
return super().__call__(*args, **kwargs)
def test_init_with_basic_auth():
"""Test initializing the client with basic auth configuration."""
with (
patch("mcp_atlassian.jira.client.Jira") as mock_jira,
patch(
"mcp_atlassian.jira.client.configure_ssl_verification"
) as mock_configure_ssl,
):
config = JiraConfig(
url="https://test.atlassian.net",
auth_type="basic",
username="test_username",
api_token="test_token",
)
client = JiraClient(config=config)
# Verify Jira was initialized correctly
mock_jira.assert_called_once_with(
url="https://test.atlassian.net",
username="test_username",
password="test_token",
cloud=True,
verify_ssl=True,
)
# Verify SSL verification was configured
mock_configure_ssl.assert_called_once_with(
service_name="Jira",
url="https://test.atlassian.net",
session=mock_jira.return_value._session,
ssl_verify=True,
)
assert client.config == config
assert client._field_ids_cache is None
assert client._current_user_account_id is None
def test_init_with_token_auth():
"""Test initializing the client with token auth configuration."""
with (
patch("mcp_atlassian.jira.client.Jira") as mock_jira,
patch(
"mcp_atlassian.jira.client.configure_ssl_verification"
) as mock_configure_ssl,
):
config = JiraConfig(
url="https://jira.example.com",
auth_type="pat",
personal_token="test_personal_token",
ssl_verify=False,
)
client = JiraClient(config=config)
# Verify Jira was initialized correctly
mock_jira.assert_called_once_with(
url="https://jira.example.com",
token="test_personal_token",
cloud=False,
verify_ssl=False,
)
# Verify SSL verification was configured with ssl_verify=False
mock_configure_ssl.assert_called_once_with(
service_name="Jira",
url="https://jira.example.com",
session=mock_jira.return_value._session,
ssl_verify=False,
)
assert client.config == config
def test_init_from_env():
"""Test initializing the client from environment variables."""
with (
patch("mcp_atlassian.jira.config.JiraConfig.from_env") as mock_from_env,
patch("mcp_atlassian.jira.client.Jira") as mock_jira,
patch("mcp_atlassian.jira.client.configure_ssl_verification"),
):
mock_config = MagicMock()
mock_config.auth_type = "basic" # needed for the if condition
mock_from_env.return_value = mock_config
client = JiraClient()
mock_from_env.assert_called_once()
assert client.config == mock_config
def test_clean_text():
"""Test the _clean_text method."""
with (
patch("mcp_atlassian.jira.client.Jira"),
patch("mcp_atlassian.jira.client.configure_ssl_verification"),
):
client = JiraClient(
config=JiraConfig(
url="https://test.atlassian.net",
auth_type="basic",
username="test_username",
api_token="test_token",
)
)
# Test with HTML
assert client._clean_text("<p>Test content</p>") == "Test content"
# Test with empty string
assert client._clean_text("") == ""
# Test with spaces and newlines
assert client._clean_text(" \n Test with spaces \n ") == "Test with spaces"
def _test_get_paged(method: Literal["get", "post"]):
"""Test the get_paged method."""
with (
patch(
"mcp_atlassian.jira.client.Jira.get", new_callable=DeepcopyMock
) as mock_get,
patch(
"mcp_atlassian.jira.client.Jira.post", new_callable=DeepcopyMock
) as mock_post,
patch("mcp_atlassian.jira.client.configure_ssl_verification"),
):
config = JiraConfig(
url="https://test.atlassian.net",
auth_type="basic",
username="test_username",
api_token="test_token",
)
client = JiraClient(config=config)
# Mock paged responses
mock_responses = [
{"data": "page1", "nextPageToken": "token1"},
{"data": "page2", "nextPageToken": "token2"},
{"data": "page3"}, # Last page does not have nextPageToken
]
# Create mock method with side effect to return responses in sequence
if method == "get":
mock_get.side_effect = mock_responses
mock_post.side_effect = RuntimeError("This should not be called")
else:
mock_post.side_effect = mock_responses
mock_get.side_effect = RuntimeError("This should not be called")
# Run the method
params = {"initial": "params"}
results = client.get_paged(method, "/test/url", params)
# Verify the results
assert results == mock_responses
# Verify call parameters
if method == "get":
expected_calls = [
call(path="/test/url", params={"initial": "params"}, absolute=False),
call(
path="/test/url",
params={"initial": "params", "nextPageToken": "token1"},
absolute=False,
),
call(
path="/test/url",
params={"initial": "params", "nextPageToken": "token2"},
absolute=False,
),
]
assert mock_get.call_args_list == expected_calls
else:
expected_calls = [
call(path="/test/url", json={"initial": "params"}, absolute=False),
call(
path="/test/url",
json={"initial": "params", "nextPageToken": "token1"},
absolute=False,
),
call(
path="/test/url",
json={"initial": "params", "nextPageToken": "token2"},
absolute=False,
),
]
assert mock_post.call_args_list == expected_calls
def test_get_paged_get():
"""Test the get_paged method for GET requests."""
_test_get_paged("get")
def test_get_paged_post():
"""Test the get_paged method for POST requests."""
_test_get_paged("post")
def test_get_paged_without_cloud():
"""Test the get_paged method without cloud."""
with patch("mcp_atlassian.jira.client.configure_ssl_verification"):
config = JiraConfig(
url="https://jira.example.com",
auth_type="pat",
personal_token="test_token",
)
client = JiraClient(config=config)
with pytest.raises(
ValueError,
match="Paged requests are only available for Jira Cloud platform",
):
client.get_paged("get", "/test/url")
def test_init_sets_proxies_and_no_proxy(monkeypatch):
"""Test that JiraClient sets session proxies and NO_PROXY env var from config."""
# Patch Jira and its _session
mock_jira = MagicMock()
mock_session = MagicMock()
mock_session.proxies = {} # Use a real dict for proxies
mock_jira._session = mock_session
monkeypatch.setattr("mcp_atlassian.jira.client.Jira", lambda **kwargs: mock_jira)
monkeypatch.setattr(
"mcp_atlassian.jira.client.configure_ssl_verification", lambda **kwargs: None
)
# Patch environment
monkeypatch.setenv("NO_PROXY", "")
config = JiraConfig(
url="https://test.atlassian.net",
auth_type="basic",
username="user",
api_token="pat",
http_proxy="http://proxy:8080",
https_proxy="https://proxy:8443",
socks_proxy="socks5://user:pass@proxy:1080",
no_proxy="localhost,127.0.0.1",
)
client = JiraClient(config=config)
assert mock_session.proxies["http"] == "http://proxy:8080"
assert mock_session.proxies["https"] == "https://proxy:8443"
assert mock_session.proxies["socks"] == "socks5://user:pass@proxy:1080"
assert os.environ["NO_PROXY"] == "localhost,127.0.0.1"
def test_init_no_proxies(monkeypatch):
"""Test that JiraClient does not set proxies if not configured."""
# Patch Jira and its _session
mock_jira = MagicMock()
mock_session = MagicMock()
mock_session.proxies = {} # Use a real dict for proxies
mock_jira._session = mock_session
monkeypatch.setattr("mcp_atlassian.jira.client.Jira", lambda **kwargs: mock_jira)
monkeypatch.setattr(
"mcp_atlassian.jira.client.configure_ssl_verification", lambda **kwargs: None
)
config = JiraConfig(
url="https://test.atlassian.net",
auth_type="basic",
username="user",
api_token="pat",
)
client = JiraClient(config=config)
assert mock_session.proxies == {}