from datetime import date from pathlib import Path from unittest.mock import patch from django.contrib.auth import get_user_model from django.test import TestCase, override_settings from django.utils import timezone from workflows.branding import get_company_email_domain from workflows.models import EmployeeProfile, NotificationTemplate, OffboardingRequest, OnboardingRequest, ScheduledWelcomeEmail from workflows.tasks import process_onboarding_request, send_scheduled_welcome_email @override_settings(PDF_OUTPUT_DIR=Path('/tmp/onoff_test_pdfs')) class BilingualSmokeTests(TestCase): def setUp(self): self.company_domain = get_company_email_domain() user_model = get_user_model() self.user = user_model.objects.create_user( username='bilingual_user', password='secret123', email=f'requester@{self.company_domain}', first_name='Mia', last_name='Beispiel', ) self.client.force_login(self.user) self.profile = EmployeeProfile.objects.create( full_name='Lara Beispiel', first_name='Lara', last_name='Beispiel', department='IT-Service', job_title='Engineer', work_email=f'lara.beispiel@{self.company_domain}', ) @patch('workflows.views.process_onboarding_request.delay') def test_onboarding_submit_persists_english_language(self, mock_delay): payload = { 'first_name': 'Max', 'last_name': 'Mustermann', 'gender': 'herr', 'job_title': 'Consultant', 'department': 'IT-Service', 'work_email': f'max.mustermann@{self.company_domain}', 'contract_start': '2026-11-01', 'employment_type': 'unbefristet', 'group_mailboxes_required_choice': 'nein', 'additional_hardware_needed_choice': 'nein', 'additional_software_needed_choice': 'nein', 'additional_access_needed_choice': 'nein', 'successor_required_choice': 'nein', 'inherit_phone_number_choice': 'nein', 'agreement_confirm': 'on', } response = self.client.post('/onboarding/new/', payload, HTTP_HOST='localhost', HTTP_ACCEPT_LANGUAGE='en') self.assertEqual(response.status_code, 302) obj = OnboardingRequest.objects.get(work_email=f'max.mustermann@{self.company_domain}') self.assertEqual(obj.preferred_language, 'en') mock_delay.assert_called_once_with(obj.id) @patch('workflows.views.process_onboarding_request.delay') def test_onboarding_submit_persists_german_language(self, mock_delay): payload = { 'first_name': 'Erika', 'last_name': 'Muster', 'gender': 'frau', 'job_title': 'Consultant', 'department': 'IT-Service', 'work_email': f'erika.muster@{self.company_domain}', 'contract_start': '2026-11-02', 'employment_type': 'unbefristet', 'group_mailboxes_required_choice': 'nein', 'additional_hardware_needed_choice': 'nein', 'additional_software_needed_choice': 'nein', 'additional_access_needed_choice': 'nein', 'successor_required_choice': 'nein', 'inherit_phone_number_choice': 'nein', 'agreement_confirm': 'on', } response = self.client.post('/onboarding/new/', payload, HTTP_HOST='localhost', HTTP_ACCEPT_LANGUAGE='de') self.assertEqual(response.status_code, 302) obj = OnboardingRequest.objects.get(work_email=f'erika.muster@{self.company_domain}') self.assertEqual(obj.preferred_language, 'de') mock_delay.assert_called_once_with(obj.id) @patch('workflows.views.process_offboarding_request.delay') def test_offboarding_submit_persists_english_language(self, mock_delay): payload = { 'full_name': self.profile.full_name, 'work_email': self.profile.work_email, 'department': self.profile.department, 'job_title': self.profile.job_title, 'last_working_day': '2026-12-31', 'notes': 'Disable accounts.', } response = self.client.post( f'/offboarding/new/?profile={self.profile.id}', payload, HTTP_HOST='localhost', HTTP_ACCEPT_LANGUAGE='en', ) self.assertEqual(response.status_code, 302) obj = OffboardingRequest.objects.get(work_email=self.profile.work_email) self.assertEqual(obj.preferred_language, 'en') mock_delay.assert_called_once_with(obj.id) @patch('workflows.tasks._apply_notification_rules') @patch('workflows.tasks._schedule_welcome_email') @patch('workflows.tasks.upload_to_nextcloud') @patch('workflows.tasks._send_workflow_email') @patch('workflows.tasks._generate_onboarding_pdf') def test_onboarding_task_uses_english_template_for_english_request( self, mock_generate_pdf, mock_send_workflow_email, mock_upload, mock_schedule, mock_rules, ): pdf_path = Path('/tmp/onoff_test_pdfs/onboarding_letter_English_Person.pdf') pdf_path.parent.mkdir(parents=True, exist_ok=True) pdf_path.write_bytes(b'%PDF-1.4\n%test\n') mock_generate_pdf.return_value = pdf_path NotificationTemplate.objects.update_or_create( key='onboarding_it', defaults={ 'subject_template': 'DE IT', 'subject_template_en': 'EN IT', 'body_template': 'DE body', 'body_template_en': 'EN body', 'is_active': True, }, ) request_obj = OnboardingRequest.objects.create( full_name='English Person', gender='herr', job_title='Engineer', department='IT-Service', work_email=f'english.person@{self.company_domain}', contract_start=date(2026, 11, 1), employment_type='unbefristet', onboarded_by_email=f'requester@{self.company_domain}', onboarded_by_name='Mia Beispiel', agreement='accepted', preferred_language='en', ) process_onboarding_request(request_obj.id) first_call = mock_send_workflow_email.call_args_list[0].kwargs self.assertEqual(first_call['subject'], 'EN IT') self.assertEqual(first_call['body'], 'EN body') @patch('workflows.tasks._send_workflow_email') def test_welcome_email_uses_english_template_for_english_request(self, mock_send_workflow_email): NotificationTemplate.objects.update_or_create( key='onboarding_welcome', defaults={ 'subject_template': 'DE Welcome', 'subject_template_en': 'EN Welcome', 'body_template': 'DE Welcome Body', 'body_template_en': 'EN Welcome Body', 'is_active': True, }, ) onboarding = OnboardingRequest.objects.create( full_name='Welcome Person', gender='frau', job_title='Manager', department='IT-Service', work_email=f'welcome.person@{self.company_domain}', contract_start=date(2026, 11, 1), employment_type='unbefristet', onboarded_by_email=f'requester@{self.company_domain}', agreement='accepted', preferred_language='en', ) scheduled = ScheduledWelcomeEmail.objects.create( onboarding_request=onboarding, recipient_email=f'welcome.person@{self.company_domain}', send_at=timezone.now(), status='scheduled', ) send_scheduled_welcome_email(scheduled.id, True) kwargs = mock_send_workflow_email.call_args.kwargs self.assertEqual(kwargs['subject'], 'EN Welcome') self.assertEqual(kwargs['body'], 'EN Welcome Body')