Refactor: Split Supabase tests

Splits the Supabase tests into smaller modules for better readability and maintainability.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 12:35:59 +00:00
parent 785e69a42c
commit f9aec98a45
6 changed files with 344 additions and 239 deletions

View File

@@ -1,239 +0,0 @@
import { supabase } from './client';
import { getSupabaseUrl, getSupabaseKey, getOriginalSupabaseUrl, isCorsProxyEnabled, getProxyType } from './config';
// 테스트용 직접 로그인 함수 (디버깅 전용)
export const testSupabaseLogin = async (email: string, password: string) => {
try {
console.log('테스트 로그인 시도:', email);
const { data, error } = await supabase.auth.signInWithPassword({
email,
password
});
if (error) {
console.error('테스트 로그인 오류:', error);
return { success: false, error };
}
console.log('테스트 로그인 성공:', data);
return { success: true, data };
} catch (err) {
console.error('테스트 로그인 중 예외 발생:', err);
return { success: false, error: err };
}
};
// API 테스트 도우미 함수
export const testSupabaseConnection = async () => {
const originalUrl = getOriginalSupabaseUrl();
const proxyUrl = getSupabaseUrl();
const usingProxy = isCorsProxyEnabled();
const proxyType = getProxyType();
const supabaseKey = getSupabaseKey();
const results = {
url: originalUrl, // 원본 URL
proxyUrl: proxyUrl, // 프록시 적용된 URL
usingProxy: usingProxy, // 프록시 사용 여부
proxyType: proxyType, // 프록시 유형
client: !!supabase,
restApi: false,
auth: false,
database: false,
errors: [] as string[],
debugInfo: {
originalUrl,
proxyUrl,
usingProxy,
proxyType,
keyLength: supabaseKey.length,
browserInfo: navigator.userAgent,
timestamp: new Date().toISOString(),
backupProxySuccess: false, // 백업 프록시 성공 여부
lastErrorDetails: '' // 마지막 오류 상세 정보
}
};
console.log('연결 테스트 시작 - 설정 정보:', {
originalUrl,
proxyUrl,
usingProxy,
proxyType
});
try {
// 1. REST API 접근 테스트 - 다양한 URL 형식 시도
try {
console.log('REST API 테스트 시작...');
// 여러 형태의 REST API 엔드포인트 URL 구성 시도
let apiUrl = '';
let response = null;
let errorBody = '';
// 1번째 시도: 기본 URL + /rest/v1/
apiUrl = proxyUrl.endsWith('/')
? `${proxyUrl}rest/v1/`
: `${proxyUrl}/rest/v1/`;
console.log('REST API 테스트 URL (시도 1):', apiUrl);
try {
response = await fetch(apiUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseKey,
},
});
if (response.ok) {
results.restApi = true;
console.log('REST API 테스트 성공 (시도 1)');
} else {
errorBody = await response.text();
console.warn(`REST API 테스트 실패 (시도 1) - 상태: ${response.status}, 오류: ${errorBody}`);
results.debugInfo.lastErrorDetails = `상태 코드: ${response.status}, 응답: ${errorBody}`;
// 2번째 시도: 다른 프록시 서비스 URL 직접 구성
if (usingProxy) {
// 서로 다른 프록시 서비스 시도
const proxyOptions = [
{ name: 'thingproxy', url: `https://thingproxy.freeboard.io/fetch/${originalUrl}/rest/v1/` },
{ name: 'allorigins', url: `https://api.allorigins.win/raw?url=${encodeURIComponent(`${originalUrl}/rest/v1/`)}` },
{ name: 'cors-anywhere', url: `https://cors-anywhere.herokuapp.com/${originalUrl}/rest/v1/` }
];
// 현재 사용 중인 프록시와 다른 프록시만 시도
const alternateProxies = proxyOptions.filter(p => p.name !== proxyType);
for (const proxy of alternateProxies) {
console.log(`REST API 테스트 URL (시도 2 - ${proxy.name}):`, proxy.url);
try {
response = await fetch(proxy.url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseKey,
},
});
if (response.ok) {
results.restApi = true;
results.debugInfo.backupProxySuccess = true;
console.log(`REST API 테스트 성공 (시도 2 - ${proxy.name})`);
results.errors.push(`REST API 성공: ${proxy.name} 프록시 사용 시 정상 작동합니다. 설정에서 이 프록시를 선택해보세요.`);
break;
} else {
const error2 = await response.text();
console.warn(`REST API 테스트 실패 (시도 2 - ${proxy.name}) - 상태: ${response.status}, 오류: ${error2}`);
}
} catch (innerErr: any) {
console.error(`REST API 테스트 시도 2 (${proxy.name}) 예외:`, innerErr);
}
}
if (!results.restApi) {
results.errors.push(`REST API 오류(${response.status}): ${errorBody || '응답 없음'} - 다른 프록시 옵션도 모두 실패했습니다.`);
}
} else {
results.errors.push(`REST API 오류(${response.status}): ${errorBody || '응답 없음'} - CORS 프록시 활성화를 시도해보세요.`);
}
}
} catch (outerErr: any) {
console.error('REST API 테스트 시도 1 예외:', outerErr);
results.errors.push(`REST API 예외 (시도 1): ${outerErr.message || '알 수 없는 오류'}`);
results.debugInfo.lastErrorDetails = outerErr.message || '알 수 없는 오류';
// 백업 시도
if (usingProxy) {
try {
// 백업 프록시 시도: 다른 CORS 프록시 서비스 사용
const backupProxyUrl = `https://api.allorigins.win/raw?url=${encodeURIComponent(`${originalUrl}/rest/v1/`)}`;
console.log('REST API 테스트 URL (백업 프록시):', backupProxyUrl);
response = await fetch(backupProxyUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseKey,
},
});
if (response.ok) {
results.restApi = true;
console.log('REST API 테스트 성공 (백업 프록시)');
results.debugInfo.backupProxySuccess = true;
results.errors.push('REST API 성공: allorigins 프록시 사용 시 정상 작동합니다. 설정에서 이 프록시를 선택해보세요.');
} else {
const backupError = await response.text();
console.warn(`REST API 테스트 실패 (백업 프록시) - 상태: ${response.status}, 오류: ${backupError}`);
}
} catch (backupErr: any) {
console.error('REST API 백업 프록시 예외:', backupErr);
}
}
}
} catch (err: any) {
results.errors.push(`REST API 예외: ${err.message || '알 수 없는 오류'}`);
console.error('REST API 테스트 중 예외:', err);
}
// 2. 인증 서비스 테스트
try {
console.log('인증 서비스 테스트 시작...');
const { data, error } = await supabase.auth.getSession();
results.auth = !error;
if (error) {
results.errors.push(`인증 오류: ${error.message}`);
console.error('인증 테스트 실패:', error);
} else {
console.log('인증 테스트 성공');
}
} catch (err: any) {
results.errors.push(`인증 예외: ${err.message || '알 수 없는 오류'}`);
console.error('인증 테스트 중 예외:', err);
}
// 3. 데이터베이스 연결 테스트
try {
console.log('데이터베이스 연결 테스트 시작...');
const { data, error } = await supabase
.from('transactions')
.select('*')
.limit(1);
results.database = !error;
if (error) {
let errorMsg = error.message;
// 익명 인증 오류 처리
if (errorMsg.includes('Auth session missing') || errorMsg.includes('JWT')) {
errorMsg += ' - 로그인이 필요하거나 권한 설정을 확인해주세요.';
}
results.errors.push(`데이터베이스 오류: ${errorMsg}`);
console.error('데이터베이스 테스트 실패:', error);
} else {
console.log('데이터베이스 테스트 성공', data);
}
} catch (err: any) {
results.errors.push(`데이터베이스 예외: ${err.message || '알 수 없는 오류'}`);
console.error('데이터베이스 테스트 중 예외:', err);
}
// 오류가 없는 경우 메시지 추가
if (results.errors.length === 0) {
results.errors.push('모든 테스트 통과! 연결 상태가 정상입니다.');
}
} catch (err: any) {
results.errors.push(`테스트 실행 예외: ${err.message || '알 수 없는 오류'}`);
console.error('전체 테스트 실행 중 예외:', err);
}
console.log('Supabase 연결 테스트 결과:', results);
return results;
};

