HR notification added
This commit is contained in:
@@ -0,0 +1,354 @@
|
||||
"""
|
||||
Tests for application view and file download functionality.
|
||||
"""
|
||||
import os
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class TestApplicationView:
|
||||
"""Test application view page for HR."""
|
||||
|
||||
def test_view_application_page_renders(self, client, create_test_application):
|
||||
"""Test that the application view page renders correctly."""
|
||||
session_id = 'test-view-123'
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='test@example.com',
|
||||
job_name='Software Engineer',
|
||||
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': 'Software Developer',
|
||||
'motivation': 'Great opportunity',
|
||||
'qualifications': 'Python, Flask',
|
||||
'salary': '100000 CHF'
|
||||
}
|
||||
)
|
||||
|
||||
response = client.get(f'/application/{session_id}/')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'Software Engineer' in response.data
|
||||
assert b'test@example.com' in response.data
|
||||
assert b'Anna' in response.data
|
||||
assert b'Great opportunity' in response.data
|
||||
|
||||
def test_view_application_404_for_invalid_session(self, client):
|
||||
"""Test that viewing a non-existent application returns 404."""
|
||||
response = client.get('/application/invalid-session-id/')
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_view_application_displays_all_personal_info(self, client, create_test_application):
|
||||
"""Test that all personal information fields are displayed."""
|
||||
session_id = 'test-personal-display'
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Data Analyst',
|
||||
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'
|
||||
}
|
||||
)
|
||||
|
||||
response = client.get(f'/application/{session_id}/')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'Schmidt' in response.data
|
||||
assert b'Max' in response.data
|
||||
assert b'Bahnhofstrasse 1' in response.data
|
||||
assert b'8000' in response.data
|
||||
assert b'verheiratet' in response.data
|
||||
|
||||
def test_view_application_displays_motivation_answers(self, client, create_test_application):
|
||||
"""Test that motivation answers are properly displayed."""
|
||||
session_id = 'test-motivation-display'
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Project Manager',
|
||||
motivation_answers={
|
||||
'current_job': 'Senior Developer at ABC Corp',
|
||||
'motivation': 'I want to work on challenging projects',
|
||||
'qualifications': '10 years of experience in software development',
|
||||
'salary': '120000 CHF per year'
|
||||
}
|
||||
)
|
||||
|
||||
response = client.get(f'/application/{session_id}/')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'Senior Developer at ABC Corp' in response.data
|
||||
assert b'challenging projects' in response.data
|
||||
assert b'10 years of experience' in response.data
|
||||
assert b'120000 CHF' in response.data
|
||||
|
||||
def test_view_application_with_uploaded_files(
|
||||
self, client, create_test_application, temp_applications_dir
|
||||
):
|
||||
"""Test that uploaded files are displayed in the application view."""
|
||||
session_id = 'test-files-display'
|
||||
|
||||
# Create the application with uploaded files
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='UI Designer',
|
||||
uploaded_files=[
|
||||
{
|
||||
'original_name': 'cv.pdf',
|
||||
'stored_name': '20250101_120000_cv.pdf',
|
||||
'size': 102400,
|
||||
'uploaded_at': '2025-01-01T12:00:00'
|
||||
},
|
||||
{
|
||||
'original_name': 'portfolio.pdf',
|
||||
'stored_name': '20250101_120100_portfolio.pdf',
|
||||
'size': 204800,
|
||||
'uploaded_at': '2025-01-01T12:01:00'
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
response = client.get(f'/application/{session_id}/')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'cv.pdf' in response.data
|
||||
assert b'portfolio.pdf' in response.data
|
||||
# Check that file sizes are displayed (in MB)
|
||||
assert b'0.10 MB' in response.data
|
||||
assert b'0.20 MB' in response.data
|
||||
|
||||
def test_view_application_without_uploaded_files(self, client, create_test_application):
|
||||
"""Test that application view works when no files are uploaded."""
|
||||
session_id = 'test-no-files'
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Sales Representative',
|
||||
uploaded_files=[]
|
||||
)
|
||||
|
||||
response = client.get(f'/application/{session_id}/')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'Keine Dokumente hochgeladen' in response.data
|
||||
|
||||
def test_view_application_shows_timestamps(self, client, create_test_application):
|
||||
"""Test that creation and update timestamps are displayed."""
|
||||
session_id = 'test-timestamps'
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Marketing Manager'
|
||||
)
|
||||
|
||||
response = client.get(f'/application/{session_id}/')
|
||||
|
||||
assert response.status_code == 200
|
||||
# Check for timestamp labels in German
|
||||
assert b'Erstellt am:' in response.data
|
||||
assert b'Zuletzt aktualisiert:' in response.data
|
||||
|
||||
|
||||
class TestFileDownload:
|
||||
"""Test file download functionality."""
|
||||
|
||||
def test_download_file_success(self, client, create_test_application, temp_applications_dir):
|
||||
"""Test that files can be successfully downloaded."""
|
||||
session_id = 'test-download-success'
|
||||
|
||||
# Create application directory and attachment
|
||||
from app import get_attachments_path
|
||||
attachments_path = get_attachments_path(session_id)
|
||||
Path(attachments_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create a test file
|
||||
test_filename = '20250101_120000_test.pdf'
|
||||
test_file_path = os.path.join(attachments_path, test_filename)
|
||||
test_content = b'Test PDF content'
|
||||
|
||||
with open(test_file_path, 'wb') as f:
|
||||
f.write(test_content)
|
||||
|
||||
# Create application with the uploaded file
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Test Job',
|
||||
uploaded_files=[
|
||||
{
|
||||
'original_name': 'test.pdf',
|
||||
'stored_name': test_filename,
|
||||
'size': len(test_content),
|
||||
'uploaded_at': '2025-01-01T12:00:00'
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
# Download the file
|
||||
response = client.get(f'/application/{session_id}/download/{test_filename}')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.data == test_content
|
||||
assert 'attachment' in response.headers.get('Content-Disposition', '')
|
||||
|
||||
def test_download_file_not_in_uploaded_list(
|
||||
self, client, create_test_application, temp_applications_dir
|
||||
):
|
||||
"""Test that downloading a file not in the uploaded list returns 404."""
|
||||
session_id = 'test-download-unauthorized'
|
||||
|
||||
# Create application directory and attachment
|
||||
from app import get_attachments_path
|
||||
attachments_path = get_attachments_path(session_id)
|
||||
Path(attachments_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create a file that exists physically but is NOT in the uploaded_files list
|
||||
unauthorized_filename = '20250101_120000_unauthorized.pdf'
|
||||
unauthorized_path = os.path.join(attachments_path, unauthorized_filename)
|
||||
|
||||
with open(unauthorized_path, 'wb') as f:
|
||||
f.write(b'Unauthorized content')
|
||||
|
||||
# Create application with NO uploaded files
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Test Job',
|
||||
uploaded_files=[]
|
||||
)
|
||||
|
||||
# Try to download the unauthorized file
|
||||
response = client.get(f'/application/{session_id}/download/{unauthorized_filename}')
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_download_file_nonexistent_file(self, client, create_test_application):
|
||||
"""Test that downloading a non-existent file returns 404."""
|
||||
session_id = 'test-download-nonexistent'
|
||||
|
||||
# Create application with a file in the list, but the file doesn't exist physically
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Test Job',
|
||||
uploaded_files=[
|
||||
{
|
||||
'original_name': 'missing.pdf',
|
||||
'stored_name': 'nonexistent_file.pdf',
|
||||
'size': 1024,
|
||||
'uploaded_at': '2025-01-01T12:00:00'
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
# Try to download the missing file
|
||||
response = client.get(f'/application/{session_id}/download/nonexistent_file.pdf')
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_download_file_invalid_session(self, client):
|
||||
"""Test that downloading with an invalid session ID returns 404."""
|
||||
response = client.get('/application/invalid-session/download/somefile.pdf')
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_download_multiple_files(self, client, create_test_application, temp_applications_dir):
|
||||
"""Test downloading multiple files from the same application."""
|
||||
session_id = 'test-download-multiple'
|
||||
|
||||
# Create application directory
|
||||
from app import get_attachments_path
|
||||
attachments_path = get_attachments_path(session_id)
|
||||
Path(attachments_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create multiple test files
|
||||
files = [
|
||||
('20250101_120000_cv.pdf', b'CV content'),
|
||||
('20250101_120100_cover_letter.pdf', b'Cover letter content'),
|
||||
('20250101_120200_certificate.pdf', b'Certificate content')
|
||||
]
|
||||
|
||||
uploaded_files = []
|
||||
for filename, content in files:
|
||||
file_path = os.path.join(attachments_path, filename)
|
||||
with open(file_path, 'wb') as f:
|
||||
f.write(content)
|
||||
|
||||
uploaded_files.append({
|
||||
'original_name': filename.split('_', 2)[2],
|
||||
'stored_name': filename,
|
||||
'size': len(content),
|
||||
'uploaded_at': '2025-01-01T12:00:00'
|
||||
})
|
||||
|
||||
# Create application with multiple files
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Test Job',
|
||||
uploaded_files=uploaded_files
|
||||
)
|
||||
|
||||
# Download each file and verify
|
||||
for filename, expected_content in files:
|
||||
response = client.get(f'/application/{session_id}/download/{filename}')
|
||||
assert response.status_code == 200
|
||||
assert response.data == expected_content
|
||||
|
||||
def test_download_file_with_special_characters(
|
||||
self, client, create_test_application, temp_applications_dir
|
||||
):
|
||||
"""Test downloading files with special characters in the name."""
|
||||
session_id = 'test-download-special-chars'
|
||||
|
||||
# Create application directory
|
||||
from app import get_attachments_path
|
||||
attachments_path = get_attachments_path(session_id)
|
||||
Path(attachments_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create a file with a secure filename (as it would be stored)
|
||||
from werkzeug.utils import secure_filename
|
||||
original_name = 'Lebenslauf Müller.pdf'
|
||||
stored_name = f'20250101_120000_{secure_filename(original_name)}'
|
||||
file_path = os.path.join(attachments_path, stored_name)
|
||||
content = b'CV with special chars'
|
||||
|
||||
with open(file_path, 'wb') as f:
|
||||
f.write(content)
|
||||
|
||||
# Create application
|
||||
create_test_application(
|
||||
session_id=session_id,
|
||||
email='applicant@example.com',
|
||||
job_name='Test Job',
|
||||
uploaded_files=[
|
||||
{
|
||||
'original_name': original_name,
|
||||
'stored_name': stored_name,
|
||||
'size': len(content),
|
||||
'uploaded_at': '2025-01-01T12:00:00'
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
# Download the file
|
||||
response = client.get(f'/application/{session_id}/download/{stored_name}')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.data == content
|
||||
@@ -0,0 +1,270 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user