626aeebbb7
pytils (русская либа) выбрасывала і/ї/є/ґ/апостроф целиком: Кіт→kt, Філіпʼєв→flpv, Ірина→rina. Добавлен премаппинг украинских букв в латиницу до slugify (translit_login), общий для найма, импорта и конвертации. Теперь: Кіт Ірина → i.kit, Філіпʼєв Дмитро → d.filipiev, Ґудзик → gudzik. - apps/hiring/services: translit_login + _username_base через него - import_employees_json: переиспользует _username_base - tests: украинская транслитерация в convert_usernames Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
from datetime import date
|
|
from io import StringIO
|
|
|
|
from django.contrib.auth import get_user_model
|
|
from django.core.management import call_command
|
|
from django.test import TestCase
|
|
|
|
Employee = get_user_model()
|
|
|
|
|
|
def emp(username, first, last, **extra):
|
|
e = Employee.objects.create(
|
|
username=username, email=f'{username}@company.local',
|
|
first_name=first, last_name=last, hire_date=date(2026, 1, 1),
|
|
user_location_type='office', mattermost_sync_enabled=False,
|
|
ad_sync_enabled=False, **extra,
|
|
)
|
|
return e
|
|
|
|
|
|
class ConvertUsernamesTests(TestCase):
|
|
def _run(self, **kwargs):
|
|
out = StringIO()
|
|
call_command('convert_usernames', stdout=out, **kwargs)
|
|
return out.getvalue()
|
|
|
|
def test_dry_run_does_not_change(self):
|
|
e = emp('ivanov.i', 'Иван', 'Иванов')
|
|
out = self._run()
|
|
e.refresh_from_db()
|
|
self.assertEqual(e.username, 'ivanov.i') # не изменён
|
|
self.assertIn('ivanov.i -> i.ivanov', out)
|
|
|
|
def test_apply_renames(self):
|
|
e = emp('ivanov.i', 'Иван', 'Иванов')
|
|
self._run(apply=True)
|
|
e.refresh_from_db()
|
|
self.assertEqual(e.username, 'i.ivanov')
|
|
|
|
def test_already_correct_untouched(self):
|
|
e = emp('i.ivanov', 'Иван', 'Иванов')
|
|
self._run(apply=True)
|
|
e.refresh_from_db()
|
|
self.assertEqual(e.username, 'i.ivanov')
|
|
|
|
def test_collision_gets_suffix(self):
|
|
a = emp('ivanov.i', 'Иван', 'Иванов')
|
|
b = emp('ivanov.i.2', 'Игорь', 'Иванов')
|
|
self._run(apply=True)
|
|
a.refresh_from_db(); b.refresh_from_db()
|
|
self.assertEqual({a.username, b.username}, {'i.ivanov', 'i.ivanov2'})
|
|
|
|
def test_superuser_skipped_by_default(self):
|
|
su = emp('admin.super', 'Админ', 'Супер', is_superuser=True, is_staff=True)
|
|
self._run(apply=True)
|
|
su.refresh_from_db()
|
|
self.assertEqual(su.username, 'admin.super') # не тронут
|
|
|
|
def test_include_superusers(self):
|
|
su = emp('admin.super', 'Админ', 'Супер', is_superuser=True, is_staff=True)
|
|
self._run(apply=True, include_superusers=True)
|
|
su.refresh_from_db()
|
|
self.assertEqual(su.username, 'a.super')
|
|
|
|
def test_exclude_by_username_and_email(self):
|
|
a = emp('keepme', 'Пётр', 'Петров')
|
|
b = emp('petrov.s', 'Сергей', 'Петров')
|
|
self._run(apply=True, exclude='keepme, petrov.s@company.local')
|
|
a.refresh_from_db(); b.refresh_from_db()
|
|
self.assertEqual(a.username, 'keepme') # исключён по логину
|
|
self.assertEqual(b.username, 'petrov.s') # исключён по email
|
|
|
|
def test_ukrainian_transliteration(self):
|
|
cases = {
|
|
'kit.old': ('Ірина', 'Кіт', 'i.kit'),
|
|
'flp.old': ('Дмитро', 'Філіпʼєв', 'd.filipiev'),
|
|
'gud.old': ('Ганна', 'Ґудзик', 'g.gudzik'),
|
|
}
|
|
objs = {u: emp(u, first, last) for u, (first, last, _) in cases.items()}
|
|
self._run(apply=True)
|
|
for u, (_first, _last, expected) in cases.items():
|
|
objs[u].refresh_from_db()
|
|
self.assertEqual(objs[u].username, expected)
|
|
|
|
def test_excluded_username_is_reserved(self):
|
|
# исключённый занимает 'p.petrov' — переименовываемый получит суффикс
|
|
kept = emp('p.petrov', 'Павел', 'Петров', is_superuser=True)
|
|
other = emp('petrov.p', 'Пётр', 'Петров')
|
|
self._run(apply=True)
|
|
kept.refresh_from_db(); other.refresh_from_db()
|
|
self.assertEqual(kept.username, 'p.petrov')
|
|
self.assertEqual(other.username, 'p.petrov2')
|