""" Performance Check Integration Tests 통합 테스트 시나리오: 1. 배너 차량 + 비로그인 → 성능점검표 미리보기만 가능 2. 배너 차량 + 로그인 (미결제) → 성능점검표 미리보기만 가능 3. 배너 차량 + 로그인 (0.1 CC 결제) → 성능점검표 전체 접근 가능 4. 일반 차량 + 비로그인 → 성능점검표 미리보기만 가능 5. 일반 차량 + 로그인 (1 CC 결제) → 성능점검표 전체 접근 가능 """ import pytest from fastapi.testclient import TestClient from unittest.mock import MagicMock, patch from sqlalchemy.orm import Session # 테스트 시나리오 정의 TEST_SCENARIOS = [ # (시나리오 이름, 배너여부, 로그인여부, 결제타입, 예상결과) ("banner_anonymous", True, False, None, {"has_access": False, "can_view_images": True}), ("banner_logged_in_no_payment", True, True, None, {"has_access": False, "can_view_images": True}), ("banner_logged_in_perf_payment", True, True, "performance", {"has_access": True, "can_view_images": True}), ("banner_logged_in_full_payment", True, True, "full", {"has_access": True, "can_view_images": True}), ("normal_anonymous", False, False, None, {"has_access": False, "can_view_images": False}), ("normal_logged_in_no_payment", False, True, None, {"has_access": False, "can_view_images": False}), ("normal_logged_in_perf_payment", False, True, "performance", {"has_access": True, "can_view_images": False}), ("normal_logged_in_full_payment", False, True, "full", {"has_access": True, "can_view_images": True}), ] class TestPerformanceCheckIntegration: """성능점검표 통합 테스트""" @pytest.mark.parametrize( "scenario_name,is_banner,is_logged_in,payment_type,expected", TEST_SCENARIOS ) def test_performance_check_access_scenarios( self, scenario_name: str, is_banner: bool, is_logged_in: bool, payment_type: str, expected: dict ): """ 모든 시나리오에 대한 성능점검표 접근 테스트 이 테스트는 실제 API를 호출하지 않고 로직만 검증합니다. 실제 API 테스트는 별도의 e2e 테스트에서 수행합니다. """ # Given user = self._create_user(is_logged_in) has_perf_view = payment_type == "performance" has_car_view = payment_type == "full" # When result = self._simulate_performance_check_access( user=user, is_banner_car=is_banner, has_perf_view=has_perf_view, has_car_view=has_car_view ) # Then assert result["has_access"] == expected["has_access"], \ f"Scenario '{scenario_name}' failed: expected has_access={expected['has_access']}, got {result['has_access']}" def _create_user(self, is_logged_in: bool): """테스트용 사용자 생성""" if not is_logged_in: return None user = MagicMock() user.is_admin = False user.id = 1 return user def _simulate_performance_check_access( self, user, is_banner_car: bool, has_perf_view: bool, has_car_view: bool ) -> dict: """ 성능점검표 접근 시뮬레이션 실제 로직: backend/app/api/carmodoo.py - get_car_performance_check() """ has_access = False # 배너 차량 여부는 성능점검표 접근에 영향 없음! # (이것이 핵심 비즈니스 로직) if user: if hasattr(user, 'is_admin') and user.is_admin: has_access = True else: has_access = has_perf_view or has_car_view return { "has_access": has_access, "preview": { "check_number": "TEST123", "check_date": "2024-01-01", "mileage": 50000 } if not has_access else None, "data": {"full": "data"} if has_access else None } class TestBannerCarIntegration: """배너 차량 통합 테스트""" def test_banner_car_free_features(self): """배너 차량의 무료 기능 확인""" is_banner_car = True # 배너 차량 무료 기능 free_features = { "all_images": True, "dealer_contact": True, "basic_info": True, } # 배너 차량 유료 기능 paid_features = { "performance_check": True, # 0.1 CC 필요 } # 비로그인 사용자도 무료 기능 접근 가능 user = None for feature, is_free in free_features.items(): can_access = is_banner_car and is_free assert can_access is True, f"Banner car should have free access to {feature}" # 성능점검표는 결제 필요 can_access_perf_check = False # 결제하지 않으면 불가 assert can_access_perf_check is False, "Performance check requires payment even for banner cars" def test_banner_vs_normal_car_comparison(self): """배너 차량 vs 일반 차량 기능 비교""" user_logged_in_no_payment = MagicMock() user_logged_in_no_payment.is_admin = False # 배너 차량 banner_car_access = { "images": True, # 무료 "contact": True, # 무료 "performance_check": False, # 결제 필요 } # 일반 차량 normal_car_access = { "images": False, # 결제 필요 "contact": False, # 결제 필요 "performance_check": False, # 결제 필요 } # 배너 차량은 이미지/연락처만 무료 assert banner_car_access["images"] is True assert banner_car_access["contact"] is True assert banner_car_access["performance_check"] is False # 일반 차량은 모두 유료 assert normal_car_access["images"] is False assert normal_car_access["performance_check"] is False class TestCCPaymentIntegration: """CC 결제 통합 테스트""" def test_performance_check_costs_01_cc(self): """성능점검표 비용은 0.1 CC""" PERFORMANCE_CHECK_COST = 0.1 user_balance = 5.0 # 신규 가입 시 지급되는 CC # 결제 후 잔액 after_payment = user_balance - PERFORMANCE_CHECK_COST assert after_payment == 4.9 def test_full_car_view_costs_1_cc(self): """차량 전체 보기 비용은 1 CC""" FULL_CAR_VIEW_COST = 1.0 user_balance = 5.0 # 결제 후 잔액 after_payment = user_balance - FULL_CAR_VIEW_COST assert after_payment == 4.0 def test_full_car_view_includes_performance_check(self): """1 CC 결제 시 성능점검표 포함""" has_full_car_view = True has_separate_perf_view = False # 1 CC 결제하면 성능점검표 접근 가능 can_access_perf_check = has_full_car_view or has_separate_perf_view assert can_access_perf_check is True def test_insufficient_balance(self): """잔액 부족 시 결제 실패""" user_balance = 0.05 PERFORMANCE_CHECK_COST = 0.1 can_purchase = user_balance >= PERFORMANCE_CHECK_COST assert can_purchase is False # 테스트 매트릭스 문서화 ACCESS_MATRIX = """ +------------------+-------------+--------------------+------------------+ | 사용자 상태 | 배너 차량 | 일반 차량 | 성능점검표 | +------------------+-------------+--------------------+------------------+ | 비로그인 | 이미지 O | 이미지 X (블러) | X | | 로그인 (미결제) | 이미지 O | 이미지 X (블러) | X | | 로그인 (0.1CC) | 이미지 O | 이미지 X (블러) | O | | 로그인 (1CC) | 이미지 O | 이미지 O | O | | 관리자 | 이미지 O | 이미지 O | O | +------------------+-------------+--------------------+------------------+ * 배너 차량: 이미지와 연락처만 무료, 성능점검표는 0.1 CC 필요 * 1 CC 결제 시 성능점검표 포함 """