View File

@@ -0,0 +1,127 @@
import { getOriginalSupabaseUrl, getSupabaseKey } from '../config';
// REST API 테스트
export const testRestApi = async (proxyUrl: string, originalUrl: string, supabaseKey: string, proxyType: string): Promise<{
success: boolean;
error?: any;
backupProxySuccess?: boolean;
lastErrorDetails?: string;
recommendedProxy?: string;
}> => {
console.log('REST API 테스트 시작...');
let apiUrl = '';
let response = null;
let errorBody = '';
let backupProxySuccess = false;
let lastErrorDetails = '';
let recommendedProxy = '';
// 1번째 시도: 기본 URL + /rest/v1/
apiUrl = proxyUrl.endsWith('/')
? `${proxyUrl}rest/v1/`
: `${proxyUrl}/rest/v1/`;
console.log('REST API 테스트 URL (시도 1):', apiUrl);
try {
response = await fetch(apiUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseKey,
},
});
if (response.ok) {
console.log('REST API 테스트 성공 (시도 1)');
return { success: true };
} else {
errorBody = await response.text();
console.warn(`REST API 테스트 실패 (시도 1) - 상태: ${response.status}, 오류: ${errorBody}`);
lastErrorDetails = `상태 코드: ${response.status}, 응답: ${errorBody}`;
// 2번째 시도: 다른 프록시 서비스 URL 직접 구성
const proxyOptions = [
{ name: 'thingproxy', url: `https://thingproxy.freeboard.io/fetch/${originalUrl}/rest/v1/` },
{ name: 'allorigins', url: `https://api.allorigins.win/raw?url=${encodeURIComponent(`${originalUrl}/rest/v1/`)}` },
{ name: 'cors-anywhere', url: `https://cors-anywhere.herokuapp.com/${originalUrl}/rest/v1/` }
];
// 현재 사용 중인 프록시와 다른 프록시만 시도
const alternateProxies = proxyOptions.filter(p => p.name !== proxyType);
for (const proxy of alternateProxies) {
console.log(`REST API 테스트 URL (시도 2 - ${proxy.name}):`, proxy.url);
try {
response = await fetch(proxy.url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseKey,
},
});
if (response.ok) {
backupProxySuccess = true;
recommendedProxy = proxy.name;
console.log(`REST API 테스트 성공 (시도 2 - ${proxy.name})`);
return {
success: false,
backupProxySuccess: true,
recommendedProxy: proxy.name,
lastErrorDetails
};
} else {
const error2 = await response.text();
console.warn(`REST API 테스트 실패 (시도 2 - ${proxy.name}) - 상태: ${response.status}, 오류: ${error2}`);
}
} catch (innerErr: any) {
console.error(`REST API 테스트 시도 2 (${proxy.name}) 예외:`, innerErr);
}
}
}
} catch (outerErr: any) {
console.error('REST API 테스트 시도 1 예외:', outerErr);
lastErrorDetails = outerErr.message || '알 수 없는 오류';
// 백업 시도
try {
// 백업 프록시 시도: 다른 CORS 프록시 서비스 사용
const backupProxyUrl = `https://api.allorigins.win/raw?url=${encodeURIComponent(`${originalUrl}/rest/v1/`)}`;
console.log('REST API 테스트 URL (백업 프록시):', backupProxyUrl);
response = await fetch(backupProxyUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apikey': supabaseKey,
},
});
if (response.ok) {
console.log('REST API 테스트 성공 (백업 프록시)');
return {
success: false,
backupProxySuccess: true,
recommendedProxy: 'allorigins',
lastErrorDetails
};
} else {
const backupError = await response.text();
console.warn(`REST API 테스트 실패 (백업 프록시) - 상태: ${response.status}, 오류: ${backupError}`);
}
} catch (backupErr: any) {
console.error('REST API 백업 프록시 예외:', backupErr);
}
}
return {
success: false,
backupProxySuccess,
recommendedProxy,
lastErrorDetails
};
};

