@@ -276,13 +276,39 @@ def test_application_module_analyzer_get_module_dependencies_none():
276276 assert len (dependencies ) == 0
277277
278278
279+ def test_application_module_analyzer_get_application_module_providers ():
280+ """Test getting providers from ApplicationModule"""
281+ from ellar .di import ProviderConfig
282+
283+ @injectable
284+ class AppLevelService :
285+ pass
286+
287+ @Module (
288+ name = "TestAppModuleWithProviders" ,
289+ modules = [AuthModule ],
290+ providers = [ProviderConfig (AppLevelService , use_class = AppLevelService )],
291+ )
292+ class TestAppModuleWithProviders (ModuleBase ):
293+ pass
294+
295+ analyzer = ApplicationModuleDependencyAnalyzer (TestAppModuleWithProviders )
296+ providers = analyzer .get_application_module_providers ()
297+
298+ # Should include AppLevelService
299+ assert AppLevelService in providers or any (
300+ hasattr (p , "get_type" ) and p .get_type () == AppLevelService for p in providers
301+ )
302+
303+
279304# ============================================================================
280305# Unit Tests: ForwardRefModule Resolution
281306# ============================================================================
282307
283308
284309def test_forward_ref_resolution_by_type ():
285310 """Test resolving ForwardRefModule by type"""
311+ from ellar .core .modules import ModuleSetup
286312
287313 # Need to have DatabaseModule actually registered in the application tree
288314 @Module (
@@ -298,7 +324,9 @@ class ForwardRefTestModule(ModuleBase):
298324 forward_ref = ForwardRefModule (module = DatabaseModule )
299325 resolved = analyzer .resolve_forward_ref (forward_ref )
300326
301- assert resolved == DatabaseModule
327+ # Should return a ModuleSetup instance
328+ assert isinstance (resolved , ModuleSetup )
329+ assert resolved .module == DatabaseModule
302330
303331
304332def test_forward_ref_resolution_by_name ():
@@ -318,7 +346,8 @@ class ForwardRefTestModule2(ModuleBase):
318346 forward_ref = ForwardRefModule (module_name = "DatabaseModule" )
319347 resolved = analyzer .resolve_forward_ref (forward_ref )
320348
321- assert resolved == DatabaseModule
349+ # When resolving by name, it returns the module type directly
350+ assert resolved .module == DatabaseModule
322351
323352
324353def test_forward_ref_resolution_not_found ():
@@ -336,6 +365,52 @@ class ForwardRefTestModule3(ModuleBase):
336365 assert resolved is None
337366
338367
368+ def test_resolve_forward_refs_handles_module_setup ():
369+ """Test that _resolve_forward_refs properly handles ModuleSetup instances"""
370+ from ellar .testing .module import Test
371+
372+ @Module (name = "TestModuleForSetup" , modules = [AuthModule , DatabaseModule ])
373+ class TestModuleForSetup (ModuleBase ):
374+ pass
375+
376+ analyzer = ApplicationModuleDependencyAnalyzer (TestModuleForSetup )
377+
378+ # Pass ForwardRefModule instances that will be resolved
379+ forward_ref_auth = ForwardRefModule (module = AuthModule )
380+ forward_ref_db = ForwardRefModule (module = DatabaseModule )
381+
382+ modules = [forward_ref_auth , forward_ref_db ]
383+ resolved = Test ._resolve_forward_refs (modules , analyzer )
384+
385+ # Should resolve both ForwardRefModules (and potentially their dependencies)
386+ assert len (resolved ) >= 2
387+
388+
389+ def test_resolve_forward_refs_recursive_extension ():
390+ """Test that _resolve_forward_refs recursively extends with nested modules"""
391+ from ellar .testing .module import Test
392+
393+ # DatabaseModule has LoggingModule as dependency
394+ @Module (
395+ name = "TestModuleForRecursive" ,
396+ modules = [DatabaseModule , AuthModule ],
397+ )
398+ class TestModuleForRecursive (ModuleBase ):
399+ pass
400+
401+ analyzer = ApplicationModuleDependencyAnalyzer (TestModuleForRecursive )
402+
403+ # Start with ForwardRefModule to DatabaseModule (which has LoggingModule as dependency)
404+ forward_ref_db = ForwardRefModule (module = DatabaseModule )
405+ modules = [forward_ref_db ]
406+ resolved = Test ._resolve_forward_refs (modules , analyzer )
407+
408+ # Should return resolved DatabaseModule (and potentially nested dependencies)
409+ # The exact count depends on whether DatabaseModule's LoggingModule dependency
410+ # has any ForwardRefModules in its metadata
411+ assert len (resolved ) >= 1
412+
413+
339414# ============================================================================
340415# Integration Tests: Test.create_test_module()
341416# ============================================================================
@@ -469,7 +544,7 @@ class TestAppWithForwardRef(ModuleBase):
469544
470545 tm = Test .create_test_module (
471546 controllers = [UserController ],
472- modules = [ ModuleWithForwardRef ], # Contains ForwardRef to AuthModule
547+ # Don't manually add ForwardRef module - let auto-resolution handle it
473548 application_module = TestAppWithForwardRef ,
474549 )
475550
@@ -622,6 +697,49 @@ def test_create_test_module_with_import_string_application_module(reflect_contex
622697 assert isinstance (controller .auth_service , IAuthService )
623698
624699
700+ def test_create_test_module_includes_application_module_providers (reflect_context ):
701+ """Test that test module includes providers from ApplicationModule"""
702+
703+ @injectable
704+ class AppLevelService :
705+ def get_value (self ):
706+ return "app_level"
707+
708+ @Module (
709+ name = "AppModuleWithProviders" ,
710+ modules = [AuthModule ],
711+ providers = [ProviderConfig (AppLevelService , use_class = AppLevelService )],
712+ )
713+ class AppModuleWithProviders (ModuleBase ):
714+ pass
715+
716+ @Controller ()
717+ class ControllerUsingAppService :
718+ def __init__ (self , app_service : AppLevelService ):
719+ self .app_service = app_service
720+
721+ @get ("/test" )
722+ def test_endpoint (self ):
723+ return {"value" : self .app_service .get_value ()}
724+
725+ tm = Test .create_test_module (
726+ controllers = [ControllerUsingAppService ],
727+ application_module = AppModuleWithProviders ,
728+ )
729+
730+ tm .create_application ()
731+
732+ # Should be able to get the app-level service
733+ app_service = tm .get (AppLevelService )
734+ assert app_service is not None
735+ assert app_service .get_value () == "app_level"
736+
737+ # Controller should also work
738+ controller = tm .get (ControllerUsingAppService )
739+ assert controller is not None
740+ assert isinstance (controller .app_service , AppLevelService )
741+
742+
625743def test_application_module_analyzer_with_import_string ():
626744 """Test that ApplicationModuleDependencyAnalyzer accepts import strings"""
627745 import_string = "tests.test_testing_dependency_resolution:ApplicationModule"
0 commit comments