diff --git a/tests/test_notifications.py b/tests/test_notifications.py index 6bf4eadf..4a73aebb 100644 --- a/tests/test_notifications.py +++ b/tests/test_notifications.py @@ -1,175 +1,165 @@ -import os -import unittest -from unittest.mock import patch, MagicMock -from app.utils.notification import notify_file_processed, send_notification +import pytest + from app.config import settings +from app.utils.notification import notify_file_processed, send_notification -class TestFileProcessedNotification(unittest.TestCase): +@pytest.mark.unit +class TestFileProcessedNotification: """Test file processing notification functionality""" - - @patch('app.utils.notification.send_notification') - def test_notify_file_processed_when_enabled(self, mock_send): + + def test_notify_file_processed_when_enabled(self, mocker): """Test that notification is sent when NOTIFY_ON_FILE_PROCESSED is True""" # Arrange + mock_send = mocker.patch("app.utils.notification.send_notification") mock_send.return_value = True original_value = settings.notify_on_file_processed settings.notify_on_file_processed = True - + filename = "test_document.pdf" file_size = 1024 * 1024 # 1 MB - metadata = { - 'document_type': 'Invoice', - 'tags': ['financial', 'urgent'] - } - destinations = ['Dropbox', 'Google Drive'] - + metadata = {"document_type": "Invoice", "tags": ["financial", "urgent"]} + destinations = ["Dropbox", "Google Drive"] + try: # Act result = notify_file_processed(filename, file_size, metadata, destinations) - + # Assert - self.assertTrue(result) + assert result is True mock_send.assert_called_once() - + # Check the call arguments call_args = mock_send.call_args - self.assertIn("test_document.pdf", call_args[1]['title']) - self.assertIn("Invoice", call_args[1]['message']) - self.assertIn("financial, urgent", call_args[1]['message']) - self.assertIn("Dropbox, Google Drive", call_args[1]['message']) - self.assertEqual(call_args[1]['notification_type'], "success") + assert "test_document.pdf" in call_args[1]["title"] + assert "Invoice" in call_args[1]["message"] + assert "financial, urgent" in call_args[1]["message"] + assert "Dropbox, Google Drive" in call_args[1]["message"] + assert call_args[1]["notification_type"] == "success" finally: settings.notify_on_file_processed = original_value - - @patch('app.utils.notification.send_notification') - def test_notify_file_processed_when_disabled(self, mock_send): + + def test_notify_file_processed_when_disabled(self, mocker): """Test that notification is not sent when NOTIFY_ON_FILE_PROCESSED is False""" # Arrange + mock_send = mocker.patch("app.utils.notification.send_notification") original_value = settings.notify_on_file_processed settings.notify_on_file_processed = False - + filename = "test_document.pdf" file_size = 1024 * 1024 - metadata = {'document_type': 'Invoice', 'tags': []} - destinations = ['Dropbox'] - + metadata = {"document_type": "Invoice", "tags": []} + destinations = ["Dropbox"] + try: # Act result = notify_file_processed(filename, file_size, metadata, destinations) - + # Assert - self.assertFalse(result) + assert result is False mock_send.assert_not_called() finally: settings.notify_on_file_processed = original_value - - @patch('app.utils.notification.send_notification') - def test_notify_file_processed_with_no_destinations(self, mock_send): + + def test_notify_file_processed_with_no_destinations(self, mocker): """Test notification when no destinations are configured""" # Arrange + mock_send = mocker.patch("app.utils.notification.send_notification") mock_send.return_value = True original_value = settings.notify_on_file_processed settings.notify_on_file_processed = True - + filename = "test_document.pdf" file_size = 512 * 1024 # 512 KB - metadata = { - 'document_type': 'Receipt', - 'tags': [] - } + metadata = {"document_type": "Receipt", "tags": []} destinations = [] - + try: # Act result = notify_file_processed(filename, file_size, metadata, destinations) - + # Assert - self.assertTrue(result) + assert result is True mock_send.assert_called_once() - + # Check that message indicates no destinations call_args = mock_send.call_args - self.assertIn("None configured", call_args[1]['message']) + assert "None configured" in call_args[1]["message"] finally: settings.notify_on_file_processed = original_value - - @patch('app.utils.notification.send_notification') - def test_notify_file_processed_formats_file_size_mb(self, mock_send): + + def test_notify_file_processed_formats_file_size_mb(self, mocker): """Test that file size is formatted correctly for MB""" # Arrange + mock_send = mocker.patch("app.utils.notification.send_notification") mock_send.return_value = True original_value = settings.notify_on_file_processed settings.notify_on_file_processed = True - + filename = "large_document.pdf" file_size = 5 * 1024 * 1024 # 5 MB - metadata = {'document_type': 'Contract', 'tags': []} - destinations = ['Dropbox'] - + metadata = {"document_type": "Contract", "tags": []} + destinations = ["Dropbox"] + try: # Act result = notify_file_processed(filename, file_size, metadata, destinations) - + # Assert - self.assertTrue(result) + assert result is True call_args = mock_send.call_args - self.assertIn("5.00 MB", call_args[1]['message']) + assert "5.00 MB" in call_args[1]["message"] finally: settings.notify_on_file_processed = original_value - - @patch('app.utils.notification.send_notification') - def test_notify_file_processed_formats_file_size_kb(self, mock_send): + + def test_notify_file_processed_formats_file_size_kb(self, mocker): """Test that file size is formatted correctly for KB""" # Arrange + mock_send = mocker.patch("app.utils.notification.send_notification") mock_send.return_value = True original_value = settings.notify_on_file_processed settings.notify_on_file_processed = True - + filename = "small_document.pdf" file_size = 512 * 1024 # 512 KB - metadata = {'document_type': 'Note', 'tags': []} - destinations = ['Dropbox'] - + metadata = {"document_type": "Note", "tags": []} + destinations = ["Dropbox"] + try: # Act result = notify_file_processed(filename, file_size, metadata, destinations) - + # Assert - self.assertTrue(result) + assert result is True call_args = mock_send.call_args - self.assertIn("512.00 KB", call_args[1]['message']) + assert "512.00 KB" in call_args[1]["message"] finally: settings.notify_on_file_processed = original_value - - @patch('app.utils.notification.send_notification') - def test_notify_file_processed_with_missing_metadata_fields(self, mock_send): + + def test_notify_file_processed_with_missing_metadata_fields(self, mocker): """Test that notification handles missing metadata fields gracefully""" # Arrange + mock_send = mocker.patch("app.utils.notification.send_notification") mock_send.return_value = True original_value = settings.notify_on_file_processed settings.notify_on_file_processed = True - + filename = "document.pdf" file_size = 1024 * 1024 metadata = {} # Empty metadata - destinations = ['Dropbox'] - + destinations = ["Dropbox"] + try: # Act result = notify_file_processed(filename, file_size, metadata, destinations) - + # Assert - self.assertTrue(result) + assert result is True mock_send.assert_called_once() - + # Check that defaults are used call_args = mock_send.call_args - self.assertIn("Unknown", call_args[1]['message']) # Default document type - self.assertIn("None", call_args[1]['message']) # No tags + assert "Unknown" in call_args[1]["message"] # Default document type + assert "None" in call_args[1]["message"] # No tags finally: settings.notify_on_file_processed = original_value - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_utils.py b/tests/test_utils.py index f6471e68..f23e3d72 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,35 +1,39 @@ import os import tempfile -import unittest + +import pytest + from app.utils import hash_file -class TestUtils(unittest.TestCase): + +@pytest.mark.unit +class TestUtils: def test_hash_file_empty(self): """Test hashing an empty file""" with tempfile.NamedTemporaryFile(delete=False) as tmp_file: pass - + try: # Known SHA-256 hash of an empty file expected_hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - self.assertEqual(hash_file(tmp_file.name), expected_hash) + assert hash_file(tmp_file.name) == expected_hash finally: os.unlink(tmp_file.name) - + def test_hash_file_with_content(self): """Test hashing a file with known content""" content = b"Hello, World!" with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(content) tmp_file.flush() - + try: # Known SHA-256 hash of "Hello, World!" expected_hash = "dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f" - self.assertEqual(hash_file(tmp_file.name), expected_hash) + assert hash_file(tmp_file.name) == expected_hash finally: os.unlink(tmp_file.name) - + def test_hash_file_large_content(self): """Test hashing a file larger than the chunk size""" # Create content larger than the default chunk size (65536) @@ -37,13 +41,10 @@ class TestUtils(unittest.TestCase): with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(content) tmp_file.flush() - + try: # Test that we can hash a large file hash_result = hash_file(tmp_file.name) - self.assertEqual(len(hash_result), 64) # SHA-256 hashes are 64 characters long + assert len(hash_result) == 64 # SHA-256 hashes are 64 characters long finally: os.unlink(tmp_file.name) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file