@@ -964,18 +964,23 @@ def setUp(self):
964964 is_public = True ,
965965 )
966966
967+ def _get_expected_participant_teams_queryset (self ):
968+ """Helper to get participant teams with prefetch for serializer"""
969+ challenge = get_challenge_model (self .challenge .pk )
970+ return challenge .participant_teams .prefetch_related (
971+ "participants__user"
972+ ).order_by ("-team_name" )
973+
967974 def test_host_downloads_participant_team (self ):
975+ """Test that host can download participant teams as CSV"""
968976 expected = io .StringIO ()
969977 expected_participant_teams = csv .writer (
970978 expected , quoting = csv .QUOTE_ALL
971979 )
972980 expected_participant_teams .writerow (
973981 ["Team Name" , "Team Members" , "Email Id" ]
974982 )
975- challenge = get_challenge_model (self .challenge .pk )
976- participant_team = challenge .participant_teams .all ().order_by (
977- "-team_name"
978- )
983+ participant_team = self ._get_expected_participant_teams_queryset ()
979984 participant_teams = ChallengeParticipantSerializer (
980985 participant_team , many = True
981986 )
@@ -993,10 +998,136 @@ def test_host_downloads_participant_team(self):
993998 self .assertEqual (response .status_code , status .HTTP_200_OK )
994999
9951000 def test_user_not_host_downloads_participant_team (self ):
1001+ """Test that non-host user cannot download participant teams"""
9961002 expected = {
9971003 "error" : "Sorry, you are not authorized to make this request"
9981004 }
9991005 self .client .force_authenticate (user = self .user2 )
10001006 response = self .client .get (self .url , {})
10011007 self .assertEqual (response .data , expected )
10021008 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
1009+
1010+ def test_host_gets_participant_team_json_format (self ):
1011+ """Test that host can get participant teams in JSON format"""
1012+ participant_team = self ._get_expected_participant_teams_queryset ()
1013+ participant_teams = ChallengeParticipantSerializer (
1014+ participant_team , many = True
1015+ )
1016+ expected = {
1017+ "participant_teams" : participant_teams .data ,
1018+ "count" : len (participant_teams .data ),
1019+ }
1020+ self .client .force_authenticate (user = self .user )
1021+ response = self .client .get (self .url , {"output" : "json" })
1022+ self .assertEqual (response .data , expected )
1023+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1024+
1025+ def test_user_not_host_gets_participant_team_json_format (self ):
1026+ """Test that non-host user cannot get participant teams in JSON format"""
1027+ expected = {
1028+ "error" : "Sorry, you are not authorized to make this request"
1029+ }
1030+ self .client .force_authenticate (user = self .user2 )
1031+ response = self .client .get (self .url , {"output" : "json" })
1032+ self .assertEqual (response .data , expected )
1033+ self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
1034+
1035+ def test_json_format_case_insensitive (self ):
1036+ """Test that output parameter is case-insensitive"""
1037+ self .client .force_authenticate (user = self .user )
1038+
1039+ # Test uppercase (use 'output' to avoid DRF format content negotiation)
1040+ response = self .client .get (self .url , {"output" : "JSON" })
1041+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1042+ self .assertIn ("participant_teams" , response .data )
1043+ self .assertIn ("count" , response .data )
1044+
1045+ # Test mixed case
1046+ response = self .client .get (self .url , {"output" : "Json" })
1047+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1048+ self .assertIn ("participant_teams" , response .data )
1049+
1050+ def test_invalid_format_defaults_to_csv (self ):
1051+ """Test that invalid output parameter defaults to CSV download"""
1052+ self .client .force_authenticate (user = self .user )
1053+ response = self .client .get (self .url , {"output" : "invalid" })
1054+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1055+ self .assertEqual (response ["Content-Type" ], "text/csv" )
1056+ self .assertIn ("attachment; filename=" , response ["Content-Disposition" ])
1057+
1058+ def test_json_response_structure (self ):
1059+ """Test that JSON response has correct structure"""
1060+ self .client .force_authenticate (user = self .user )
1061+ response = self .client .get (self .url , {"output" : "json" })
1062+
1063+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1064+ self .assertIn ("participant_teams" , response .data )
1065+ self .assertIn ("count" , response .data )
1066+ self .assertEqual (response .data ["count" ], 2 ) # Two teams added in setUp
1067+
1068+ # Verify each team has required fields
1069+ for team in response .data ["participant_teams" ]:
1070+ self .assertIn ("team_name" , team )
1071+ self .assertIn ("team_members" , team )
1072+ self .assertIn ("team_members_email_ids" , team )
1073+ self .assertIsInstance (team ["team_members" ], list )
1074+ self .assertIsInstance (team ["team_members_email_ids" ], list )
1075+
1076+ def test_json_response_contains_correct_data (self ):
1077+ """Test that JSON response contains correct participant data"""
1078+ self .client .force_authenticate (user = self .user )
1079+ response = self .client .get (self .url , {"output" : "json" })
1080+
1081+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1082+
1083+ # Find participant_team in response
1084+ team_names = [
1085+ team ["team_name" ] for team in response .data ["participant_teams" ]
1086+ ]
1087+ self .assertIn ("Participant Team" , team_names )
1088+ self .assertIn ("Participant Team3" , team_names )
1089+
1090+ # Verify member data for participant_team
1091+ for team in response .data ["participant_teams" ]:
1092+ if team ["team_name" ] == "Participant Team" :
1093+ self .assertIn ("otheruser" , team ["team_members" ])
1094+ self .assertIn (
1095+ "otheruser@test.com" , team ["team_members_email_ids" ]
1096+ )
1097+ elif team ["team_name" ] == "Participant Team3" :
1098+ self .assertIn ("user3" , team ["team_members" ])
1099+ self .assertIn ("user3@test.com" , team ["team_members_email_ids" ])
1100+
1101+ def test_csv_response_headers (self ):
1102+ """Test that CSV response has correct headers"""
1103+ self .client .force_authenticate (user = self .user )
1104+ response = self .client .get (self .url , {})
1105+
1106+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1107+ self .assertEqual (response ["Content-Type" ], "text/csv" )
1108+ self .assertIn (
1109+ "participant_teams_{}.csv" .format (self .challenge .pk ),
1110+ response ["Content-Disposition" ],
1111+ )
1112+
1113+ def test_empty_participant_teams (self ):
1114+ """Test response when challenge has no participant teams"""
1115+ # Remove all participant teams
1116+ self .challenge .participant_teams .clear ()
1117+
1118+ self .client .force_authenticate (user = self .user )
1119+
1120+ # Test JSON format
1121+ response = self .client .get (self .url , {"output" : "json" })
1122+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1123+ self .assertEqual (response .data ["participant_teams" ], [])
1124+ self .assertEqual (response .data ["count" ], 0 )
1125+
1126+ # Test CSV format
1127+ response = self .client .get (self .url , {})
1128+ self .assertEqual (response .status_code , status .HTTP_200_OK )
1129+ content = response .content .decode ("utf-8" )
1130+ # Should only have header row
1131+ lines = content .strip ().split ("\n " )
1132+ self .assertEqual (len (lines ), 1 )
1133+ self .assertIn ("Team Name" , lines [0 ])
0 commit comments