56 lines
2.7 KiB
Python
56 lines
2.7 KiB
Python
"""
|
|
LoginEvent: سابقهی ماندگارِ ورود/خروج. آزموده: ورودِ موفق، کدِ غلط، مسدودشدن، خروج، ماندنِ
|
|
ردیف بعد از حذفِ حساب. آزموده نشده: حجمِ بالا و نوشتن همزمان.
|
|
"""
|
|
from django.core.cache import cache
|
|
from django.test import TestCase
|
|
from django.utils import timezone
|
|
from rest_framework.test import APIClient
|
|
|
|
from accounts.authentication import issue_access_token
|
|
from accounts.models import LoginEvent, OTPCode, User
|
|
|
|
|
|
class LoginEventTests(TestCase):
|
|
def setUp(self):
|
|
cache.clear()
|
|
self.phone = '09121116001'
|
|
self.api = APIClient()
|
|
|
|
def otp(self, code='482913'):
|
|
OTPCode.objects.create(phone=self.phone, code=code,
|
|
expires_at=timezone.now() + timezone.timedelta(minutes=5))
|
|
|
|
def login(self, code):
|
|
return self.api.post('/api/auth/login', {'phone': self.phone, 'otp': code}, format='json',
|
|
HTTP_USER_AGENT='test-agent', REMOTE_ADDR='203.0.113.7')
|
|
|
|
def test_success_and_failure_are_recorded(self):
|
|
self.assertEqual(self.login('000000').status_code, 400)
|
|
self.otp()
|
|
self.assertEqual(self.login('482913').status_code, 200)
|
|
events = list(LoginEvent.objects.order_by('id').values_list('event', 'phone', 'ip', 'user_agent'))
|
|
self.assertEqual(events, [
|
|
('login_failed', self.phone, '203.0.113.7', 'test-agent'),
|
|
('login_ok', self.phone, '203.0.113.7', 'test-agent'),
|
|
])
|
|
self.assertEqual(LoginEvent.objects.get(event='login_ok').user_id,
|
|
User.objects.get(phone=self.phone).id)
|
|
|
|
def test_logout_is_recorded(self):
|
|
user = User.objects.create(phone=self.phone)
|
|
self.api.credentials(HTTP_AUTHORIZATION=f'Bearer {issue_access_token(user.id)}')
|
|
self.assertEqual(self.api.post('/api/auth/logout', {}, format='json').status_code, 200)
|
|
self.assertTrue(LoginEvent.objects.filter(event='logout', user_id=user.id).exists())
|
|
|
|
def test_events_survive_account_deletion(self):
|
|
user = User.objects.create(phone=self.phone)
|
|
LoginEvent.objects.create(event='login_ok', user_id=user.id, phone=self.phone)
|
|
self.api.credentials(HTTP_AUTHORIZATION=f'Bearer {issue_access_token(user.id)}')
|
|
self.otp()
|
|
r = self.api.post('/api/user/delete', {'otp': '482913'}, format='json')
|
|
self.assertEqual(r.status_code, 200, r.content)
|
|
self.assertFalse(User.objects.filter(pk=user.pk).exists())
|
|
self.assertEqual(set(LoginEvent.objects.values_list('event', flat=True)),
|
|
{'login_ok', 'account_deleted'})
|