"""Test for the rule logic.""" from unittest.mock import patch from owsresponse import response import pytest from redis import exceptions as redis_exceptions from tests.unit.conftest import get_rules_formatted from tests.unit.conftest import get_rules_formatted_empty_fixture from vector_job_rules.connectors.redis import redis_client from vector_job_rules.logic import rule @pytest.mark.parametrize( 'empty_redis, status, rule_ids, result', [ (True, None, (1,), get_rules_formatted()), (False, None, (1,), get_rules_formatted()), (True, None, (0,), get_rules_formatted_empty_fixture()), (True, None, (2,), get_rules_formatted_empty_fixture()), (True, 'active', None, get_rules_formatted()), (True, 'inactive', None, get_rules_formatted_empty_fixture()), ], ) @patch('vector_job_rules.logic.rule.rule_model') def test_get_rules_logic( mock_rule_model, get_rules_fixture, empty_redis, status, rule_ids, result ): """Test getting and formatting rules.""" if empty_redis: redis_client.flushall() mock_rule_model.get_rules.return_value = response.Response(get_rules_fixture) mock_rule_model.format_rules_into_response_format.return_value = ( response.Response(get_rules_fixture) ) mock_rule_model.filter_formatted_rules.return_value = response.Response( result['items'] ) else: mock_rule_model.get_rules_from_cache.return_value = response.Response( result['items'] ) redis_client.hset('ows_vector_job_rules', 'foo', 'bar') all_rules = rule.get_rules(status=status, rule_ids=rule_ids) if empty_redis: mock_rule_model.get_rules.assert_called() mock_rule_model.format_rules_into_response_format.assert_called_with( mock_rule_model.get_rules.return_value ) mock_rule_model.push_rules_into_cache.assert_called() mock_rule_model.filter_formatted_rules.assert_called() else: mock_rule_model.get_rules_from_cache.assert_called() mock_rule_model.push_rules_into_cache.assert_not_called() mock_rule_model.get_rules.assert_not_called() assert all_rules.message == result @pytest.mark.parametrize( 'redis_side_effect', [redis_exceptions.TimeoutError(), redis_exceptions.ConnectionError()], ) @patch('vector_job_rules.logic.rule.rule_model') @patch('vector_job_rules.logic.rule.redis_client') @patch('vector_job_rules.logic.rule.capture_exception') def test_rules_when_redis_down( mock_sentry_client, mock_redis_client, mock_rule_model, get_rules_fixture, get_rules_formatted_fixture, redis_side_effect, ): """Test getting rules when redis is down.""" mock_redis_client.exists.side_effect = redis_side_effect mock_rule_model.get_rules.return_value = response.Response(get_rules_fixture) mock_rule_model.format_rules_into_response_format.return_value = response.Response( get_rules_fixture ) mock_rule_model.filter_formatted_rules.return_value = response.Response( get_rules_formatted_fixture['items'] ) all_rules = rule.get_rules() mock_sentry_client.assert_called() assert all_rules.message == get_rules_formatted_fixture @patch('vector_job_rules.logic.rule.rule_model') @patch('vector_job_rules.logic.rule.get_rules') def test_update_rules_rules_mismatch_error(mock_get_rules, mock_rule_model): """Test updating rules with mismatch.""" mock_get_rules.return_value = response.Response( message={'items': [{'id': 1, 'priority': 1}]} ) data = [ {'rule_id': 1, 'priority': 3}, {'rule_id': 2, 'priority': 2}, {'rule_id': 3, 'priority': 1}, ] result = rule.update_rules(data) mock_rule_model.update_rule.assert_not_called() assert result.errors == { 'code': 'invalid_request', 'message': 'Rule ids in request must match database.', } assert result.status == 400 @patch('vector_job_rules.logic.rule.rule_model') @patch('vector_job_rules.logic.rule.get_rules') @patch('vector_job_rules.logic.rule.redis_client') def test_update_rules_success(mock_redis_client, mock_get_rules, mock_rule_model): """Test updating rules successfully.""" mock_get_rules.return_value = response.Response( message={'items': [{'id': 1, 'priority': 1}]} ) data = [{'rule_id': 1, 'priority': 3, 'updated_by': 1734}] result = rule.update_rules(data) mock_rule_model.update_rule.assert_called_with( 1, priority=3, description=None, updated_by=1734 ) mock_redis_client.flushall.assert_called() assert result.message == 'Rule priorities successfully updated.' assert result.status == 200 @pytest.mark.parametrize( 'redis_side_effect', [redis_exceptions.TimeoutError(), redis_exceptions.ConnectionError()], ) @patch('vector_job_rules.logic.rule.capture_exception') @patch('vector_job_rules.logic.rule.rule_model') @patch('vector_job_rules.logic.rule.get_rules') @patch('vector_job_rules.logic.rule.redis_client') def test_update_rules_redis_error( mock_redis_client, mock_get_rules, mock_rule_model, mock_sentry_client, redis_side_effect, ): """Test updating rules successfully.""" mock_redis_client.flushall.side_effect = redis_side_effect mock_get_rules.return_value = response.Response( message={'items': [{'id': 1, 'priority': 1}]} ) data = [{'rule_id': 1, 'priority': 3}] result = rule.update_rules(data) mock_rule_model.update_rule.assert_called_with( 1, priority=3, description=None, updated_by=None ) mock_redis_client.flushall.assert_called() mock_sentry_client.assert_called() assert result.message == 'Rule priorities successfully updated.' assert result.status == 200