@@ -386,3 +386,114 @@ def test_prepare_entitlements_accepts_id_range(self):
386386 self .fail ("_prepare_entitlements must accept min_id/max_id params" )
387387 except UserError :
388388 pass # Expected: no entitlement manager configured
389+
390+ def test_check_eligibility_async_uses_compute_id_ranges (self ):
391+ """_check_eligibility_async must use compute_id_ranges for dispatch."""
392+ partners = self .env ["res.partner" ].create (
393+ [{"name" : f"Registrant { i } " , "is_registrant" : True } for i in range (5 )]
394+ )
395+ self .env ["spp.cycle.membership" ].create (
396+ [
397+ {
398+ "partner_id" : p .id ,
399+ "cycle_id" : self .cycle .id ,
400+ "state" : "draft" ,
401+ }
402+ for p in partners
403+ ]
404+ )
405+
406+ cycle_manager = self .env ["spp.cycle.manager.default" ].create (
407+ {
408+ "name" : "Test Cycle Manager" ,
409+ "program_id" : self .program .id ,
410+ }
411+ )
412+
413+ with patch (
414+ "odoo.addons.spp_programs.models.managers.cycle_manager_base.compute_id_ranges" ,
415+ return_value = [(1 , 3 ), (4 , 6 )],
416+ ) as mock_ranges :
417+ with patch .object (type (cycle_manager ), "delayable" , return_value = cycle_manager ):
418+ try :
419+ cycle_manager ._check_eligibility_async (self .cycle , 5 )
420+ except Exception : # pylint: disable=except-pass
421+ pass
422+
423+ mock_ranges .assert_called_once ()
424+ self .assertEqual (mock_ranges .call_args [0 ][1 ], "spp_cycle_membership" )
425+
426+ def test_prepare_entitlements_async_uses_compute_id_ranges (self ):
427+ """_prepare_entitlements_async must use compute_id_ranges for dispatch."""
428+ partners = self .env ["res.partner" ].create (
429+ [{"name" : f"Registrant { i } " , "is_registrant" : True } for i in range (5 )]
430+ )
431+ self .env ["spp.cycle.membership" ].create (
432+ [
433+ {
434+ "partner_id" : p .id ,
435+ "cycle_id" : self .cycle .id ,
436+ "state" : "enrolled" ,
437+ }
438+ for p in partners
439+ ]
440+ )
441+
442+ cycle_manager = self .env ["spp.cycle.manager.default" ].create (
443+ {
444+ "name" : "Test Cycle Manager" ,
445+ "program_id" : self .program .id ,
446+ }
447+ )
448+
449+ with patch (
450+ "odoo.addons.spp_programs.models.managers.cycle_manager_base.compute_id_ranges" ,
451+ return_value = [(1 , 3 ), (4 , 6 )],
452+ ) as mock_ranges :
453+ with patch .object (type (cycle_manager ), "delayable" , return_value = cycle_manager ):
454+ try :
455+ cycle_manager ._prepare_entitlements_async (self .cycle , 5 )
456+ except Exception : # pylint: disable=except-pass
457+ pass
458+
459+ mock_ranges .assert_called_once ()
460+ self .assertEqual (mock_ranges .call_args [0 ][1 ], "spp_cycle_membership" )
461+
462+ def test_enroll_eligible_async_handles_string_state (self ):
463+ """_enroll_eligible_registrants_async must handle string state arg."""
464+ partners = self .env ["res.partner" ].create (
465+ [{"name" : f"Registrant { i } " , "is_registrant" : True } for i in range (5 )]
466+ )
467+ self .env ["spp.program.membership" ].create (
468+ [
469+ {
470+ "partner_id" : p .id ,
471+ "program_id" : self .program .id ,
472+ "state" : "draft" ,
473+ }
474+ for p in partners
475+ ]
476+ )
477+
478+ manager = self .env ["spp.program.manager.default" ].create (
479+ {
480+ "name" : "Test Manager" ,
481+ "program_id" : self .program .id ,
482+ }
483+ )
484+
485+ # Pass a string instead of list — the isinstance branch should convert it
486+ with patch (
487+ "odoo.addons.spp_programs.models.managers.program_manager.compute_id_ranges" ,
488+ return_value = [(1 , 5 )],
489+ ) as mock_ranges :
490+ with patch .object (type (manager ), "delayable" , return_value = manager ):
491+ try :
492+ manager ._enroll_eligible_registrants_async ("draft" , 5 )
493+ except Exception : # pylint: disable=except-pass
494+ pass
495+
496+ mock_ranges .assert_called_once ()
497+ # Verify the states param was converted from string to tuple
498+ call_params = mock_ranges .call_args [0 ][3 ]
499+ self .assertIsInstance (call_params [1 ], tuple )
0 commit comments