ac0418083b
Модель вакансий, флоу рекрутинга и панели HR-портала (заявки/вакансии). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
106 lines
3.9 KiB
Python
106 lines
3.9 KiB
Python
from datetime import date
|
|
|
|
from django.contrib.auth.models import Group, Permission
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.test import TestCase
|
|
|
|
from apps.employees.models import Employee
|
|
from apps.hiring.models import Vacancy
|
|
from apps.hiring.recruiting import (
|
|
user_can_manage_vacancies,
|
|
user_can_view_recruiting,
|
|
)
|
|
from core.models import PortalAccess
|
|
from core.test_utils import login_2fa
|
|
|
|
|
|
def make_employee(**overrides):
|
|
n = Employee.objects.count() + 1
|
|
defaults = {
|
|
'username': f'rec.user{n}',
|
|
'email': f'rec.user{n}@company.local',
|
|
'first_name': 'Тест',
|
|
'last_name': 'Рекрутинг',
|
|
'hire_date': date(2026, 1, 1),
|
|
'user_location_type': 'pharmacy',
|
|
'mattermost_sync_enabled': False,
|
|
'ad_sync_enabled': False,
|
|
'is_staff': False,
|
|
}
|
|
defaults.update(overrides)
|
|
return Employee.objects.create(**defaults)
|
|
|
|
|
|
def portal_perm(codename: str) -> Permission:
|
|
ct = ContentType.objects.get_for_model(PortalAccess, for_concrete_model=False)
|
|
return Permission.objects.get(content_type=ct, codename=codename)
|
|
|
|
|
|
def clear_perm_cache(user):
|
|
for attr in ('_perm_cache', '_user_perm_cache', '_group_perm_cache'):
|
|
if hasattr(user, attr):
|
|
delattr(user, attr)
|
|
|
|
|
|
class RecruitingAccessTests(TestCase):
|
|
def test_pharmacist_can_view_vacancies_tab(self):
|
|
user = make_employee()
|
|
group = Group.objects.get(name='Фармацевт')
|
|
group.permissions.add(portal_perm('access_recruiting'))
|
|
user.groups.add(group)
|
|
clear_perm_cache(user)
|
|
self.assertTrue(user_can_view_recruiting(user))
|
|
self.assertFalse(user_can_manage_vacancies(user))
|
|
|
|
login_2fa(self.client, user)
|
|
resp = self.client.get('/hr-portal/?tab=vacancies', HTTP_HX_REQUEST='true')
|
|
self.assertEqual(resp.status_code, 200)
|
|
self.assertTrue(resp.context['can_view_recruiting'])
|
|
self.assertEqual(resp.context['hr_active_tab'], 'vacancies')
|
|
|
|
def test_manager_can_create_vacancy(self):
|
|
from apps.locations.models.pharmacies import Pharmacy
|
|
from core.models import Directory, DirectoryType
|
|
|
|
org_type, _ = DirectoryType.objects.get_or_create(
|
|
code='organization', defaults={'name': 'Организация'},
|
|
)
|
|
region_type, _ = DirectoryType.objects.get_or_create(
|
|
code='region', defaults={'name': 'Регион'},
|
|
)
|
|
region = Directory.objects.create(directory_type=region_type, code='rec-r', name='Рег')
|
|
org = Directory.objects.create(directory_type=org_type, code='rec-o', name='Орг')
|
|
pharmacy = Pharmacy.objects.create(
|
|
organization=org,
|
|
location_region=region,
|
|
pharmacy_number=99,
|
|
location_type='pharmacy',
|
|
street='Тест',
|
|
house_number='1',
|
|
status='open',
|
|
)
|
|
user = make_employee(user_pharmacy=pharmacy)
|
|
group = Group.objects.get(name='Заведующий аптекой')
|
|
group.permissions.add(portal_perm('access_recruiting'))
|
|
user.groups.add(group)
|
|
clear_perm_cache(user)
|
|
self.assertTrue(user_can_manage_vacancies(user))
|
|
|
|
login_2fa(self.client, user)
|
|
resp = self.client.post('/vacancies/save/', {
|
|
'title': 'Фармацевт',
|
|
'priority': 'urgent',
|
|
'candidates_count': '2',
|
|
'user_location_type': 'pharmacy',
|
|
'pharmacy_id': str(pharmacy.pk),
|
|
})
|
|
self.assertEqual(resp.status_code, 302)
|
|
self.assertTrue(Vacancy.objects.filter(title='Фармацевт', pharmacy=pharmacy).exists())
|
|
|
|
def test_recruiting_redirects_to_hr(self):
|
|
user = make_employee(user_location_type='office')
|
|
login_2fa(self.client, user)
|
|
resp = self.client.get('/recruiting/')
|
|
self.assertEqual(resp.status_code, 302)
|
|
self.assertIn('/hr-portal/', resp['Location'])
|