@@ -817,6 +817,84 @@ public void scheduleJobShouldThrowWhenNameInRequestIsEmpty() {
817817 assertEquals ("Name in the request cannot be null or empty" , exception .getMessage ());
818818 }
819819
820+ @ Test
821+ public void scheduleJobShouldThrowWhenNameAlreadyExists () {
822+ AtomicInteger callCount = new AtomicInteger (0 );
823+
824+ doAnswer (invocation -> {
825+ StreamObserver <DaprProtos .ScheduleJobResponse > observer = invocation .getArgument (1 );
826+ if (callCount .incrementAndGet () == 1 ) {
827+ // First call succeeds
828+ observer .onCompleted ();
829+ } else {
830+ // Second call fails with ALREADY_EXISTS
831+ observer .onError (newStatusRuntimeException ("ALREADY_EXISTS" , "Job with name 'testJob' already exists" ));
832+ }
833+ return null ;
834+ }).when (daprStub ).scheduleJobAlpha1 (any (DaprProtos .ScheduleJobRequest .class ), any ());
835+
836+ // First call should succeed
837+ ScheduleJobRequest firstRequest = new ScheduleJobRequest ("testJob" , Instant .now ());
838+ assertDoesNotThrow (() -> previewClient .scheduleJob (firstRequest ).block ());
839+
840+ ArgumentCaptor <DaprProtos .ScheduleJobRequest > captor =
841+ ArgumentCaptor .forClass (DaprProtos .ScheduleJobRequest .class );
842+
843+ verify (daprStub , times (1 )).scheduleJobAlpha1 (captor .capture (), Mockito .any ());
844+ DaprProtos .ScheduleJobRequest actualScheduleJobRequest = captor .getValue ();
845+ DaprProtos .Job job = actualScheduleJobRequest .getJob ();
846+ assertEquals ("testJob" , job .getName ());
847+ assertFalse (job .hasData ());
848+ assertEquals (0 , job .getRepeats ());
849+ assertFalse (job .hasTtl ());
850+
851+ // Second call with same name should fail
852+ ScheduleJobRequest secondRequest = new ScheduleJobRequest ("testJob" , Instant .now ());
853+
854+ assertThrowsDaprException (
855+ ExecutionException .class ,
856+ "ALREADY_EXISTS" ,
857+ "ALREADY_EXISTS: Job with name 'testJob' already exists" ,
858+ () -> previewClient .scheduleJob (secondRequest ).block ());
859+ }
860+
861+ @ Test
862+ public void scheduleJobShouldSucceedWhenNameAlreadyExistsWithOverwrite () {
863+ doAnswer (invocation -> {
864+ StreamObserver <DaprProtos .ScheduleJobResponse > observer = invocation .getArgument (1 );
865+ observer .onCompleted (); // Simulate successful response for both calls
866+ return null ;
867+ }).when (daprStub ).scheduleJobAlpha1 (any (DaprProtos .ScheduleJobRequest .class ), any ());
868+
869+ // First call should succeed
870+ ScheduleJobRequest firstRequest = new ScheduleJobRequest ("testJob" , Instant .now ());
871+ assertDoesNotThrow (() -> previewClient .scheduleJob (firstRequest ).block ());
872+
873+ // Second call with same name but overwrite=true should also succeed
874+ ScheduleJobRequest secondRequest = new ScheduleJobRequest ("testJob" , Instant .now ())
875+ .setOverwrite (true );
876+ assertDoesNotThrow (() -> previewClient .scheduleJob (secondRequest ).block ());
877+
878+ // Verify that both calls were made successfully
879+ ArgumentCaptor <DaprProtos .ScheduleJobRequest > captor =
880+ ArgumentCaptor .forClass (DaprProtos .ScheduleJobRequest .class );
881+ verify (daprStub , times (2 )).scheduleJobAlpha1 (captor .capture (), any ());
882+
883+ // Verify the first call doesn't have overwrite set
884+ DaprProtos .ScheduleJobRequest firstActualRequest = captor .getAllValues ().get (0 );
885+ assertFalse (firstActualRequest .getJob ().getOverwrite ());
886+ assertEquals ("testJob" , firstActualRequest .getJob ().getName ());
887+
888+ // Verify the second call has overwrite set to true
889+ DaprProtos .ScheduleJobRequest secondActualRequest = captor .getAllValues ().get (1 );
890+ assertTrue (secondActualRequest .getJob ().getOverwrite ());
891+ assertEquals ("testJob" , secondActualRequest .getJob ().getName ());
892+ }
893+
894+
895+
896+
897+
820898 @ Test
821899 public void getJobShouldReturnResponseWhenAllFieldsArePresentInRequest () {
822900 DateTimeFormatter iso8601Formatter = DateTimeFormatter .ofPattern ("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" )
0 commit comments