CoolFace
Apppublic

findEthics/Atlas

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
test_backward_compatibility.py596 linesDownload Raw Back to tests
1#!/usr/bin/env python32"""3Backward compatibility tests for user authentication feature4 5This test file ensures that existing anonymous user workflows continue to work6exactly as they did before the user authentication feature was added.7"""8 9import sys10import os11sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))12 13# Load environment variables14try:15    from dotenv import load_dotenv16    load_dotenv()17except ImportError:18    pass  # dotenv not available, continue without it19 20import asyncio21import httpx22import time23from datetime import datetime24from typing import Optional, Dict, Any25 26from analytics.collectors import create_session, track_message, track_search27from analytics.dashboard import get_basic_stats, get_hourly_message_stats, get_session_stats28from analytics.database import get_sessions_collection, get_messages_collection, get_search_analytics_collection29 30 31class TestAnonymousUserCompatibility:32    """Test that anonymous users work exactly as before"""33    34    async def test_create_session_without_user_id(self):35        """Test creating sessions without user_id parameter (old way)"""36        # Create session the old way (no user_id parameter)37        session = await create_session(user_agent="TestAgent")38        39        assert session.user_id is None40        assert session.user_agent == "TestAgent"41        assert session.session_id is not None42        assert session.status == "active"43        44        print("✅ Anonymous session creation works as before")45    46    async def test_create_session_with_none_user_id(self):47        """Test creating sessions with explicit None user_id"""48        # Create session with explicit None49        session = await create_session(user_agent="TestAgent", user_id=None)50        51        assert session.user_id is None52        assert session.user_agent == "TestAgent"53        assert session.session_id is not None54        assert session.status == "active"55        56        print("✅ Session creation with None user_id works")57    58    async def test_track_message_without_user_id(self):59        """Test tracking messages without user_id parameter (old way)"""60        # Create session first61        session = await create_session(user_agent="TestAgent")62        63        # Track message the old way (no user_id parameter)64        message = await track_message(65            session_id=session.session_id,66            prompt_length=50,67            response_length=100,68            response_time_ms=1000,69            used_search=True,70            max_tokens=500,71            temperature=0.7,72            success=True73        )74        75        assert message is not None76        assert message.user_id is None77        assert message.session_id == session.session_id78        assert message.prompt_length == 5079        assert message.response_length == 10080        assert message.used_search is True81        82        print("✅ Anonymous message tracking works as before")83    84    async def test_track_message_with_none_user_id(self):85        """Test tracking messages with explicit None user_id"""86        # Create session first87        session = await create_session()88        89        # Track message with explicit None user_id90        message = await track_message(91            session_id=session.session_id,92            prompt_length=40,93            response_length=80,94            response_time_ms=800,95            used_search=False,96            user_id=None97        )98        99        assert message is not None100        assert message.user_id is None101        assert message.session_id == session.session_id102        103        print("✅ Message tracking with None user_id works")104    105    async def test_track_search_without_user_id(self):106        """Test tracking search without user_id parameter (old way)"""107        # Create session and message first108        session = await create_session()109        message = await track_message(110            session_id=session.session_id,111            prompt_length=50,112            response_length=100,113            response_time_ms=1000114        )115        116        # Track search the old way (no user_id parameter)117        search = await track_search(118            message_id=message.message_id,119            search_query="test query",120            search_terms=["test", "query"],121            brave_results=5,122            duckduckgo_results=3,123            total_unique_results=7,124            brave_response_time_ms=1000,125            duckduckgo_response_time_ms=800,126            search_engines_used=["brave", "duckduckgo"],127            search_success=True,128            fallback_used=False129        )130        131        assert search is not None132        assert search.user_id is None133        assert search.message_id == message.message_id134        assert search.search_query == "test query"135        136        print("✅ Anonymous search tracking works as before")137    138    async def test_track_search_with_none_user_id(self):139        """Test tracking search with explicit None user_id"""140        # Create session and message first141        session = await create_session()142        message = await track_message(143            session_id=session.session_id,144            prompt_length=50,145            response_length=100,146            response_time_ms=1000147        )148        149        # Track search with explicit None user_id150        search = await track_search(151            message_id=message.message_id,152            search_query="test query",153            search_terms=["test", "query"],154            user_id=None155        )156        157        assert search is not None158        assert search.user_id is None159        160        print("✅ Search tracking with None user_id works")161 162 163class TestAnonymousChatRequests:164    """Test that anonymous chat requests work as before"""165    166    async def test_chat_request_without_user_id_field(self):167        """Test chat request without user_id field (old API format)"""168        chat_data = {169            "prompt": "Test anonymous chat request",170            "max_new_tokens": 100,171            "use_search": False,172            "temperature": 0.7173            # No user_id field - this is the old format174        }175        176        try:177            async with httpx.AsyncClient(timeout=30.0) as client:178                response = await client.post(179                    "http://localhost:7860/chat",180                    json=chat_data,181                    headers={"Content-Type": "application/json"}182                )183                184                assert response.status_code == 200185                result = response.json()186                assert "response" in result187                assert isinstance(result["response"], str)188                assert len(result["response"]) > 0189                190                # Check session ID in headers191                session_id = response.headers.get('X-Session-ID')192                assert session_id is not None193                194                print("✅ Anonymous chat request (old format) works")195                return session_id196                197        except httpx.ConnectError:198            print("⚠️  Server not running - skipping chat request test")199            return None200    201    async def test_chat_request_with_null_user_id(self):202        """Test chat request with null user_id"""203        chat_data = {204            "prompt": "Test chat request with null user_id",205            "max_new_tokens": 100,206            "use_search": False,207            "temperature": 0.7,208            "user_id": None209        }210        211        try:212            async with httpx.AsyncClient(timeout=30.0) as client:213                response = await client.post(214                    "http://localhost:7860/chat",215                    json=chat_data,216                    headers={"Content-Type": "application/json"}217                )218                219                assert response.status_code == 200220                result = response.json()221                assert "response" in result222                223                print("✅ Chat request with null user_id works")224                225        except httpx.ConnectError:226            print("⚠️  Server not running - skipping chat request test")227    228    async def test_multiple_anonymous_requests(self):229        """Test multiple anonymous requests work as before"""230        try:231            async with httpx.AsyncClient(timeout=30.0) as client:232                # First anonymous request233                chat_data1 = {234                    "prompt": "First anonymous message",235                    "max_new_tokens": 50,236                    "use_search": False,237                    "temperature": 0.7238                }239                240                response1 = await client.post(241                    "http://localhost:7860/chat",242                    json=chat_data1,243                    headers={"Content-Type": "application/json"}244                )245                246                assert response1.status_code == 200247                session_id1 = response1.headers.get('X-Session-ID')248                249                # Second anonymous request (different session)250                chat_data2 = {251                    "prompt": "Second anonymous message",252                    "max_new_tokens": 50,253                    "use_search": False,254                    "temperature": 0.7255                }256                257                response2 = await client.post(258                    "http://localhost:7860/chat",259                    json=chat_data2,260                    headers={"Content-Type": "application/json"}261                )262                263                assert response2.status_code == 200264                session_id2 = response2.headers.get('X-Session-ID')265                266                # Should get different sessions (as before)267                assert session_id1 != session_id2268                269                print("✅ Multiple anonymous requests work as before")270                271        except httpx.ConnectError:272            print("⚠️  Server not running - skipping multiple requests test")273    274    async def test_anonymous_session_continuation(self):275        """Test that anonymous sessions can be continued with session ID"""276        try:277            async with httpx.AsyncClient(timeout=30.0) as client:278                # First request creates session279                chat_data1 = {280                    "prompt": "First message in session",281                    "max_new_tokens": 50,282                    "use_search": False,283                    "temperature": 0.7284                }285                286                response1 = await client.post(287                    "http://localhost:7860/chat",288                    json=chat_data1,289                    headers={"Content-Type": "application/json"}290                )291                292                assert response1.status_code == 200293                session_id = response1.headers.get('X-Session-ID')294                295                # Second request continues same session296                chat_data2 = {297                    "prompt": "Second message in same session",298                    "max_new_tokens": 50,299                    "use_search": True,300                    "temperature": 0.7301                }302                303                response2 = await client.post(304                    "http://localhost:7860/chat",305                    json=chat_data2,306                    headers={307                        "Content-Type": "application/json",308                        "X-Session-ID": session_id309                    }310                )311                312                assert response2.status_code == 200313                session_id2 = response2.headers.get('X-Session-ID')314                315                # Should be same session316                assert session_id2 == session_id317                318                print("✅ Anonymous session continuation works as before")319                320        except httpx.ConnectError:321            print("⚠️  Server not running - skipping session continuation test")322 323 324class TestAnalyticsFunctionCompatibility:325    """Test that analytics functions work with anonymous data"""326    327    async def test_basic_stats_with_anonymous_data(self):328        """Test that get_basic_stats works with anonymous data"""329        # Create some anonymous data330        session = await create_session()331        await track_message(332            session_id=session.session_id,333            prompt_length=50,334            response_length=100,335            response_time_ms=1000336        )337        338        # Test basic stats function339        stats = await get_basic_stats()340        341        assert isinstance(stats, dict)342        assert "total_sessions" in stats343        assert "total_messages" in stats344        assert "active_sessions" in stats345        assert stats["total_sessions"] >= 1346        assert stats["total_messages"] >= 1347        348        print("✅ Basic stats work with anonymous data")349    350    async def test_hourly_stats_with_anonymous_data(self):351        """Test that get_hourly_message_stats works with anonymous data"""352        # Create some anonymous data353        session = await create_session()354        await track_message(355            session_id=session.session_id,356            prompt_length=50,357            response_length=100,358            response_time_ms=1000359        )360        361        # Test hourly stats function362        hourly_stats = await get_hourly_message_stats(hours=24)363        364        assert isinstance(hourly_stats, list)365        # Should have 24 hours of data366        assert len(hourly_stats) == 24367        368        for hour_data in hourly_stats:369            assert "hour" in hour_data370            assert "message_count" in hour_data371            assert "search_count" in hour_data372            assert "avg_response_time_ms" in hour_data373        374        print("✅ Hourly stats work with anonymous data")375    376    async def test_session_stats_with_anonymous_data(self):377        """Test that get_session_stats works with anonymous data"""378        # Create some anonymous data379        session = await create_session()380        await track_message(381            session_id=session.session_id,382            prompt_length=50,383            response_length=100,384            response_time_ms=1000385        )386        387        # Test session stats function388        session_stats = await get_session_stats()389        390        assert isinstance(session_stats, dict)391        assert "total_sessions" in session_stats392        assert "active_sessions" in session_stats393        assert "ended_sessions" in session_stats394        assert session_stats["total_sessions"] >= 1395        396        print("✅ Session stats work with anonymous data")397 398 399class TestDatabaseCompatibility:400    """Test that database operations work with anonymous data"""401    402    async def test_anonymous_data_storage(self):403        """Test that anonymous data is stored correctly in database"""404        # Create anonymous session and message405        session = await create_session(user_agent="TestAgent")406        message = await track_message(407            session_id=session.session_id,408            prompt_length=50,409            response_length=100,410            response_time_ms=1000411        )412        413        # Wait for data to be written414        await asyncio.sleep(1)415        416        # Check database storage417        sessions_collection = await get_sessions_collection()418        messages_collection = await get_messages_collection()419        420        if sessions_collection and messages_collection:421            # Check session document422            session_doc = await sessions_collection.find_one({"_id": session.session_id})423            assert session_doc is not None424            assert session_doc.get("user_id") is None425            assert session_doc.get("user_agent") == "TestAgent"426            427            # Check message document428            message_doc = await messages_collection.find_one({"_id": message.message_id})429            assert message_doc is not None430            assert message_doc.get("user_id") is None431            assert message_doc.get("session_id") == session.session_id432            433            print("✅ Anonymous data stored correctly in database")434        else:435            print("⚠️  Database not available - skipping storage test")436    437    async def test_anonymous_data_queries(self):438        """Test that queries work correctly with anonymous data"""439        # Create anonymous data440        session = await create_session()441        await track_message(442            session_id=session.session_id,443            prompt_length=50,444            response_length=100,445            response_time_ms=1000446        )447        448        # Wait for data to be written449        await asyncio.sleep(1)450        451        # Test queries452        sessions_collection = await get_sessions_collection()453        messages_collection = await get_messages_collection()454        455        if sessions_collection and messages_collection:456            # Query anonymous sessions457            anonymous_sessions = await sessions_collection.count_documents({"user_id": None})458            assert anonymous_sessions >= 1459            460            # Query anonymous messages461            anonymous_messages = await messages_collection.count_documents({"user_id": None})462            assert anonymous_messages >= 1463            464            # Query all sessions (should include anonymous)465            all_sessions = await sessions_collection.count_documents({})466            assert all_sessions >= anonymous_sessions467            468            print("✅ Anonymous data queries work correctly")469        else:470            print("⚠️  Database not available - skipping query test")471 472 473class TestMixedDataCompatibility:474    """Test that systems work with both anonymous and authenticated data"""475    476    async def test_mixed_data_analytics(self):477        """Test analytics functions with mixed anonymous and authenticated data"""478        # Create anonymous data479        anon_session = await create_session()480        await track_message(481            session_id=anon_session.session_id,482            prompt_length=50,483            response_length=100,484            response_time_ms=1000485        )486        487        # Create authenticated data488        auth_session = await create_session(user_id="test_user")489        await track_message(490            session_id=auth_session.session_id,491            prompt_length=60,492            response_length=120,493            response_time_ms=1200,494            user_id="test_user"495        )496        497        # Test that analytics work with mixed data498        stats = await get_basic_stats()499        500        assert isinstance(stats, dict)501        assert stats["total_sessions"] >= 2502        assert stats["total_messages"] >= 2503        504        print("✅ Analytics work with mixed anonymous and authenticated data")505    506    async def test_mixed_data_queries(self):507        """Test database queries with mixed data"""508        # Create mixed data509        anon_session = await create_session()510        auth_session = await create_session(user_id="mixed_test_user")511        512        await track_message(513            session_id=anon_session.session_id,514            prompt_length=50,515            response_length=100,516            response_time_ms=1000517        )518        519        await track_message(520            session_id=auth_session.session_id,521            prompt_length=60,522            response_length=120,523            response_time_ms=1200,524            user_id="mixed_test_user"525        )526        527        # Wait for data to be written528        await asyncio.sleep(1)529        530        # Test queries531        sessions_collection = await get_sessions_collection()532        messages_collection = await get_messages_collection()533        534        if sessions_collection and messages_collection:535            # Count anonymous vs authenticated536            anonymous_sessions = await sessions_collection.count_documents({"user_id": None})537            authenticated_sessions = await sessions_collection.count_documents({"user_id": {"$ne": None}})538            total_sessions = await sessions_collection.count_documents({})539            540            assert anonymous_sessions >= 1541            assert authenticated_sessions >= 1542            assert total_sessions == anonymous_sessions + authenticated_sessions543            544            print("✅ Mixed data queries work correctly")545        else:546            print("⚠️  Database not available - skipping mixed query test")547 548 549async def run_compatibility_tests():550    """Run all backward compatibility tests"""551    print("🔄 Running Backward Compatibility Tests")552    print("=" * 50)553    554    # Test anonymous user compatibility555    anon_test = TestAnonymousUserCompatibility()556    await anon_test.test_create_session_without_user_id()557    await anon_test.test_create_session_with_none_user_id()558    await anon_test.test_track_message_without_user_id()559    await anon_test.test_track_message_with_none_user_id()560    await anon_test.test_track_search_without_user_id()561    await anon_test.test_track_search_with_none_user_id()562    print("✅ Anonymous user compatibility tests passed")563    564    # Test anonymous chat requests565    chat_test = TestAnonymousChatRequests()566    await chat_test.test_chat_request_without_user_id_field()567    await chat_test.test_chat_request_with_null_user_id()568    await chat_test.test_multiple_anonymous_requests()569    await chat_test.test_anonymous_session_continuation()570    print("✅ Anonymous chat request tests passed")571    572    # Test analytics function compatibility573    analytics_test = TestAnalyticsFunctionCompatibility()574    await analytics_test.test_basic_stats_with_anonymous_data()575    await analytics_test.test_hourly_stats_with_anonymous_data()576    await analytics_test.test_session_stats_with_anonymous_data()577    print("✅ Analytics function compatibility tests passed")578    579    # Test database compatibility580    db_test = TestDatabaseCompatibility()581    await db_test.test_anonymous_data_storage()582    await db_test.test_anonymous_data_queries()583    print("✅ Database compatibility tests passed")584    585    # Test mixed data compatibility586    mixed_test = TestMixedDataCompatibility()587    await mixed_test.test_mixed_data_analytics()588    await mixed_test.test_mixed_data_queries()589    print("✅ Mixed data compatibility tests passed")590    591    print("\n🎉 ALL BACKWARD COMPATIBILITY TESTS PASSED!")592    print("Existing anonymous user workflows continue to work as before.")593 594 595if __name__ == "__main__":596    asyncio.run(run_compatibility_tests())