Skip to content

Commit 63d1406

Browse files
committed
test(django): add comprehensive async middleware tests
Add 5 additional tests covering edge cases for async middleware: - Unauthenticated users - Requests without user attribute (no auth middleware) - extra_tags callbacks in async context - tag_map callbacks in async context - Full header extraction with authenticated user Ensures async middleware works correctly in all scenarios users might encounter. 24 middleware tests now pass (up from 19).
1 parent f581293 commit 63d1406

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

posthog/test/integrations/test_middleware.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,185 @@ async def mock_auser():
543543

544544
asyncio.run(run_test())
545545

546+
def test_async_middleware_with_unauthenticated_user(self):
547+
"""
548+
Test that async middleware handles unauthenticated users correctly.
549+
"""
550+
551+
async def run_test():
552+
mock_response = Mock()
553+
mock_user = Mock()
554+
mock_user.is_authenticated = False # Not authenticated
555+
556+
async def async_get_response(request):
557+
# Verify no distinct_id was set (no user)
558+
distinct_id = get_context_distinct_id()
559+
self.assertIsNone(distinct_id)
560+
return mock_response
561+
562+
middleware = PosthogContextMiddleware(async_get_response)
563+
middleware.client = Mock()
564+
565+
request = MockRequest(
566+
headers={"X-POSTHOG-SESSION-ID": "test-session"}, method="GET"
567+
)
568+
569+
async def mock_auser():
570+
return mock_user
571+
572+
request.auser = mock_auser
573+
574+
with new_context():
575+
result = middleware(request)
576+
response = await result
577+
self.assertEqual(response, mock_response)
578+
579+
asyncio.run(run_test())
580+
581+
def test_async_middleware_without_user_attribute(self):
582+
"""
583+
Test that async middleware handles requests without user attribute (no auth middleware).
584+
"""
585+
586+
async def run_test():
587+
mock_response = Mock()
588+
589+
async def async_get_response(request):
590+
return mock_response
591+
592+
middleware = PosthogContextMiddleware(async_get_response)
593+
middleware.client = Mock()
594+
595+
# Request without auser method (no auth middleware)
596+
request = MockRequest(
597+
headers={"X-POSTHOG-SESSION-ID": "test-session"}, method="GET"
598+
)
599+
600+
with new_context():
601+
result = middleware(request)
602+
response = await result
603+
self.assertEqual(response, mock_response)
604+
605+
asyncio.run(run_test())
606+
607+
def test_async_middleware_with_extra_tags(self):
608+
"""
609+
Test that async middleware works with extra_tags callback.
610+
"""
611+
612+
async def run_test():
613+
mock_response = Mock()
614+
615+
def extra_tags_callback(request):
616+
# Simple sync callback - should work
617+
return {"custom_tag": "custom_value"}
618+
619+
async def async_get_response(request):
620+
return mock_response
621+
622+
middleware = PosthogContextMiddleware(async_get_response)
623+
middleware.extra_tags = extra_tags_callback
624+
middleware.client = Mock()
625+
626+
request = MockRequest(
627+
headers={"X-POSTHOG-SESSION-ID": "test-session"}, method="GET"
628+
)
629+
630+
# Mock auser for no user
631+
async def mock_auser():
632+
return None
633+
634+
request.auser = mock_auser
635+
636+
with new_context():
637+
result = middleware(request)
638+
response = await result
639+
self.assertEqual(response, mock_response)
640+
641+
asyncio.run(run_test())
642+
643+
def test_async_middleware_with_tag_map(self):
644+
"""
645+
Test that async middleware works with tag_map callback.
646+
"""
647+
648+
async def run_test():
649+
mock_response = Mock()
650+
651+
def tag_map_callback(tags):
652+
# Simple sync callback - should work
653+
tags["mapped"] = "yes"
654+
return tags
655+
656+
async def async_get_response(request):
657+
return mock_response
658+
659+
middleware = PosthogContextMiddleware(async_get_response)
660+
middleware.tag_map = tag_map_callback
661+
middleware.client = Mock()
662+
663+
request = MockRequest(
664+
headers={"X-POSTHOG-SESSION-ID": "test-session"}, method="GET"
665+
)
666+
667+
# Mock auser for no user
668+
async def mock_auser():
669+
return None
670+
671+
request.auser = mock_auser
672+
673+
with new_context():
674+
result = middleware(request)
675+
response = await result
676+
self.assertEqual(response, mock_response)
677+
678+
asyncio.run(run_test())
679+
680+
def test_async_middleware_user_extraction_with_all_headers(self):
681+
"""
682+
Test async middleware extracts all request info correctly.
683+
"""
684+
685+
async def run_test():
686+
mock_response = Mock()
687+
mock_user = Mock()
688+
mock_user.is_authenticated = True
689+
mock_user.pk = 456
690+
mock_user.email = "[email protected]"
691+
692+
async def async_get_response(request):
693+
# Verify all context was set correctly
694+
distinct_id = get_context_distinct_id()
695+
session_id = get_context_session_id()
696+
self.assertEqual(distinct_id, "456")
697+
self.assertEqual(session_id, "async-sess-123")
698+
return mock_response
699+
700+
middleware = PosthogContextMiddleware(async_get_response)
701+
middleware.client = Mock()
702+
703+
request = MockRequest(
704+
headers={
705+
"X-POSTHOG-SESSION-ID": "async-sess-123",
706+
"X-Forwarded-For": "192.168.1.1",
707+
"User-Agent": "TestAgent/1.0",
708+
},
709+
method="POST",
710+
path="/api/test",
711+
)
712+
713+
async def mock_auser():
714+
return mock_user
715+
716+
request.auser = mock_auser
717+
718+
with new_context():
719+
result = middleware(request)
720+
response = await result
721+
self.assertEqual(response, mock_response)
722+
723+
asyncio.run(run_test())
724+
546725

547726
class TestPosthogContextMiddlewareHybrid(unittest.TestCase):
548727
"""Test hybrid middleware behavior with mixed sync/async chains"""

0 commit comments

Comments
 (0)