#!/usr/bin/env python3 """ Unit tests for configuration management """ import unittest from unittest.mock import Mock, patch, mock_open import os import json import sys # Add parent directory to path to import modules sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from config import ConfigManager from sigma_api_client import SigmaConfig class TestConfigManager(unittest.TestCase): """Test cases for ConfigManager""" def setUp(self): """Set up test fixtures""" self.test_config_data = { 'client_id': 'test_client_id', 'base_url': 'https://api.test.sigmacomputing.com', 'snowflake_connection_name': 'TEST_CONNECTION' } @patch('pathlib.Path.exists') def test_init_no_config_file(self, mock_exists): """Test initialization when config file doesn't exist""" mock_exists.return_value = False with patch.dict(os.environ, {}, clear=True): config_manager = ConfigManager('nonexistent.json') self.assertEqual(config_manager.config_data, {}) @patch('builtins.open', new_callable=mock_open) @patch('pathlib.Path.exists') def test_init_with_config_file(self, mock_exists, mock_file): """Test initialization with existing config file""" mock_exists.return_value = True mock_file.return_value.read.return_value = json.dumps(self.test_config_data) with patch('json.load', return_value=self.test_config_data): config_manager = ConfigManager('test_config.json') self.assertEqual(config_manager.config_data['client_id'], 'test_client_id') self.assertEqual(config_manager.config_data['base_url'], 'https://api.test.sigmacomputing.com') @patch('pathlib.Path.exists') def test_load_from_env(self, mock_exists): """Test loading configuration from environment variables""" mock_exists.return_value = False env_vars = { 'SIGMA_CLIENT_ID': 'env_client_id', 'SIGMA_CLIENT_SECRET': 'env_client_secret', 'SIGMA_BASE_URL': 'https://api.env.sigmacomputing.com', 'SIGMA_SNOWFLAKE_CONNECTION': 'ENV_CONNECTION' } with patch.dict(os.environ, env_vars, clear=True): config_manager = ConfigManager('test.json') # Environment variables should override self.assertEqual(config_manager.config_data['client_id'], 'env_client_id') self.assertEqual(config_manager.config_data['client_secret'], 'env_client_secret') self.assertEqual(config_manager.config_data['base_url'], 'https://api.env.sigmacomputing.com') @patch('builtins.open', new_callable=mock_open) def test_save_config_excludes_secrets(self, mock_file): """Test that save_config excludes sensitive data""" config_manager = ConfigManager() test_data = { 'client_id': 'test_id', 'client_secret': 'secret_value', 'base_url': 'https://api.test.com' } config_manager.save_config(test_data) # Verify json.dump was called without client_secret mock_file.assert_called_once() written_data = json.loads(mock_file().write.call_args[0][0]) self.assertIn('client_id', written_data) self.assertIn('base_url', written_data) self.assertNotIn('client_secret', written_data) def test_get_sigma_config_success(self): """Test successful Sigma config creation""" config_manager = ConfigManager() config_manager.config_data = { 'client_id': 'test_id', 'client_secret': 'test_secret', 'base_url': 'https://api.test.com' } sigma_config = config_manager.get_sigma_config() self.assertIsInstance(sigma_config, SigmaConfig) self.assertEqual(sigma_config.client_id, 'test_id') self.assertEqual(sigma_config.client_secret, 'test_secret') self.assertEqual(sigma_config.base_url, 'https://api.test.com') def test_get_sigma_config_missing_fields(self): """Test Sigma config creation with missing required fields""" config_manager = ConfigManager() config_manager.config_data = { 'client_id': 'test_id' # Missing client_secret and base_url } with self.assertRaises(ValueError) as context: config_manager.get_sigma_config() self.assertIn('Missing required configuration fields', str(context.exception)) def test_get_snowflake_connection_name(self): """Test getting Snowflake connection name""" config_manager = ConfigManager() config_manager.config_data = { 'snowflake_connection_name': 'TEST_SNOWFLAKE_CONN' } result = config_manager.get_snowflake_connection_name() self.assertEqual(result, 'TEST_SNOWFLAKE_CONN') def test_get_snowflake_connection_name_missing(self): """Test getting Snowflake connection name when not configured""" config_manager = ConfigManager() config_manager.config_data = {} result = config_manager.get_snowflake_connection_name() self.assertIsNone(result) def test_set_config(self): """Test setting configuration values""" config_manager = ConfigManager() config_manager.set_config( client_id='new_id', base_url='https://api.new.com' ) self.assertEqual(config_manager.config_data['client_id'], 'new_id') self.assertEqual(config_manager.config_data['base_url'], 'https://api.new.com') def test_get_base_urls(self): """Test getting base URLs by region""" config_manager = ConfigManager() base_urls = config_manager.get_base_urls() self.assertIn('us', base_urls) self.assertIn('eu', base_urls) self.assertIn('ca', base_urls) self.assertIn('uk', base_urls) self.assertIn('au', base_urls) self.assertTrue(base_urls['us'].startswith('https://')) @patch('builtins.input') @patch('builtins.open', new_callable=mock_open) def test_setup_interactive(self, mock_file, mock_input): """Test interactive setup""" # Mock user inputs mock_input.side_effect = [ 'us', # region 'test_client_id', # client id 'test_client_secret', # client secret 'TEST_CONNECTION' # snowflake connection ] config_manager = ConfigManager() config_manager.setup_interactive() # Verify configuration was set self.assertEqual(config_manager.config_data['client_id'], 'test_client_id') self.assertEqual(config_manager.config_data['client_secret'], 'test_client_secret') self.assertEqual(config_manager.config_data['base_url'], 'https://api.sigmacomputing.com') self.assertEqual(config_manager.config_data['snowflake_connection_name'], 'TEST_CONNECTION') if __name__ == '__main__': unittest.main()