""" Integration tests for the complete application workflow. """ import pytest from unittest.mock import patch from app import load_application_data @pytest.mark.integration class TestCompleteWorkflow: """Integration tests for the complete application workflow.""" def test_complete_application_workflow(self, client, app, sample_pdf_file): """Test the complete workflow from email to confirmation.""" # Step 1: Submit email with patch('app.mail.send'): response = client.post('/apply/submit-email', data={ 'email': 'integration@test.com', 'job_name': 'Integration Test Position' }, follow_redirects=True) assert response.status_code == 200 # For testing, create a known session from app import save_application_data session_id = 'integration-test-123' save_application_data(session_id, { 'session_id': session_id, 'email': 'integration@test.com', 'job_name': 'Integration Test Position', 'current_page': 2, 'personal_info': {}, 'motivation_answers': {}, 'uploaded_files': [] }) # Step 2: Submit personal information response = client.post(f'/apply/{session_id}/submit-personal', data={ 'name': 'Schmidt', 'firstname': 'Thomas', 'address': 'Bahnhofstrasse 100', 'zip_code': '8001', 'city': 'Zürich', 'phone': '+41 79 999 88 77', 'birth_year': '1985', 'civil_status': 'verheiratet' }, follow_redirects=True) assert response.status_code == 200 # Verify data was saved data = load_application_data(session_id) assert data['personal_info']['name'] == 'Schmidt' assert data['current_page'] == 3 # Step 3: Submit motivation answers response = client.post(f'/apply/{session_id}/submit-motivation', data={ 'current_job': 'Senior Software Entwickler bei Tech Corp', 'motivation': 'Ich möchte Teil eines innovativen Teams werden', 'qualifications': 'Python, Flask, React, 10 Jahre Erfahrung', 'salary': '120000 CHF pro Jahr' }, follow_redirects=True) assert response.status_code == 200 # Verify motivation was saved data = load_application_data(session_id) assert data['motivation_answers']['current_job'] == 'Senior Software Entwickler bei Tech Corp' assert data['current_page'] == 4 # Step 4: Upload a file sample_pdf_file.seek(0) response = client.post( f'/apply/{session_id}/upload-file', data={'file': (sample_pdf_file, 'lebenslauf.pdf')}, content_type='multipart/form-data', follow_redirects=True ) assert response.status_code == 200 # Verify file was uploaded data = load_application_data(session_id) assert len(data['uploaded_files']) == 1 assert data['uploaded_files'][0]['original_name'] == 'lebenslauf.pdf' # Step 5: Submit final application response = client.post(f'/apply/{session_id}/submit-application', follow_redirects=True) assert response.status_code == 200 assert b'Vielen Dank' in response.data or b'erfolgreich' in response.data # Verify application was marked as submitted data = load_application_data(session_id) assert data['current_page'] == 5 assert data.get('status') == 'submitted' def test_workflow_with_resume(self, client, app, create_test_application): """Test resuming an application at different stages.""" session_id = 'resume-test-456' # Create an application at page 2 (personal info) create_test_application( session_id=session_id, current_page=2, email='resume@test.com', job_name='Resume Test Job' ) # Resume should redirect to personal info page response = client.get(f'/resume/{session_id}', follow_redirects=False) assert response.status_code == 302 assert b'/personal' in response.data # Fill in personal info client.post(f'/apply/{session_id}/submit-personal', data={ 'name': 'Weber', 'firstname': 'Maria', 'address': 'Seestrasse 50', 'zip_code': '8002', 'city': 'Zürich', 'phone': '+41 79 888 77 66', 'birth_year': '1992' }) # Now resume should go to motivation page response = client.get(f'/resume/{session_id}', follow_redirects=False) assert response.status_code == 302 assert b'/motivation' in response.data def test_multiple_concurrent_applications(self, client, app): """Test handling multiple concurrent applications with different sessions.""" from app import save_application_data # Create multiple applications sessions = [] for i in range(3): session_id = f'concurrent-{i}' sessions.append(session_id) save_application_data(session_id, { 'session_id': session_id, 'email': f'user{i}@test.com', 'job_name': f'Job {i}', 'current_page': 2, 'personal_info': {}, 'motivation_answers': {}, 'uploaded_files': [] }) # Verify all applications are independent for i, session_id in enumerate(sessions): data = load_application_data(session_id) assert data is not None assert data['email'] == f'user{i}@test.com' assert data['job_name'] == f'Job {i}' # Update one application client.post(f'/apply/{sessions[1]}/submit-personal', data={ 'name': 'Test', 'firstname': 'User', 'address': 'Street 1', 'zip_code': '12345', 'city': 'City', 'phone': '+41 79 123 45 67', 'birth_year': '1990' }) # Verify only that application was updated data0 = load_application_data(sessions[0]) data1 = load_application_data(sessions[1]) data2 = load_application_data(sessions[2]) assert data0['current_page'] == 2 # Not updated assert data1['current_page'] == 3 # Updated assert data2['current_page'] == 2 # Not updated @pytest.mark.integration class TestWorkflowEdgeCases: """Integration tests for edge cases in the workflow.""" def test_skip_optional_fields(self, client, app): """Test completing workflow without filling optional fields.""" from app import save_application_data session_id = 'optional-test' save_application_data(session_id, { 'session_id': session_id, 'email': 'optional@test.com', 'job_name': 'Test Job', 'current_page': 2, 'personal_info': {}, 'motivation_answers': {}, 'uploaded_files': [] }) # Submit personal info with minimal fields client.post(f'/apply/{session_id}/submit-personal', data={ 'name': 'Min', 'firstname': 'User', 'address': 'Addr 1', 'zip_code': '1', 'city': 'City', 'phone': '+1 123', 'birth_year': '1990', 'civil_status': '' # Optional, empty }) # Submit empty motivation (all fields optional) client.post(f'/apply/{session_id}/submit-motivation', data={ 'current_job': '', 'motivation': '', 'qualifications': '', 'salary': '' }) # Submit without files (optional) response = client.post(f'/apply/{session_id}/submit-application', follow_redirects=True) assert response.status_code == 200 # Verify application was submitted data = load_application_data(session_id) assert data['status'] == 'submitted' def test_workflow_with_unicode_data(self, client, app): """Test workflow with German special characters.""" from app import save_application_data session_id = 'unicode-test' save_application_data(session_id, { 'session_id': session_id, 'email': 'ümlaut@test.com', 'job_name': 'Geschäftsführer Position', 'current_page': 2, 'personal_info': {}, 'motivation_answers': {}, 'uploaded_files': [] }) # Submit with German characters client.post(f'/apply/{session_id}/submit-personal', data={ 'name': 'Müller', 'firstname': 'Björn', 'address': 'Königstrasse 42', 'zip_code': '80539', 'city': 'München', 'phone': '+49 89 123 45 67', 'birth_year': '1988' }) # Verify data persisted correctly data = load_application_data(session_id) assert data['personal_info']['name'] == 'Müller' assert data['personal_info']['firstname'] == 'Björn' assert data['personal_info']['city'] == 'München' assert data['job_name'] == 'Geschäftsführer Position' @pytest.mark.integration @pytest.mark.slow class TestDataIntegrity: """Integration tests for data integrity throughout the workflow.""" def test_data_not_lost_between_pages(self, client, app): """Test that data persists correctly when navigating between pages.""" from app import save_application_data session_id = 'persistence-test' save_application_data(session_id, { 'session_id': session_id, 'email': 'persist@test.com', 'job_name': 'Persistence Job', 'current_page': 2, 'personal_info': {}, 'motivation_answers': {}, 'uploaded_files': [] }) # Add personal info personal_data = { 'name': 'Persistence', 'firstname': 'Test', 'address': 'Test Street 1', 'zip_code': '12345', 'city': 'Test City', 'phone': '+1 555 1234', 'birth_year': '1990' } client.post(f'/apply/{session_id}/submit-personal', data=personal_data) # Verify personal data data = load_application_data(session_id) for key, value in personal_data.items(): assert data['personal_info'][key] == value # Add motivation motivation_data = { 'current_job': 'Developer', 'motivation': 'Test motivation', 'qualifications': 'Test skills', 'salary': '100k' } client.post(f'/apply/{session_id}/submit-motivation', data=motivation_data) # Verify both personal and motivation data still exist data = load_application_data(session_id) for key, value in personal_data.items(): assert data['personal_info'][key] == value for key, value in motivation_data.items(): assert data['motivation_answers'][key] == value # Submit application client.post(f'/apply/{session_id}/submit-application') # Verify all data still intact after submission data = load_application_data(session_id) assert data['email'] == 'persist@test.com' for key, value in personal_data.items(): assert data['personal_info'][key] == value for key, value in motivation_data.items(): assert data['motivation_answers'][key] == value