import pytest from unittest.mock import AsyncMock, MagicMock, patch from fastapi import Request from app.dependencies import get_google_service class TestSocialAPI: """소셜 로그인 관련 API 테스트""" def test_google_login_without_return_url(self, client, mock_google_service): """return_url 없이 Google 로그인 시작 테스트""" # Mock 설정 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&redirect_uri=test" } # 테스트 실행 response = client.get("/api/v1/social/google/login") # 검증 assert response.status_code == 200 assert mock_google_service.get_login_url.called # return_url이 None으로 호출되었는지 확인 assert mock_google_service.get_login_url.call_args[0][0] is None def test_google_login_with_return_url(self, client, mock_google_service): """return_url과 함께 Google 로그인 시작 테스트""" # Mock 설정 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&redirect_uri=test&state=encoded_return_url" } # 테스트 실행 return_url = "http://localhost:3300/dashboard" response = client.get(f"/api/v1/social/google/login?return_url={return_url}") # 검증 assert response.status_code == 200 assert mock_google_service.get_login_url.called # return_url이 제대로 전달되었는지 확인 assert mock_google_service.get_login_url.call_args[0][0] == return_url def test_google_callback_success(self, client, mock_google_service): """Google OAuth 콜백 성공 테스트""" # Mock 설정 client.app.dependency_overrides[get_google_service] = lambda: mock_google_service # handle_callback이 반환할 mock 객체 생성 mock_result = MagicMock() mock_result.temp_token_id = "temp_token_123" mock_result.return_url = "http://localhost:3300/dashboard" mock_google_service.handle_callback.return_value = mock_result # 테스트 실행 response = client.get("/api/v1/social/google/callback?code=test_auth_code&state=test_state") # 검증 - 리다이렉트 응답 assert response.status_code == 307 # FastAPI의 RedirectResponse assert response.headers["location"] == "http://localhost:3300/dashboard?token=temp_token_123&auth_success=true" assert mock_google_service.handle_callback.called def test_google_callback_with_error(self, client): """Google OAuth 콜백 에러 파라미터 처리 테스트""" # 테스트 실행 response = client.get("/api/v1/social/google/callback?error=access_denied") # 검증 - 에러 페이지로 리다이렉트 assert response.status_code == 307 assert response.headers["location"] == "http://localhost:3300/auth/error?error=access_denied" def test_google_callback_exception(self, client, mock_google_service): """Google OAuth 콜백 중 예외 발생 테스트""" # Mock 설정 client.app.dependency_overrides[get_google_service] = lambda: mock_google_service mock_google_service.handle_callback.side_effect = Exception("OAuth 처리 중 오류 발생") # 테스트 실행 response = client.get("/api/v1/social/google/callback?code=test_auth_code") # 검증 - 에러 페이지로 리다이렉트 assert response.status_code == 307 assert "auth/error" in response.headers["location"] assert "OAuth" in response.headers["location"] def test_google_callback_no_return_url(self, client, mock_google_service): """return_url 없이 Google OAuth 콜백 테스트""" # Mock 설정 client.app.dependency_overrides[get_google_service] = lambda: mock_google_service # handle_callback이 반환할 mock 객체 생성 (return_url이 None) mock_result = MagicMock() mock_result.temp_token_id = "temp_token_456" mock_result.return_url = None mock_google_service.handle_callback.return_value = mock_result # 테스트 실행 response = client.get("/api/v1/social/google/callback?code=test_auth_code") # 검증 - 기본 성공 페이지로 리다이렉트 assert response.status_code == 307 assert response.headers["location"] == "http://localhost:3300/auth/success?token=temp_token_456&auth_success=true" def test_get_google_token_info_success(self, client, mock_google_service): """Google 토큰 정보 조회 성공 테스트""" # Mock 설정 client.app.dependency_overrides[get_google_service] = lambda: mock_google_service mock_google_service.get_token_by_temp_id.return_value = { "access_token": "google_access_token_123", "refresh_token": "google_refresh_token_123", "expires_in": 3600, "token_type": "Bearer", "user_info": { "id": "google_user_123", "email": "test@gmail.com", "name": "Test User", "picture": "https://example.com/picture.jpg" } } # 테스트 실행 response = client.get("/api/v1/social/google/token/temp_token_123") # 검증 assert response.status_code == 200 data = response.json() assert data["access_token"] == "google_access_token_123" assert data["user_info"]["email"] == "test@gmail.com" assert mock_google_service.get_token_by_temp_id.called assert mock_google_service.get_token_by_temp_id.call_args[0][0] == "temp_token_123" def test_get_google_token_info_not_found(self, client, mock_google_service): """존재하지 않는 임시 토큰으로 조회 테스트""" # Mock 설정 client.app.dependency_overrides[get_google_service] = lambda: mock_google_service mock_google_service.get_token_by_temp_id.side_effect = ValueError("임시 토큰을 찾을 수 없습니다") # 테스트 실행 response = client.get("/api/v1/social/google/token/invalid_token") # 검증 assert response.status_code == 404 # 또는 서비스 구현에 따라 400 assert mock_google_service.get_token_by_temp_id.called def test_get_google_token_info_expired(self, client, mock_google_service): """만료된 임시 토큰으로 조회 테스트""" # Mock 설정 client.app.dependency_overrides[get_google_service] = lambda: mock_google_service mock_google_service.get_token_by_temp_id.side_effect = ValueError("임시 토큰이 만료되었습니다") # 테스트 실행 response = client.get("/api/v1/social/google/token/expired_token") # 검증 assert response.status_code == 404 # 또는 서비스 구현에 따라 400