"""Test for the Rule Model.""" import json from unittest.mock import patch from owsresponse import response import pytest from redis import exceptions as redis_exceptions from sqlalchemy.orm.exc import NoResultFound from tests.unit.conftest import get_rules from tests.unit.conftest import get_rules_data from vector_job_rules.connectors.redis import redis_client from vector_job_rules.models import rule @pytest.mark.parametrize( 'status, rule_ids, result', [ (None, None, get_rules_data()), (None, (1,), get_rules_data()), (None, (0,), []), (None, (2,), []), ('active', None, get_rules_data()), ('inactive', None, []), ], ) def test_get_rules_filtered(status, rule_ids, result, db_fixture): """Test getting all rules filtered.""" all_rules = rule.get_rules(status=status, rule_ids=rule_ids) assert all_rules.message == result @pytest.mark.parametrize( 'get_rules, result', [ (get_rules_data(), get_rules()), ([], []), ], ) def test_formatting_rules(get_rules, result): """Test formatting rules helper.""" all_rules_formatted = rule.format_rules_into_response_format( response.Response(get_rules) ) assert all_rules_formatted.message == result @pytest.mark.parametrize( 'formatted_rules, result', [ ( get_rules(), get_rules(), ), ([], []), ], ) def test_push_rules_into_cache(formatted_rules, result, db_fixture): """Test getting all rules.""" redis_client.flushall() rule.push_rules_into_cache(response.Response(formatted_rules)) all_rules = rule.get_rules_from_cache() assert all_rules.message == result @pytest.mark.parametrize( 'redis_side_effect', [redis_exceptions.TimeoutError(), redis_exceptions.ConnectionError()], ) @patch('vector_job_rules.models.rule.redis_client') @patch('vector_job_rules.models.rule.capture_exception') def test_push_rules_into_cache_when_redis_down( mock_sentry_client, mock_redis_client, get_rules_formatted_fixture, redis_side_effect, ): """Test setting rules when redis is down.""" mock_redis_client.hset.side_effect = redis_side_effect formatted_rules = get_rules_formatted_fixture['items'] rule.push_rules_into_cache(response.Response(formatted_rules)) mock_sentry_client.assert_called() def test_push_rules_into_cache_set(db_fixture, get_rules_formatted_fixture): """Test getting one rule by key.""" redis_client.flushall() rule.push_rules_into_cache(response.Response(get_rules_formatted_fixture['items'])) get_single_rule = json.loads(redis_client.get('ows_vector_job_rules_rule_1')) assert get_single_rule == get_rules_formatted_fixture['items'][0] @pytest.mark.parametrize( 'status, rule_ids, result', [ (None, (1,), get_rules()), (None, (0,), []), (None, (2,), []), ('active', None, get_rules()), ('inactive', None, []), ], ) def test_get_rules_from_cache( get_rules_formatted_fixture, status, rule_ids, result, db_fixture ): """Test getting all rules and test filters.""" redis_client.flushall() formatted_rules = response.Response(get_rules_formatted_fixture['items']) rule.push_rules_into_cache(formatted_rules) all_rules = rule.get_rules_from_cache(status=status, rule_ids=rule_ids) assert all_rules.message == result @pytest.mark.parametrize( 'status,rule_ids,result', [ (None, (1,), get_rules()), (None, (0,), []), (None, (2,), []), ('active', None, get_rules()), ('inactive', None, []), ], ) def test_filter_formatted_rules(get_rules_formatted_fixture, status, rule_ids, result): """Test filter formatted rules.""" formatted_rules = response.Response(get_rules_formatted_fixture['items']) filtered_rules = rule.filter_formatted_rules( formatted_rules, status=status, rule_ids=rule_ids ) assert filtered_rules.message == result def test_update_rule_not_found(db_fixture): """Test updating a rule with invalid id returns an error.""" try: rule.update_rule(1000) except NoResultFound as e: assert str(e) == 'No row was found when one was required' @pytest.mark.parametrize( 'rule_id, updated_priority, ' 'updated_description, priority, description', [ (1, None, None, 1, 'Rule 1'), (1, 2, 'changed', 2, 'changed'), (1, None, 'changed again', 1, 'changed again'), (1, 2, None, 2, 'Rule 1'), ], ) def test_update_rule( db_fixture, rule_id, updated_priority, updated_description, priority, description ): """Test updating a rule.""" result = rule.update_rule( rule_id, priority=updated_priority, description=updated_description ) assert result.message['priority'] == priority assert result.message['rule_id'] == rule_id assert result.message['description'] == description @pytest.mark.parametrize( 'rule_id, updated_priority, ' 'updated_description, priority, description, updated_by', [ (1, None, None, 1, 'Rule 1', 1734), (1, 2, 'changed', 2, 'changed', 1734), (1, None, 'changed again', 1, 'changed again', 1734), (1, 2, None, 2, 'Rule 1', 1734), ], ) def test_update_rule_with_updated_by( db_fixture, rule_id, updated_priority, updated_description, priority, description, updated_by, ): """Test updating a rule.""" result = rule.update_rule( rule_id, priority=updated_priority, description=updated_description, updated_by=updated_by, ) assert result.message['priority'] == priority assert result.message['rule_id'] == rule_id assert result.message['description'] == description assert result.message['updated_by'] == updated_by