Skip to content

Commit 1eb2687

Browse files
Mark Saroufimmsaroufim
authored andcommitted
Add tests for admin update-problems endpoint
Add 7 tests covering the admin update-problems API endpoint: - Authorization requirement - Successful sync with created/updated/skipped results - Custom problem_set, force, repository, and branch parameters - ValueError handling (400 response) - Error reporting in response
1 parent c664c2b commit 1eb2687

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

tests/test_admin_api.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,149 @@ def test_delete_leaderboard_force(self, test_client, mock_backend):
259259
assert response.status_code == 200
260260
assert response.json()["force"] is True
261261
mock_backend.db.delete_leaderboard.assert_called_once_with("test-leaderboard", force=True)
262+
263+
264+
class TestAdminUpdateProblems:
265+
"""Test admin update-problems endpoint."""
266+
267+
def test_update_problems_requires_auth(self, test_client):
268+
"""POST /admin/update-problems requires authorization."""
269+
response = test_client.post("/admin/update-problems", json={})
270+
assert response.status_code == 401
271+
272+
def test_update_problems_success(self, test_client, mock_backend):
273+
"""POST /admin/update-problems returns sync results."""
274+
mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db)
275+
mock_backend.db.__exit__ = MagicMock(return_value=None)
276+
277+
mock_result = MagicMock()
278+
mock_result.created = ["problem1", "problem2"]
279+
mock_result.updated = ["problem3"]
280+
mock_result.skipped = [{"name": "problem4", "reason": "no changes"}]
281+
mock_result.errors = []
282+
283+
with patch('kernelbot.api.main.sync_problems', return_value=mock_result) as mock_sync:
284+
response = test_client.post(
285+
"/admin/update-problems",
286+
headers={"Authorization": "Bearer test_token"},
287+
json={}
288+
)
289+
assert response.status_code == 200
290+
data = response.json()
291+
assert data["status"] == "ok"
292+
assert data["created"] == ["problem1", "problem2"]
293+
assert data["updated"] == ["problem3"]
294+
assert data["skipped"] == [{"name": "problem4", "reason": "no changes"}]
295+
assert data["errors"] == []
296+
297+
# Verify default parameters
298+
mock_sync.assert_called_once()
299+
call_kwargs = mock_sync.call_args[1]
300+
assert call_kwargs["repository"] == "gpu-mode/reference-kernels"
301+
assert call_kwargs["branch"] == "main"
302+
assert call_kwargs["force"] is False
303+
assert call_kwargs["problem_set"] is None
304+
305+
def test_update_problems_with_problem_set(self, test_client, mock_backend):
306+
"""POST /admin/update-problems with specific problem_set."""
307+
mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db)
308+
mock_backend.db.__exit__ = MagicMock(return_value=None)
309+
310+
mock_result = MagicMock()
311+
mock_result.created = ["nvidia-problem"]
312+
mock_result.updated = []
313+
mock_result.skipped = []
314+
mock_result.errors = []
315+
316+
with patch('kernelbot.api.main.sync_problems', return_value=mock_result) as mock_sync:
317+
response = test_client.post(
318+
"/admin/update-problems",
319+
headers={"Authorization": "Bearer test_token"},
320+
json={"problem_set": "nvidia"}
321+
)
322+
assert response.status_code == 200
323+
call_kwargs = mock_sync.call_args[1]
324+
assert call_kwargs["problem_set"] == "nvidia"
325+
326+
def test_update_problems_with_force(self, test_client, mock_backend):
327+
"""POST /admin/update-problems with force=True."""
328+
mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db)
329+
mock_backend.db.__exit__ = MagicMock(return_value=None)
330+
331+
mock_result = MagicMock()
332+
mock_result.created = []
333+
mock_result.updated = ["updated-problem"]
334+
mock_result.skipped = []
335+
mock_result.errors = []
336+
337+
with patch('kernelbot.api.main.sync_problems', return_value=mock_result) as mock_sync:
338+
response = test_client.post(
339+
"/admin/update-problems",
340+
headers={"Authorization": "Bearer test_token"},
341+
json={"force": True}
342+
)
343+
assert response.status_code == 200
344+
call_kwargs = mock_sync.call_args[1]
345+
assert call_kwargs["force"] is True
346+
347+
def test_update_problems_with_custom_repo_and_branch(self, test_client, mock_backend):
348+
"""POST /admin/update-problems with custom repository and branch."""
349+
mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db)
350+
mock_backend.db.__exit__ = MagicMock(return_value=None)
351+
352+
mock_result = MagicMock()
353+
mock_result.created = []
354+
mock_result.updated = []
355+
mock_result.skipped = []
356+
mock_result.errors = []
357+
358+
with patch('kernelbot.api.main.sync_problems', return_value=mock_result) as mock_sync:
359+
response = test_client.post(
360+
"/admin/update-problems",
361+
headers={"Authorization": "Bearer test_token"},
362+
json={
363+
"repository": "other-org/other-repo",
364+
"branch": "develop"
365+
}
366+
)
367+
assert response.status_code == 200
368+
call_kwargs = mock_sync.call_args[1]
369+
assert call_kwargs["repository"] == "other-org/other-repo"
370+
assert call_kwargs["branch"] == "develop"
371+
372+
def test_update_problems_value_error(self, test_client, mock_backend):
373+
"""POST /admin/update-problems returns 400 on ValueError."""
374+
mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db)
375+
mock_backend.db.__exit__ = MagicMock(return_value=None)
376+
377+
with patch('kernelbot.api.main.sync_problems', side_effect=ValueError("Invalid branch name")):
378+
response = test_client.post(
379+
"/admin/update-problems",
380+
headers={"Authorization": "Bearer test_token"},
381+
json={"branch": "invalid/branch"}
382+
)
383+
assert response.status_code == 400
384+
assert "Invalid branch name" in response.json()["detail"]
385+
386+
def test_update_problems_with_errors(self, test_client, mock_backend):
387+
"""POST /admin/update-problems includes errors in response."""
388+
mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db)
389+
mock_backend.db.__exit__ = MagicMock(return_value=None)
390+
391+
mock_result = MagicMock()
392+
mock_result.created = []
393+
mock_result.updated = []
394+
mock_result.skipped = []
395+
mock_result.errors = [{"name": "bad-problem", "error": "create failed: DB error"}]
396+
397+
with patch('kernelbot.api.main.sync_problems', return_value=mock_result):
398+
response = test_client.post(
399+
"/admin/update-problems",
400+
headers={"Authorization": "Bearer test_token"},
401+
json={}
402+
)
403+
assert response.status_code == 200
404+
data = response.json()
405+
assert data["status"] == "ok"
406+
assert len(data["errors"]) == 1
407+
assert data["errors"][0]["name"] == "bad-problem"

0 commit comments

Comments
 (0)