"""Test BlacklistWords Model.""" from datetime import datetime import os from tempfile import NamedTemporaryFile from unittest.mock import MagicMock from unittest.mock import patch import pytest from sqlalchemy import column from sqlalchemy import func from sqlalchemy.exc import SQLAlchemyError from blacklist_manager.models import blacklist_words from tests.unit.conftest import valid_blacklist_word_data, \ valid_blacklist_word_data2 from tests.unit.utils import db @pytest.mark.parametrize( ('term', 'expected_response'), [ ( None, [ valid_blacklist_word_data.__name__, valid_blacklist_word_data2.__name__, ], ), ( 'Word', [ valid_blacklist_word_data.__name__, ], ), ] ) def test_blacklist_words_success( db_fixture, term, expected_response, valid_blacklist_words_response): """Test successful retrieval of blacklist words.""" db.insert_mock_records() result = blacklist_words.get_blacklist_words(term=term) assert result.message == valid_blacklist_words_response(expected_response) assert result.status == 200 @pytest.mark.parametrize('term', [None, 'Word']) @patch('blacklist_manager.models.blacklist_words.capture_exception') @patch('blacklist_manager.connectors.mysql.ar_database_session') def test_get_blacklist_words_failure(ar_db_session, mock_sentry, term): """Test fatal db error while retrieval of blacklist words.""" session = MagicMock() session.query = MagicMock(side_effect=SQLAlchemyError()) ar_db_session.return_value = session result = blacklist_words.get_blacklist_words(term=term) assert result.status == 500 assert mock_sentry.called @pytest.mark.parametrize(('term', 'expected_count'), [(None, 2), ('Word', 1)]) def test_blacklist_words_count_success(db_fixture, term, expected_count): """Test successful retrieval of blacklist words count.""" db.insert_mock_records() result = blacklist_words.get_blacklist_words_count(term=term) assert result.message == expected_count @pytest.mark.parametrize('term', [None, 'Word']) @patch('blacklist_manager.models.blacklist_words.capture_exception') @patch('blacklist_manager.connectors.mysql.ar_database_session') def test_blacklist_words_count_failure(ar_db_session, mock_sentry, term): """Test fatal db error while retrieval of blacklist words count.""" session = MagicMock() session.query = MagicMock(side_effect=SQLAlchemyError()) ar_db_session.return_value = session result = blacklist_words.get_blacklist_words_count(term=term) assert result.status == 500 assert mock_sentry.called def test_delete_blacklist_word(db_fixture): """Check that delete blacklist word works.""" blacklist_id = 1 db.insert_mock_records() result = blacklist_words.delete_blacklist_word(blacklist_id) assert result.status == 200 def test_delete_blacklist_word_not_found(db_fixture): """Check that delete blacklist word works when it is missed.""" blacklist_id = 9 db.insert_mock_records() response = blacklist_words.delete_blacklist_word(blacklist_id) assert response.status == 404 @patch('blacklist_manager.models.blacklist_words.capture_exception') @patch('blacklist_manager.connectors.mysql.ar_database_session', side_effect=SQLAlchemyError()) def test_delete_blacklist_word_failure(ar_db_session, mock_sentry): """Test fatal db error while deleting a blacklist word.""" blacklist_id = 9 result = blacklist_words.delete_blacklist_word(blacklist_id) assert result.status == 500 def test_create_blacklist_word_success( db_fixture, blacklist_word_response, blacklist_word_data): """Test successful creation of blacklist word.""" result = blacklist_words.create_blacklist_word(blacklist_word_data) assert result.message == blacklist_word_response assert result.status == 201 @patch('blacklist_manager.models.blacklist_words.capture_exception') @patch('blacklist_manager.connectors.mysql.ar_database_session', side_effect=SQLAlchemyError()) def test_create_blacklist_word_failure( ar_db_session, mock_sentry, blacklist_word_data, monkeypatch): """Test fatal db error while creating a blacklist word.""" monkeypatch.setattr( ar_db_session, 'add', value=MagicMock(return_value='')) result = blacklist_words.create_blacklist_word(blacklist_word_data) assert result.status == 500 assert mock_sentry.called def test_update_blacklist_word_success( db_fixture, blacklist_word_response, blacklist_update_word_data): """Test successful update of blacklist word.""" blacklist_id = 1 db.insert_mock_records() result = blacklist_words.update_blacklist_word( blacklist_id, blacklist_update_word_data) assert result.message == blacklist_word_response assert result.status == 200 @patch('blacklist_manager.models.blacklist_words.capture_exception') @patch('blacklist_manager.connectors.mysql.ar_database_session', side_effect=SQLAlchemyError()) def test_update_blacklist_word_failure(ar_db_session, mock_sentry, blacklist_update_word_data): """Test fatal db error while updating a blacklist word.""" blacklist_id = 1 result = blacklist_words.update_blacklist_word( blacklist_id, blacklist_update_word_data) assert result.status == 500 assert mock_sentry.called def test_update_blacklist_word_not_found( db_fixture, blacklist_update_word_data): """Check that update blacklist word works when it is missed.""" blacklist_id = 2 db.insert_mock_records() response = blacklist_words.update_blacklist_word( blacklist_id, blacklist_update_word_data) assert response.status == 404 def test_blacklist_words_for_validation_success( db_fixture, valid_response_for_release_validation): """Test successful retrieval of blacklist words.""" db.insert_mock_records() with db.ar_db_session() as session: result = blacklist_words.get_blacklist_words_for_validation(session) assert result.message == \ valid_response_for_release_validation assert result.status == 200 @patch('blacklist_manager.models.blacklist_words.capture_exception') def test_get_blacklist_words_for_validation_failure(mock_sentry): """Test fatal db error while retrieval of blacklist words.""" session = MagicMock() session.query = MagicMock(side_effect=SQLAlchemyError()) result = blacklist_words.get_blacklist_words_for_validation(session) assert result.status == 500 assert mock_sentry.called def test_write_blacklist_words_to_file(db_fixture, mocker): """Test write_blacklist_words_to_file.""" db.insert_mock_records() # sqllite does not have concat() fn, so replace that with just f_name. mocker.patch.object(func, 'concat', return_value=column('f_name'), autospec=True) file = NamedTemporaryFile(delete=False, mode='w') file_path = file.name result = blacklist_words.write_blacklist_words_to_file(file_path) assert result assert result.message == {'count': 2} with open(file_path, 'r') as file: content = file.readline() assert content == '"Id","Word","Notes","Reason","Date Added","Added By"\n' content = file.readline() assert content == '1,"Blacklist Word","Blacklist Notes","Valid Reason","2018-09-02 00:00:00","test"\n' os.remove(file_path) def test_write_blacklist_words_no_rows(db_fixture, mocker): """Test write_blacklist_words_to_file.""" # sqllite does not have concat() fn, so replace that with just f_name. mocker.patch.object(func, 'concat', return_value=column('f_name'), autospec=True) file_path = '/tmp/blacklist_{}.csv'.format(datetime.now().timestamp()) result = blacklist_words.write_blacklist_words_to_file(file_path) assert result.status == 404 assert result.errors['message'] == 'no blacklist records found' assert not os.path.exists(file_path) @patch('blacklist_manager.models.blacklist_words.capture_exception') @patch('blacklist_manager.connectors.mysql.ar_database_session') def test_write_blacklist_words_db_error(ar_db_session, mock_sentry): """Test write_blacklist_words_to_file.""" session = MagicMock() error_msg = 'dummy error' session.query = MagicMock(side_effect=SQLAlchemyError(error_msg)) ar_db_session.return_value = session file_path = '/tmp/blacklist_{}.csv'.format(datetime.now().timestamp()) result = blacklist_words.write_blacklist_words_to_file(file_path) assert result.status == 500 assert result.errors['message'] == error_msg assert not os.path.exists(file_path) def test_get_blacklist_words_by_reason_ids_success(db_fixture): """Test successful retrieval of blacklist words by reason IDs.""" db.insert_mock_records() with db.ar_db_session() as session: reason_ids = [3] # 3 is a valid reason_id in mock data result = blacklist_words.get_blacklist_words_by_reason_ids(session, reason_ids) assert result.status == 200 assert 'items' in result.message expected = [{'word': 'Blacklist Word', 'reason_id': 3}] assert result.message['items'] == expected @patch('blacklist_manager.models.blacklist_words.capture_exception') def test_get_blacklist_words_by_reason_ids_failure(mock_sentry): """Test fatal db error while retrieving blacklist words by reason IDs.""" session = MagicMock() session.query = MagicMock(side_effect=SQLAlchemyError()) reason_ids = [1] result = blacklist_words.get_blacklist_words_by_reason_ids(session, reason_ids) assert result.status == 500 assert mock_sentry.called