Files
service-finder/tests/active/test_use_unverified_provider.py
2026-07-01 19:49:58 +00:00

165 lines
6.6 KiB
Python

"""
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())