Projet

Général

Profil

0001-api-handle-multiple-objects-returned-in-get-or-creat.patch

Paul Marillonnet, 30 juillet 2020 17:39

Télécharger (3,16 ko)

Voir les différences:

Subject: [PATCH] api: handle multiple objects returned in get-or-create mixin
 (#44301)

 src/authentic2/api_mixins.py |  4 ++++
 tests/test_api.py            | 37 ++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)
src/authentic2/api_mixins.py
49 49
            return ModelClass.objects.get(**kwargs)
50 50
        except ModelClass.DoesNotExist:
51 51
            return None
52
        except ModelClass.MultipleObjectsReturned:
53
            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: [
54
                'retrieved several instances of model %s for key attributes %s' % (ModelClass.__name__, kwargs)]
55
            })
52 56

  
53 57
    def _validate_get_keys(self, keys):
54 58
        ModelClass = self._get_model_class()
tests/test_api.py
1420 1420
    assert User.objects.get(id=id).last_name == 'Doe'
1421 1421

  
1422 1422

  
1423
def test_api_users_get_or_create_email_not_unique(settings, app, admin):
1424
    settings.A2_EMAIL_IS_UNIQUE = False
1425
    User = get_user_model()
1426
    OU = get_ou_model()
1427
    ou1 = OU.objects.create(name='OU1', slug='ou1', email_is_unique=True)
1428
    ou2 = OU.objects.create(name='OU2', slug='ou2', email_is_unique=False)
1429

  
1430
    app.authorization = ('Basic', (admin.username, admin.username))
1431
    payload = {
1432
        'email': 'john.doe@example.net',
1433
        'first_name': 'John',
1434
        'last_name': 'Doe',
1435
        'ou': 'ou1'
1436
    }
1437
    # 1. create
1438
    resp = app.post_json('/api/users/?get_or_create=email', params=payload, status=201)
1439
    id_user = resp.json['id']
1440
    assert User.objects.get(id=id_user).first_name == 'John'
1441
    assert User.objects.get(id=id_user).last_name == 'Doe'
1442
    assert User.objects.get(id=id_user).ou == ou1
1443
    # 2. get
1444
    resp = app.post_json('/api/users/?get_or_create=email', params=payload, status=200)
1445
    # 3. explicitly create in a different OU
1446
    payload['ou'] = 'ou2'
1447
    resp = app.post_json('/api/users/', params=payload, status=201)
1448
    id_user2 = resp.json['id']
1449
    assert id_user2 != id_user
1450
    assert User.objects.get(id=id_user2).first_name == 'John'
1451
    assert User.objects.get(id=id_user2).last_name == 'Doe'
1452
    assert User.objects.get(id=id_user2).ou == ou2
1453
    # 4. fail to retrieve a single instance for an ambiguous get-or-create key
1454
    resp = app.post_json('/api/users/?get_or_create=email', params=payload, status=400)
1455
    assert resp.json['errors'] == {
1456
        '__all__': ["retrieved several instances of model User for key attributes {'email': 'john.doe@example.net'}"],
1457
    }
1458

  
1459

  
1423 1460
def test_api_users_get_or_create_multi_key(settings, app, admin):
1424 1461
    app.authorization = ('Basic', (admin.username, admin.username))
1425 1462
    # test missing first_name
1426
-