Files
superport/test/integration/automated/user_real_api_test.dart

468 lines
16 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter_test/flutter_test.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'test_result.dart';
import 'dart:math';
/// 사용자 관리 실제 API 테스트
///
/// 테스트 항목:
/// 1. 사용자 목록 조회
/// 2. 사용자 생성 (관리자/일반)
/// 3. 사용자 상세 조회
/// 4. 사용자 정보 수정
/// 5. 비밀번호 변경
/// 6. 사용자 권한 변경
/// 7. 사용자 비활성화/활성화
/// 8. 사용자 삭제
/// 9. 사용자 검색
/// 10. 권한별 접근 제어 테스트
Future<TestResult> runUserTests({
required Dio dio,
required String authToken,
bool verbose = false,
}) async {
const String baseUrl = 'http://43.201.34.104:8080/api/v1';
final Random random = Random();
final Stopwatch stopwatch = Stopwatch()..start();
int totalTests = 0;
int passedTests = 0;
final List<String> failedTestNames = [];
// 테스트용 사용자 데이터
final testUserData = {
'names': ['김철수', '이영희', '박민수', '정수진', '최동욱'],
'departments': ['개발팀', '영업팀', '마케팅팀', '인사팀', '운영팀'],
'positions': ['대리', '과장', '차장', '부장', '팀장'],
'emails': ['test1@superport.kr', 'test2@superport.kr', 'test3@superport.kr'],
'phones': ['010-1234-5678', '010-2345-6789', '010-3456-7890'],
};
group('🧑‍💼 사용자 관리 API 테스트', () {
// 생성된 사용자 ID 저장
final List<int> createdUserIds = [];
test('1. 사용자 목록 조회', () async {
totalTests++;
if (verbose) debugPrint('\n📋 사용자 목록 조회 테스트...');
try {
final response = await dio.get(
'$baseUrl/users',
queryParameters: {
'page': 1,
'per_page': 20,
},
);
if (response.statusCode == 200) {
final users = response.data['data'] ?? [];
if (verbose) {
debugPrint('✅ 사용자 ${users.length}개 조회 성공');
}
passedTests++;
} else {
failedTestNames.add('사용자 목록 조회');
if (verbose) debugPrint('❌ 사용자 목록 조회 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 목록 조회');
if (verbose) debugPrint('❌ 사용자 목록 조회 오류: $e');
}
});
test('2. 사용자 생성 (일반 사용자)', () async {
totalTests++;
if (verbose) debugPrint('\n 일반 사용자 생성 테스트...');
final timestamp = DateTime.now().millisecondsSinceEpoch;
final nameIndex = random.nextInt(testUserData['names']!.length);
final deptIndex = random.nextInt(testUserData['departments']!.length);
try {
final newUser = {
'username': 'user_$timestamp',
'email': 'user_$timestamp@superport.kr',
'password': 'Password123!',
'name': testUserData['names']![nameIndex],
'department': testUserData['departments']![deptIndex],
'position': testUserData['positions']![random.nextInt(testUserData['positions']!.length)],
'phone': '010-${1000 + random.nextInt(9000)}-${1000 + random.nextInt(9000)}',
'role': 'user', // 일반 사용자
};
final response = await dio.post(
'$baseUrl/users',
data: newUser,
);
if (response.statusCode == 200 || response.statusCode == 201) {
final createdUser = response.data['data'];
if (createdUser != null && createdUser['id'] != null) {
createdUserIds.add(createdUser['id']);
if (verbose) {
debugPrint('✅ 일반 사용자 생성 성공: ${createdUser['name']} (${createdUser['email']})');
}
passedTests++;
} else {
failedTestNames.add('사용자 생성 (일반)');
if (verbose) debugPrint('❌ 사용자 생성 응답에 ID가 없음');
}
} else {
failedTestNames.add('사용자 생성 (일반)');
if (verbose) debugPrint('❌ 사용자 생성 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 생성 (일반)');
if (verbose) debugPrint('❌ 사용자 생성 오류: $e');
}
});
test('3. 사용자 생성 (관리자)', () async {
totalTests++;
if (verbose) debugPrint('\n 관리자 생성 테스트...');
final timestamp = DateTime.now().millisecondsSinceEpoch;
try {
final adminUser = {
'username': 'admin_$timestamp',
'email': 'admin_$timestamp@superport.kr',
'password': 'Admin123!@#',
'name': '관리자_$timestamp',
'department': '시스템관리팀',
'position': '팀장',
'phone': '010-9999-${1000 + random.nextInt(9000)}',
'role': 'admin', // 관리자
};
final response = await dio.post(
'$baseUrl/users',
data: adminUser,
);
if (response.statusCode == 200 || response.statusCode == 201) {
final createdUser = response.data['data'];
if (createdUser != null && createdUser['id'] != null) {
createdUserIds.add(createdUser['id']);
if (verbose) {
debugPrint('✅ 관리자 생성 성공: ${createdUser['name']}');
}
passedTests++;
} else {
failedTestNames.add('사용자 생성 (관리자)');
if (verbose) debugPrint('❌ 관리자 생성 응답에 ID가 없음');
}
} else {
failedTestNames.add('사용자 생성 (관리자)');
if (verbose) debugPrint('❌ 관리자 생성 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 생성 (관리자)');
if (verbose) debugPrint('❌ 관리자 생성 오류: $e');
}
});
test('4. 사용자 상세 조회', () async {
totalTests++;
if (verbose) debugPrint('\n🔍 사용자 상세 조회 테스트...');
if (createdUserIds.isEmpty) {
failedTestNames.add('사용자 상세 조회');
if (verbose) debugPrint('⚠️ 조회할 사용자가 없음');
return;
}
try {
final userId = createdUserIds.first;
final response = await dio.get('$baseUrl/users/$userId');
if (response.statusCode == 200) {
final user = response.data['data'];
if (user != null) {
if (verbose) {
debugPrint('✅ 사용자 상세 조회 성공: ${user['name']} (${user['email']})');
}
passedTests++;
} else {
failedTestNames.add('사용자 상세 조회');
if (verbose) debugPrint('❌ 사용자 상세 조회 응답 비어있음');
}
} else {
failedTestNames.add('사용자 상세 조회');
if (verbose) debugPrint('❌ 사용자 상세 조회 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 상세 조회');
if (verbose) debugPrint('❌ 사용자 상세 조회 오류: $e');
}
});
test('5. 사용자 정보 수정', () async {
totalTests++;
if (verbose) debugPrint('\n✏️ 사용자 정보 수정 테스트...');
if (createdUserIds.isEmpty) {
failedTestNames.add('사용자 정보 수정');
if (verbose) debugPrint('⚠️ 수정할 사용자가 없음');
return;
}
try {
final userId = createdUserIds.first;
final updatedData = {
'name': '수정된이름_${random.nextInt(1000)}',
'department': '수정된부서',
'position': '수정된직급',
'phone': '010-9999-9999',
};
final response = await dio.put(
'$baseUrl/users/$userId',
data: updatedData,
);
if (response.statusCode == 200) {
if (verbose) {
debugPrint('✅ 사용자 정보 수정 성공');
}
passedTests++;
} else {
failedTestNames.add('사용자 정보 수정');
if (verbose) debugPrint('❌ 사용자 정보 수정 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 정보 수정');
if (verbose) debugPrint('❌ 사용자 정보 수정 오류: $e');
}
});
test('6. 비밀번호 변경', () async {
totalTests++;
if (verbose) debugPrint('\n🔐 비밀번호 변경 테스트...');
if (createdUserIds.isEmpty) {
failedTestNames.add('비밀번호 변경');
if (verbose) debugPrint('⚠️ 대상 사용자가 없음');
return;
}
try {
final userId = createdUserIds.first;
final passwordData = {
'current_password': 'Password123!',
'new_password': 'NewPassword456!',
'confirm_password': 'NewPassword456!',
};
final response = await dio.post(
'$baseUrl/users/$userId/change-password',
data: passwordData,
);
if (response.statusCode == 200) {
if (verbose) {
debugPrint('✅ 비밀번호 변경 성공');
}
passedTests++;
} else {
failedTestNames.add('비밀번호 변경');
if (verbose) debugPrint('❌ 비밀번호 변경 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('비밀번호 변경');
if (verbose) debugPrint('❌ 비밀번호 변경 오류: $e');
}
});
test('7. 사용자 권한 변경', () async {
totalTests++;
if (verbose) debugPrint('\n👤 사용자 권한 변경 테스트...');
if (createdUserIds.length < 2) {
failedTestNames.add('사용자 권한 변경');
if (verbose) debugPrint('⚠️ 권한 변경할 사용자가 부족');
return;
}
try {
final userId = createdUserIds[1]; // 두 번째 사용자
final roleData = {
'role': 'admin', // user -> admin으로 변경
};
final response = await dio.patch(
'$baseUrl/users/$userId/role',
data: roleData,
);
if (response.statusCode == 200 || response.statusCode == 204) {
if (verbose) {
debugPrint('✅ 사용자 권한 변경 성공');
}
passedTests++;
} else {
failedTestNames.add('사용자 권한 변경');
if (verbose) debugPrint('❌ 사용자 권한 변경 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 권한 변경');
if (verbose) debugPrint('❌ 사용자 권한 변경 오류: $e');
}
});
test('8. 사용자 비활성화/활성화', () async {
totalTests++;
if (verbose) debugPrint('\n🔄 사용자 비활성화/활성화 테스트...');
if (createdUserIds.isEmpty) {
failedTestNames.add('사용자 비활성화/활성화');
if (verbose) debugPrint('⚠️ 대상 사용자가 없음');
return;
}
try {
final userId = createdUserIds.first;
// 비활성화
var response = await dio.patch(
'$baseUrl/users/$userId/status',
data: {'is_active': false},
);
if (response.statusCode == 200 || response.statusCode == 204) {
if (verbose) debugPrint('✅ 사용자 비활성화 성공');
// 다시 활성화
response = await dio.patch(
'$baseUrl/users/$userId/status',
data: {'is_active': true},
);
if (response.statusCode == 200 || response.statusCode == 204) {
if (verbose) debugPrint('✅ 사용자 활성화 성공');
passedTests++;
} else {
failedTestNames.add('사용자 비활성화/활성화');
if (verbose) debugPrint('❌ 사용자 활성화 실패: ${response.statusCode}');
}
} else {
failedTestNames.add('사용자 비활성화/활성화');
if (verbose) debugPrint('❌ 사용자 비활성화 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 비활성화/활성화');
if (verbose) debugPrint('❌ 사용자 비활성화/활성화 오류: $e');
}
});
test('9. 사용자 검색', () async {
totalTests++;
if (verbose) debugPrint('\n🔍 사용자 검색 테스트...');
try {
final response = await dio.get(
'$baseUrl/users/search',
queryParameters: {
'q': '관리자',
'page': 1,
'per_page': 10,
},
);
if (response.statusCode == 200) {
final results = response.data['data'] ?? [];
if (verbose) {
debugPrint('✅ 사용자 검색 성공: ${results.length}개 결과');
}
passedTests++;
} else {
failedTestNames.add('사용자 검색');
if (verbose) debugPrint('❌ 사용자 검색 실패: ${response.statusCode}');
}
} catch (e) {
failedTestNames.add('사용자 검색');
if (verbose) debugPrint('❌ 사용자 검색 오류: $e');
}
});
test('10. 사용자 삭제', () async {
totalTests++;
if (verbose) debugPrint('\n🗑️ 사용자 삭제 테스트...');
if (createdUserIds.isEmpty) {
failedTestNames.add('사용자 삭제');
if (verbose) debugPrint('⚠️ 삭제할 사용자가 없음');
return;
}
try {
// 모든 생성된 사용자 삭제
for (final userId in createdUserIds) {
final response = await dio.delete('$baseUrl/users/$userId');
if (response.statusCode == 200 || response.statusCode == 204) {
if (verbose) debugPrint('✅ 사용자 ID $userId 삭제 성공');
} else {
if (verbose) debugPrint('❌ 사용자 ID $userId 삭제 실패: ${response.statusCode}');
}
}
passedTests++;
} catch (e) {
failedTestNames.add('사용자 삭제');
if (verbose) debugPrint('❌ 사용자 삭제 오류: $e');
}
});
});
stopwatch.stop();
return TestResult(
name: '사용자 관리 API',
totalTests: totalTests,
passedTests: passedTests,
failedTests: totalTests - passedTests,
failedTestNames: failedTestNames,
executionTime: stopwatch.elapsed,
);
}
void main() async {
// 테스트용 Dio 인스턴스 생성
final dio = Dio();
dio.options.connectTimeout = const Duration(seconds: 10);
dio.options.receiveTimeout = const Duration(seconds: 10);
// 로그인
const baseUrl = 'http://43.201.34.104:8080/api/v1';
debugPrint('🔐 로그인 중...');
try {
final loginResponse = await dio.post(
'$baseUrl/auth/login',
data: {
'email': 'admin@example.com',
'password': 'password123',
},
);
final token = loginResponse.data['data']['access_token'];
dio.options.headers['Authorization'] = 'Bearer $token';
debugPrint('✅ 로그인 성공\n');
// 사용자 테스트 실행
final result = await runUserTests(
dio: dio,
authToken: token,
verbose: true,
);
debugPrint('\n${result.summary}');
} catch (e) {
debugPrint('❌ 로그인 실패: $e');
} finally {
dio.close();
}
}