"""Test FlaskCortexSearch extension.""" from unittest.mock import patch from flask import Flask import pytest import payment.connectors.cortex_search as module from payment.connectors.cortex_search.ext.flask import FlaskCortexSearch @pytest.fixture(autouse=True) def reset_singleton(): module._client = None yield module._client = None def make_app(**config_overrides): app = Flask(__name__) app.config.update( SNOWFLAKE_ACCOUNT='test-account', SNOWFLAKE_USER='test-user', SNOWFLAKE_DATABASE='TEST_DB', SNOWFLAKE_SCHEMA='TEST_SCHEMA', SNOWFLAKE_CORTEX_SEARCH_SERVICE_NAME='TEST_SVC', SNOWFLAKE_PRIVATE_KEY_PATH='/path/to/key.p8', ) app.config.update(config_overrides) return app @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_with_app_calls_init_app(mock_init): app = make_app() ext = FlaskCortexSearch(app) assert 'cortex_search' in app.extensions @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_without_app_does_not_call_init_app(mock_init): ext = FlaskCortexSearch() mock_init.assert_not_called() @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_registers_extension(mock_init): app = make_app() ext = FlaskCortexSearch() ext.init_app(app) assert app.extensions['cortex_search'] is ext @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_initializes_cortex_search_with_key_path(mock_init): app = make_app( SNOWFLAKE_PRIVATE_KEY_PATH='/path/to/key.p8', SNOWFLAKE_PRIVATE_KEY=None ) FlaskCortexSearch(app) mock_init.assert_called_once() config_arg = mock_init.call_args.args[0] assert config_arg.SNOWFLAKE_ACCOUNT == 'test-account' assert config_arg.SNOWFLAKE_PRIVATE_KEY_PATH == '/path/to/key.p8' @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_initializes_cortex_search_with_raw_key(mock_init): app = make_app(SNOWFLAKE_PRIVATE_KEY_PATH=None, SNOWFLAKE_PRIVATE_KEY=b'raw_key') FlaskCortexSearch(app) mock_init.assert_called_once() config_arg = mock_init.call_args.args[0] assert config_arg.SNOWFLAKE_PRIVATE_KEY == b'raw_key' @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_skips_init_when_no_key_configured(mock_init): app = make_app(SNOWFLAKE_PRIVATE_KEY_PATH=None, SNOWFLAKE_PRIVATE_KEY=None) FlaskCortexSearch(app) mock_init.assert_not_called() @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_raises_if_already_registered(mock_init): app = make_app() FlaskCortexSearch(app) with pytest.raises(RuntimeError, match='already initialised'): FlaskCortexSearch(app) @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_passes_scoring_config(mock_init): scoring = {'semantic_weight': 0.7} app = make_app(SNOWFLAKE_CORTEX_SEARCH_SCORING_CONFIG=scoring) FlaskCortexSearch(app) config_arg = mock_init.call_args.args[0] assert config_arg.SNOWFLAKE_CORTEX_SEARCH_SCORING_CONFIG == scoring @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_passes_timeout_config(mock_init): app = make_app(SNOWFLAKE_LOGIN_TIMEOUT=15, SNOWFLAKE_NETWORK_TIMEOUT=60) FlaskCortexSearch(app) config_arg = mock_init.call_args.args[0] assert config_arg.SNOWFLAKE_LOGIN_TIMEOUT == 15 assert config_arg.SNOWFLAKE_NETWORK_TIMEOUT == 60 @patch('payment.connectors.cortex_search.ext.flask.init_cortex_search') def test_init_app_timeout_defaults_to_none(mock_init): app = make_app() FlaskCortexSearch(app) config_arg = mock_init.call_args.args[0] assert config_arg.SNOWFLAKE_LOGIN_TIMEOUT is None assert config_arg.SNOWFLAKE_NETWORK_TIMEOUT is None