Add RRO, portal section perms, dislocation presets, and hiring intern flow.
Ship cash-register registry, section-based portal access, configurable dislocation columns, and trial-hire intern accounts with credentials PDF.
This commit is contained in:
@@ -135,3 +135,127 @@ class CarbonioPasswordSyncTests(TestCase):
|
||||
self.assertEqual(p.carbonio_password, '') # на update пароль не трогаем
|
||||
fake.create_account.assert_not_called()
|
||||
fake.set_account_status.assert_called_once_with('acc-existing', 'active')
|
||||
|
||||
|
||||
class DislocationColumnsTests(TestCase):
|
||||
"""Whitelist, резолв пресета default и сохранение preference пользователя."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
from datetime import date
|
||||
from django.contrib.auth import get_user_model
|
||||
from apps.locations.dislocation_columns import HR_COLUMNS, OPS_COLUMNS, STANDARD_COLUMNS
|
||||
from apps.locations.models import DislocationColumnPreset
|
||||
|
||||
Employee = get_user_model()
|
||||
org_type = DirectoryType.objects.create(code='organization', name='Организация')
|
||||
region_type = DirectoryType.objects.create(code='region', name='Регион')
|
||||
cls.region = Directory.objects.create(directory_type=region_type, code='kv', name='Киев')
|
||||
cls.org = Directory.objects.create(directory_type=org_type, code='org', name='ТестОрг')
|
||||
cls.user = Employee.objects.create(
|
||||
username='dislo.cols',
|
||||
email='dislo.cols@company.local',
|
||||
first_name='Коля',
|
||||
last_name='Колонки',
|
||||
hire_date=date(2026, 1, 1),
|
||||
user_location_type='office',
|
||||
mattermost_sync_enabled=False,
|
||||
ad_sync_enabled=False,
|
||||
)
|
||||
DislocationColumnPreset.objects.update_or_create(
|
||||
code='standard',
|
||||
defaults={
|
||||
'name': 'Стандарт',
|
||||
'columns': list(STANDARD_COLUMNS),
|
||||
'is_default': True,
|
||||
},
|
||||
)
|
||||
DislocationColumnPreset.objects.update_or_create(
|
||||
code='hr',
|
||||
defaults={'name': 'HR', 'columns': list(HR_COLUMNS), 'is_default': False},
|
||||
)
|
||||
DislocationColumnPreset.objects.update_or_create(
|
||||
code='ops',
|
||||
defaults={'name': 'Ops', 'columns': list(OPS_COLUMNS), 'is_default': False},
|
||||
)
|
||||
Pharmacy.objects.create(
|
||||
organization=cls.org, location_region=cls.region,
|
||||
pharmacy_number=101, location_type='pharmacy', street='Тестовая', house_number='1',
|
||||
)
|
||||
|
||||
def test_normalize_whitelist_and_locked_pharmacy(self):
|
||||
from apps.locations.dislocation_columns import normalize_columns
|
||||
|
||||
self.assertEqual(
|
||||
normalize_columns(['email', 'pharmacy', 'unknown', 'email', 'region']),
|
||||
['email', 'pharmacy', 'region'],
|
||||
)
|
||||
self.assertEqual(
|
||||
normalize_columns(['organization', 'pharmacy', 'phone']),
|
||||
['organization', 'pharmacy', 'phone'],
|
||||
)
|
||||
self.assertEqual(normalize_columns([]), ['pharmacy'])
|
||||
self.assertEqual(normalize_columns(['secret', 'password']), ['pharmacy'])
|
||||
# pharmacy обязательна, но если её нет в списке — добавляется первой
|
||||
self.assertEqual(
|
||||
normalize_columns(['region', 'phone']),
|
||||
['pharmacy', 'region', 'phone'],
|
||||
)
|
||||
def test_resolve_uses_default_preset(self):
|
||||
from apps.locations.dislocation_columns import STANDARD_COLUMNS, resolve_columns_for_user
|
||||
|
||||
self.user.dislocation_columns = None
|
||||
self.user.save(update_fields=['dislocation_columns'])
|
||||
self.assertEqual(resolve_columns_for_user(self.user), list(STANDARD_COLUMNS))
|
||||
|
||||
def test_resolve_uses_custom_preference(self):
|
||||
from apps.locations.dislocation_columns import resolve_columns_for_user
|
||||
|
||||
self.user.dislocation_columns = ['region', 'phone', 'bogus']
|
||||
self.user.save(update_fields=['dislocation_columns'])
|
||||
self.assertEqual(
|
||||
resolve_columns_for_user(self.user),
|
||||
['pharmacy', 'region', 'phone'],
|
||||
)
|
||||
|
||||
def test_post_saves_columns_preference(self):
|
||||
self.client.force_login(self.user)
|
||||
session = self.client.session
|
||||
session['2fa_verified'] = True
|
||||
session.save()
|
||||
|
||||
resp = self.client.post(
|
||||
'/dislocation/columns/',
|
||||
{'columns': ['organization', 'pharmacy', 'staff', 'region', 'email', 'evil']},
|
||||
HTTP_HX_REQUEST='true',
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(
|
||||
self.user.dislocation_columns,
|
||||
['organization', 'pharmacy', 'staff', 'region', 'email'],
|
||||
)
|
||||
self.assertContains(resp, "disloSortBy('organization'")
|
||||
self.assertContains(resp, "disloSortBy('region'")
|
||||
self.assertContains(resp, "disloSortBy('email'")
|
||||
self.assertNotContains(resp, "disloSortBy('phone'")
|
||||
|
||||
def test_post_preset_code_applies_hr(self):
|
||||
from apps.locations.dislocation_columns import HR_COLUMNS
|
||||
|
||||
self.client.force_login(self.user)
|
||||
session = self.client.session
|
||||
session['2fa_verified'] = True
|
||||
session.save()
|
||||
|
||||
resp = self.client.post(
|
||||
'/dislocation/columns/',
|
||||
{'preset_code': 'hr'},
|
||||
HTTP_HX_REQUEST='true',
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.dislocation_columns, list(HR_COLUMNS))
|
||||
self.assertContains(resp, "disloSortBy('curator'")
|
||||
self.assertContains(resp, "disloSortBy('manager'")
|
||||
self.assertNotContains(resp, "disloSortBy('phone'")
|
||||
|
||||
Reference in New Issue
Block a user