Files
guilan-ace-backend/apps/users/tests/integration/test_users.py
Amirhossein Khalili ff99130938 test: migrate backend suites to pytest with module coverage gate
Split backend tests into unit and integration suites, add isolated fixtures and coverage enforcement, and update CI and test documentation. Cover current authentication, content, notification, payment, media, and admin flows; fix behaviors revealed by the new tests. Validate both suites and the per-module gate against local PostgreSQL.
2026-09-26 16:50:29 +03:30

73 lines
3.7 KiB
Python

import pytest
import json
from django.core.files.uploadedfile import SimpleUploadedFile
from apps.users.models import User
from core.authentication import create_jwt_token
@pytest.mark.django_db
@pytest.mark.integration
class TestUsersAPIIntegrationTests:
def setup_method(self):
self.user = User.objects.create_user(username='mobile_user', mobile='09192000001', email='person@example.com', password='Sup3rSecure!123', is_mobile_verified=True)
def _auth(self):
return {'HTTP_AUTHORIZATION': f'Bearer {create_jwt_token(self.user)}'}
def test_password_login_accepts_mobile_identity(self):
response = self.client.post('/api/auth/login', json.dumps({'identifier': self.user.mobile, 'password': 'Sup3rSecure!123'}), content_type='application/json')
assert response.status_code == 200
assert 'access_token' in response.json()
def test_profile_update_treats_supplied_email_as_identity(self):
response = self.client.put('/api/auth/profile', json.dumps({'email': 'new@example.com'}), content_type='application/json', **self._auth())
assert response.status_code == 200
self.user.refresh_from_db()
assert self.user.email == 'new@example.com'
assert self.user.is_email_verified
def test_profile_update_clears_email_identity_flag(self):
response = self.client.put('/api/auth/profile', json.dumps({'email': ''}), content_type='application/json', **self._auth())
assert response.status_code == 200
self.user.refresh_from_db()
assert self.user.email is None
assert not self.user.is_email_verified
def test_profile_requires_authentication_and_returns_account_identity(self):
assert self.client.get('/api/auth/profile').status_code == 401
response = self.client.get('/api/auth/profile', **self._auth())
assert response.status_code == 200
assert response.json()['mobile'] == self.user.mobile
def test_profile_rejects_duplicate_email(self):
User.objects.create_user(username='second', mobile='09192000002', email='taken@example.com', password='password')
response = self.client.put('/api/auth/profile', json.dumps({'email': 'taken@example.com'}), content_type='application/json', **self._auth())
assert response.status_code == 400
self.user.refresh_from_db()
assert self.user.email == 'person@example.com'
def test_profile_picture_rejects_non_image_upload(self):
image = SimpleUploadedFile('notes.txt', b'not an image', content_type='text/plain')
response = self.client.post('/api/auth/profile/picture', {'file': image}, **self._auth())
assert response.status_code == 400
def test_check_username_reports_existing_user(self):
response = self.client.get('/api/auth/check-username', {'username': self.user.username})
assert response.status_code == 200
assert response.json()['exists']
def test_legacy_email_auth_routes_are_gone(self):
assert self.client.get('/api/auth/verify-email/token').status_code == 404
assert self.client.post('/api/auth/resend-verification').status_code == 404
assert self.client.post('/api/auth/request-password-reset').status_code == 404
def test_mobile_otp_password_reset_route_remains_available(self, mocker):
reset = mocker.patch('apps.users.api.views.reset_password_with_otp')
response = self.client.post('/api/auth/reset-password', json.dumps({'mobile': self.user.mobile, 'code': '123456', 'new_password': 'AnotherSecurePass!123'}), content_type='application/json')
assert response.status_code == 200
reset.assert_called_once()
@pytest.fixture(autouse=True)
def _pytest_client(self, client):
self.client = client