"""Tests for jira_cli SecretsManagerClient.""" from unittest.mock import MagicMock, patch import pytest from jira_client.secrets_manager import SecretsManagerClient @patch('boto3.client') def test_get_jira_api_token_returns_secret_string(mock_boto_client: MagicMock) -> None: """get_jira_api_token returns the SecretString value from the response. :param mock_boto_client: :return: """ mock_sm = MagicMock() mock_boto_client.return_value = mock_sm mock_sm.get_secret_value.return_value = {'SecretString': 'jira_token_abc'} client = SecretsManagerClient() token = client.get_jira_api_token('my/secret/name') assert token == 'jira_token_abc' @patch('boto3.client') def test_get_jira_api_token_uses_correct_secret_id(mock_boto_client: MagicMock) -> None: """get_jira_api_token calls get_secret_value with the expected SecretId. :param mock_boto_client: :return: """ mock_sm = MagicMock() mock_boto_client.return_value = mock_sm mock_sm.get_secret_value.return_value = {'SecretString': 'jira_token_abc'} client = SecretsManagerClient() client.get_jira_api_token('prod/jira/token') mock_sm.get_secret_value.assert_called_once_with(SecretId='prod/jira/token') @patch('boto3.client') def test_get_jira_api_token_returns_decoded_secret_binary( mock_boto_client: MagicMock, ) -> None: """get_jira_api_token decodes SecretBinary when SecretString is absent. :param mock_boto_client: :return: """ mock_sm = MagicMock() mock_boto_client.return_value = mock_sm mock_sm.get_secret_value.return_value = {'SecretBinary': b'jira_binary_token'} client = SecretsManagerClient() token = client.get_jira_api_token('my/binary/secret') assert token == 'jira_binary_token' @patch('boto3.client') def test_get_jira_api_token_raises_when_neither_key_present( mock_boto_client: MagicMock, ) -> None: """get_jira_api_token raises ValueError when the response has no secret data. :param mock_boto_client: :return: """ mock_sm = MagicMock() mock_boto_client.return_value = mock_sm mock_sm.get_secret_value.return_value = {} client = SecretsManagerClient() with pytest.raises(ValueError, match='neither SecretString nor SecretBinary'): client.get_jira_api_token('empty/secret') @patch('boto3.client') def test_get_jira_api_token_propagates_boto3_error(mock_boto_client: MagicMock) -> None: """get_jira_api_token propagates exceptions raised by boto3. :param mock_boto_client: :return: """ mock_sm = MagicMock() mock_boto_client.return_value = mock_sm mock_sm.get_secret_value.side_effect = Exception('ResourceNotFoundException') client = SecretsManagerClient() with pytest.raises(Exception, match='ResourceNotFoundException'): client.get_jira_api_token('nonexistent/secret')