import json import uuid from django.contrib.auth.hashers import make_password from django.test import TestCase from apps.user.models import User class SignUpAPITestCase(TestCase): def test_successful_sign_up(self): payload = { "email": "user@example.com", "password": "securepassword123", "username": "123", } response = self.client.post( "/api/v1/sign-up", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 201) self.assertIn("token", response.json()) self.assertEqual(User.objects.count(), 1) def test_missing_required_fields(self): payload = {"password": "testpass123", "username": "sffsdf"} response = self.client.post( "/api/v1/sign-up", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 400) def test_invalid_email_format(self): payload = { "email": "ervtb uktr bym", "password": "securepassword123", "username": "123", } response = self.client.post( "/api/v1/sign-up", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 400) def test_existing_user_conflict(self): User.objects.create( email="existing@example.com", password="existingpass123", username="testing", ) payload = { "email": "existing@example.com", "password": "sfsad", "username": "testing", } response = self.client.post( "/api/v1/sign-up", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 409) self.assertIn("detail", response.json()) class SignInAPITestCase(TestCase): def setUp(self): self.user = User.objects.create( email="valid@example.com", password=make_password("securepassword123"), username="testuser", ) self.valid_payload = { "email": "valid@example.com", "password": "securepassword123", } def test_successful_sign_in(self): response = self.client.post( "/api/v1/sign-in", data=json.dumps(self.valid_payload), content_type="application/json", ) self.assertEqual(response.status_code, 200) self.assertIn("token", response.json()) def test_missing_credentials(self): # Test missing email response = self.client.post( "/api/v1/sign-in", data=json.dumps({"password": "pass"}), content_type="application/json", ) self.assertEqual(response.status_code, 400) # Test missing password response = self.client.post( "/api/v1/sign-in", data=json.dumps({"email": "test@example.com"}), content_type="application/json", ) self.assertEqual(response.status_code, 400) def test_invalid_email_format(self): payload = {"email": "invalid-email", "password": "password123"} response = self.client.post( "/api/v1/sign-in", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 401) def test_incorrect_password(self): payload = {"email": "valid@example.com", "password": "wrongpassword"} response = self.client.post( "/api/v1/sign-in", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 401) self.assertEqual(response.json()["detail"], "Unauthorized") def test_nonexistent_user(self): payload = {"email": "notexist@example.com", "password": "password123"} response = self.client.post( "/api/v1/sign-in", data=json.dumps(payload), content_type="application/json", ) self.assertEqual(response.status_code, 401) self.assertEqual(response.json()["detail"], "Unauthorized") class UserMeEndpointTestCase(TestCase): def setUp(self): # Create test user and token self.user = User.objects.create( email="johndoe@example.com", username="johndoe", password=make_password("securepassword123"), ) resp = self.client.post( "/api/v1/sign-in", data=json.dumps( { "email": "johndoe@example.com", "password": "securepassword123", } ), content_type="application/json", ).json() self.token = resp["token"] self.url = "/api/v1/me" def test_get_authenticated_user_data(self): """Test authenticated user can retrieve their profile (200 OK)""" response = self.client.get( self.url, HTTP_AUTHORIZATION=f"Bearer {self.token}" ) self.assertEqual(response.status_code, 200) data = response.json() # Validate UserSchema structure self.assertIn("id", data) self.assertIn("email", data) self.assertIn("username", data) # Validate UUID format if ID is present if data["id"] is not None: try: uuid.UUID(data["id"]) except ValueError: self.fail("ID is not a valid UUID") # Validate response content self.assertEqual(data["email"], "johndoe@example.com") self.assertEqual(data["username"], "johndoe") def test_unauthenticated_access(self): """Test unauthorized access returns 401 Unauthorized""" response = self.client.get(self.url) self.assertEqual(response.status_code, 401) self.assertEqual(response.json()["detail"], "Unauthorized") def test_invalid_auth_scheme(self): """Test invalid authentication scheme returns 401""" response = self.client.get( self.url, HTTP_AUTHORIZATION=f"InvalidScheme {self.token}" ) self.assertEqual(response.status_code, 401) self.assertEqual(response.json()["detail"], "Unauthorized") def test_malformed_token(self): """Test malformed token returns 401""" test_cases = ["invalid.token.123", "Bearer", "", "123456"] for token in test_cases: with self.subTest(token=token): response = self.client.get( self.url, HTTP_AUTHORIZATION=f"Bearer {token}" ) self.assertEqual(response.status_code, 401) self.assertEqual(response.json()["detail"], "Unauthorized")