Files
orion/app/modules/loyalty/tests/conftest.py
Samir Boulahtit 4aa6f76e46
Some checks failed
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / ruff (push) Successful in 10s
refactor(arch): move auth schemas to tenancy module and add cross-module service methods
Move all auth schemas (UserContext, UserLogin, LoginResponse, etc.) from
legacy models/schema/auth.py to app/modules/tenancy/schemas/auth.py per
MOD-019. Update 84 import sites across 14 modules. Legacy file now
re-exports for backwards compatibility.

Add missing tenancy service methods for cross-module consumers:
- merchant_service.get_merchant_by_owner_id()
- merchant_service.get_merchant_count_for_owner()
- admin_service.get_user_by_id() (public, was private-only)
- platform_service.get_active_store_count()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:57:04 +01:00

277 lines
7.4 KiB
Python

# app/modules/loyalty/tests/conftest.py
"""
Module-specific fixtures for loyalty tests.
Core fixtures (db, client, etc.) are inherited from the root conftest.py.
"""
import uuid
from datetime import UTC, datetime
import pytest
from app.api.deps import get_current_merchant_api, get_merchant_for_current_user
from app.modules.loyalty.models import LoyaltyCard, LoyaltyProgram
from app.modules.loyalty.models.loyalty_program import LoyaltyType
from app.modules.tenancy.models import Merchant, Platform, Store, User
from app.modules.tenancy.models.store import StoreUser
from app.modules.tenancy.models.store_platform import StorePlatform
from app.modules.tenancy.schemas.auth import UserContext
from main import app
@pytest.fixture
def loyalty_platform(db):
"""Create a platform for loyalty store tests."""
platform = Platform(
code=f"loyalty_{uuid.uuid4().hex[:8]}",
name="Loyalty Test Platform",
is_active=True,
)
db.add(platform)
db.commit()
db.refresh(platform)
return platform
@pytest.fixture
def loyalty_store_setup(db, loyalty_platform):
"""
Full store setup for loyalty integration tests.
Creates: User -> Merchant -> Store -> StoreUser -> StorePlatform
+ LoyaltyProgram + LoyaltyCard (with customer)
Returns dict with all objects for easy access.
"""
from app.modules.customers.models.customer import Customer
from middleware.auth import AuthManager
auth = AuthManager()
uid = uuid.uuid4().hex[:8]
# Owner user
owner = User(
email=f"loyaltyowner_{uid}@test.com",
username=f"loyaltyowner_{uid}",
hashed_password=auth.hash_password("storepass123"),
role="merchant_owner",
is_active=True,
is_email_verified=True,
)
db.add(owner)
db.commit()
db.refresh(owner)
# Merchant
merchant = Merchant(
name=f"Loyalty Merchant {uid}",
owner_user_id=owner.id,
contact_email=owner.email,
is_active=True,
is_verified=True,
)
db.add(merchant)
db.commit()
db.refresh(merchant)
# Store
store = Store(
merchant_id=merchant.id,
store_code=f"LOYTEST_{uid.upper()}",
subdomain=f"loytest{uid}",
name=f"Loyalty Test Store {uid}",
is_active=True,
is_verified=True,
)
db.add(store)
db.commit()
db.refresh(store)
# StoreUser
store_user = StoreUser(
store_id=store.id,
user_id=owner.id,
is_active=True,
)
db.add(store_user)
db.commit()
# StorePlatform
sp = StorePlatform(
store_id=store.id,
platform_id=loyalty_platform.id,
)
db.add(sp)
db.commit()
# Customer
customer = Customer(
email=f"customer_{uid}@test.com",
first_name="Test",
last_name="Customer",
hashed_password="!test!unused", # noqa: SEC-001
customer_number=f"CUST-{uid.upper()}",
store_id=store.id,
is_active=True,
)
db.add(customer)
db.commit()
db.refresh(customer)
# Loyalty Program
program = LoyaltyProgram(
merchant_id=merchant.id,
loyalty_type=LoyaltyType.POINTS.value,
points_per_euro=10,
welcome_bonus_points=50,
minimum_redemption_points=100,
minimum_purchase_cents=0,
points_expiration_days=365,
cooldown_minutes=0,
max_daily_stamps=10,
require_staff_pin=False,
card_name="Test Rewards",
card_color="#4F46E5",
is_active=True,
points_rewards=[
{"id": "reward_1", "name": "€5 off", "points_required": 100, "is_active": True},
],
)
db.add(program)
db.commit()
db.refresh(program)
# Loyalty Card
card = LoyaltyCard(
merchant_id=merchant.id,
program_id=program.id,
customer_id=customer.id,
enrolled_at_store_id=store.id,
card_number=f"TESTCARD-{uid.upper()}",
points_balance=100,
total_points_earned=150,
points_redeemed=50,
is_active=True,
last_activity_at=datetime.now(UTC),
)
db.add(card)
db.commit()
db.refresh(card)
return {
"owner": owner,
"merchant": merchant,
"store": store,
"platform": loyalty_platform,
"customer": customer,
"program": program,
"card": card,
}
@pytest.fixture
def loyalty_merchant_setup(db, loyalty_platform):
"""
Merchant-only setup for loyalty integration tests (no program).
Creates: User -> Merchant (no program yet).
Use this for testing program creation via merchant API.
"""
from middleware.auth import AuthManager
auth = AuthManager()
uid = uuid.uuid4().hex[:8]
owner = User(
email=f"merchowner_{uid}@test.com",
username=f"merchowner_{uid}",
hashed_password=auth.hash_password("merchpass123"),
role="merchant_owner",
is_active=True,
is_email_verified=True,
)
db.add(owner)
db.commit()
db.refresh(owner)
merchant = Merchant(
name=f"Loyalty Merchant {uid}",
owner_user_id=owner.id,
contact_email=owner.email,
is_active=True,
is_verified=True,
)
db.add(merchant)
db.commit()
db.refresh(merchant)
return {
"owner": owner,
"merchant": merchant,
}
@pytest.fixture
def loyalty_merchant_headers(loyalty_store_setup):
"""
Override auth dependencies to return merchant/user for the merchant owner.
Uses the full loyalty_store_setup which includes a program.
"""
owner = loyalty_store_setup["owner"]
merchant = loyalty_store_setup["merchant"]
user_context = UserContext(
id=owner.id,
email=owner.email,
username=owner.username,
role="merchant_owner",
is_active=True,
)
app.dependency_overrides[get_merchant_for_current_user] = lambda: merchant
app.dependency_overrides[get_current_merchant_api] = lambda: user_context
yield {"Authorization": "Bearer fake-token"}
app.dependency_overrides.pop(get_merchant_for_current_user, None)
app.dependency_overrides.pop(get_current_merchant_api, None)
@pytest.fixture
def loyalty_merchant_headers_no_program(loyalty_merchant_setup):
"""
Override auth dependencies for a merchant that has no program yet.
"""
owner = loyalty_merchant_setup["owner"]
merchant = loyalty_merchant_setup["merchant"]
user_context = UserContext(
id=owner.id,
email=owner.email,
username=owner.username,
role="merchant_owner",
is_active=True,
)
app.dependency_overrides[get_merchant_for_current_user] = lambda: merchant
app.dependency_overrides[get_current_merchant_api] = lambda: user_context
yield {"Authorization": "Bearer fake-token"}
app.dependency_overrides.pop(get_merchant_for_current_user, None)
app.dependency_overrides.pop(get_current_merchant_api, None)
@pytest.fixture
def loyalty_store_headers(client, loyalty_store_setup):
"""
Get real JWT auth headers by logging in via store auth endpoint.
"""
owner = loyalty_store_setup["owner"]
response = client.post(
"/api/v1/store/auth/login",
json={
"email_or_username": owner.username,
"password": "storepass123",
},
)
assert response.status_code == 200, f"Store login failed: {response.text}"
token = response.json()["access_token"]
return {"Authorization": f"Bearer {token}"}