Files
workdock-platform/backend/workflows/tests/test_onboarding_flow.py
2026-03-27 12:54:47 +01:00

174 lines
7.3 KiB
Python

from unittest.mock import patch
from django.contrib.auth import get_user_model
from django.test import TestCase
from workflows.branding import get_company_email_domain
from workflows.models import FormConditionalRuleConfig, FormFieldConfig, FormSectionConfig, OnboardingRequest
class OnboardingFlowTests(TestCase):
def setUp(self):
self.company_domain = get_company_email_domain()
user_model = get_user_model()
self.user = user_model.objects.create_user(
username='onboard_user',
password='secret123',
email=f'requester@{self.company_domain}',
first_name='Mia',
last_name='Beispiel',
)
self.client.force_login(self.user)
@patch('workflows.views.process_onboarding_request.delay')
def test_onboarding_submit_persists_and_enqueues_task(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')
self.assertEqual(response.status_code, 302)
self.assertIn('/onboarding/new/?saved=1&id=', response['Location'])
obj = OnboardingRequest.objects.get(work_email=f'max.mustermann@{self.company_domain}')
self.assertEqual(obj.full_name, 'Max Mustermann')
self.assertEqual(obj.onboarded_by_email, f'requester@{self.company_domain}')
self.assertEqual(obj.onboarded_by_name, 'Mia Beispiel')
mock_delay.assert_called_once_with(obj.id)
@patch('workflows.views.process_onboarding_request.delay')
def test_hidden_non_locked_field_does_not_block_submission(self, mock_delay):
FormFieldConfig.objects.update_or_create(
form_type='onboarding',
field_name='department',
defaults={'is_visible': False},
)
payload = {
'first_name': 'Nora',
'last_name': 'Neutral',
'gender': 'frau',
'job_title': 'Consultant',
'work_email': f'nora.neutral@{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')
self.assertEqual(response.status_code, 302)
obj = OnboardingRequest.objects.get(work_email=f'nora.neutral@{self.company_domain}')
self.assertEqual(obj.department, '')
mock_delay.assert_called_once_with(obj.id)
@patch('workflows.views.process_onboarding_request.delay')
def test_required_override_blocks_submission_when_field_is_missing(self, mock_delay):
FormFieldConfig.objects.update_or_create(
form_type='onboarding',
field_name='job_title',
defaults={'is_required': True},
)
payload = {
'first_name': 'Lina',
'last_name': 'Leer',
'gender': 'frau',
'department': 'IT-Service',
'work_email': f'lina.leer@{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')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Dieses Feld ist zwingend erforderlich.')
self.assertFalse(OnboardingRequest.objects.filter(work_email=f'lina.leer@{self.company_domain}').exists())
mock_delay.assert_not_called()
@patch('workflows.views.process_onboarding_request.delay')
def test_hidden_itsetup_section_is_removed_from_form_and_submission(self, mock_delay):
FormSectionConfig.objects.update_or_create(
form_type='onboarding',
section_key='itsetup',
defaults={'is_visible': False},
)
response = self.client.get('/onboarding/new/', HTTP_HOST='localhost')
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, '3. IT-Setup')
payload = {
'first_name': 'Nora',
'last_name': 'Neutral',
'gender': 'frau',
'job_title': 'Consultant',
'department': 'IT-Service',
'work_email': f'nora.section@{self.company_domain}',
'contract_start': '2026-11-01',
'employment_type': 'unbefristet',
'group_mailboxes_required_choice': 'nein',
'agreement_confirm': 'on',
}
submit_response = self.client.post('/onboarding/new/', payload, HTTP_HOST='localhost')
self.assertEqual(submit_response.status_code, 302)
self.assertTrue(OnboardingRequest.objects.filter(work_email=f'nora.section@{self.company_domain}').exists())
mock_delay.assert_called_once()
def test_onboarding_page_renders_conditional_rules_payload(self):
response = self.client.get('/onboarding/new/', HTTP_HOST='localhost')
html = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
self.assertIn('id="onboarding-conditional-rules"', html)
self.assertIn('business-card-box', html)
self.assertIn('employment-end-box', html)
self.assertIn('data-conditional-target="business-card-box"', html)
self.assertIn('data-conditional-target="phone-box"', html)
def test_onboarding_page_uses_stored_conditional_rule_config(self):
FormConditionalRuleConfig.objects.update_or_create(
form_type='onboarding',
target_key='employment-end-box',
defaults={
'is_active': True,
'clauses': [{'field': 'employment_type', 'operator': 'equals', 'value': 'unbefristet'}],
},
)
response = self.client.get('/onboarding/new/', HTTP_HOST='localhost')
html = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
self.assertIn('employment-end-box', html)
self.assertIn('"value": "unbefristet"', html)