@@ -131,6 +131,7 @@ async def test_get_jobs_for_single_job(jp_fetch):
131131 url = "url_a" ,
132132 create_time = 1664305872620 ,
133133 update_time = 1664305872620 ,
134+ completed_cells = 5 ,
134135 )
135136 response = await jp_fetch ("scheduler" , "jobs" , job_id , method = "GET" )
136137
@@ -140,6 +141,7 @@ async def test_get_jobs_for_single_job(jp_fetch):
140141 assert body ["job_id" ] == job_id
141142 assert body ["input_filename" ]
142143 assert body ["job_files" ]
144+ assert body ["completed_cells" ] == 5
143145
144146
145147@pytest .mark .parametrize (
@@ -320,6 +322,28 @@ async def test_patch_jobs(jp_fetch):
320322 mock_update_job .assert_called_once_with (job_id , UpdateJob (** body ))
321323
322324
325+ async def test_patch_jobs_with_completed_cells (jp_fetch ):
326+ with patch ("jupyter_scheduler.scheduler.Scheduler.update_job" ) as mock_update_job :
327+ job_id = "542e0fac-1274-4a78-8340-a850bdb559c8"
328+ body = {"name" : "updated job" , "completed_cells" : 10 }
329+ response = await jp_fetch (
330+ "scheduler" , "jobs" , job_id , method = "PATCH" , body = json .dumps (body )
331+ )
332+ assert response .code == 204
333+ mock_update_job .assert_called_once_with (job_id , UpdateJob (** body ))
334+
335+
336+ async def test_patch_jobs_completed_cells_only (jp_fetch ):
337+ with patch ("jupyter_scheduler.scheduler.Scheduler.update_job" ) as mock_update_job :
338+ job_id = "542e0fac-1274-4a78-8340-a850bdb559c8"
339+ body = {"completed_cells" : 15 }
340+ response = await jp_fetch (
341+ "scheduler" , "jobs" , job_id , method = "PATCH" , body = json .dumps (body )
342+ )
343+ assert response .code == 204
344+ mock_update_job .assert_called_once_with (job_id , UpdateJob (** body ))
345+
346+
323347async def test_patch_jobs_for_stop_job (jp_fetch ):
324348 with patch ("jupyter_scheduler.scheduler.Scheduler.stop_job" ) as mock_stop_job :
325349 job_id = "542e0fac-1274-4a78-8340-a850bdb559c8"
@@ -677,3 +701,73 @@ async def test_delete_job_definition_for_unexpected_error(jp_fetch):
677701 assert expected_http_error (
678702 e , 500 , "Unexpected error occurred while deleting the job definition."
679703 )
704+
705+
706+ # Model validation tests for completed_cells field
707+ def test_describe_job_completed_cells_validation ():
708+ """Test DescribeJob model validation for completed_cells field"""
709+ # Test valid integer values
710+ job_data = {
711+ "name" : "test_job" ,
712+ "input_filename" : "test.ipynb" ,
713+ "runtime_environment_name" : "test_env" ,
714+ "job_id" : "test-job-id" ,
715+ "url" : "http://test.com/jobs/test-job-id" ,
716+ "create_time" : 1234567890 ,
717+ "update_time" : 1234567890 ,
718+ "completed_cells" : 5
719+ }
720+ job = DescribeJob (** job_data )
721+ assert job .completed_cells == 5
722+
723+ # Test None value
724+ job_data ["completed_cells" ] = None
725+ job = DescribeJob (** job_data )
726+ assert job .completed_cells is None
727+
728+ # Test zero value
729+ job_data ["completed_cells" ] = 0
730+ job = DescribeJob (** job_data )
731+ assert job .completed_cells == 0
732+
733+ # Test invalid type
734+ job_data ["completed_cells" ] = "invalid"
735+ with pytest .raises (ValidationError ):
736+ DescribeJob (** job_data )
737+
738+
739+ def test_update_job_completed_cells_validation ():
740+ """Test UpdateJob model validation for completed_cells field"""
741+ # Test valid integer values
742+ update_data = {"completed_cells" : 10 }
743+ update_job = UpdateJob (** update_data )
744+ assert update_job .completed_cells == 10
745+
746+ # Test None value
747+ update_data = {"completed_cells" : None }
748+ update_job = UpdateJob (** update_data )
749+ assert update_job .completed_cells is None
750+
751+ # Test zero value
752+ update_data = {"completed_cells" : 0 }
753+ update_job = UpdateJob (** update_data )
754+ assert update_job .completed_cells == 0
755+
756+ # Test invalid type
757+ update_data = {"completed_cells" : "invalid" }
758+ with pytest .raises (ValidationError ):
759+ UpdateJob (** update_data )
760+
761+ # Test exclude_none behavior
762+ update_data = {"name" : "test" , "completed_cells" : None }
763+ update_job = UpdateJob (** update_data )
764+ job_dict = update_job .dict (exclude_none = True )
765+ assert "completed_cells" not in job_dict
766+ assert job_dict ["name" ] == "test"
767+
768+ # Test include completed_cells when not None
769+ update_data = {"name" : "test" , "completed_cells" : 5 }
770+ update_job = UpdateJob (** update_data )
771+ job_dict = update_job .dict (exclude_none = True )
772+ assert job_dict ["completed_cells" ] == 5
773+ assert job_dict ["name" ] == "test"
0 commit comments