O2Sound_ver2_final/backend/tests/test_integration_scenarios.py

206 lines
8.5 KiB
Python

# 통합 테스트 시나리오
import pytest
from fastapi.testclient import TestClient
from unittest.mock import MagicMock, AsyncMock, patch
from tests.utils import TestUtils
from app.dependencies import get_auth_service, get_user_service, get_video_service
class TestIntegrationScenarios:
"""엔드투엔드 통합 테스트 시나리오"""
def test_complete_user_journey(self, client, mock_auth_service, mock_user_service, mock_video_service):
"""사용자의 전체 여정 테스트: 회원가입 → 로그인 → 프로필 → 아이템 → 비디오"""
utils = TestUtils()
# 1. 회원가입
client.app.dependency_overrides[get_auth_service] = lambda: mock_auth_service
mock_auth_service.join.return_value = utils.create_test_user()
response = client.post("/api/v1/auth/join", json={
"email": "newuser@example.com",
"password": "NewUser1234!",
"password_confirm": "NewUser1234!",
"name": "New User"
})
user_data = utils.assert_response_success(response)
user_id = user_data["id"]
# 2. 로그인
mock_auth_service.login.return_value = {
"access_token": utils.create_test_token(user_id),
"token_type": "bearer",
"user_id": user_id
}
response = client.post("/api/v1/auth/login", json={
"email": "newuser@example.com",
"password": "NewUser1234!"
})
login_data = utils.assert_response_success(response)
token = login_data["access_token"]
# 3. 인증 헤더 설정
client.headers = {"Authorization": f"Bearer {token}"}
# 4. 프로필 조회
client.app.dependency_overrides[get_user_service] = lambda: mock_user_service
mock_user_service.get_user_profile.return_value = {
"user_id": user_id,
"email": "newuser@example.com",
"name": "New User",
"bio": None
}
response = client.post("/api/v1/user/profile", json={"user_id": user_id})
profile_data = utils.assert_response_success(response)
# 5. 프로필 업데이트
mock_user_service.update_user_profile.return_value = {
"user_id": user_id,
"name": "Updated User",
"bio": "I love making videos!",
"updated": True
}
response = client.put("/api/v1/user/profile/update", json={
"user_id": user_id,
"name": "Updated User",
"bio": "I love making videos!"
})
utils.assert_response_success(response)
# 6. 아이템 생성 시뮬레이션 (서비스에서 처리)
mock_user_service.get_items.return_value = {
"items": [utils.create_test_item(1, user_id)],
"total": 1
}
response = client.post("/api/v1/user/items", json={
"user_id": user_id,
"page": 1,
"limit": 10
})
items_data = utils.assert_response_success(response)
assert items_data["total"] == 1
# 7. 비디오 생성 시뮬레이션
client.app.dependency_overrides[get_video_service] = lambda: mock_video_service
mock_video_service.get_all_by_user_id.return_value = {
"videos": [utils.create_test_video(1, user_id)],
"total": 1
}
response = client.post("/api/v1/user/videos", json={
"user_id": user_id,
"page": 1,
"limit": 10
})
videos_data = utils.assert_response_success(response)
assert videos_data["total"] == 1
def test_moviemaker_workflow_complete(self, client, mock_redis_manager):
"""MovieMaker 워크플로우 전체 과정 테스트"""
utils = TestUtils()
# 1. 워크플로우 시작
with patch('app.presentation.api.v1.moviemakers.RedisManager', return_value=mock_redis_manager):
with patch('app.presentation.api.v1.moviemakers.Process') as mock_process_class:
mock_process = MagicMock()
mock_process.init_task_status = AsyncMock(return_value=None)
mock_process_class.return_value = mock_process
# Celery tasks mock
with patch('app.workers.tasks.task1_crawl.s'), \
patch('app.workers.tasks.task2_generate_lyrics.s'), \
patch('app.workers.tasks.task3_generate_music.s'), \
patch('app.workers.tasks.task1_crawl_images.s'), \
patch('app.workers.tasks.task4_generate_video.s'), \
patch('app.workers.tasks.task5_merge_results.s'):
response = client.post("/api/v1/moviemaker/start-workflow", json={
"url": "https://example.com/video"
})
workflow_data = utils.assert_response_success(response)
task_id = workflow_data["task_id"]
# 2. 진행상황 확인 - 초기 상태
mock_process.get_task_status = AsyncMock(return_value={
"metadata": True,
"lyrics": False,
"songs": False,
"images": False,
"movies": False,
"combined": False
})
response = client.post("/api/v1/moviemaker/progress", json={
"task_id": task_id
})
progress_data = response.json()
assert progress_data["progress"]["metadata"] == True
assert progress_data["progress"]["lyrics"] == False
# 3. 진행상황 확인 - 중간 상태
mock_process.get_task_status = AsyncMock(return_value={
"metadata": True,
"lyrics": True,
"songs": True,
"images": True,
"movies": False,
"combined": False
})
response = client.post("/api/v1/moviemaker/progress", json={
"task_id": task_id
})
progress_data = response.json()
assert progress_data["progress"]["songs"] == True
assert progress_data["progress"]["movies"] == False
# 4. 진행상황 확인 - 완료 상태
mock_process.get_task_status = AsyncMock(return_value={
"metadata": True,
"lyrics": True,
"songs": True,
"images": True,
"movies": True,
"combined": True
})
response = client.post("/api/v1/moviemaker/progress", json={
"task_id": task_id
})
progress_data = response.json()
assert all(progress_data["progress"].values()) == True
def test_google_oauth_flow(self, client, mock_google_service):
"""Google OAuth 전체 플로우 테스트"""
utils = TestUtils()
# 1. Google 로그인 URL 요청
client.app.dependency_overrides[get_google_service] = lambda: mock_google_service
mock_google_service.get_login_url.return_value = {
"url": "https://accounts.google.com/oauth2/v2/auth?client_id=test"
}
response = client.get("/api/v1/social/google/login?return_url=/dashboard")
assert response.status_code == 200
# 2. Google OAuth 콜백 처리
mock_result = MagicMock()
mock_result.temp_token_id = "temp_google_token_123"
mock_result.return_url = "/dashboard"
mock_google_service.handle_callback.return_value = mock_result
response = client.get("/api/v1/social/google/callback?code=google_auth_code&state=state_data")
assert response.status_code == 307 # Redirect
assert "temp_google_token_123" in response.headers["location"]
# 3. 임시 토큰으로 정보 조회
google_data = utils.create_google_oauth_data()
mock_google_service.get_token_by_temp_id.return_value = google_data
response = client.get("/api/v1/social/google/token/temp_google_token_123")
token_data = utils.assert_response_success(response)
assert token_data["user_info"]["email"] == "test@gmail.com"