@@ -624,3 +624,336 @@ def test_27_edge_case_regex_generation_complex(self):
624624 result2 = generator .generate_id_from_regex (pattern2 )
625625 self .assertIsNotNone (result2 )
626626 self .assertEqual (len (result2 ), 5 )
627+
628+ def test_28_compute_queue_job_ids (self ):
629+ """Test that generator correctly computes related queue jobs"""
630+ generator1 = self .env ["spp.demo.data.generator" ].create (
631+ {
632+ "name" : "Generator with Jobs" ,
633+ "locale_origin" : self .test_country .id ,
634+ }
635+ )
636+ generator2 = self .env ["spp.demo.data.generator" ].create (
637+ {
638+ "name" : "Generator without Jobs" ,
639+ "locale_origin" : self .test_country .id ,
640+ }
641+ )
642+
643+ # Create jobs for generator1
644+ job1 = self .env ["queue.job" ].create (
645+ {
646+ "name" : "Job 1 for Generator 1" ,
647+ "model_name" : "spp.demo.data.generator" ,
648+ "method_name" : "_process_batch" ,
649+ "res_model" : "spp.demo.data.generator" ,
650+ "res_id" : generator1 .id ,
651+ "state" : "done" ,
652+ }
653+ )
654+ job2 = self .env ["queue.job" ].create (
655+ {
656+ "name" : "Job 2 for Generator 1" ,
657+ "model_name" : "spp.demo.data.generator" ,
658+ "method_name" : "_process_batch" ,
659+ "res_model" : "spp.demo.data.generator" ,
660+ "res_id" : generator1 .id ,
661+ "state" : "pending" ,
662+ }
663+ )
664+
665+ # Trigger compute
666+ generator1 ._compute_queue_job_ids ()
667+ generator2 ._compute_queue_job_ids ()
668+
669+ # Assert generator1 has 2 jobs
670+ self .assertEqual (len (generator1 .queue_job_ids ), 2 )
671+ self .assertIn (job1 , generator1 .queue_job_ids )
672+ self .assertIn (job2 , generator1 .queue_job_ids )
673+
674+ # Assert generator2 has no jobs
675+ self .assertEqual (len (generator2 .queue_job_ids ), 0 )
676+
677+ def test_29_compute_queue_job_count (self ):
678+ """Test queue job count computation"""
679+ generator = self .env ["spp.demo.data.generator" ].create (
680+ {
681+ "name" : "Generator for Count Test" ,
682+ "locale_origin" : self .test_country .id ,
683+ }
684+ )
685+
686+ # Initially no jobs
687+ generator ._compute_queue_job_ids ()
688+ generator ._compute_queue_job_count ()
689+ self .assertEqual (generator .queue_job_count , 0 )
690+
691+ # Create 3 jobs
692+ for i in range (3 ):
693+ self .env ["queue.job" ].create (
694+ {
695+ "name" : f"Job { i + 1 } " ,
696+ "model_name" : "spp.demo.data.generator" ,
697+ "method_name" : "_process_batch" ,
698+ "res_model" : "spp.demo.data.generator" ,
699+ "res_id" : generator .id ,
700+ "state" : "done" ,
701+ }
702+ )
703+
704+ # Recompute
705+ generator ._compute_queue_job_ids ()
706+ generator ._compute_queue_job_count ()
707+ self .assertEqual (generator .queue_job_count , 3 )
708+
709+ def test_30_has_ongoing_jobs_no_jobs (self ):
710+ """Test has_ongoing_jobs when there are no jobs"""
711+ # Clean up any existing jobs
712+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
713+
714+ generator = self .env ["spp.demo.data.generator" ].create (
715+ {
716+ "name" : "Generator No Jobs" ,
717+ "locale_origin" : self .test_country .id ,
718+ }
719+ )
720+
721+ generator ._compute_ongoing_jobs_info ()
722+ self .assertFalse (generator .has_ongoing_jobs )
723+ self .assertFalse (generator .ongoing_job_generator_id )
724+
725+ def test_31_has_ongoing_jobs_with_pending_job (self ):
726+ """Test has_ongoing_jobs detects pending jobs"""
727+ # Clean up any existing jobs
728+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
729+
730+ generator = self .env ["spp.demo.data.generator" ].create (
731+ {
732+ "name" : "Generator with Pending Job" ,
733+ "locale_origin" : self .test_country .id ,
734+ }
735+ )
736+
737+ # Create a pending job
738+ self .env ["queue.job" ].create (
739+ {
740+ "name" : "Pending Job" ,
741+ "model_name" : "spp.demo.data.generator" ,
742+ "method_name" : "_process_batch" ,
743+ "res_model" : "spp.demo.data.generator" ,
744+ "res_id" : generator .id ,
745+ "state" : "pending" ,
746+ }
747+ )
748+
749+ generator ._compute_ongoing_jobs_info ()
750+ self .assertTrue (generator .has_ongoing_jobs )
751+ self .assertEqual (generator .ongoing_job_generator_id , generator )
752+
753+ def test_32_has_ongoing_jobs_with_enqueued_job (self ):
754+ """Test has_ongoing_jobs detects enqueued jobs"""
755+ # Clean up any existing jobs
756+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
757+
758+ generator = self .env ["spp.demo.data.generator" ].create (
759+ {
760+ "name" : "Generator with Enqueued Job" ,
761+ "locale_origin" : self .test_country .id ,
762+ }
763+ )
764+
765+ # Create an enqueued job
766+ self .env ["queue.job" ].create (
767+ {
768+ "name" : "Enqueued Job" ,
769+ "model_name" : "spp.demo.data.generator" ,
770+ "method_name" : "_process_batch" ,
771+ "res_model" : "spp.demo.data.generator" ,
772+ "res_id" : generator .id ,
773+ "state" : "enqueued" ,
774+ }
775+ )
776+
777+ generator ._compute_ongoing_jobs_info ()
778+ self .assertTrue (generator .has_ongoing_jobs )
779+ self .assertEqual (generator .ongoing_job_generator_id , generator )
780+
781+ def test_33_has_ongoing_jobs_with_started_job (self ):
782+ """Test has_ongoing_jobs detects started jobs"""
783+ # Clean up any existing jobs
784+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
785+
786+ generator = self .env ["spp.demo.data.generator" ].create (
787+ {
788+ "name" : "Generator with Started Job" ,
789+ "locale_origin" : self .test_country .id ,
790+ }
791+ )
792+
793+ # Create a started job
794+ self .env ["queue.job" ].create (
795+ {
796+ "name" : "Started Job" ,
797+ "model_name" : "spp.demo.data.generator" ,
798+ "method_name" : "_process_batch" ,
799+ "res_model" : "spp.demo.data.generator" ,
800+ "res_id" : generator .id ,
801+ "state" : "started" ,
802+ }
803+ )
804+
805+ generator ._compute_ongoing_jobs_info ()
806+ self .assertTrue (generator .has_ongoing_jobs )
807+ self .assertEqual (generator .ongoing_job_generator_id , generator )
808+
809+ def test_34_has_ongoing_jobs_with_done_job (self ):
810+ """Test has_ongoing_jobs with completed jobs"""
811+ # Clean up any existing jobs
812+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
813+
814+ generator = self .env ["spp.demo.data.generator" ].create (
815+ {
816+ "name" : "Generator with Done Job" ,
817+ "locale_origin" : self .test_country .id ,
818+ }
819+ )
820+
821+ # Create only done jobs
822+ self .env ["queue.job" ].create (
823+ {
824+ "name" : "Done Job" ,
825+ "model_name" : "spp.demo.data.generator" ,
826+ "method_name" : "_process_batch" ,
827+ "res_model" : "spp.demo.data.generator" ,
828+ "res_id" : generator .id ,
829+ "state" : "done" ,
830+ }
831+ )
832+
833+ generator ._compute_ongoing_jobs_info ()
834+ self .assertFalse (generator .has_ongoing_jobs )
835+ self .assertFalse (generator .ongoing_job_generator_id )
836+
837+ def test_35_has_ongoing_jobs_cross_record (self ):
838+ """Test has_ongoing_jobs affects all records when any generator has ongoing jobs"""
839+ # Clean up any existing jobs
840+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
841+
842+ generator1 = self .env ["spp.demo.data.generator" ].create (
843+ {
844+ "name" : "Generator 1" ,
845+ "locale_origin" : self .test_country .id ,
846+ }
847+ )
848+ generator2 = self .env ["spp.demo.data.generator" ].create (
849+ {
850+ "name" : "Generator 2" ,
851+ "locale_origin" : self .test_country .id ,
852+ }
853+ )
854+
855+ # Create a pending job for generator1 only
856+ self .env ["queue.job" ].create (
857+ {
858+ "name" : "Pending Job for Generator 1" ,
859+ "model_name" : "spp.demo.data.generator" ,
860+ "method_name" : "_process_batch" ,
861+ "res_model" : "spp.demo.data.generator" ,
862+ "res_id" : generator1 .id ,
863+ "state" : "pending" ,
864+ }
865+ )
866+
867+ # Trigger compute on both
868+ generator1 ._compute_ongoing_jobs_info ()
869+ generator2 ._compute_ongoing_jobs_info ()
870+
871+ # Both should show has_ongoing_jobs = True
872+ self .assertTrue (generator1 .has_ongoing_jobs )
873+ self .assertTrue (generator2 .has_ongoing_jobs )
874+
875+ # Both should point to generator1 as the one with ongoing jobs
876+ self .assertEqual (generator1 .ongoing_job_generator_id , generator1 )
877+ self .assertEqual (generator2 .ongoing_job_generator_id , generator1 )
878+
879+ def test_36_has_ongoing_jobs_mixed_states (self ):
880+ """Test has_ongoing_jobs with mixed job states"""
881+ # Clean up any existing jobs
882+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
883+
884+ generator = self .env ["spp.demo.data.generator" ].create (
885+ {
886+ "name" : "Generator Mixed States" ,
887+ "locale_origin" : self .test_country .id ,
888+ }
889+ )
890+
891+ # Create jobs with different states
892+ self .env ["queue.job" ].create (
893+ {
894+ "name" : "Done Job" ,
895+ "model_name" : "spp.demo.data.generator" ,
896+ "method_name" : "_process_batch" ,
897+ "res_model" : "spp.demo.data.generator" ,
898+ "res_id" : generator .id ,
899+ "state" : "done" ,
900+ }
901+ )
902+ self .env ["queue.job" ].create (
903+ {
904+ "name" : "Failed Job" ,
905+ "model_name" : "spp.demo.data.generator" ,
906+ "method_name" : "_process_batch" ,
907+ "res_model" : "spp.demo.data.generator" ,
908+ "res_id" : generator .id ,
909+ "state" : "failed" ,
910+ }
911+ )
912+ self .env ["queue.job" ].create (
913+ {
914+ "name" : "Pending Job" ,
915+ "model_name" : "spp.demo.data.generator" ,
916+ "method_name" : "_process_batch" ,
917+ "res_model" : "spp.demo.data.generator" ,
918+ "res_id" : generator .id ,
919+ "state" : "pending" ,
920+ }
921+ )
922+
923+ generator ._compute_ongoing_jobs_info ()
924+
925+ # Should be True because there's one pending job
926+ self .assertTrue (generator .has_ongoing_jobs )
927+ self .assertEqual (generator .ongoing_job_generator_id , generator )
928+
929+ def test_37_queue_job_isolation_from_other_models (self ):
930+ """Test that jobs from other models don't affect demo generator"""
931+ # Clean up any existing jobs
932+ self .env ["queue.job" ].search ([("res_model" , "=" , "spp.demo.data.generator" )]).unlink ()
933+
934+ generator = self .env ["spp.demo.data.generator" ].create (
935+ {
936+ "name" : "Generator Isolation Test" ,
937+ "locale_origin" : self .test_country .id ,
938+ }
939+ )
940+
941+ # Create a pending job for a different model
942+ self .env ["queue.job" ].create (
943+ {
944+ "name" : "Job for different model" ,
945+ "model_name" : "res.partner" ,
946+ "method_name" : "test_method" ,
947+ "res_model" : "res.partner" ,
948+ "res_id" : 1 ,
949+ "state" : "pending" ,
950+ }
951+ )
952+
953+ generator ._compute_ongoing_jobs_info ()
954+ generator ._compute_queue_job_ids ()
955+
956+ # Should not be affected by jobs from other models
957+ self .assertFalse (generator .has_ongoing_jobs )
958+ self .assertFalse (generator .ongoing_job_generator_id )
959+ self .assertEqual (len (generator .queue_job_ids ), 0 )
0 commit comments