from unittest.mock import MagicMock, patch from django.test import TestCase from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient, APITestCase from torrent.models import Torrent from .models import FriendRequest, Invitation, User class UserModelTestCase(TestCase): def setUp(self): self.user = User.objects.create_user( username="testuser", email="test@example.com", password="testpassword", max_size=1000000, ) self.friend = User.objects.create_user( username="frienduser", email="friend@example.com", password="friendpassword" ) def test_size_used_property(self): """Test the size_used property returns the correct total size of user's torrents""" # Initially no torrents, so size should be 0 self.assertEqual(self.user.size_used, 0) # Create a torrent for the user Torrent.objects.create( id="abc123", name="Test Torrent", user=self.user, size=5000, transmission_data={}, ) # Create another torrent Torrent.objects.create( id="def456", name="Another Torrent", user=self.user, size=3000, transmission_data={}, ) # Clear cached_property if it exists if hasattr(self.user, "total_size"): delattr(self.user, "total_size") # Size used should be the sum of torrent sizes self.assertEqual(self.user.size_used, 8000) def test_min_infos_property(self): """Test the min_infos property returns the correct user info""" expected_info = {"username": "testuser", "id": self.user.id} self.assertEqual(self.user.min_infos, expected_info) class UsernameUserManagerTestCase(TestCase): def test_create_user(self): """Test creating a regular user""" user = User.objects.create_user( username="newuser", email="new@example.com", password="newpassword" ) self.assertFalse(user.is_staff) self.assertFalse(user.is_superuser) self.assertEqual(user.username, "newuser") self.assertEqual(user.email, "new@example.com") self.assertTrue(user.check_password("newpassword")) def test_create_superuser(self): """Test creating a superuser""" admin = User.objects.create_superuser( username="admin", email="admin@example.com", password="adminpassword" ) self.assertTrue(admin.is_staff) self.assertTrue(admin.is_superuser) self.assertEqual(admin.username, "admin") self.assertEqual(admin.email, "admin@example.com") def test_create_user_without_username(self): """Test creating a user without username raises error""" with self.assertRaises(ValueError): User.objects.create_user( username="", email="test@example.com", password="testpassword" ) def test_create_user_without_email(self): """Test creating a user without email raises error""" with self.assertRaises(ValueError): User.objects.create_user( username="testuser", email="", password="testpassword" ) class FriendRequestModelTestCase(TestCase): def setUp(self): self.sender = User.objects.create_user( username="sender", email="sender@example.com", password="senderpassword" ) self.receiver = User.objects.create_user( username="receiver", email="receiver@example.com", password="receiverpassword", ) def test_friend_request_creation(self): """Test creating a friend request""" friend_request = FriendRequest.objects.create( sender=self.sender, receiver=self.receiver ) self.assertEqual(friend_request.sender, self.sender) self.assertEqual(friend_request.receiver, self.receiver) def test_unique_together_constraint(self): """Test that the unique_together constraint works""" FriendRequest.objects.create(sender=self.sender, receiver=self.receiver) # Creating another request with the same sender and receiver should raise an error with self.assertRaises(Exception): FriendRequest.objects.create(sender=self.sender, receiver=self.receiver) class InvitationModelTestCase(TestCase): def setUp(self): self.creator = User.objects.create_user( username="creator", email="creator@example.com", password="creatorpassword" ) def test_invitation_creation(self): """Test creating an invitation""" invitation = Invitation.objects.create(created_by=self.creator) self.assertEqual(invitation.created_by, self.creator) self.assertIsNotNone(invitation.token) self.assertIsNone(invitation.user) def test_invitation_assignment(self): """Test assigning an invitation to a user""" invitation = Invitation.objects.create(created_by=self.creator) new_user = User.objects.create_user( username="newuser", email="new@example.com", password="newpassword" ) invitation.user = new_user invitation.save() # Refresh from database invitation.refresh_from_db() self.assertEqual(invitation.user, new_user) class UserViewSetTestCase(APITestCase): def setUp(self): self.user = User.objects.create_user( username="testuser", email="test@example.com", password="testpassword" ) self.friend = User.objects.create_user( username="frienduser", email="friend@example.com", password="friendpassword" ) self.client = APIClient() self.client.force_authenticate(user=self.user) def test_list_users(self): """Test listing users""" url = reverse("user-list") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 2) # Should include both users def test_retrieve_user(self): """Test retrieving a specific user""" url = reverse("user-detail", args=[self.friend.id]) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["username"], "frienduser") def test_add_friend_request(self): """Test adding a friend request""" url = reverse("user-add-friend-request", args=[self.friend.username]) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(response.data["success"]) self.assertEqual(response.data["message"], "Request sent") # Verify the friend request was created self.assertTrue( FriendRequest.objects.filter( sender=self.user, receiver=self.friend ).exists() ) def test_add_friend_request_nonexistent_user(self): """Test adding a friend request to a nonexistent user""" url = reverse("user-add-friend-request", args=["nonexistentuser"]) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertFalse(response.data["success"]) self.assertEqual( response.data["message"], "User 'nonexistentuser' doesn't exist" ) def test_remove_friend(self): """Test removing a friend""" # First add as friend self.user.friends.add(self.friend) url = reverse("user-remove-friend", args=[self.friend.id]) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(response.data["success"]) # Verify the friend was removed self.assertFalse(self.user.friends.filter(id=self.friend.id).exists()) @patch("user.views.shutil.disk_usage") def test_user_stats(self, mock_disk_usage): """Test getting user stats""" # Mock disk_usage return value mock_disk_usage.return_value = MagicMock( total=1000000, used=500000, free=500000 ) # Create torrents for the user Torrent.objects.create( id="abc123", name="Test Torrent", user=self.user, size=5000, transmission_data={}, ) url = reverse("user-user-stats") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) # Check that the response contains the expected fields self.assertIn("torrents_size", response.data) self.assertIn("torrents_len", response.data) self.assertIn("user_max_size", response.data) self.assertIn("disk_total", response.data) self.assertIn("disk_used", response.data) self.assertIn("disk_free", response.data) class FriendRequestViewSetTestCase(APITestCase): def setUp(self): self.user = User.objects.create_user( username="testuser", email="test@example.com", password="testpassword" ) self.sender = User.objects.create_user( username="sender", email="sender@example.com", password="senderpassword" ) self.client = APIClient() self.client.force_authenticate(user=self.user) # Create a friend request self.friend_request = FriendRequest.objects.create( sender=self.sender, receiver=self.user ) def test_list_friend_requests(self): """Test listing friend requests""" url = reverse("friendrequest-list") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]["sender"]["username"], "sender") def test_delete_friend_request(self): """Test deleting a friend request""" url = reverse("friendrequest-detail", args=[self.friend_request.id]) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) # Verify the friend request was deleted self.assertFalse( FriendRequest.objects.filter(id=self.friend_request.id).exists() )