permission과 테스트코드에 대해 공부, 여러 알고리즘 문제 풀이, 다음 주 프로젝트 발제를 위한 회의를 진행하였다
Today I Learned
class ArticleReadTest(APITestCase):
@classmethod
def setUpTestData(cls):
cls.faker = Faker()
cls.articles = []
for i in range(10):
cls.user = User.objects.create_user(cls.faker.email(), cls.faker.password())
cls.articles.append(TodoArticle.objects.create(title=cls.faker.sentence(), user=cls.user))
def test_get_todoarticle(self):
for article in self.articles:
url = article.get_absolute_url()
response = self.client.get(url)
print(response.data, "체크")
serializer = TodoSerializer(article).data
for key, value in serializer.items():
self.assertEqual(response.data[key], value)
print(key, value)
위 테스트 코드는 todoArticle의 상세정보를 가져오는 API 엔드포인트를 테스트
1. setUpTestData 메서드를 통해 테스트 데이터를 설정
- Faker를 install 하여 사용 => 가짜 데이터를 생성하는 객체를 만듬
- articles라는 빈 리스트를 만들고 for문으로 순회
=> fake 유저와 fake게시글을 가지는 TodoArticle객체를 생성하여 빈 리스트에 append
2. test_get_todoarticle 메서드를 통해 TodoAritcle의 상세정보를 가져오는 API 엔드포인트를 테스트
- get_absolute_url()을 호출, TodoArticle 객체의 상세정보를 가져올 수 있는 URL을 얻음
- self.client.get(url)로 해당 URL에 GET요청
- serializer변수에 직렬화된 article데이터를 할당
- for문 순회를 통해 response.data키의 값과 serializer의 해당 값이 일치하는 지 테스트
>_ 문제 발생
$ python manage.py test todo
Found 3 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..{'detail': ErrorDetail(string='자격 인증데이터(authentication credentials)가 제공되지 않았습니다.', code='not_authenticated')} 체크
E
======================================================================
ERROR: test_get_todoarticle (todo.tests.ArticleReadTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\user\Desktop\develop_study\drf_todo_list\todo\tests.py", line 53, in test_get_todoarticle
self.assertEqual(response.data[key], value)
KeyError: 'id'
----------------------------------------------------------------------
Ran 3 tests in 5.027s
FAILED (errors=1)
Destroying test database for alias 'default'...
에러 내용을 보니 인증 관련 에러였음
방법은 테스트데이터를 설정할 때 토큰을 발급해주지 않았고, 해당 view함수에서는
permission_classes = [permissions.IsAuthenticated]
인증된 사용자에게만 요청을 허용하는 permission이기 때문에
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
위와 같이 인증되지 않은 사용자에게 ReadOnly가 가능하도록 변경해주었다.
#permissions.py
class IsAuthorOrReadonly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.user == request.user
위 코드는 permissions.BasePermission을 상속받아서 has_object_permission메서드를 오버라이딩한 class
SAFE_METHODS는 Django REST Framework에서 제공하는 상수.
HTTP요청 중 안전한(read-only)메서드를 나타내는데, 일반적으로 GET, HEAD,OPTIONS같은 메서드가 안전한 메서드로 간주된다. 이러한 메서드들은 서버의 상태나 데이터를 변경하지 않고 리소스에 대한 정보를 가져오는 용도로 사용됨
- GET: 리소스의 정보를 가져오는 요청
- HEAD: 리소스의 헤더 정보를 가져오는 요청
- OPTIONS: 리소스가 지원하는 메서드 목록을 가져오는 요청
- 위의 permission 클래스에서도 SAFE_METHODS를 사용하여 안전한 메서드에 대해선 추가적 권한 검사 없이 항상 True를 반환
- 그 외의 요청 : 객체의 작성자와 요청한 사용자가 일치할 경우에만 권한을 부여해주도록 작성
'내일배움캠프 > 내일배움캠프 TIL' 카테고리의 다른 글
내일배움캠프 TIL 52일차 - Tosspay render에서 fetch API로 변경하기 (0) | 2023.05.24 |
---|---|
내일배움캠프 TIL 51일차 (0) | 2023.05.23 |
내일배움캠프 TIL 49일차 (0) | 2023.05.19 |
내일배움캠프 TIL 47일차 (1) | 2023.05.18 |
내일배움캠프 TIL 46일차 (0) | 2023.05.15 |