Projet

Général

Profil

0001-api_views-provide-a-default-slug-for-roles-22251.patch

Paul Marillonnet, 17 septembre 2020 15:05

Télécharger (4,44 ko)

Voir les différences:

Subject: [PATCH] api_views: provide a default slug for roles (#22251)

 src/authentic2/api_views.py | 40 ++++++++++++++++++++++++++-----------
 tests/test_api.py           | 29 +++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 12 deletions(-)
src/authentic2/api_views.py
35 35
from django_rbac.utils import get_ou_model, get_role_model
36 36

  
37 37
from rest_framework import serializers, pagination
38
from rest_framework.validators import UniqueTogetherValidator
38 39
from rest_framework.views import APIView
39 40
from rest_framework.viewsets import ModelViewSet
40 41
from rest_framework.routers import SimpleRouter
......
522 523
        exclude = ('user_permissions', 'groups')
523 524

  
524 525

  
526
class SlugFromNameDefault:
527
    requires_context = False
528
    serializer_instance = None
529

  
530
    def set_context(self, instance):
531
        self.serializer_instance = instance
532

  
533
    def __call__(self):
534
        name = self.serializer_instance.context['request'].data.get('name', '')
535
        return slugify(name)
536

  
537

  
525 538
class RoleSerializer(serializers.ModelSerializer):
526 539
    ou = serializers.SlugRelatedField(
527 540
        many=False,
......
529 542
        default=CreateOnlyDefault(get_default_ou),
530 543
        queryset=get_ou_model().objects.all(),
531 544
        slug_field='slug')
545
    slug = serializers.SlugField(
546
        required=False,
547
        allow_blank=False,
548
        max_length=256,
549
        default=SlugFromNameDefault())
532 550

  
533 551
    @property
534 552
    def user(self):
......
564 582
        model = get_role_model()
565 583
        fields = ('uuid', 'name', 'slug', 'ou',)
566 584
        extra_kwargs = {'uuid': {'read_only': True}}
585
        validators = [
586
            UniqueTogetherValidator(
587
                queryset=get_role_model().objects.all(),
588
                fields=['name', 'ou']
589
            ),
590
            UniqueTogetherValidator(
591
                queryset=get_role_model().objects.all(),
592
                fields=['slug', 'ou']
593
            )
594
        ]
567 595

  
568 596

  
569 597
# override to handle ambiguous naive DateTime on DST change
......
888 916
role_memberships = RoleMembershipsAPI.as_view()
889 917

  
890 918

  
891
class SlugFromNameDefault:
892
    requires_context = False
893
    serializer_instance = None
894

  
895
    def set_context(self, instance):
896
        self.serializer_instance = instance
897

  
898
    def __call__(self):
899
        name = self.serializer_instance.context['request'].data.get('name', '')
900
        return slugify(name)
901

  
902

  
903 919
class BaseOrganizationalUnitSerializer(serializers.ModelSerializer):
904 920
    slug = serializers.SlugField(
905 921
            required=False,
tests/test_api.py
1255 1255
    assert role.ou == get_default_ou()
1256 1256

  
1257 1257

  
1258
def test_api_post_role_no_slug(app, superuser):
1259
    app.authorization = ('Basic', (superuser.username, superuser.username))
1260
    Role = get_role_model()
1261

  
1262
    role_data = {
1263
        'name': 'Some Role',
1264
        }
1265
    resp = app.post_json('/api/roles/', params=role_data)
1266
    uuid = resp.json['uuid']
1267
    role = Role.objects.get(uuid=uuid)
1268
    assert role.slug == slugify(role.name)
1269
    assert role.slug == slugify(role_data['name'])
1270
    # another call with same role name
1271
    role_data = {
1272
        'name': 'Some Role',
1273
        }
1274
    resp = app.post_json('/api/roles/', params=role_data, status=400)
1275
    assert resp.json['errors']['__all__'] == [
1276
            'The fields name, ou must make a unique set.',
1277
            'The fields slug, ou must make a unique set.',
1278
        ]
1279
    # no slug no name
1280
    role_data = {
1281
        'id': 42,
1282
        }
1283
    resp = app.post_json('/api/roles/', params=role_data, status=400)
1284
    assert resp.json['errors']['name'] == ['This field is required.']
1285

  
1286

  
1258 1287
def test_api_post_ou_no_slug(app, superuser):
1259 1288
    app.authorization = ('Basic', (superuser.username, superuser.username))
1260 1289
    OU = get_ou_model()
1261
-