@@ -156,26 +156,29 @@ def test_quiz_workflow(api_endpoint):
156156
157157 time .sleep (5 )
158158
159- leaderboard_url = f"{ api_endpoint } /getleaderboard?quiz_id={ quiz_id } &top=3"
160- response = requests .get (leaderboard_url )
159+ top_n = 3
160+ expected_leaderboard_size = min (top_n , len (users ))
161+ leaderboard_url = f"{ api_endpoint } /getleaderboard?quiz_id={ quiz_id } &top={ top_n } "
161162 leaderboard = None
162163
163- if response .json ():
164+ # Scoring runs asynchronously, so keep polling until all expected top entries are available.
165+ leaderboard_deadline = time .time () + 30
166+ while time .time () < leaderboard_deadline :
167+ response = requests .get (leaderboard_url )
164168 assert response .status_code == 200
165- leaderboard = response .json ()
166- else :
167- # If the response is empty, retry it for 5 times with a 2 second delay.
168- # TODO: This is a hack to get around the fact that the leaderboard is not available immediately.
169- for _ in range (5 ):
170- time .sleep (2 )
171- response = requests .get (leaderboard_url )
172- if response .json ():
173- assert response .status_code == 200
174- leaderboard = response .json ()
175- break
176-
177- assert leaderboard is not None , "Failed to retrieve leaderboard data after retries"
178- assert len (leaderboard ) == 3
169+ current_leaderboard = response .json ()
170+ if (
171+ isinstance (current_leaderboard , list )
172+ and len (current_leaderboard ) == expected_leaderboard_size
173+ ):
174+ leaderboard = current_leaderboard
175+ break
176+ time .sleep (2 )
177+
178+ assert leaderboard is not None , (
179+ f"Failed to retrieve { expected_leaderboard_size } leaderboard entries after retries"
180+ )
181+ assert len (leaderboard ) == expected_leaderboard_size
179182 expected_scores = {
180183 "user1" : None ,
181184 "user2" : None ,
0 commit comments