""" Test: find_or_create_provider_by_name() refactored signature (P0 Architecture Cleanup) ======================================================================================= Ellenőrzi, hogy a find_or_create_provider_by_name() függvény az új (provider, created) tuple-t adja vissza a gamification logika nélkül. P0 ARCHITECTURE CLEANUP (2026-07-01): ====================================== - A gamification/XP logika ELTÁVOLÍTVA a service rétegből. - A visszatérési érték immár (provider, created) tuple. - created=True: új provider lett létrehozva - created=False: meglévő provider lett lekérve - A pg_trgm similarity threshold 0.3 -> 0.6 (hamis pozitívok csökkentése) Logika: 1. Ha a provider nem létezik -> új provider létrehozva, created=True 2. Ha a provider már létezik -> meglévő visszaadva, created=False Használat: docker compose exec sf_api python3 /app/backend/tests/active/test_use_unverified_provider.py """ import asyncio import logging import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent / "backend")) from sqlalchemy import select, delete from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker from app.core.config import settings from app.models.identity.social import ServiceProvider, ModerationStatus, SourceType from app.services.provider_service import find_or_create_provider_by_name logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") logger = logging.getLogger("Test-USE_UNVERIFIED_PROVIDER") TEST_USER_ID = 1 # Provider creator (superadmin@profibot.hu) TEST_OTHER_USER_ID = 2 # Other user using the provider (admin@profibot.hu) TEST_PROVIDER_NAME = "Test Unverified Provider Card362" async def cleanup_test_data(db: AsyncSession): """Clean up any leftover test data.""" await db.execute( delete(ServiceProvider).where(ServiceProvider.name == TEST_PROVIDER_NAME) ) await db.commit() async def test_find_or_create_provider(): """ Test scenario: 1. User A (TEST_USER_ID) creates a provider via find_or_create_provider_by_name() -> Should return (provider, created=True) - new provider 2. User A uses the same provider again -> Should return (provider, created=False) - existing provider 3. User B (TEST_OTHER_USER_ID) uses the same provider -> Should return (provider, created=False) - existing provider """ engine = create_async_engine(settings.DATABASE_URL, echo=False) async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) async with async_session() as db: try: # Clean up first await cleanup_test_data(db) # ========================================================= # STEP 1: User A creates a new provider (created=True) # ========================================================= logger.info("=" * 60) logger.info("STEP 1: User A creates a new provider") logger.info("=" * 60) provider, created = await find_or_create_provider_by_name( db=db, name=TEST_PROVIDER_NAME, added_by_user_id=TEST_USER_ID, ) assert provider is not None, "Provider should be created" assert created is True, ( f"Expected created=True for new provider, got {created}" ) assert provider.status == ModerationStatus.pending, ( f"Expected pending status, got {provider.status}" ) assert provider.added_by_user_id == TEST_USER_ID, ( f"Expected added_by_user_id={TEST_USER_ID}, got {provider.added_by_user_id}" ) logger.info(f"✅ STEP 1 PASS: created={created}, provider_id={provider.id}") # ========================================================= # STEP 2: User A uses the same provider again (created=False) # ========================================================= logger.info("=" * 60) logger.info("STEP 2: User A uses the same provider again") logger.info("=" * 60) # Re-fetch to get clean state await db.refresh(provider) provider2, created2 = await find_or_create_provider_by_name( db=db, name=TEST_PROVIDER_NAME, added_by_user_id=TEST_USER_ID, ) assert provider2.id == provider.id, "Should be the same provider" assert created2 is False, ( f"Expected created=False for existing provider, got {created2}" ) logger.info(f"✅ STEP 2 PASS: created={created2}") # ========================================================= # STEP 3: User B uses the same provider (created=False) # ========================================================= logger.info("=" * 60) logger.info("STEP 3: User B uses the same provider") logger.info("=" * 60) provider3, created3 = await find_or_create_provider_by_name( db=db, name=TEST_PROVIDER_NAME, added_by_user_id=TEST_OTHER_USER_ID, ) assert provider3.id == provider.id, "Should be the same provider" assert created3 is False, ( f"Expected created=False for existing provider, got {created3}" ) logger.info(f"✅ STEP 3 PASS: created={created3}") # ========================================================= # SUMMARY # ========================================================= logger.info("=" * 60) logger.info("🎉 ALL TESTS PASSED!") logger.info(f" - New provider created: ✅ created=True") logger.info(f" - Same user re-fetch: ✅ created=False") logger.info(f" - Different user re-fetch: ✅ created=False") logger.info("=" * 60) # Clean up await cleanup_test_data(db) except AssertionError as e: logger.error(f"❌ TEST FAILED: {e}") await db.rollback() await cleanup_test_data(db) sys.exit(1) except Exception as e: logger.error(f"❌ UNEXPECTED ERROR: {e}", exc_info=True) await db.rollback() await cleanup_test_data(db) sys.exit(1) finally: await engine.dispose() if __name__ == "__main__": asyncio.run(test_find_or_create_provider())