|
1 | 1 | from django.contrib.auth.models import User |
| 2 | +from django.db.models import Prefetch |
2 | 3 | from django.test import RequestFactory, TestCase |
| 4 | +from participants.models import Participant, ParticipantTeam |
3 | 5 | from participants.serializers import ( |
4 | 6 | ChallengeParticipantSerializer, |
5 | 7 | InviteParticipantToTeamSerializer, |
| 8 | + ParticipantSerializer, |
| 9 | + ParticipantTeamDetailSerializer, |
6 | 10 | ) |
7 | 11 | from rest_framework import serializers |
8 | 12 |
|
@@ -52,3 +56,154 @@ def test_validate_email_self_invite(self): |
52 | 56 | serializers.ValidationError, "A participant cannot invite himself" |
53 | 57 | ): |
54 | 58 | serializer.validate_email("test@example.com") |
| 59 | + |
| 60 | + |
| 61 | +class TestParticipantTeamDetailSerializer(TestCase): |
| 62 | + def setUp(self): |
| 63 | + self.user1 = User.objects.create( |
| 64 | + username="user1", |
| 65 | + email="user1@test.com", |
| 66 | + first_name="First1", |
| 67 | + last_name="Last1", |
| 68 | + ) |
| 69 | + self.user2 = User.objects.create( |
| 70 | + username="user2", |
| 71 | + email="user2@test.com", |
| 72 | + first_name="First2", |
| 73 | + last_name="Last2", |
| 74 | + ) |
| 75 | + |
| 76 | + self.team = ParticipantTeam.objects.create( |
| 77 | + team_name="Test Team", |
| 78 | + created_by=self.user1, |
| 79 | + ) |
| 80 | + |
| 81 | + self.participant1 = Participant.objects.create( |
| 82 | + user=self.user1, |
| 83 | + status=Participant.SELF, |
| 84 | + team=self.team, |
| 85 | + ) |
| 86 | + self.participant2 = Participant.objects.create( |
| 87 | + user=self.user2, |
| 88 | + status=Participant.ACCEPTED, |
| 89 | + team=self.team, |
| 90 | + ) |
| 91 | + |
| 92 | + def test_get_members_returns_all_team_members(self): |
| 93 | + """Test that get_members returns all participants of a team.""" |
| 94 | + serializer = ParticipantTeamDetailSerializer(self.team) |
| 95 | + data = serializer.data |
| 96 | + |
| 97 | + self.assertEqual(len(data["members"]), 2) |
| 98 | + member_names = [m["member_name"] for m in data["members"]] |
| 99 | + self.assertIn("user1", member_names) |
| 100 | + self.assertIn("user2", member_names) |
| 101 | + |
| 102 | + def test_get_members_with_prefetched_data(self): |
| 103 | + """ |
| 104 | + Test that get_members works correctly with prefetched participants. |
| 105 | + This verifies the N+1 query fix works when data is prefetched. |
| 106 | + """ |
| 107 | + # Query with prefetch_related (as done in the fixed view) |
| 108 | + team_with_prefetch = ( |
| 109 | + ParticipantTeam.objects.filter(pk=self.team.pk) |
| 110 | + .prefetch_related( |
| 111 | + Prefetch( |
| 112 | + "participants", |
| 113 | + queryset=Participant.objects.select_related( |
| 114 | + "user", "user__profile" |
| 115 | + ), |
| 116 | + ) |
| 117 | + ) |
| 118 | + .first() |
| 119 | + ) |
| 120 | + |
| 121 | + serializer = ParticipantTeamDetailSerializer(team_with_prefetch) |
| 122 | + data = serializer.data |
| 123 | + |
| 124 | + self.assertEqual(len(data["members"]), 2) |
| 125 | + member_names = [m["member_name"] for m in data["members"]] |
| 126 | + self.assertIn("user1", member_names) |
| 127 | + self.assertIn("user2", member_names) |
| 128 | + |
| 129 | + def test_serializer_includes_all_expected_fields(self): |
| 130 | + """Test that the serializer includes all expected fields.""" |
| 131 | + serializer = ParticipantTeamDetailSerializer(self.team) |
| 132 | + data = serializer.data |
| 133 | + |
| 134 | + self.assertIn("id", data) |
| 135 | + self.assertIn("team_name", data) |
| 136 | + self.assertIn("created_by", data) |
| 137 | + self.assertIn("members", data) |
| 138 | + self.assertIn("team_url", data) |
| 139 | + |
| 140 | + # Check member fields |
| 141 | + member = data["members"][0] |
| 142 | + self.assertIn("member_name", member) |
| 143 | + self.assertIn("first_name", member) |
| 144 | + self.assertIn("last_name", member) |
| 145 | + self.assertIn("email", member) |
| 146 | + self.assertIn("status", member) |
| 147 | + self.assertIn("profile", member) |
| 148 | + |
| 149 | + |
| 150 | +class TestParticipantSerializer(TestCase): |
| 151 | + def setUp(self): |
| 152 | + self.user = User.objects.create( |
| 153 | + username="testuser", |
| 154 | + email="testuser@test.com", |
| 155 | + first_name="Test", |
| 156 | + last_name="User", |
| 157 | + ) |
| 158 | + self.team = ParticipantTeam.objects.create( |
| 159 | + team_name="Test Team", |
| 160 | + created_by=self.user, |
| 161 | + ) |
| 162 | + self.participant = Participant.objects.create( |
| 163 | + user=self.user, |
| 164 | + status=Participant.SELF, |
| 165 | + team=self.team, |
| 166 | + ) |
| 167 | + |
| 168 | + def test_get_profile_returns_user_profile(self): |
| 169 | + """ |
| 170 | + Test that get_profile correctly returns the user's profile. |
| 171 | + Profile is auto-created by a signal when User is created. |
| 172 | + """ |
| 173 | + serializer = ParticipantSerializer(self.participant) |
| 174 | + data = serializer.data |
| 175 | + |
| 176 | + self.assertIn("profile", data) |
| 177 | + self.assertIsInstance(data["profile"], dict) |
| 178 | + # Profile should have these fields from UserProfileSerializer |
| 179 | + self.assertIn("affiliation", data["profile"]) |
| 180 | + self.assertIn("github_url", data["profile"]) |
| 181 | + self.assertIn("google_scholar_url", data["profile"]) |
| 182 | + self.assertIn("linkedin_url", data["profile"]) |
| 183 | + |
| 184 | + def test_get_profile_with_prefetched_profile(self): |
| 185 | + """ |
| 186 | + Test that get_profile works correctly when profile is prefetched |
| 187 | + via select_related on user__profile. |
| 188 | + """ |
| 189 | + # Query participant with select_related (as done in the fixed view) |
| 190 | + participant_with_prefetch = Participant.objects.select_related( |
| 191 | + "user", "user__profile" |
| 192 | + ).get(pk=self.participant.pk) |
| 193 | + |
| 194 | + serializer = ParticipantSerializer(participant_with_prefetch) |
| 195 | + data = serializer.data |
| 196 | + |
| 197 | + self.assertIn("profile", data) |
| 198 | + self.assertIsInstance(data["profile"], dict) |
| 199 | + |
| 200 | + def test_member_fields_are_correct(self): |
| 201 | + """Test that member fields return correct values.""" |
| 202 | + serializer = ParticipantSerializer(self.participant) |
| 203 | + data = serializer.data |
| 204 | + |
| 205 | + self.assertEqual(data["member_name"], "testuser") |
| 206 | + self.assertEqual(data["first_name"], "Test") |
| 207 | + self.assertEqual(data["last_name"], "User") |
| 208 | + self.assertEqual(data["email"], "testuser@test.com") |
| 209 | + self.assertEqual(data["status"], Participant.SELF) |
0 commit comments