def test_core_file_prescription_with_files_for_doctor(api_client): # pass doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) file_prescription = FilePrescription.objects.filter(user=doctor.user_id).first() api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:file-prescription-with-patient-file', kwargs={'pk': file_prescription.id}) response = api_client.get(url) assert response.status_code == 200 # fail - 다른 의사가 생성한 FilePrescription 객체에 접근할 경우 file_prescription = FilePrescription.objects.exclude(user=doctor.user_id).first() api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:file-prescription-with-patient-file', kwargs={'pk': file_prescription.id}) response = api_client.get(url) assert response.status_code == 403 # fail - 환자가 접근할 경우 patient = Patient.objects.first() token = CustomRefreshToken.for_user(patient.user) file_prescription = FilePrescription.objects.filter(patient_id=patient.user_id).first() api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:file-prescription-with-patient-file', kwargs={'pk': file_prescription.id}) response = api_client.get(url) assert response.status_code == 403
def test_core_prescriptions_with_file_prescription_for_doctor(api_client): doctor = Doctor.objects.first() patients = Patient.objects.filter(doctor_id=doctor.user_id) prescription = Prescription.objects.filter(patient_id=patients.first().user_id).first() token = CustomRefreshToken.for_user(doctor.user) # pass api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:prescription-file', kwargs={'pk': prescription.id}) response = api_client.get(url) assert response.status_code == 200 # fail - 소견서 작성자가 다를 경우 doctor = Doctor.objects.last() token = CustomRefreshToken.for_user(doctor.user) prescription = Prescription.objects.exclude(writer_id=doctor.user_id).first() api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:prescription-file', kwargs={'pk': prescription.id}) response = api_client.get(url) assert response.status_code == 403 # fail - 환자가 접근할 경우 patient = patients.first() token = CustomRefreshToken.for_user(patient.user) prescription = Prescription.objects.filter(patient_id=patient.user_id).first() api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:prescription-file', kwargs={'pk': prescription.id}) response = api_client.get(url) assert response.status_code == 403
def test_token_for_user_with_error(doctor_with_group): with pytest.raises(Exception): CustomRefreshToken.for_user(doctor_with_group.user, raise_error=True) # CustomRefreshToken.for_user() 중간에 에러가 발생할 경우 user.token_expired=<epoch_time> 및 OutstandingToken은 생성되면 안됨 assert doctor_with_group.user.token_expired == 0 assert OutstandingToken.objects.all().exists() is False CustomRefreshToken.for_user(doctor_with_group.user) assert doctor_with_group.user.token_expired != 0
def test_compare_user_token_expired_with_accesstoken_expired( get_token_from_doctor): doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) access_token = token.access_token # 토큰 타입 검사 assert get_token_from_doctor['token_type'] == 'refresh' assert access_token['token_type'] == 'access' # user 모델에 등록된 토큰 만료 시간과 발급된 토큰(access_token)의 만료 시간이 동일한지 확인 assert access_token['exp'] == doctor.user.token_expired
def test_prescription_detail(api_client): # prescription.writer_id=2, prescription.patient_id=5 doctor = Doctor.objects.get(user_id=2) patient = Patient.objects.get(user_id=5) prescription = Prescription.objects.filter(writer_id=doctor.user_id).first() url = reverse('prescriptions:prescription-detail', kwargs={'pk': prescription.id}) # pass: writer 접근 token = CustomRefreshToken.for_user(doctor.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) response = api_client.get(url) assert response.status_code == 200 update_url = response.data.get('url', None) assert update_url is not None # pass: patient 접근 token = CustomRefreshToken.for_user(patient.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) response = api_client.get(url) assert response.status_code == 200 update_url = response.data.get('url', None) assert update_url is None # fail: 잘못된 writer 접근 other_doctor = Doctor.objects.get(user_id=3) token = CustomRefreshToken.for_user(other_doctor.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) response = api_client.get(url) assert response.status_code == 403 # fail: 잘못된 patient 접근 other_patient = Patient.objects.get(user_id=6) token = CustomRefreshToken.for_user(other_patient.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) response = api_client.get(url) assert response.status_code == 403 # fail: 미인증 api_client.credentials() response = api_client.get(url) assert response.status_code == 403
def test_core_history_uploaded_patient_file(api_client): # pass doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) # 새로 업로드된 파일 필터 = checked=False, uploaded=True file_prescriptions = FilePrescription.objects.filter(user=doctor.user_id, checked=False, uploaded=True) file_prescriptions_count = file_prescriptions.count() api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:new-patient-file') response = api_client.get(url) assert response.status_code == 200 assert response.data['count'] == file_prescriptions_count # pass - 환자가 새로운 파일을 업로드 할 경우 patient = Patient.objects.filter(doctor_id=doctor.user_id).first() patient_token = CustomRefreshToken.for_user(patient.user) file_prescription = FilePrescription.objects.filter(user=doctor.user_id, checked=True).first() file = SimpleUploadedFile('test_file.md', b'test histroy', content_type='multipart/form-data') api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(patient_token.access_token)) value = { 'file_prescription': file_prescription.id, 'file': file, } uploaded_url = reverse('files:patient-file-upload') response = api_client.post(uploaded_url, data=value, format='multipart') assert response.status_code == 201 api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:new-patient-file') response = api_client.get(url) assert file_prescriptions.count() == file_prescriptions_count + 1 assert response.data['count'] == file_prescriptions_count + 1 # fail - 환자가 접근할 경우 patient = Patient.objects.first() token = CustomRefreshToken.for_user(patient.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:new-patient-file') response = api_client.get(url) assert response.status_code == 403
def test_core_doctor_detail_for_doctor(api_client): # pass doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:detail', kwargs={'pk': doctor.user_id}) response = api_client.get(url) assert response.status_code == 200 # fail: 다른 의사의 정보를 열람할 경우 other_doctor = Doctor.objects.last() token = CustomRefreshToken.for_user(other_doctor.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:detail', kwargs={'pk': doctor.user_id}) response_fail = api_client.get(url) assert response_fail.status_code == 403
def test_api_update_doctor(api_client): doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) # 토큰 인증 api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('accounts:doctor-update', kwargs={'pk': doctor.user_id}) # 데이터 변경(PUT) data = {'description': 'changed description'} response = api_client.put(url, data=data, format='json') assert response.status_code == 200 assert response.data['description'] == 'changed description'
def test_prescription_list(api_client): # pass doctor = Doctor.objects.get(user_id=2) token = CustomRefreshToken.for_user(doctor.user) url = reverse('prescriptions:prescription-list') api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) response = api_client.get(url) assert response.status_code == 200 result_data = response.data['results'][0] result_dic = {key: value for key, value in result_data.items() if key == 'writer_id'} # pass: 접근한 의사 계정으로 작성한 prescription만 출력되는지 테스트 for writer_id in result_dic.values(): assert writer_id == doctor.user_id # pass: 환자 계정으로 접근 + 자신과 관련된 소견서 리스트 patient = Patient.objects.first() token = CustomRefreshToken.for_user(patient.user) url = reverse('prescriptions:prescription-list') api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) response = api_client.get(url) assert response.status_code == 200 result_list = response.data['results'] for result in result_list: patient_id = result['patient'] assert patient.user_id == patient_id # prescription-list 결과와 환자 계정으로 필터링된 Prescription 모델 수 비교 prescription_count = Prescription.objects.filter(patient_id=patient.user_id).count() assert prescription_count == len(result_list) # fail: 미인증 api_client.credentials() response = api_client.get(url) assert response.status_code == 403
def test_authenticate_jwt_token_user(rf): doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) access_token = token.access_token url = reverse('token-login') request = rf.post(url, HTTP_AUTHORIZATION=f'Bearer {str(access_token)}') authentication = CustomJWTTokenUserAuthentication() auth_user, validated_token = authentication.authenticate(request) assert auth_user == doctor.user assert token['token_type'] == 'refresh' assert access_token['token_type'] == 'access' assert access_token['jti'] == validated_token['jti']
def validate(self, attrs: Dict[str, Union[AnyStr, int]]) -> Dict[str, Union[AnyStr, int]]: refresh_obj = CustomRefreshToken(attrs['refresh']) data = {'access': str(refresh_obj.access_token)} access_token_exp = refresh_obj.access_token.payload['exp'] self.try_blacklist(refresh=refresh_obj) self.set_refresh_payload(refresh=refresh_obj) self.set_user_expired_to(epoch_time=access_token_exp) refresh_token = str(refresh_obj) data['refresh'] = refresh_token return data
def test_custom_refresh_token(): user = BaseUser.objects.get(id=2) # expired time token = CustomRefreshToken.for_user(user) assert user.token_expired == token.access_token['exp'] assert BlacklistedToken.objects.all().exists() is False outstanding_token = OutstandingToken.objects.first() assert outstanding_token.token == str(token) assert outstanding_token.jti == token['jti'] assert outstanding_token.expires_at == datetime_from_epoch(token['exp']) token.blacklist() black_token = BlacklistedToken.objects.get(token_id=outstanding_token.id) assert black_token
def test_api_retrieve_doctor(api_client): doctor = Doctor.objects.first() token = CustomRefreshToken.for_user(doctor.user) # authenticate token api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) doctor = Doctor.objects.get(user_id=2) # detail - success url = reverse('accounts:doctor-detail', kwargs={'pk': doctor.user_id}) response = api_client.get(url, format='json') assert response.status_code == 200 # fail - 인증 x api_client.credentials() response = api_client.get(url, format='json') assert response.status_code == 403 # 401: 익명, 403: 로그인은 했지만 권한이 없음
def test_core_patients_prescription_list_for_doctor(api_client): # pass doctor = Doctor.objects.first() patients = Patient.objects.filter(doctor_id=doctor.user_id) patient = patients.first() token = CustomRefreshToken.for_user(doctor.user) api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) url = reverse('core-api:doctors:prescription-list', kwargs={'pk': patient.user_id}) response = api_client.get(url) assert response.status_code == 200 # fail - 담당 환자가 아닐 경우 patients = Patient.objects.exclude(doctor_id=doctor.user_id) patient = patients.first() url = reverse('core-api:doctors:prescription-list', kwargs={'pk': patient.user_id}) response = api_client.get(url) assert response.status_code == 403
def get_token_from_patient(patient_with_group): return CustomRefreshToken.for_user(patient_with_group.user)
def get_token_from_doctor(doctor_with_group): return CustomRefreshToken.for_user(doctor_with_group.user)
def get_access_and_refresh_token_from_doctor(doctor_with_group): token = CustomRefreshToken.for_user(doctor_with_group.user) return str(token), str(token.access_token)
def test_create_and_update_prescription(api_client): # pass - prescription create doctor = Doctor.objects.get(user_id=2) token = CustomRefreshToken.for_user(doctor.user) # authenticate token api_client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(token.access_token)) patient = Patient.objects.get(user_id=5) url = reverse('prescriptions:prescription-create') file1 = SimpleUploadedFile('test_file1.md', b'test prescription 1', content_type='ultipart/form-data') file2 = SimpleUploadedFile('test_file2.md', b'test prescription 2', content_type='multipart/form-data') value = { "description": "new test", "patient": patient.user_id, "doctor_upload_files": [file1, file2], "start_date": '2021-02-01', "end_date": '2021-02-10' } response = api_client.post(url, data=value, format='multipart') assert response.status_code == 201 assert response.data['description'] == "new test" prescription = Prescription.objects.first() assert prescription.description == "new test" # 생성된 file prescription 확인 fp = FilePrescription.objects.filter(prescription_id=prescription.id) assert fp.count() == 10 assert fp.first().patient_id == patient.user_id and fp.last().patient_id == patient.user_id assert fp.first().writer_id == doctor.user_id and fp.last().writer_id == doctor.user_id assert fp.first().day_number == 10 and fp.last().day_number == 1 # 생성된 doctor file 확인 doctor_files = DoctorFile.objects.filter(prescription_id=prescription.id) assert doctor_files.count() == 2 assert "test_file2.md" in doctor_files.first().file.name and "test_file1.md" in doctor_files.last().file.name # pass - file update update_url = reverse('prescriptions:prescription-update', kwargs={'pk': prescription.id}) test_file = SimpleUploadedFile('updated_file1.md', b'update prescription', content_type='multipart/form-data') updated_value = { "description": "updated description", "doctor_upload_files": [test_file], } response = api_client.put(update_url, data=updated_value, formart='multipart') assert response.status_code == 200 assert response.data['description'] == updated_value['description'] assert len(response.data['doctor_files']) == 1 assert prescription.doctor_files.filter_not_deleted().count() == 1 assert prescription.file_prescriptions.filter(deleted=False).count() == 10 # 수정전 FilePrescription 객체의 수 # pass - file prescription update update_url = reverse('prescriptions:prescription-update', kwargs={'pk': prescription.id}) updated_value = { "description": "file prescription update", "start_date": "2021-03-03", "end_date": "2021-03-06" } response = api_client.put(update_url, data=updated_value, formart='multipart') assert response.status_code == 200 assert response.data['description'] == updated_value['description'] assert prescription.file_prescriptions.count() == 4 # 수정된 FilePrescription 객체의 수 # cleanup(fixture cleanup -> yield): 테스트 파일 삭제 for file in DoctorFile.objects.filter(prescription_id=prescription.id): file.hard_delete()
def get_token_with_doctor(): doctor = Doctor.objects.first() refresh = CustomRefreshToken.for_user(doctor.user) return doctor, refresh
def get_token_with_patient(): patient = Patient.objects.first() refresh = CustomRefreshToken.for_user(patient.user) return patient, refresh
def get_token(cls, user: User) -> Token: token = CustomRefreshToken.for_user(user) return token