import pytest from app import create_app from app.models import User, db, Folder class TestIMAPRoutes: def test_imap_config_modal(self, authenticated_client): response = authenticated_client.get('/api/imap/config') assert response.status_code == 200 assert b'Configure IMAP Connection' in response.data def test_imap_connection_test_success(self, authenticated_client, app): response = authenticated_client.post('/api/imap/test', data={ 'server': 'localhost', 'port': '5143', 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False }) print(response.data) assert response.status_code == 200 # After successful connection, it should show the folder selection modal assert b'Configure IMAP Folders' in response.data def test_imap_sync_selected_folders_no_config(self, authenticated_client): """Test sync-selected fails when no IMAP config is set""" response = authenticated_client.post('/api/imap/sync-selected', data={}) assert response.status_code == 400 assert b'No IMAP configuration found' in response.data def test_imap_sync_selected_folders_no_selection(self, authenticated_client, mock_user): """Test sync-selected fails when no folders are selected""" # Set up IMAP config mock_user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} db.session.commit() response = authenticated_client.post('/api/imap/sync-selected', data={}) assert response.status_code == 400 assert b'No folders selected' in response.data def test_imap_sync_selected_folders_with_real_folders(self, authenticated_client, mock_user): """Test sync-selected succeeds with real folders from the IMAP server""" # Set up IMAP config mock_user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} db.session.commit() # Get initial folder count initial_folders = Folder.query.filter_by(user_id=mock_user.id).all() initial_count = len(initial_folders) # Use real folder names from the IMAP server that we saw in the test output # Note: The endpoint strips leading/trailing spaces before storing form_data = { 'folder_0': ' Receipts', 'folder_type_0': 'destination', 'folder_1': ' Marketing', 'folder_type_1': 'tidy' } response = authenticated_client.post('/api/imap/sync-selected', data=form_data) # Should return 200 with proper headers assert response.status_code == 200 assert response.headers.get('HX-Trigger') == 'close-modal, folder-list-invalidated' # Check that new folders were created new_folders = Folder.query.filter_by(user_id=mock_user.id).all() assert len(new_folders) > initial_count # Verify folder types were set correctly (names are stripped before storing) receipts_folder = Folder.query.filter_by(user_id=mock_user.id, name='Receipts').first() marketing_folder = Folder.query.filter_by(user_id=mock_user.id, name='Marketing').first() assert receipts_folder is not None assert receipts_folder.folder_type == 'destination' assert marketing_folder is not None assert marketing_folder.folder_type == 'tidy' def test_imap_sync_selected_folders_existing_folders(self, authenticated_client, mock_user): """Test sync-selected updates existing folders instead of creating duplicates""" # Set up IMAP config mock_user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} db.session.commit() # Clean up any existing folders first Folder.query.filter_by(user_id=mock_user.id).delete() db.session.commit() # Create an existing folder (without leading spaces since they get stripped) existing_folder = Folder( user_id=mock_user.id, name='Receipts', # This is how it will be stored after stripping folder_type='destination', total_count=5, pending_count=2 ) db.session.add(existing_folder) db.session.commit() initial_count = Folder.query.filter_by(user_id=mock_user.id).count() # Select the existing folder and a new one form_data = { 'folder_0': ' Receipts', # IMAP returns with space, but gets stripped 'folder_type_0': 'tidy', # Different type to test update 'folder_1': ' Personal', 'folder_type_1': 'destination' } response = authenticated_client.post('/api/imap/sync-selected', data=form_data) assert response.status_code == 200 # Check that we have exactly one more folder (the new one) final_folders = Folder.query.filter_by(user_id=mock_user.id).all() assert len(final_folders) == initial_count + 1 # Check that existing folder type was updated updated_folder = Folder.query.filter_by(user_id=mock_user.id, name='Receipts').first() assert updated_folder is not None assert updated_folder.folder_type == 'tidy' # Check that new folder was created (name gets stripped) new_folder = Folder.query.filter_by(user_id=mock_user.id, name='Personal').first() assert new_folder is not None assert new_folder.folder_type == 'destination' def test_imap_sync_selected_folders_special_folders_skipped(self, authenticated_client, mock_user): """Test sync-selected skips special folders like sent, drafts, spam, trash""" # Set up IMAP config mock_user.imap_config = {'server': 'localhost', 'port': 5143, 'username': 'user1@example.com', 'password': 'password1', 'use_ssl': False} db.session.commit() initial_count = Folder.query.filter_by(user_id=mock_user.id).count() # Clean up any existing folders first Folder.query.filter_by(user_id=mock_user.id).delete() db.session.commit() initial_count = Folder.query.filter_by(user_id=mock_user.id).count() # Try to select special folders along with real folders form_data = { 'folder_0': 'Sent', 'folder_type_0': 'destination', 'folder_1': 'Drafts', 'folder_type_1': 'tidy', 'folder_2': 'Spam', 'folder_type_2': 'destination', 'folder_3': 'Trash', 'folder_type_3': 'tidy', 'folder_4': ' Work', 'folder_type_4': 'destination' } response = authenticated_client.post('/api/imap/sync-selected', data=form_data) assert response.status_code == 200 # Check that only Work folder was created (special folders should be skipped) final_folders = Folder.query.filter_by(user_id=mock_user.id).all() assert len(final_folders) == initial_count + 1 # Check that Work folder exists (name gets stripped) work_folder = Folder.query.filter_by(user_id=mock_user.id, name='Work').first() assert work_folder is not None assert work_folder.folder_type == 'destination' # Check that special folders don't exist special_folders = ['Sent', 'Drafts', 'Spam', 'Trash'] for folder_name in special_folders: folder = Folder.query.filter_by(user_id=mock_user.id, name=folder_name).first() assert folder is None, f"Special folder {folder_name} should not have been created"