View File

@@ -0,0 +1,45 @@
import { supabase } from '../client';
import { LoginTestResult } from './types';
// 테스트용 직접 로그인 함수 (디버깅 전용)
export const testSupabaseLogin = async (email: string, password: string): Promise<LoginTestResult> => {
try {
console.log('테스트 로그인 시도:', email);
const { data, error } = await supabase.auth.signInWithPassword({
email,
password
});
if (error) {
console.error('테스트 로그인 오류:', error);
return { success: false, error };
}
console.log('테스트 로그인 성공:', data);
return { success: true, data };
} catch (err) {
console.error('테스트 로그인 중 예외 발생:', err);
return { success: false, error: err };
}
};
// 인증 서비스 테스트
export const testAuthService = async (): Promise<{ success: boolean; error?: any }> => {
try {
console.log('인증 서비스 테스트 시작...');
const { data, error } = await supabase.auth.getSession();
if (error) {
console.error('인증 테스트 실패:', error);
return { success: false, error };
}
console.log('인증 테스트 성공');
return { success: true };
} catch (err) {
console.error('인증 테스트 중 예외:', err);
return { success: false, error: err };
}
};

View File

@@ -0,0 +1,31 @@
import { supabase } from '../client';
// 데이터베이스 연결 테스트
export const testDatabaseConnection = async (): Promise<{ success: boolean; error?: any }> => {
try {
console.log('데이터베이스 연결 테스트 시작...');
const { data, error } = await supabase
.from('transactions')
.select('*')
.limit(1);
if (error) {
let errorMsg = error.message;
// 익명 인증 오류 처리
if (errorMsg.includes('Auth session missing') || errorMsg.includes('JWT')) {
errorMsg += ' - 로그인이 필요하거나 권한 설정을 확인해주세요.';
}
console.error('데이터베이스 테스트 실패:', error);
return { success: false, error: { message: errorMsg } };
} else {
console.log('데이터베이스 테스트 성공', data);
return { success: true };
}
} catch (err) {
console.error('데이터베이스 테스트 중 예외:', err);
return { success: false, error: err };
}
};

View File

