|
| 1 | +import json |
1 | 2 | import os |
2 | 3 | import tempfile |
3 | 4 | import unittest |
@@ -392,6 +393,92 @@ def test_legacy_filename_key_does_not_crash(self): |
392 | 393 | self.assertIn("missing", result["feedback"].lower()) |
393 | 394 |
|
394 | 395 |
|
| 396 | +class TestFilesInResponsePayload(unittest.TestCase): |
| 397 | + """The LF web client delivers uploads inside the response payload as |
| 398 | + {"code": ..., "files": [...]} rather than in params["files"].""" |
| 399 | + |
| 400 | + @patch("evaluation_function.evaluation.download_files") |
| 401 | + def test_response_dict_with_code_and_files(self, mock_download): |
| 402 | + mock_download.side_effect = _stub_download({"data.csv": "1,2,3"}) |
| 403 | + response = { |
| 404 | + "code": "print(open('data.csv').read())", |
| 405 | + "files": [{"url": "https://example.com/k", "name": "data.csv"}], |
| 406 | + } |
| 407 | + result = evaluation_function(response, None, {"mode": "demo"}).to_dict() |
| 408 | + |
| 409 | + self.assertIn("1,2,3", result["feedback"]) |
| 410 | + mock_download.assert_called_once() |
| 411 | + passed_specs = mock_download.call_args[0][0] |
| 412 | + self.assertEqual(passed_specs, [{"url": "https://example.com/k", "name": "data.csv"}]) |
| 413 | + |
| 414 | + @patch("evaluation_function.evaluation.download_files") |
| 415 | + def test_response_dict_file_entries_are_json_strings(self, mock_download): |
| 416 | + mock_download.side_effect = _stub_download({"data.csv": "42"}) |
| 417 | + response = { |
| 418 | + "code": "print(open('data.csv').read())", |
| 419 | + "files": [json.dumps({"url": "https://example.com/k", "name": "data.csv"})], |
| 420 | + } |
| 421 | + result = evaluation_function(response, None, {"mode": "demo"}).to_dict() |
| 422 | + |
| 423 | + self.assertIn("42", result["feedback"]) |
| 424 | + passed_specs = mock_download.call_args[0][0] |
| 425 | + self.assertEqual(passed_specs, [{"url": "https://example.com/k", "name": "data.csv"}]) |
| 426 | + |
| 427 | + @patch("evaluation_function.evaluation.download_files") |
| 428 | + def test_response_is_json_string_of_payload(self, mock_download): |
| 429 | + mock_download.side_effect = _stub_download({"data.csv": "7"}) |
| 430 | + response = json.dumps({ |
| 431 | + "code": "print(open('data.csv').read())", |
| 432 | + "files": [{"url": "https://example.com/k", "name": "data.csv"}], |
| 433 | + }) |
| 434 | + result = evaluation_function(response, None, {"mode": "demo"}).to_dict() |
| 435 | + |
| 436 | + self.assertIn("7", result["feedback"]) |
| 437 | + mock_download.assert_called_once() |
| 438 | + |
| 439 | + @patch("evaluation_function.evaluation.download_files") |
| 440 | + def test_unit_test_mode_reads_files_from_response(self, mock_download): |
| 441 | + mock_download.side_effect = _stub_download({"data.csv": "x"}) |
| 442 | + response = { |
| 443 | + "code": "", |
| 444 | + "files": [{"url": "https://example.com/k", "name": "data.csv"}], |
| 445 | + } |
| 446 | + params = { |
| 447 | + "mode": "unit_test", |
| 448 | + "test_code": "import os\ndef test_present():\n assert os.path.isfile('data.csv')\n", |
| 449 | + } |
| 450 | + result = evaluation_function(response, None, params).to_dict() |
| 451 | + |
| 452 | + self.assertTrue(result["is_correct"]) |
| 453 | + self.assertIn("1/1 tests passed", result["feedback"]) |
| 454 | + |
| 455 | + @patch("evaluation_function.evaluation.download_files") |
| 456 | + def test_plain_string_response_still_uses_params_files(self, mock_download): |
| 457 | + mock_download.side_effect = _stub_download({"data.csv": "9"}) |
| 458 | + params = {"mode": "demo", "files": [{"url": "https://example.com/k", "name": "data.csv"}]} |
| 459 | + result = evaluation_function("print(open('data.csv').read())", None, params).to_dict() |
| 460 | + |
| 461 | + self.assertIn("9", result["feedback"]) |
| 462 | + |
| 463 | + @patch("evaluation_function.evaluation.download_files") |
| 464 | + def test_response_files_take_precedence_over_params_files(self, mock_download): |
| 465 | + mock_download.side_effect = _stub_download({"data.csv": "from_response"}) |
| 466 | + response = { |
| 467 | + "code": "print(open('data.csv').read())", |
| 468 | + "files": [{"url": "https://example.com/response", "name": "data.csv"}], |
| 469 | + } |
| 470 | + params = {"mode": "demo", "files": [{"url": "https://example.com/params", "name": "other.csv"}]} |
| 471 | + evaluation_function(response, None, params) |
| 472 | + |
| 473 | + passed_specs = mock_download.call_args[0][0] |
| 474 | + self.assertEqual(passed_specs, [{"url": "https://example.com/response", "name": "data.csv"}]) |
| 475 | + |
| 476 | + def test_response_dict_without_files_no_download(self): |
| 477 | + with patch("evaluation_function.evaluation.download_files") as mock_download: |
| 478 | + evaluation_function({"code": "print('hi')"}, None, {"mode": "demo"}) |
| 479 | + mock_download.assert_not_called() |
| 480 | + |
| 481 | + |
395 | 482 | class TestUnexpectedExceptionHandling(unittest.TestCase): |
396 | 483 |
|
397 | 484 | @patch("evaluation_function.evaluation._run_code") |
|
0 commit comments