# app/modules/loyalty/tests/integration/test_merchant_pages.py """ Integration tests for merchant loyalty page routes (HTML rendering). Tests the merchant page routes at: /merchants/loyalty/program /merchants/loyalty/program/edit /merchants/loyalty/analytics Authentication: Uses dependency overrides for cookie-based merchant auth. """ import uuid import pytest from app.api.deps import ( get_current_merchant_from_cookie_or_header, get_merchant_for_current_user_page, ) from app.modules.tenancy.models import Merchant, User from app.modules.tenancy.schemas.auth import UserContext from main import app BASE = "/merchants/loyalty" # ============================================================================ # Fixtures # ============================================================================ @pytest.fixture def merchant_page_setup(db): """Create a merchant owner for page tests.""" from middleware.auth import AuthManager auth = AuthManager() uid = uuid.uuid4().hex[:8] owner = User( email=f"merchpageowner_{uid}@test.com", username=f"merchpageowner_{uid}", hashed_password=auth.hash_password("testpass123"), role="merchant_owner", is_active=True, is_email_verified=True, ) db.add(owner) db.commit() db.refresh(owner) merchant = Merchant( name=f"Page Test 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 merchant_page_headers(merchant_page_setup): """Override auth dependencies for merchant page routes.""" owner = merchant_page_setup["owner"] merchant = merchant_page_setup["merchant"] user_context = UserContext( id=owner.id, email=owner.email, username=owner.username, role="merchant_owner", is_active=True, ) app.dependency_overrides[get_current_merchant_from_cookie_or_header] = lambda: user_context app.dependency_overrides[get_merchant_for_current_user_page] = lambda: merchant yield {"Cookie": "merchant_token=fake-token"} app.dependency_overrides.pop(get_current_merchant_from_cookie_or_header, None) app.dependency_overrides.pop(get_merchant_for_current_user_page, None) # ============================================================================ # Program View Page # ============================================================================ @pytest.mark.integration @pytest.mark.loyalty class TestMerchantProgramPage: """Tests for GET /merchants/loyalty/program.""" def test_program_page_renders(self, client, merchant_page_headers): """Program page returns HTML.""" response = client.get( f"{BASE}/program", headers=merchant_page_headers, ) assert response.status_code == 200 assert "text/html" in response.headers["content-type"] def test_program_page_requires_auth(self, client): """Unauthenticated request is rejected.""" response = client.get(f"{BASE}/program") assert response.status_code in [401, 403] # ============================================================================ # Program Edit Page # ============================================================================ @pytest.mark.integration @pytest.mark.loyalty class TestMerchantProgramEditPage: """Tests for GET /merchants/loyalty/program/edit.""" def test_program_edit_page_renders(self, client, merchant_page_headers): """Program edit page returns HTML.""" response = client.get( f"{BASE}/program/edit", headers=merchant_page_headers, ) assert response.status_code == 200 assert "text/html" in response.headers["content-type"] def test_program_edit_page_requires_auth(self, client): """Unauthenticated request is rejected.""" response = client.get(f"{BASE}/program/edit") assert response.status_code in [401, 403] # ============================================================================ # Analytics Page # ============================================================================ @pytest.mark.integration @pytest.mark.loyalty class TestMerchantAnalyticsPage: """Tests for GET /merchants/loyalty/analytics.""" def test_analytics_page_renders(self, client, merchant_page_headers): """Analytics page returns HTML.""" response = client.get( f"{BASE}/analytics", headers=merchant_page_headers, ) assert response.status_code == 200 assert "text/html" in response.headers["content-type"] def test_analytics_page_requires_auth(self, client): """Unauthenticated request is rejected.""" response = client.get(f"{BASE}/analytics") assert response.status_code in [401, 403]