@@ -0,0 +1,108 @@
import { getSupabaseUrl, getSupabaseKey, getOriginalSupabaseUrl, isCorsProxyEnabled, getProxyType } from '../config';
import { testAuthService } from './authTests';
import { testRestApi } from './apiTests';
import { testDatabaseConnection } from './databaseTests';
import { ConnectionTestResult, LoginTestResult } from './types';
export { testSupabaseLogin } from './authTests';
// API 테스트 도우미 함수
export const testSupabaseConnection = async (): Promise<ConnectionTestResult> => {
const originalUrl = getOriginalSupabaseUrl();
const proxyUrl = getSupabaseUrl();
const usingProxy = isCorsProxyEnabled();
const proxyType = getProxyType();
const supabaseKey = getSupabaseKey();
const results: ConnectionTestResult = {
url: originalUrl, // 원본 URL
proxyUrl: proxyUrl, // 프록시 적용된 URL
usingProxy: usingProxy, // 프록시 사용 여부
proxyType: proxyType, // 프록시 유형
client: !!supabase,
restApi: false,
auth: false,
database: false,
errors: [] as string[],
debugInfo: {
originalUrl,
proxyUrl,
usingProxy,
proxyType,
keyLength: supabaseKey.length,
browserInfo: navigator.userAgent,
timestamp: new Date().toISOString(),
backupProxySuccess: false,
lastErrorDetails: ''
}
};
console.log('연결 테스트 시작 - 설정 정보:', {
originalUrl,
proxyUrl,
usingProxy,
proxyType
});
try {
// 1. REST API 테스트
try {
const apiTestResult = await testRestApi(proxyUrl, originalUrl, supabaseKey, proxyType);
results.restApi = apiTestResult.success;
if (!apiTestResult.success) {
results.debugInfo.lastErrorDetails = apiTestResult.lastErrorDetails || '';
results.debugInfo.backupProxySuccess = !!apiTestResult.backupProxySuccess;
if (apiTestResult.backupProxySuccess && apiTestResult.recommendedProxy) {
results.errors.push(`REST API 성공: ${apiTestResult.recommendedProxy} 프록시 사용 시 정상 작동합니다. 설정에서 이 프록시를 선택해보세요.`);
} else if (usingProxy) {
results.errors.push(`REST API 오류: ${apiTestResult.lastErrorDetails || '응답 없음'} - 다른 프록시 옵션도 모두 실패했습니다.`);
} else {
results.errors.push(`REST API 오류: ${apiTestResult.lastErrorDetails || '응답 없음'} - CORS 프록시 활성화를 시도해보세요.`);
}
}
} catch (err: any) {
results.errors.push(`REST API 예외: ${err.message || '알 수 없는 오류'}`);
console.error('REST API 테스트 중 예외:', err);
}
// 2. 인증 서비스 테스트
try {
const authTestResult = await testAuthService();
results.auth = authTestResult.success;
if (!authTestResult.success) {
results.errors.push(`인증 오류: ${authTestResult.error?.message || '알 수 없는 오류'}`);
}
} catch (err: any) {
results.errors.push(`인증 예외: ${err.message || '알 수 없는 오류'}`);
console.error('인증 테스트 중 예외:', err);
}
// 3. 데이터베이스 연결 테스트
try {
const dbTestResult = await testDatabaseConnection();
results.database = dbTestResult.success;
if (!dbTestResult.success) {
results.errors.push(`데이터베이스 오류: ${dbTestResult.error?.message || '알 수 없는 오류'}`);
}
} catch (err: any) {
results.errors.push(`데이터베이스 예외: ${err.message || '알 수 없는 오류'}`);
console.error('데이터베이스 테스트 중 예외:', err);
}
// 오류가 없는 경우 메시지 추가
if (results.errors.length === 0) {
results.errors.push('모든 테스트 통과! 연결 상태가 정상입니다.');
}
} catch (err: any) {
results.errors.push(`테스트 실행 예외: ${err.message || '알 수 없는 오류'}`);
console.error('전체 테스트 실행 중 예외:', err);
}
console.log('Supabase 연결 테스트 결과:', results);
return results;
};

View File

@@ -0,0 +1,33 @@
// 테스트 결과를 위한 공통 타입 정의
export interface TestDebugInfo {
originalUrl: string;
proxyUrl: string;
usingProxy: boolean;
proxyType: string;
keyLength: number;
browserInfo: string;
timestamp: string;
backupProxySuccess: boolean;
lastErrorDetails: string;
}
export interface ConnectionTestResult {
url: string;
proxyUrl: string;
usingProxy: boolean;
proxyType: string;
client: boolean;
restApi: boolean;
auth: boolean;
database: boolean;
errors: string[];
debugInfo: TestDebugInfo;
}
export interface LoginTestResult {
success: boolean;
data?: any;
error?: any;
}