2017-02-14 23 views
3

나는 pytest 3.0.6과 pytest-django 3.1.2를 사용하여 장고를위한 라이브러리에서 작업한다. 나는이 매우 간단한 테스트 실패가 있고, 나는 일이 무엇인지 이해하지 않습니다Pytest-django : 사용자 권한 설정

# test_mytest.py 
import pytest 
from django.contrib.auth.models import Permission 
from django.contrib.contenttypes.models import ContentType 


@pytest.mark.django_db 
def test_user_has_perm(django_user_model): 
    # Create a new user 
    john_doe = django_user_model.objects.create_user('johndoe', email='[email protected]', password='123456') 

    # Get or create the permission to set on user 
    user_ct = ContentType.objects.get(app_label='auth', model='user') 
    p, _ = Permission.objects.get_or_create(content_type=user_ct, codename='delete_user', name="Can delete user") 

    # User don't have the permission 
    assert john_doe.has_perm(p) is False 

    # Set permission to user 
    john_doe.user_permissions.add(p) 
    assert john_doe.has_perm(p) is True # ---> FAIL 

그냥 경우, 시험의 결과는 다음과 같습니다

$ pytest 
============================= test session starts ============================= 
platform win32 -- Python 3.5.3, pytest-3.0.6, py-1.4.32, pluggy-0.4.0 
Django settings: testsite.settings (from ini file) 
rootdir: D:\Dev\foss\django-modern-rpc, inifile: tox.ini 
plugins: pythonpath-0.7.1, django-3.1.2, cov-2.4.0 
collected 1 items 

modernrpc\tests\test_test_test.py F 

================================== FAILURES =================================== 
_____________________________ test_user_has_perm ______________________________ 

django_user_model = <class 'django.contrib.auth.models.User'> 

    @pytest.mark.django_db 
    def test_user_has_perm(django_user_model): 
     # Create a new user 
     john_doe = django_user_model.objects.create_user('johndoe', email='[email protected]', password='123456') 

     # Get or create the permission to set on user 
     user_ct = ContentType.objects.get(app_label='auth', model='user') 
     p, _ = Permission.objects.get_or_create(content_type=user_ct, codename='delete_user', name="Can delete user") 

     # User don't have the permission 
     assert john_doe.has_perm(p) is False 

     # Set permission to user 
     john_doe.user_permissions.add(p) 
>  assert john_doe.has_perm(p) is True # ---> FAIL 
E  assert False is True 
E  + where False = <bound method PermissionsMixin.has_perm of <User: johndoe>>(<Permission: auth | user | Can delete user>) 
E  + where <bound method PermissionsMixin.has_perm of <User: johndoe>> = <User: johndoe>.has_perm 

modernrpc\tests\test_test_test.py:20: AssertionError 
========================== 1 failed in 0.32 seconds =========================== 

config 블록, tox.ini에서

BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 
DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.sqlite3', 
     'NAME': os.path.join(BASE_DIR, 'modern_rpc.sqlite3'), 
    }, 
} 
: 테스트 설정에서

[pytest] 
DJANGO_SETTINGS_MODULE = testsite.settings 
norecursedirs = .git __pycache__ build dist venv* .tox .vscode .cache *.egg-info 
python_paths = modernrpc/tests 
testpaths = modernrpc/tests 
python_files = test_*.py dummy_*.py 

그리고 DB 구성,

내가 뭘 잘못하고 있니? docs에서

답변

4

를 다시 반입 후 그것은 작동합니다 : 사용자가 파마의 형식에 지정된 권한을 가지고있는 경우

반환 사실을 " < 앱 라벨 > < 허가 코드 명 > ".

del john_doe._perm_cache 
del john_doe._user_perm_cache 
# OR 
john_doe = django_user_model.objects.get(username='johndoe') 
:

또한, 당신은 당신이 마지막 호출 이후 권한을 변경 한 경우 has_permuser._perm_cacheuser._user_perm_cache를 지우거나 확인하기 위해 DB에서이 사용자의 새로운 인스턴스를 검색해야합니다 모르겠 음 캐시가없는

has_perm이 auth 백엔드를 호출하고 차례로 이들 캐시를 먼저 참조하기 때문입니다.

+0

고맙습니다. 권한을 얻기 위해 캐시 시스템을 완전히 놓쳤습니다. – Antwane

+0

예. Django는 캐싱이 잘 문서화되어 있지 않기 때문에 코드를 파고 들게합니다. – schwobaseggl

2

:

has_perm (파마, OBJ = 없음) 사용자가 파마의 형식

"<app label>.<permission codename>"에 지정된 권한을 가지고있는 경우

true를 돌려줍니다.

(사용 권한 설명서 참조) 사용자가 비활성 상태 인 경우이 메서드 은 항상 False를 반환합니다.

obj가 전달 된 경우이 메서드는 모델에 대한 사용 권한을 검사하지 않지만이 특정 개체에 대해 사용 권한을 확인합니다.

그래서이 방법은 True을 반환해야 문자열이 아닌 권한 객체

john_doe.has_perm('auth.delete_user')

을 받아들입니다. (user_ct의 앱이 auth 인 경우 user_ct을 사용 했으므로 권한에 auth 앱이 할당되어 있습니다.

그러나 예를 들어 permission check caching이 있으므로이 예는 즉시 발생하지 않습니다.

당신은 당신은 문자열 'app_label.codename' 사용할 필요가 개체

#Be aware this only works after Django 1.9+ 
#https://code.djangoproject.com/ticket/26514 
john_doe.refresh_from_db() 
#Otherwise use: 
john_doe = User.objects.get(pk=john_doe.pk)