@@ -412,3 +412,247 @@ def test_alternative_plugin_selection(self, clean_env):
412412 # With USE_ANOTHER=True, AnotherSimplePlugin should be selected
413413 result = get_extension ("simple-ext" , v )
414414 assert result ["status" ] == "another_initialized"
415+
416+
417+ class TestOnRegistration :
418+ """Tests for on_registration hook."""
419+
420+ def test_on_registration_called (self , clean_env ):
421+ """Test that on_registration is called when plugin is registered."""
422+ from scitrera_app_framework import init_framework_test_harness
423+ from scitrera_app_framework .core .plugins import register_plugin
424+
425+ on_reg_calls = []
426+
427+ class OnRegPlugin (Plugin ):
428+ def extension_point_name (self , v ):
429+ return "onreg-ext"
430+
431+ def on_registration (self , v ):
432+ on_reg_calls .append (("registered" , v ))
433+
434+ def initialize (self , v , logger ):
435+ return "value"
436+
437+ v = init_framework_test_harness ("test-app" )
438+ register_plugin (OnRegPlugin , v , init = False )
439+
440+ assert len (on_reg_calls ) == 1
441+ assert on_reg_calls [0 ][0 ] == "registered"
442+ assert on_reg_calls [0 ][1 ] is v
443+
444+ def test_on_registration_called_before_initialize (self , clean_env ):
445+ """Test that on_registration is called before initialize."""
446+ from scitrera_app_framework import init_framework_test_harness
447+ from scitrera_app_framework .core .plugins import register_plugin
448+
449+ call_order = []
450+
451+ class OrderTestPlugin (Plugin ):
452+ def extension_point_name (self , v ):
453+ return "order-ext"
454+
455+ def on_registration (self , v ):
456+ call_order .append ("on_registration" )
457+
458+ def initialize (self , v , logger ):
459+ call_order .append ("initialize" )
460+ return "value"
461+
462+ v = init_framework_test_harness ("test-app" )
463+ register_plugin (OrderTestPlugin , v , init = True )
464+
465+ assert call_order == ["on_registration" , "initialize" ]
466+
467+ def test_on_registration_not_called_twice (self , clean_env ):
468+ """Test that on_registration is only called once per plugin, not on duplicate registration."""
469+ from scitrera_app_framework import init_framework_test_harness
470+ from scitrera_app_framework .core .plugins import register_plugin
471+
472+ on_reg_calls = []
473+
474+ class SingleRegPlugin (Plugin ):
475+ def extension_point_name (self , v ):
476+ return "singlereg-ext"
477+
478+ def on_registration (self , v ):
479+ on_reg_calls .append ("called" )
480+
481+ def initialize (self , v , logger ):
482+ return "value"
483+
484+ v = init_framework_test_harness ("test-app" )
485+
486+ # Register multiple times
487+ register_plugin (SingleRegPlugin , v , init = False )
488+ register_plugin (SingleRegPlugin , v , init = False )
489+ register_plugin (SingleRegPlugin , v , init = True )
490+
491+ # on_registration should only be called once
492+ assert len (on_reg_calls ) == 1
493+
494+ def test_on_registration_default_noop (self , clean_env ):
495+ """Test that plugins without on_registration override work fine (backwards compatibility)."""
496+ from scitrera_app_framework import init_framework_test_harness
497+ from scitrera_app_framework .core .plugins import register_plugin , get_extension
498+
499+ v = init_framework_test_harness ("test-app" )
500+
501+ # SimplePlugin doesn't override on_registration
502+ register_plugin (SimplePlugin , v , init = True )
503+
504+ # Should work normally
505+ result = get_extension ("simple-ext" , v )
506+ assert result ["status" ] == "initialized"
507+
508+ def test_on_registration_can_register_other_plugins (self , clean_env ):
509+ """Test that on_registration can register additional plugins."""
510+ from scitrera_app_framework import init_framework_test_harness
511+ from scitrera_app_framework .core .plugins import register_plugin , get_extension
512+
513+ class HelperPlugin (Plugin ):
514+ def extension_point_name (self , v ):
515+ return "helper-ext"
516+
517+ def initialize (self , v , logger ):
518+ return "helper_value"
519+
520+ class MainPlugin (Plugin ):
521+ def extension_point_name (self , v ):
522+ return "main-ext"
523+
524+ def on_registration (self , v ):
525+ # Register another plugin during on_registration
526+ register_plugin (HelperPlugin , v , init = False )
527+
528+ def initialize (self , v , logger ):
529+ return "main_value"
530+
531+ v = init_framework_test_harness ("test-app" )
532+ register_plugin (MainPlugin , v , init = True )
533+
534+ # Both plugins should be accessible
535+ assert get_extension ("main-ext" , v ) == "main_value"
536+ assert get_extension ("helper-ext" , v ) == "helper_value"
537+
538+ def test_on_registration_can_set_variables (self , clean_env ):
539+ """Test that on_registration can modify the Variables instance."""
540+ from scitrera_app_framework import init_framework_test_harness
541+ from scitrera_app_framework .core .plugins import register_plugin , get_extension
542+
543+ class ConfigPlugin (Plugin ):
544+ def extension_point_name (self , v ):
545+ return "config-ext"
546+
547+ def on_registration (self , v ):
548+ # Set some default configuration
549+ v .set ("CONFIG_DEFAULT" , "default_value" )
550+
551+ def initialize (self , v , logger ):
552+ return v .get ("CONFIG_DEFAULT" )
553+
554+ v = init_framework_test_harness ("test-app" )
555+ register_plugin (ConfigPlugin , v , init = True )
556+
557+ result = get_extension ("config-ext" , v )
558+ assert result == "default_value"
559+
560+ def test_on_registration_with_multi_extension (self , clean_env ):
561+ """Test that on_registration works with multi-extension plugins."""
562+ from scitrera_app_framework import init_framework_test_harness
563+ from scitrera_app_framework .core .plugins import register_plugin , get_extensions
564+
565+ on_reg_calls = []
566+
567+ class MultiRegPlugin1 (Plugin ):
568+ def extension_point_name (self , v ):
569+ return "multireg-ext"
570+
571+ def is_multi_extension (self , v ):
572+ return True
573+
574+ def on_registration (self , v ):
575+ on_reg_calls .append ("multi1" )
576+
577+ def initialize (self , v , logger ):
578+ return "multi1_value"
579+
580+ class MultiRegPlugin2 (Plugin ):
581+ def extension_point_name (self , v ):
582+ return "multireg-ext"
583+
584+ def is_multi_extension (self , v ):
585+ return True
586+
587+ def on_registration (self , v ):
588+ on_reg_calls .append ("multi2" )
589+
590+ def initialize (self , v , logger ):
591+ return "multi2_value"
592+
593+ v = init_framework_test_harness ("test-app" )
594+ register_plugin (MultiRegPlugin1 , v , init = True )
595+ register_plugin (MultiRegPlugin2 , v , init = True )
596+
597+ # Both on_registration hooks should be called
598+ assert on_reg_calls == ["multi1" , "multi2" ]
599+
600+ # Both extensions should work
601+ results = get_extensions ("multireg-ext" , v )
602+ assert len (results ) == 2
603+
604+ def test_on_registration_with_disabled_plugin (self , clean_env ):
605+ """Test that on_registration is called even for disabled plugins."""
606+ from scitrera_app_framework import init_framework_test_harness
607+ from scitrera_app_framework .core .plugins import register_plugin
608+
609+ on_reg_calls = []
610+
611+ class DisabledRegPlugin (Plugin ):
612+ def extension_point_name (self , v ):
613+ return "disabledreg-ext"
614+
615+ def is_enabled (self , v ):
616+ return False
617+
618+ def on_registration (self , v ):
619+ on_reg_calls .append ("disabled_registered" )
620+
621+ def initialize (self , v , logger ):
622+ return "should_not_init"
623+
624+ v = init_framework_test_harness ("test-app" )
625+ register_plugin (DisabledRegPlugin , v , init = True )
626+
627+ # on_registration should still be called even though plugin is disabled
628+ assert len (on_reg_calls ) == 1
629+ assert on_reg_calls [0 ] == "disabled_registered"
630+
631+ def test_on_registration_with_lazy_plugin (self , clean_env ):
632+ """Test that on_registration is called immediately for lazy plugins."""
633+ from scitrera_app_framework import init_framework_test_harness
634+ from scitrera_app_framework .core .plugins import register_plugin
635+
636+ call_order = []
637+
638+ class LazyRegPlugin (Plugin ):
639+ eager = False
640+
641+ def extension_point_name (self , v ):
642+ return "lazyreg-ext"
643+
644+ def on_registration (self , v ):
645+ call_order .append ("on_registration" )
646+
647+ def initialize (self , v , logger ):
648+ call_order .append ("initialize" )
649+ return "lazy_value"
650+
651+ v = init_framework_test_harness ("test-app" )
652+ register_plugin (LazyRegPlugin , v , init = False )
653+
654+ # on_registration should be called immediately upon registration
655+ assert call_order == ["on_registration" ]
656+
657+ # initialize should not be called yet (lazy)
658+ assert "initialize" not in call_order
0 commit comments