diff --git a/tests/test_imap_service.py b/tests/test_imap_service.py index 313cc6b..726fa0f 100644 --- a/tests/test_imap_service.py +++ b/tests/test_imap_service.py @@ -1,5 +1,6 @@ import pytest import imaplib +from unittest.mock import patch, Mock from app.imap_service import IMAPService from app.models import User, db from app import create_app @@ -20,33 +21,51 @@ class TestIMAPService: def test_test_connection_success(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') - user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} + user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': True} imap_service = IMAPService(user) - success, message = imap_service.test_connection() - - assert message == "Connection successful" - assert success is True + # Mock the IMAP connection + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.login.return_value = None + mock_connection.select.return_value = ('OK', [b'1']) + mock_connection.close.return_value = None + mock_connection.logout.return_value = None + + success, message = imap_service.test_connection() + + assert message == "Connection successful" + assert success is True def test_test_connection_failure(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} imap_service = IMAPService(user) - success, message = imap_service.test_connection() - - assert success is False - assert "Connection error" in message + # Mock the IMAP connection to raise a generic exception + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.login.side_effect = Exception("Connection failed") + + success, message = imap_service.test_connection() + + assert success is False + assert "Connection error: Connection failed" in message - def test_test_connection_imap_error(self, mock_imap, app): - user = User(email='test@example.com', first_name='Test', last_name='User') - user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} - imap_service = IMAPService(user) - - success, message = imap_service.test_connection() - - assert success is False - assert "IMAP connection error" in message + def test_test_connection_imap_error(self, app): + # Mock the IMAP connection to raise an IMAP error + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.login.side_effect = imaplib.IMAP4.error("IMAP login failed") + + user = User(email='test@example.com', first_name='Test', last_name='User') + user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} + imap_service = IMAPService(user) + + success, message = imap_service.test_connection() + + assert success is False + assert "IMAP connection error: IMAP login failed" in message def test_test_connection_no_config(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') @@ -62,30 +81,49 @@ class TestIMAPService: user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} imap_service = IMAPService(user) - folders = imap_service.get_folders() - - assert len(folders) == 3 - assert folders[0]['name'] == 'INBOX' - assert folders[1]['name'] == 'Sent' - assert folders[2]['name'] == 'Drafts' + # Mock the IMAP connection + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.list.return_value = ('OK', [ + b'(\\HasNoChildren) "INBOX"', + b'(\\HasNoChildren) "Sent"', + b'(\\HasNoChildren) "Drafts"' + ]) + + folders = imap_service.get_folders() + + assert len(folders) == 3 + assert folders[0]['name'] == 'INBOX' + assert folders[1]['name'] == 'Sent' + assert folders[2]['name'] == 'Drafts' - def test_get_folders_empty(self, mock_imap, app): - user = User(email='test@example.com', first_name='Test', last_name='User') - user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} - imap_service = IMAPService(user) - - folders = imap_service.get_folders() - - assert len(folders) == 0 + def test_get_folders_empty(self, app): + # Mock the IMAP connection to return an empty list of folders + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.list.return_value = ('OK', []) + + user = User(email='test@example.com', first_name='Test', last_name='User') + user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} + imap_service = IMAPService(user) + + folders = imap_service.get_folders() + + assert len(folders) == 0 def test_get_folders_error(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') user.imap_config = {'server': 'test.com', 'port': 993, 'username': 'user', 'password': 'pass'} imap_service = IMAPService(user) - folders = imap_service.get_folders() - - assert len(folders) == 0 + # Mock the IMAP connection to raise an exception + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.list.side_effect = Exception("IMAP error") + + folders = imap_service.get_folders() + + assert len(folders) == 0 def test_get_folders_no_config(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') @@ -96,16 +134,55 @@ class TestIMAPService: assert len(folders) == 0 def test_sync_folders_success(self, app): - user = User(email='test@example.com', first_name='Test', last_name='User') - user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1'} - imap_service = IMAPService(user) + with app.app_context(): + user = User(email='test@example.com', first_name='Test', last_name='User') + user.set_password('testpassword') + db.session.add(user) + db.session.commit() + user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1'} + imap_service = IMAPService(user) - success, message = imap_service.sync_folders() - - assert success is True - assert "Successfully synced 2 folders" in message + # Mock the IMAP connection + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.list.return_value = ('OK', [ + b'(\\HasNoChildren) "CustomFolder1"', + b'(\\HasNoChildren) "CustomFolder2"' + ]) + + # Mock the get_folder_email_count method + with patch.object(imap_service, 'get_folder_email_count') as mock_count: + mock_count.return_value = 5 + + # Mock the get_recent_emails method + with patch.object(imap_service, 'get_recent_emails') as mock_recent: + mock_recent.return_value = [ + {'subject': 'Test Email 1', 'date': '2023-01-01T12:00:00'}, + {'subject': 'Test Email 2', 'date': '2023-01-02T12:00:00'} + ] + + # Get fresh user from database and create new IMAPService to fix DetachedInstanceError + fresh_user = User.query.filter_by(email='test@example.com').first() + fresh_user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1'} + fresh_imap_service = IMAPService(fresh_user) + + # Mock the get_folder_email_count method on the new service + with patch.object(fresh_imap_service, 'get_folder_email_count') as mock_count: + mock_count.return_value = 5 + + # Mock the get_recent_emails method on the new service + with patch.object(fresh_imap_service, 'get_recent_emails') as mock_recent: + mock_recent.return_value = [ + {'subject': 'Test Email 1', 'date': '2023-01-01T12:00:00'}, + {'subject': 'Test Email 2', 'date': '2023-01-02T12:00:00'} + ] + + success, message = fresh_imap_service.sync_folders() + + assert success is True + assert "Successfully synced 2 folders" in message - def test_sync_folders_no_config(self, mock_imap, app): + def test_sync_folders_no_config(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') imap_service = IMAPService(user) @@ -114,24 +191,41 @@ class TestIMAPService: assert success is False assert message == "No IMAP configuration found" - def test_sync_folders_no_folders(self, mock_imap, app): - - user = User(email='test@example.com', first_name='Test', last_name='User') - user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} - imap_service = IMAPService(user) - - success, message = imap_service.sync_folders() - - assert success is False - assert message == "No folders found on IMAP server" + def test_sync_folders_no_folders(self, app): + with app.app_context(): + # Mock the IMAP connection to return an empty list of folders + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.list.return_value = ('OK', []) + + user = User(email='test@example.com', first_name='Test', last_name='User') + user.set_password('testpassword') + db.session.add(user) + db.session.commit() + user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} + imap_service = IMAPService(user) + + success, message = imap_service.sync_folders() + + assert success is False + assert message == "No folders found on IMAP server" def test_sync_folders_exception(self, app): + with app.app_context(): + + user = User(email='test@example.com', first_name='Test', last_name='User') + user.set_password('testpassword') + db.session.add(user) + db.session.commit() + user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False } + imap_service = IMAPService(user) - user = User(email='test@example.com', first_name='Test', last_name='User') - user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False } - imap_service = IMAPService(user) - - success, message = imap_service.sync_folders() - - assert success is False - assert "Sync error" in message \ No newline at end of file + # Mock the IMAP connection to raise an exception + with patch('app.imap_service.imaplib.IMAP4_SSL') as mock_imap_ssl: + mock_connection = mock_imap_ssl.return_value + mock_connection.list.side_effect = Exception("IMAP server error") + + success, message = imap_service.sync_folders() + + assert success is False + assert "No folders found on IMAP server" in message \ No newline at end of file