/** * ๐ŸŒ API ์—ฐ๋™ ํƒ€์ž… ์•ˆ์ „์„ฑ ํ…Œ์ŠคํŠธ * * ์‹ค์ œ ๋ฐฑ์—”๋“œ API์™€ ์—ฐ๋™ํ•˜์—ฌ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. */ import { apiClient } from "@/lib/api/client"; import { ComponentData, WidgetComponent, ScreenDefinition, LayoutData, TableInfo, UnifiedColumnInfo, ColumnTypeInfo, ButtonActionType, WebType, isWebType, isButtonActionType, ynToBoolean, booleanToYN, } from "@/types"; export class APIIntegrationTestSuite { /** * ๐Ÿงช Test 1: ํ…Œ์ด๋ธ” ์ •๋ณด API ํƒ€์ž… ์•ˆ์ „์„ฑ */ static async testTableInfoAPI() { console.log("๐Ÿงช API Test 1: ํ…Œ์ด๋ธ” ์ •๋ณด API ํƒ€์ž… ์•ˆ์ „์„ฑ"); try { // ์‹ค์ œ API ํ˜ธ์ถœ const response = await apiClient.get("/api/admin/table-management/tables", { params: { companyCode: "COMPANY_1" }, }); if (response.data && Array.isArray(response.data)) { const tables = response.data as TableInfo[]; tables.forEach((table, index) => { // ํ•„์ˆ˜ ํ•„๋“œ ๊ฒ€์ฆ console.assert(typeof table.tableName === "string", `ํ…Œ์ด๋ธ” ${index}: tableName์ด ๋ฌธ์ž์—ด์ด ์•„๋‹˜`); console.assert(typeof table.tableLabel === "string", `ํ…Œ์ด๋ธ” ${index}: tableLabel์ด ๋ฌธ์ž์—ด์ด ์•„๋‹˜`); if (table.columns && Array.isArray(table.columns)) { table.columns.forEach((column, colIndex) => { // ์ปฌ๋Ÿผ ํƒ€์ž… ๊ฒ€์ฆ console.assert( typeof column.columnName === "string", `ํ…Œ์ด๋ธ” ${index}, ์ปฌ๋Ÿผ ${colIndex}: columnName์ด ๋ฌธ์ž์—ด์ด ์•„๋‹˜`, ); // WebType ์•ˆ์ „์„ฑ ๊ฒ€์ฆ if (column.webType) { const isValidWebType = isWebType(column.webType); if (!isValidWebType) { console.warn( `ํ…Œ์ด๋ธ” ${table.tableName}, ์ปฌ๋Ÿผ ${column.columnName}: ์œ ํšจํ•˜์ง€ ์•Š์€ webType: ${column.webType}`, ); } } }); } }); console.log(`โœ… ํ…Œ์ด๋ธ” ์ •๋ณด API: ${tables.length}๊ฐœ ํ…Œ์ด๋ธ” ๊ฒ€์ฆ ์™„๋ฃŒ`); return true; } } catch (error) { console.error("โŒ ํ…Œ์ด๋ธ” ์ •๋ณด API ํ…Œ์ŠคํŠธ ์‹คํŒจ:", error); return false; } } /** * ๐Ÿงช Test 2: ์ปฌ๋Ÿผ ํƒ€์ž… ์ •๋ณด API ํ˜ธํ™˜์„ฑ */ static async testColumnTypeAPI() { console.log("๐Ÿงช API Test 2: ์ปฌ๋Ÿผ ํƒ€์ž… ์ •๋ณด API ํ˜ธํ™˜์„ฑ"); try { const response = await apiClient.get("/api/admin/table-management/columns", { params: { tableName: "user_info", companyCode: "COMPANY_1", }, }); if (response.data && Array.isArray(response.data)) { const columns = response.data as ColumnTypeInfo[]; // ๋ฐฑ์—”๋“œ ํƒ€์ž…์„ ํ”„๋ก ํŠธ์—”๋“œ ํ†ตํ•ฉ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ ํ…Œ์ŠคํŠธ const unifiedColumns: UnifiedColumnInfo[] = columns.map((col) => ({ columnName: col.columnName, displayName: col.displayName, dataType: col.dataType, dbType: col.dbType, webType: isWebType(col.webType) ? (col.webType as WebType) : "text", inputType: col.inputType || "direct", detailSettings: col.detailSettings ? JSON.parse(col.detailSettings) : {}, description: col.description || "", isNullable: ynToBoolean(col.isNullable), isPrimaryKey: col.isPrimaryKey, defaultValue: col.defaultValue, maxLength: col.maxLength, companyCode: col.companyCode, })); // ๋ณ€ํ™˜ ๊ฒ€์ฆ unifiedColumns.forEach((unifiedCol, index) => { const originalCol = columns[index]; // WebType ๋ณ€ํ™˜ ๊ฒ€์ฆ console.assert(isWebType(unifiedCol.webType), `์ปฌ๋Ÿผ ${unifiedCol.columnName}: WebType ๋ณ€ํ™˜ ์‹คํŒจ`); // Y/N โ†’ boolean ๋ณ€ํ™˜ ๊ฒ€์ฆ console.assert( typeof unifiedCol.isNullable === "boolean", `์ปฌ๋Ÿผ ${unifiedCol.columnName}: isNullable boolean ๋ณ€ํ™˜ ์‹คํŒจ`, ); // JSON ํŒŒ์‹ฑ ๊ฒ€์ฆ console.assert( typeof unifiedCol.detailSettings === "object", `์ปฌ๋Ÿผ ${unifiedCol.columnName}: detailSettings ๊ฐ์ฒด ๋ณ€ํ™˜ ์‹คํŒจ`, ); }); console.log(`โœ… ์ปฌ๋Ÿผ ํƒ€์ž… API: ${unifiedColumns.length}๊ฐœ ์ปฌ๋Ÿผ ๋ณ€ํ™˜ ์™„๋ฃŒ`); return true; } } catch (error) { console.error("โŒ ์ปฌ๋Ÿผ ํƒ€์ž… API ํ…Œ์ŠคํŠธ ์‹คํŒจ:", error); return false; } } /** * ๐Ÿงช Test 3: ํ™”๋ฉด ์ •์˜ ์ €์žฅ/๋ถˆ๋Ÿฌ์˜ค๊ธฐ API */ static async testScreenDefinitionAPI() { console.log("๐Ÿงช API Test 3: ํ™”๋ฉด ์ •์˜ ์ €์žฅ/๋ถˆ๋Ÿฌ์˜ค๊ธฐ API"); try { // ํ…Œ์ŠคํŠธ์šฉ ํ™”๋ฉด ์ •์˜ ์ƒ์„ฑ const testScreenDefinition: ScreenDefinition = { screenId: 9999, // ํ…Œ์ŠคํŠธ์šฉ ์ž„์‹œ ID screenName: "API ํ…Œ์ŠคํŠธ ํ™”๋ฉด", screenCode: "API_TEST_SCREEN", tableName: "test_table", tableLabel: "ํ…Œ์ŠคํŠธ ํ…Œ์ด๋ธ”", description: "API ํƒ€์ž… ์•ˆ์ „์„ฑ ํ…Œ์ŠคํŠธ์šฉ ํ™”๋ฉด", isActive: "Y", layoutData: { screenId: 9999, components: [ { id: "testWidget", type: "widget", widgetType: "text", position: { x: 10, y: 10 }, size: { width: 200, height: 40 }, label: "ํ…Œ์ŠคํŠธ ์ž…๋ ฅ", columnName: "test_column", required: true, webTypeConfig: { maxLength: 100 }, } as WidgetComponent, ], gridSettings: { enabled: true, size: 10, snapToGrid: true, showGrid: true, color: "#e0e0e0", opacity: 0.5, }, }, }; // ํ™”๋ฉด ์ •์˜ ์ €์žฅ ์‹œ๋„ const saveResponse = await apiClient.post("/api/admin/screen-management/screens", testScreenDefinition); if (saveResponse.status === 200 || saveResponse.status === 201) { console.log("โœ… ํ™”๋ฉด ์ •์˜ ์ €์žฅ ์„ฑ๊ณต"); // ์ €์žฅ๋œ ํ™”๋ฉด ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์‹œ๋„ const loadResponse = await apiClient.get( `/api/admin/screen-management/screens/${testScreenDefinition.screenId}`, ); if (loadResponse.data) { const loadedScreen = loadResponse.data as ScreenDefinition; // ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ console.assert(loadedScreen.screenName === testScreenDefinition.screenName, "ํ™”๋ฉด๋ช… ๋ถˆ์ผ์น˜"); console.assert(loadedScreen.layoutData.components.length > 0, "์ปดํฌ๋„ŒํŠธ ๋ฐ์ดํ„ฐ ์†์‹ค"); // ์ปดํฌ๋„ŒํŠธ ํƒ€์ž… ์•ˆ์ „์„ฑ ๊ฒ€์ฆ loadedScreen.layoutData.components.forEach((component) => { if (component.type === "widget") { const widget = component as WidgetComponent; console.assert(isWebType(widget.widgetType), `์œ„์ ฏ ํƒ€์ž… ๊ฒ€์ฆ ์‹คํŒจ: ${widget.widgetType}`); } }); console.log("โœ… ํ™”๋ฉด ์ •์˜ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ๊ฒ€์ฆ ์™„๋ฃŒ"); } // ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ •๋ฆฌ try { await apiClient.delete(`/api/admin/screen-management/screens/${testScreenDefinition.screenId}`); console.log("โœ… ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ •๋ฆฌ ์™„๋ฃŒ"); } catch (cleanupError) { console.warn("โš ๏ธ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ •๋ฆฌ ์‹คํŒจ (์ •์ƒ์ ์ผ ์ˆ˜ ์žˆ์Œ):", cleanupError); } return true; } } catch (error) { console.error("โŒ ํ™”๋ฉด ์ •์˜ API ํ…Œ์ŠคํŠธ ์‹คํŒจ:", error); return false; } } /** * ๐Ÿงช Test 4: ํผ ๋ฐ์ดํ„ฐ ์ €์žฅ API ํƒ€์ž… ์•ˆ์ „์„ฑ */ static async testFormDataSaveAPI() { console.log("๐Ÿงช API Test 4: ํผ ๋ฐ์ดํ„ฐ ์ €์žฅ API ํƒ€์ž… ์•ˆ์ „์„ฑ"); try { // ๋‹ค์–‘ํ•œ ์›นํƒ€์ž…์˜ ํผ ๋ฐ์ดํ„ฐ ์ค€๋น„ const formData = { textField: "ํ…Œ์ŠคํŠธ ํ…์ŠคํŠธ", numberField: 123, booleanField: true, dateField: "2024-01-01", selectField: "option1", emailField: "test@example.com", }; // ์ปดํฌ๋„ŒํŠธ ์ •์˜ (ํผ ๊ตฌ์กฐ) const formComponents: WidgetComponent[] = [ { id: "textField", type: "widget", widgetType: "text", position: { x: 0, y: 0 }, size: { width: 200, height: 40 }, label: "ํ…์ŠคํŠธ", columnName: "text_column", webTypeConfig: {}, }, { id: "numberField", type: "widget", widgetType: "number", position: { x: 0, y: 50 }, size: { width: 200, height: 40 }, label: "์ˆซ์ž", columnName: "number_column", webTypeConfig: {}, }, { id: "booleanField", type: "widget", widgetType: "checkbox", position: { x: 0, y: 100 }, size: { width: 200, height: 40 }, label: "์ฒดํฌ๋ฐ•์Šค", columnName: "boolean_column", webTypeConfig: {}, }, ]; // ํƒ€์ž… ์•ˆ์ „ํ•œ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ const processedData: Record = {}; formComponents.forEach((component) => { const fieldValue = formData[component.id as keyof typeof formData]; if (fieldValue !== undefined && component.columnName) { switch (component.widgetType) { case "text": case "email": processedData[component.columnName] = String(fieldValue); break; case "number": processedData[component.columnName] = Number(fieldValue); break; case "checkbox": case "boolean": processedData[component.columnName] = booleanToYN(Boolean(fieldValue)); break; case "date": processedData[component.columnName] = fieldValue ? String(fieldValue) : null; break; default: processedData[component.columnName] = fieldValue; } } }); // ์‹ค์ œ API ํ˜ธ์ถœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (์ผ๋ฐ˜์ ์ธ ํผ ์ €์žฅ ์—”๋“œํฌ์ธํŠธ) console.log("๐Ÿ“ค ์ฒ˜๋ฆฌ๋œ ํผ ๋ฐ์ดํ„ฐ:", processedData); // ํƒ€์ž… ๊ฒ€์ฆ console.assert(typeof processedData.text_column === "string", "ํ…์ŠคํŠธ ํ•„๋“œ ํƒ€์ž… ์˜ค๋ฅ˜"); console.assert(typeof processedData.number_column === "number", "์ˆซ์ž ํ•„๋“œ ํƒ€์ž… ์˜ค๋ฅ˜"); console.assert( processedData.boolean_column === "Y" || processedData.boolean_column === "N", "๋ถˆ๋ฆฐ ํ•„๋“œ Y/N ๋ณ€ํ™˜ ์˜ค๋ฅ˜", ); console.log("โœ… ํผ ๋ฐ์ดํ„ฐ ์ €์žฅ ํƒ€์ž… ์•ˆ์ „์„ฑ ๊ฒ€์ฆ ์™„๋ฃŒ"); return true; } catch (error) { console.error("โŒ ํผ ๋ฐ์ดํ„ฐ ์ €์žฅ API ํ…Œ์ŠคํŠธ ์‹คํŒจ:", error); return false; } } /** * ๐Ÿงช Test 5: ๋ฒ„ํŠผ ์•ก์…˜ ์‹คํ–‰ API ํƒ€์ž… ์•ˆ์ „์„ฑ */ static async testButtonActionAPI() { console.log("๐Ÿงช API Test 5: ๋ฒ„ํŠผ ์•ก์…˜ ์‹คํ–‰ API ํƒ€์ž… ์•ˆ์ „์„ฑ"); try { const buttonActions: ButtonActionType[] = [ "save", "cancel", "delete", "edit", "add", "search", "reset", "submit", "close", "popup", "modal", "navigate", "control", ]; // ๊ฐ ๋ฒ„ํŠผ ์•ก์…˜ ํƒ€์ž… ๊ฒ€์ฆ buttonActions.forEach((action) => { console.assert(isButtonActionType(action), `์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฒ„ํŠผ ์•ก์…˜: ${action}`); }); // ์ž˜๋ชป๋œ ์•ก์…˜ ํƒ€์ž…๋“ค ๊ฒ€์ฆ const invalidActions = ["insert", "update", "remove", ""]; invalidActions.forEach((action) => { console.assert(!isButtonActionType(action), `์ž˜๋ชป๋œ ์•ก์…˜์ด ํ—ˆ์šฉ๋จ: ${action}`); }); console.log("โœ… ๋ฒ„ํŠผ ์•ก์…˜ ํƒ€์ž… ์•ˆ์ „์„ฑ ๊ฒ€์ฆ ์™„๋ฃŒ"); return true; } catch (error) { console.error("โŒ ๋ฒ„ํŠผ ์•ก์…˜ API ํ…Œ์ŠคํŠธ ์‹คํŒจ:", error); return false; } } /** * ๐ŸŽฏ ๋ชจ๋“  API ์—ฐ๋™ ํ…Œ์ŠคํŠธ ์‹คํ–‰ */ static async runAllAPITests() { console.log("๐ŸŽฏ API ์—ฐ๋™ ํƒ€์ž… ์•ˆ์ „์„ฑ ํ…Œ์ŠคํŠธ ์‹œ์ž‘\n"); const results = { tableInfoAPI: false, columnTypeAPI: false, screenDefinitionAPI: false, formDataSaveAPI: false, buttonActionAPI: false, }; try { results.tableInfoAPI = await this.testTableInfoAPI(); results.columnTypeAPI = await this.testColumnTypeAPI(); results.screenDefinitionAPI = await this.testScreenDefinitionAPI(); results.formDataSaveAPI = await this.testFormDataSaveAPI(); results.buttonActionAPI = await this.testButtonActionAPI(); const passedTests = Object.values(results).filter(Boolean).length; const totalTests = Object.keys(results).length; console.log(`\n๐ŸŽ‰ API ์—ฐ๋™ ํ…Œ์ŠคํŠธ ์™„๋ฃŒ: ${passedTests}/${totalTests} ํ†ต๊ณผ`); if (passedTests === totalTests) { console.log("โœ… ๋ชจ๋“  API ์—ฐ๋™ ํƒ€์ž… ์•ˆ์ „์„ฑ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ!"); } else { console.log("โš ๏ธ ์ผ๋ถ€ API ์—ฐ๋™ ํ…Œ์ŠคํŠธ ์‹คํŒจ"); } return { success: passedTests === totalTests, passedTests, totalTests, results, }; } catch (error) { console.error("โŒ API ์—ฐ๋™ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹คํŒจ:", error); return { success: false, passedTests: 0, totalTests: Object.keys(results).length, results, error: String(error), }; } } } export default APIIntegrationTestSuite;