271 lines
9.8 KiB
Python
271 lines
9.8 KiB
Python
"""
|
|||
|
|
Tests for HR email notifications functionality.
|
||
|
|
"""
|
||
|
|
import pytest
|
||
|
|
from unittest.mock import patch, MagicMock
|
||
|
|
from app import send_hr_notification
|
||
|
|
|
||
|
|
|
||
|
|
class TestHRNotifications:
|
||
|
|
"""Test HR notification email functionality."""
|
||
|
|
|
||
|
|
def test_hr_notification_sent_on_submission(self, client, create_test_application, mock_mail):
|
||
|
|
"""Test that HR receives email when application is submitted."""
|
||
|
|
# Set HR_EMAIL in config
|
||
|
|
from app import app
|
||
|
|
app.config['HR_EMAIL'] = 'hr@example.com'
|
||
|
|
app.config['APPLICATION_URL_BASE'] = 'http://localhost:5000'
|
||
|
|
|
||
|
|
# Create a test application with all required data
|
||
|
|
session_id = 'test-session-123'
|
||
|
|
create_test_application(
|
||
|
|
session_id=session_id,
|
||
|
|
email='applicant@example.com',
|
||
|
|
job_name='Software Developer',
|
||
|
|
current_page=4,
|
||
|
|
personal_info={
|
||
|
|
'name': 'Müller',
|
||
|
|
'firstname': 'Anna',
|
||
|
|
'address': 'Hauptstrasse 123',
|
||
|
|
'zip_code': '8001',
|
||
|
|
'city': 'Zürich',
|
||
|
|
'phone': '+41 79 123 45 67',
|
||
|
|
'birth_year': '1990',
|
||
|
|
'civil_status': 'ledig'
|
||
|
|
},
|
||
|
|
motivation_answers={
|
||
|
|
'current_job': 'Developer',
|
||
|
|
'motivation': 'Great company',
|
||
|
|
'qualifications': 'Python expert',
|
||
|
|
'salary': '100000'
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
# Submit the application
|
||
|
|
response = client.post(f'/apply/{session_id}/submit-application')
|
||
|
|
|
||
|
|
# Verify redirect to confirmation page
|
||
|
|
assert response.status_code == 302
|
||
|
|
assert f'/apply/{session_id}/confirmation' in response.location
|
||
|
|
|
||
|
|
# Verify HR email was sent
|
||
|
|
assert len(mock_mail.sent_messages) == 1
|
||
|
|
hr_email = mock_mail.sent_messages[0]
|
||
|
|
|
||
|
|
assert 'hr@example.com' in hr_email.recipients
|
||
|
|
assert 'Neue Bewerbung eingegangen: Software Developer' == hr_email.subject
|
||
|
|
assert 'Anna Müller' in hr_email.body
|
||
|
|
assert 'applicant@example.com' in hr_email.body
|
||
|
|
assert f'/application/{session_id}/' in hr_email.body
|
||
|
|
|
||
|
|
def test_hr_notification_not_sent_when_hr_email_not_configured(
|
||
|
|
self, client, create_test_application, mock_mail, caplog
|
||
|
|
):
|
||
|
|
"""Test that HR notification is skipped when HR_EMAIL is not configured."""
|
||
|
|
# Ensure HR_EMAIL is not set
|
||
|
|
from app import app
|
||
|
|
app.config['HR_EMAIL'] = None
|
||
|
|
|
||
|
|
# Create a test application
|
||
|
|
session_id = 'test-session-456'
|
||
|
|
create_test_application(
|
||
|
|
session_id=session_id,
|
||
|
|
email='applicant@example.com',
|
||
|
|
job_name='Data Analyst',
|
||
|
|
current_page=4,
|
||
|
|
personal_info={
|
||
|
|
'name': 'Schmidt',
|
||
|
|
'firstname': 'Max',
|
||
|
|
'address': 'Bahnhofstrasse 1',
|
||
|
|
'zip_code': '8000',
|
||
|
|
'city': 'Zürich',
|
||
|
|
'phone': '+41 79 999 88 77',
|
||
|
|
'birth_year': '1985',
|
||
|
|
'civil_status': 'verheiratet'
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
# Submit the application
|
||
|
|
response = client.post(f'/apply/{session_id}/submit-application')
|
||
|
|
|
||
|
|
# Verify redirect to confirmation page
|
||
|
|
assert response.status_code == 302
|
||
|
|
|
||
|
|
# Verify no HR email was sent
|
||
|
|
assert len(mock_mail.sent_messages) == 0
|
||
|
|
|
||
|
|
# Verify warning was logged
|
||
|
|
assert 'HR_EMAIL not configured' in caplog.text
|
||
|
|
|
||
|
|
def test_hr_notification_includes_file_count(self, client, create_test_application, mock_mail):
|
||
|
|
"""Test that HR notification includes the count of uploaded files."""
|
||
|
|
from app import app
|
||
|
|
app.config['HR_EMAIL'] = 'hr@example.com'
|
||
|
|
app.config['APPLICATION_URL_BASE'] = 'http://localhost:5000'
|
||
|
|
|
||
|
|
# Create application with uploaded files
|
||
|
|
session_id = 'test-session-789'
|
||
|
|
create_test_application(
|
||
|
|
session_id=session_id,
|
||
|
|
email='applicant@example.com',
|
||
|
|
job_name='Project Manager',
|
||
|
|
current_page=4,
|
||
|
|
personal_info={
|
||
|
|
'name': 'Weber',
|
||
|
|
'firstname': 'Lisa',
|
||
|
|
'address': 'Seestrasse 45',
|
||
|
|
'zip_code': '8002',
|
||
|
|
'city': 'Zürich',
|
||
|
|
'phone': '+41 79 555 44 33',
|
||
|
|
'birth_year': '1992',
|
||
|
|
'civil_status': 'ledig'
|
||
|
|
},
|
||
|
|
uploaded_files=[
|
||
|
|
{
|
||
|
|
'original_name': 'cv.pdf',
|
||
|
|
'stored_name': '20250101_120000_cv.pdf',
|
||
|
|
'size': 102400,
|
||
|
|
'uploaded_at': '2025-01-01T12:00:00'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
'original_name': 'certificate.pdf',
|
||
|
|
'stored_name': '20250101_120100_certificate.pdf',
|
||
|
|
'size': 204800,
|
||
|
|
'uploaded_at': '2025-01-01T12:01:00'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
)
|
||
|
|
|
||
|
|
# Submit the application
|
||
|
|
response = client.post(f'/apply/{session_id}/submit-application')
|
||
|
|
|
||
|
|
assert response.status_code == 302
|
||
|
|
|
||
|
|
# Verify HR email contains file count
|
||
|
|
assert len(mock_mail.sent_messages) == 1
|
||
|
|
hr_email = mock_mail.sent_messages[0]
|
||
|
|
assert 'Anzahl der hochgeladenen Dokumente: 2' in hr_email.body
|
||
|
|
|
||
|
|
def test_hr_notification_with_zero_files(self, client, create_test_application, mock_mail):
|
||
|
|
"""Test that HR notification works even when no files are uploaded."""
|
||
|
|
from app import app
|
||
|
|
app.config['HR_EMAIL'] = 'hr@example.com'
|
||
|
|
app.config['APPLICATION_URL_BASE'] = 'http://localhost:5000'
|
||
|
|
|
||
|
|
# Create application without uploaded files
|
||
|
|
session_id = 'test-session-000'
|
||
|
|
create_test_application(
|
||
|
|
session_id=session_id,
|
||
|
|
email='applicant@example.com',
|
||
|
|
job_name='Sales Representative',
|
||
|
|
current_page=4,
|
||
|
|
personal_info={
|
||
|
|
'name': 'Fischer',
|
||
|
|
'firstname': 'Tom',
|
||
|
|
'address': 'Hauptplatz 10',
|
||
|
|
'zip_code': '8003',
|
||
|
|
'city': 'Zürich',
|
||
|
|
'phone': '+41 79 111 22 33',
|
||
|
|
'birth_year': '1988',
|
||
|
|
'civil_status': 'ledig'
|
||
|
|
},
|
||
|
|
uploaded_files=[]
|
||
|
|
)
|
||
|
|
|
||
|
|
# Submit the application
|
||
|
|
response = client.post(f'/apply/{session_id}/submit-application')
|
||
|
|
|
||
|
|
assert response.status_code == 302
|
||
|
|
|
||
|
|
# Verify HR email was sent with 0 file count
|
||
|
|
assert len(mock_mail.sent_messages) == 1
|
||
|
|
hr_email = mock_mail.sent_messages[0]
|
||
|
|
assert 'Anzahl der hochgeladenen Dokumente: 0' in hr_email.body
|
||
|
|
|
||
|
|
def test_send_hr_notification_function_directly(self, app):
|
||
|
|
"""Test the send_hr_notification function directly."""
|
||
|
|
from app import send_hr_notification
|
||
|
|
|
||
|
|
app.config['HR_EMAIL'] = 'hr@example.com'
|
||
|
|
app.config['APPLICATION_URL_BASE'] = 'http://localhost:5000'
|
||
|
|
|
||
|
|
session_id = 'test-123'
|
||
|
|
app_data = {
|
||
|
|
'email': 'applicant@example.com',
|
||
|
|
'job_name': 'Test Job',
|
||
|
|
'submitted_at': '2025-01-01T12:00:00',
|
||
|
|
'personal_info': {
|
||
|
|
'firstname': 'John',
|
||
|
|
'name': 'Doe'
|
||
|
|
},
|
||
|
|
'uploaded_files': [
|
||
|
|
{'original_name': 'cv.pdf', 'stored_name': 'cv_stored.pdf', 'size': 1024}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
|
||
|
|
with app.app_context():
|
||
|
|
# Mock mail.send to prevent actual sending
|
||
|
|
with patch('app.mail.send') as mock_send:
|
||
|
|
result = send_hr_notification(session_id, app_data)
|
||
|
|
assert result is True
|
||
|
|
assert mock_send.called
|
||
|
|
|
||
|
|
def test_send_hr_notification_handles_email_failure(self, app, caplog):
|
||
|
|
"""Test that send_hr_notification handles email sending failures gracefully."""
|
||
|
|
from app import send_hr_notification
|
||
|
|
|
||
|
|
app.config['HR_EMAIL'] = 'hr@example.com'
|
||
|
|
app.config['APPLICATION_URL_BASE'] = 'http://localhost:5000'
|
||
|
|
|
||
|
|
session_id = 'test-456'
|
||
|
|
app_data = {
|
||
|
|
'email': 'applicant@example.com',
|
||
|
|
'job_name': 'Test Job',
|
||
|
|
'submitted_at': '2025-01-01T12:00:00',
|
||
|
|
'personal_info': {
|
||
|
|
'firstname': 'Jane',
|
||
|
|
'name': 'Smith'
|
||
|
|
},
|
||
|
|
'uploaded_files': []
|
||
|
|
}
|
||
|
|
|
||
|
|
with app.app_context():
|
||
|
|
# Mock mail.send to raise an exception
|
||
|
|
with patch('app.mail.send', side_effect=Exception('SMTP error')):
|
||
|
|
result = send_hr_notification(session_id, app_data)
|
||
|
|
assert result is False
|
||
|
|
assert 'Failed to send HR notification email' in caplog.text
|
||
|
|
|
||
|
|
def test_hr_notification_url_format(self, client, create_test_application, mock_mail):
|
||
|
|
"""Test that the application URL in HR notification is correctly formatted."""
|
||
|
|
from app import app
|
||
|
|
app.config['HR_EMAIL'] = 'hr@example.com'
|
||
|
|
app.config['APPLICATION_URL_BASE'] = 'https://example.com'
|
||
|
|
|
||
|
|
session_id = 'test-url-format'
|
||
|
|
create_test_application(
|
||
|
|
session_id=session_id,
|
||
|
|
email='applicant@example.com',
|
||
|
|
job_name='Test Position',
|
||
|
|
current_page=4,
|
||
|
|
personal_info={
|
||
|
|
'name': 'Test',
|
||
|
|
'firstname': 'User',
|
||
|
|
'address': 'Street 1',
|
||
|
|
'zip_code': '8000',
|
||
|
|
'city': 'City',
|
||
|
|
'phone': '+41 79 123 45 67',
|
||
|
|
'birth_year': '1990',
|
||
|
|
'civil_status': 'ledig'
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
# Submit the application
|
||
|
|
client.post(f'/apply/{session_id}/submit-application')
|
||
|
|
|
||
|
|
# Verify URL format in email
|
||
|
|
assert len(mock_mail.sent_messages) == 1
|
||
|
|
hr_email = mock_mail.sent_messages[0]
|
||
|
|
expected_url = f'https://example.com/application/{session_id}/'
|
||
|
|
assert expected_url in hr_email.body
|