import base64 import os import unittest from unittest.mock import MagicMock, patch from sliutil import secret class SecretTest(unittest.TestCase): def setUp(self): secret._load_secret.cache_clear() def tearDown(self): secret._load_secret.cache_clear() @patch("sliutil.secret.boto3.client") def test_get_secret_reads_json_and_caches_response(self, boto3_client): client = MagicMock() client.get_secret_value.return_value = { "SecretString": '{"API_KEY": "test-value"}' } boto3_client.return_value = client with patch.dict(os.environ, {"SLI_SECRET_NAME": "test-secret"}, clear=True): self.assertEqual(secret.get_secret("API_KEY"), "test-value") self.assertEqual(secret.get_secret("API_KEY"), "test-value") client.get_secret_value.assert_called_once_with(SecretId="test-secret") @patch("sliutil.secret.boto3.client") def test_get_secret_supports_binary_json(self, boto3_client): encoded_secret = base64.b64encode(b'{"PASSWORD": "test-value"}') boto3_client.return_value.get_secret_value.return_value = { "SecretBinary": encoded_secret } self.assertEqual( secret.get_secret("PASSWORD", secret_name="test-secret"), "test-value" ) @patch("sliutil.secret.boto3.client") def test_get_secret_rejects_invalid_json(self, boto3_client): boto3_client.return_value.get_secret_value.return_value = { "SecretString": "not-json" } with self.assertRaisesRegex(RuntimeError, "must contain valid JSON"): secret.get_secret("API_KEY", secret_name="test-secret") @patch("sliutil.secret.boto3.client") def test_get_secret_rejects_missing_key(self, boto3_client): boto3_client.return_value.get_secret_value.return_value = {"SecretString": "{}"} with self.assertRaisesRegex(RuntimeError, "missing required string key"): secret.get_secret("API_KEY", secret_name="test-secret") def test_get_secret_requires_secret_name(self): with ( patch.dict(os.environ, {}, clear=True), self.assertRaisesRegex(RuntimeError, "SLI_SECRET_NAME is required"), ): secret.get_secret("API_KEY") if __name__ == "__main__": unittest.main()