@@ -442,6 +442,185 @@ async def mock_auser():
442442
443443        asyncio .run (run_test ())
444444
445+     def  test_async_middleware_with_unauthenticated_user (self ):
446+         """ 
447+         Test that async middleware handles unauthenticated users correctly. 
448+         """ 
449+ 
450+         async  def  run_test ():
451+             mock_response  =  Mock ()
452+             mock_user  =  Mock ()
453+             mock_user .is_authenticated  =  False   # Not authenticated 
454+ 
455+             async  def  async_get_response (request ):
456+                 # Verify no distinct_id was set (no user) 
457+                 distinct_id  =  get_context_distinct_id ()
458+                 self .assertIsNone (distinct_id )
459+                 return  mock_response 
460+ 
461+             middleware  =  PosthogContextMiddleware (async_get_response )
462+             middleware .client  =  Mock ()
463+ 
464+             request  =  MockRequest (
465+                 headers = {"X-POSTHOG-SESSION-ID" : "test-session" }, method = "GET" 
466+             )
467+ 
468+             async  def  mock_auser ():
469+                 return  mock_user 
470+ 
471+             request .auser  =  mock_auser 
472+ 
473+             with  new_context ():
474+                 result  =  middleware (request )
475+                 response  =  await  result 
476+                 self .assertEqual (response , mock_response )
477+ 
478+         asyncio .run (run_test ())
479+ 
480+     def  test_async_middleware_without_user_attribute (self ):
481+         """ 
482+         Test that async middleware handles requests without user attribute (no auth middleware). 
483+         """ 
484+ 
485+         async  def  run_test ():
486+             mock_response  =  Mock ()
487+ 
488+             async  def  async_get_response (request ):
489+                 return  mock_response 
490+ 
491+             middleware  =  PosthogContextMiddleware (async_get_response )
492+             middleware .client  =  Mock ()
493+ 
494+             # Request without auser method (no auth middleware) 
495+             request  =  MockRequest (
496+                 headers = {"X-POSTHOG-SESSION-ID" : "test-session" }, method = "GET" 
497+             )
498+ 
499+             with  new_context ():
500+                 result  =  middleware (request )
501+                 response  =  await  result 
502+                 self .assertEqual (response , mock_response )
503+ 
504+         asyncio .run (run_test ())
505+ 
506+     def  test_async_middleware_with_extra_tags (self ):
507+         """ 
508+         Test that async middleware works with extra_tags callback. 
509+         """ 
510+ 
511+         async  def  run_test ():
512+             mock_response  =  Mock ()
513+ 
514+             def  extra_tags_callback (request ):
515+                 # Simple sync callback - should work 
516+                 return  {"custom_tag" : "custom_value" }
517+ 
518+             async  def  async_get_response (request ):
519+                 return  mock_response 
520+ 
521+             middleware  =  PosthogContextMiddleware (async_get_response )
522+             middleware .extra_tags  =  extra_tags_callback 
523+             middleware .client  =  Mock ()
524+ 
525+             request  =  MockRequest (
526+                 headers = {"X-POSTHOG-SESSION-ID" : "test-session" }, method = "GET" 
527+             )
528+ 
529+             # Mock auser for no user 
530+             async  def  mock_auser ():
531+                 return  None 
532+ 
533+             request .auser  =  mock_auser 
534+ 
535+             with  new_context ():
536+                 result  =  middleware (request )
537+                 response  =  await  result 
538+                 self .assertEqual (response , mock_response )
539+ 
540+         asyncio .run (run_test ())
541+ 
542+     def  test_async_middleware_with_tag_map (self ):
543+         """ 
544+         Test that async middleware works with tag_map callback. 
545+         """ 
546+ 
547+         async  def  run_test ():
548+             mock_response  =  Mock ()
549+ 
550+             def  tag_map_callback (tags ):
551+                 # Simple sync callback - should work 
552+                 tags ["mapped" ] =  "yes" 
553+                 return  tags 
554+ 
555+             async  def  async_get_response (request ):
556+                 return  mock_response 
557+ 
558+             middleware  =  PosthogContextMiddleware (async_get_response )
559+             middleware .tag_map  =  tag_map_callback 
560+             middleware .client  =  Mock ()
561+ 
562+             request  =  MockRequest (
563+                 headers = {"X-POSTHOG-SESSION-ID" : "test-session" }, method = "GET" 
564+             )
565+ 
566+             # Mock auser for no user 
567+             async  def  mock_auser ():
568+                 return  None 
569+ 
570+             request .auser  =  mock_auser 
571+ 
572+             with  new_context ():
573+                 result  =  middleware (request )
574+                 response  =  await  result 
575+                 self .assertEqual (response , mock_response )
576+ 
577+         asyncio .run (run_test ())
578+ 
579+     def  test_async_middleware_user_extraction_with_all_headers (self ):
580+         """ 
581+         Test async middleware extracts all request info correctly. 
582+         """ 
583+ 
584+         async  def  run_test ():
585+             mock_response  =  Mock ()
586+             mock_user  =  Mock ()
587+             mock_user .is_authenticated  =  True 
588+             mock_user .pk  =  456 
589+             mock_user .email  =  "async@test.com" 
590+ 
591+             async  def  async_get_response (request ):
592+                 # Verify all context was set correctly 
593+                 distinct_id  =  get_context_distinct_id ()
594+                 session_id  =  get_context_session_id ()
595+                 self .assertEqual (distinct_id , "456" )
596+                 self .assertEqual (session_id , "async-sess-123" )
597+                 return  mock_response 
598+ 
599+             middleware  =  PosthogContextMiddleware (async_get_response )
600+             middleware .client  =  Mock ()
601+ 
602+             request  =  MockRequest (
603+                 headers = {
604+                     "X-POSTHOG-SESSION-ID" : "async-sess-123" ,
605+                     "X-Forwarded-For" : "192.168.1.1" ,
606+                     "User-Agent" : "TestAgent/1.0" ,
607+                 },
608+                 method = "POST" ,
609+                 path = "/api/test" ,
610+             )
611+ 
612+             async  def  mock_auser ():
613+                 return  mock_user 
614+ 
615+             request .auser  =  mock_auser 
616+ 
617+             with  new_context ():
618+                 result  =  middleware (request )
619+                 response  =  await  result 
620+                 self .assertEqual (response , mock_response )
621+ 
622+         asyncio .run (run_test ())
623+ 
445624
446625class  TestPosthogContextMiddlewareHybrid (unittest .TestCase ):
447626    """Test hybrid middleware behavior with mixed sync/async chains""" 
0 commit comments