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 class TestIMAPService: def test_init_with_user(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') user.imap_config = {'server': 'test.com', 'port': 993} imap_service = IMAPService(user) assert imap_service.user == user assert imap_service.config == {'server': 'test.com', 'port': 993} def test_init_without_config(self, app): user = User(email='test@example.com', first_name='Test', last_name='User') imap_service = IMAPService(user) assert imap_service.user == user assert imap_service.config == {} 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': True} imap_service = IMAPService(user) # 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) # 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, 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') imap_service = IMAPService(user) success, message = imap_service.test_connection() assert success is False assert message == "No IMAP configuration found" def test_get_folders_success(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) # 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, 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', []) 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 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) # 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.login.return_value = None 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') imap_service = IMAPService(user) folders = imap_service.get_folders() assert len(folders) == 0 def test_sync_folders_success(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'} imap_service = IMAPService(user) # 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, app): user = User(email='test@example.com', first_name='Test', last_name='User') imap_service = IMAPService(user) success, message = imap_service.sync_folders() assert success is False assert message == "No IMAP configuration found" def test_sync_folders_no_folders(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) # Mock the get_folders method to return an empty list with patch.object(imap_service, 'get_folders', return_value=[]): 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) # Mock the get_folders method to raise an exception with patch.object(imap_service, 'get_folders', side_effect=Exception("IMAP server error")): success, message = imap_service.sync_folders() assert success is False assert "Sync error: IMAP server error" in message