From eccdfb4c1be1af4b5e2e523d48c2961088a906b3 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 5 Jan 2022 14:47:34 +0100 Subject: [PATCH 2/2] manager: add option groups to role member add field (#60271) --- src/authentic2/manager/role_views.py | 34 +++++++++++++---------- tests/test_role_manager.py | 40 +++++++++++++++++----------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/authentic2/manager/role_views.py b/src/authentic2/manager/role_views.py index 28e37d5d..cc1ff196 100644 --- a/src/authentic2/manager/role_views.py +++ b/src/authentic2/manager/role_views.py @@ -836,7 +836,7 @@ class UserOrRoleSelect2View(DetailView): role_qs = role_qs.exclude(pk__in=children.filter(is_direct=True)) role_qs = self.filter_queryset(role_qs, search_term, ['name', 'service__name', 'ou__name']) - role_paginator = Paginator(role_qs, 10) + role_paginator = Paginator(role_qs, 10, allow_empty_first_page=False) try: role_page = role_paginator.page(page_number) except EmptyPage: @@ -844,6 +844,9 @@ class UserOrRoleSelect2View(DetailView): has_next = False else: has_next = role_page.has_next() + role_page = [self.get_role_choice(role) for role in role_page] + if page_number == 1: + role_page = [{'text': _('Roles'), 'children': role_page}] user_page = [] if not has_next: @@ -853,18 +856,22 @@ class UserOrRoleSelect2View(DetailView): user_qs, search_term, ['username', 'first_name', 'last_name', 'email'] ) - page_number = page_number - role_paginator.num_pages + 1 - user_paginator = Paginator(user_qs, 10) + if role_paginator.num_pages != 0: + page_number = page_number - role_paginator.num_pages + 1 + user_paginator = Paginator(user_qs, 10, allow_empty_first_page=False) try: user_page = user_paginator.page(page_number) except EmptyPage: has_next = False else: has_next = user_page.has_next() + user_page = [self.get_user_choice(user) for user in user_page] + if page_number == 1: + user_page = [{'text': _('Users'), 'children': user_page}] return JsonResponse( { - "results": [self.get_choice(obj) for obj in list(role_page) + list(user_page)], + "results": role_page + user_page, "more": has_next, } ) @@ -876,16 +883,15 @@ class UserOrRoleSelect2View(DetailView): lookups &= reduce(Q.__or__, (Q(**{'%s__icontains' % field: term}) for field in search_fields)) return qs.filter(lookups) - def get_choice(self, obj): - if isinstance(obj, Role): - text = str(obj) - if obj.ou and get_ou_count() > 1: - text = f'{obj.ou} - {obj}' - key = 'role-%s' - elif isinstance(obj, User): - text = label_from_user(obj) - key = 'user-%s' - return {'id': key % obj.pk, 'text': text} + def get_role_choice(self, role): + text = str(role) + if role.ou and get_ou_count() > 1: + text = f'{role.ou} - {role}' + return {'id': 'role-%s' % role.pk, 'text': text} + + def get_user_choice(self, user): + text = label_from_user(user) + return {'id': 'user-%s' % user.pk, 'text': text} user_or_role_select2 = UserOrRoleSelect2View.as_view() diff --git a/tests/test_role_manager.py b/tests/test_role_manager.py index 0765ec38..b6b49a51 100644 --- a/tests/test_role_manager.py +++ b/tests/test_role_manager.py @@ -495,12 +495,13 @@ def test_role_members_user_role_mixed_field_choices( resp = login(app, superuser, url) select2_json = request_select2(app, resp) - assert len(select2_json['results']) == 10 + assert len(select2_json['results']) == 1 + assert select2_json['results'][0]['text'] == 'Roles' + assert len(select2_json['results'][0]['children']) == 10 assert select2_json['more'] is True select2_json = request_select2(app, resp, fetch_all=True) - assert len(select2_json['results']) == 17 - choices = [x['text'] for x in select2_json['results']] + choices = [x['text'] for k in select2_json['results'] for x in k.get('children') or (k,)] assert choices == [ 'Default organizational unit - Managers of role "simple role"', 'Default organizational unit - Roles - Default organizational unit', @@ -522,38 +523,47 @@ def test_role_members_user_role_mixed_field_choices( ] select2_json = request_select2(app, resp, term='user') - choices = [x['text'] for x in select2_json['results']] - assert choices == [ + assert len(select2_json['results']) == 2 + assert select2_json['results'][0]['text'] == 'Roles' + role_choices = [x['text'] for x in select2_json['results'][0]['children']] + assert role_choices == [ 'Default organizational unit - Users - Default organizational unit', 'OU1 - Users - OU1', 'Manager of users', + ] + assert select2_json['results'][1]['text'] == 'Users' + user_choices = [x['text'] for x in select2_json['results'][1]['children']] + assert user_choices == [ 'Jôhn Dôe - user@example.net - user', 'super user - superuser@example.net - superuser', ] assert select2_json['more'] is False select2_json = request_select2(app, resp, term='Manager') - assert len(select2_json['results']) == 8 + assert len(select2_json['results'][0]['children']) == 8 select2_json = request_select2(app, resp, term='Manager of') - assert len(select2_json['results']) == 7 + assert len(select2_json['results'][0]['children']) == 7 select2_json = request_select2(app, resp, term='Manager of serv') - assert len(select2_json['results']) == 1 + assert len(select2_json['results'][0]['children']) == 1 for i in range(25): Role.objects.create(name=f'test_role_{i}') select2_json = request_select2(app, resp, term='test_role_', fetch_all=True) - assert len(select2_json['results']) == 25 + flat_results = [x for k in select2_json['results'] for x in k.get('children') or (k,)] + assert len(flat_results) == 25 for i in range(25): User.objects.create(username=f'test_user_{i}') select2_json = request_select2(app, resp, term='test_user_', fetch_all=True) - assert len(select2_json['results']) == 25 + flat_results = [x for k in select2_json['results'] for x in k.get('children') or (k,)] + assert len(flat_results) == 25 for i in range(10): Role.objects.create(name=f'test_xxx_{i}') User.objects.create(username='test_xxx_10') select2_json = request_select2(app, resp, term='test_xxx_') - assert len(select2_json['results']) == 11 + flat_results = [x for k in select2_json['results'] for x in k.get('children') or (k,)] + assert len(flat_results) == 11 def test_role_members_user_role_add_remove(app, superuser, settings, simple_role, simple_user, role_ou1): @@ -561,9 +571,9 @@ def test_role_members_user_role_add_remove(app, superuser, settings, simple_role resp = login(app, superuser, url) select2_json = request_select2(app, resp, term='Jôhn') - assert len(select2_json['results']) == 1 + assert len(select2_json['results'][0]['children']) == 1 form = resp.forms['add-member'] - form['user_or_role'].force_value(select2_json['results'][0]['id']) + form['user_or_role'].force_value(select2_json['results'][0]['children'][0]['id']) resp = form.submit().follow() assert 'Jôhn Dôe' in resp.text @@ -576,9 +586,9 @@ def test_role_members_user_role_add_remove(app, superuser, settings, simple_role assert data_pk_args == ['user_or_role'] select2_json = request_select2(app, resp, term='role_ou1') - assert len(select2_json['results']) == 1 + assert len(select2_json['results'][0]['children']) == 1 form = resp.forms['add-member'] - form['user_or_role'].force_value(select2_json['results'][0]['id']) + form['user_or_role'].force_value(select2_json['results'][0]['children'][0]['id']) resp = form.submit().follow() assert 'role_ou1' in resp.text -- 2.30.2