Skip to content

Commit f5731a1

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 0950d49 commit f5731a1

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
@@ -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

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

0 commit comments

Comments
 (0)