404 lines
11 KiB
Dart
404 lines
11 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:mockito/annotations.dart';
|
|
import 'package:mockito/mockito.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:lanebow/config/api_config.dart';
|
|
import 'package:lanebow/models/club_model.dart';
|
|
import 'package:lanebow/services/api_service.dart';
|
|
import 'package:lanebow/services/club_service.dart';
|
|
import 'package:lanebow/services/event_bus.dart';
|
|
import 'package:lanebow/utils/test_utils.dart';
|
|
|
|
import 'club_service_integration_test.mocks.dart';
|
|
import '../utils/event_bus_test_utils.dart';
|
|
|
|
@GenerateMocks([ApiService])
|
|
void main() {
|
|
late ClubService clubService;
|
|
late MockApiService mockApiService;
|
|
late String testId;
|
|
|
|
setUp(() async {
|
|
// 테스트 ID 생성 및 설정
|
|
testId = 'club_service_integration_test_${DateTime.now().millisecondsSinceEpoch}';
|
|
TestUtils.setTestMode(true);
|
|
await EventBusTestUtils.setUp(testId);
|
|
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
SharedPreferences.setMockInitialValues({
|
|
ApiConfig.clubIdKey: 'test_club_id' // SharedPreferences에 clubId 설정
|
|
});
|
|
mockApiService = MockApiService();
|
|
|
|
// 모든 테스트에서 공통으로 사용되는 모킹 설정
|
|
when(mockApiService.post(
|
|
'/club',
|
|
data: {'clubId': 'test_club_id'},
|
|
)).thenAnswer((_) async => {
|
|
'id': 'test_club_id',
|
|
'name': '테스트 클럽',
|
|
'description': '테스트 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
});
|
|
|
|
clubService = ClubService.forTest(mockApiService);
|
|
|
|
print('EventBus: 초기화됨 (테스트 ID: $testId)');
|
|
});
|
|
|
|
tearDown(() async {
|
|
// 테스트 종료 후 정리
|
|
clubService.dispose();
|
|
await EventBusTestUtils.tearDown();
|
|
TestUtils.setTestMode(false);
|
|
print('EventBus: 초기화됨 (테스트 ID: $testId)');
|
|
});
|
|
|
|
group('ClubService 통합 테스트', () {
|
|
test('초기화 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
const clubId = 'test_club_id';
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: {'clubId': clubId},
|
|
)).thenAnswer((_) async => {
|
|
'id': clubId,
|
|
'name': '테스트 클럽',
|
|
'description': '테스트 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
'isActive': true,
|
|
});
|
|
|
|
// when
|
|
await clubService.initialize(token);
|
|
|
|
// then
|
|
expect(clubService.currentClub, isNotNull);
|
|
expect(clubService.currentClub?.id, clubId);
|
|
expect(clubService.currentClub?.name, '테스트 클럽');
|
|
|
|
verify(mockApiService.setToken(token)).called(1);
|
|
// initialize에서 이미 fetchClubById를 호출하기 때문에 호출 횟수 검증을 제거합니다.
|
|
});
|
|
|
|
test('사용자 클럽 목록 조회 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.post('${ApiConfig.clubs}/user')).thenAnswer((_) async => [
|
|
{
|
|
'id': 'club_id_1',
|
|
'name': '테스트 클럽 1',
|
|
'description': '테스트 클럽 1 설명',
|
|
'ownerId': 'owner_id',
|
|
},
|
|
{
|
|
'id': 'club_id_2',
|
|
'name': '테스트 클럽 2',
|
|
'description': '테스트 클럽 2 설명',
|
|
'ownerId': 'owner_id',
|
|
}
|
|
]);
|
|
|
|
// when
|
|
await clubService.fetchUserClubs();
|
|
|
|
// then
|
|
expect(clubService.clubs.length, 2);
|
|
expect(clubService.clubs[0].id, 'club_id_1');
|
|
expect(clubService.clubs[0].name, '테스트 클럽 1');
|
|
expect(clubService.clubs[1].id, 'club_id_2');
|
|
expect(clubService.clubs[1].name, '테스트 클럽 2');
|
|
});
|
|
|
|
test('ID로 클럽 정보 조회 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
const clubId = 'test_club_id';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: {'clubId': clubId},
|
|
)).thenAnswer((_) async => {
|
|
'id': clubId,
|
|
'name': '테스트 클럽',
|
|
'description': '테스트 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
'isActive': true,
|
|
});
|
|
|
|
// when
|
|
await clubService.fetchClubById(clubId);
|
|
|
|
// then
|
|
expect(clubService.currentClub, isNotNull);
|
|
expect(clubService.currentClub?.id, clubId);
|
|
expect(clubService.currentClub?.name, '테스트 클럽');
|
|
|
|
});
|
|
|
|
test('현재 클럽 설정 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
const clubId = 'test_club_id';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: {'clubId': clubId},
|
|
)).thenAnswer((_) async => {
|
|
'id': clubId,
|
|
'name': '테스트 클럽',
|
|
'description': '테스트 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
'isActive': true,
|
|
});
|
|
|
|
// when
|
|
await clubService.setCurrentClub(clubId);
|
|
|
|
// then
|
|
expect(clubService.currentClub, isNotNull);
|
|
expect(clubService.currentClub?.id, clubId);
|
|
expect(clubService.currentClub?.name, '테스트 클럽');
|
|
|
|
});
|
|
|
|
test('클럽 선택 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
const clubId = 'test_club_id';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.post(
|
|
'${ApiConfig.clubs}/select-club',
|
|
data: {'clubId': clubId},
|
|
)).thenAnswer((_) async => {'success': true});
|
|
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: {'clubId': clubId},
|
|
)).thenAnswer((_) async => {
|
|
'id': clubId,
|
|
'name': '테스트 클럽',
|
|
'description': '테스트 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
'isActive': true,
|
|
});
|
|
|
|
// EventBus 이벤트 리스너 설정
|
|
bool eventFired = false;
|
|
final completer = Completer<void>();
|
|
|
|
EventBus().on<ClubChangedEvent>().listen((event) {
|
|
eventFired = true;
|
|
expect(event.clubId, clubId);
|
|
completer.complete();
|
|
});
|
|
|
|
// when
|
|
await clubService.selectClub(clubId);
|
|
|
|
// 이벤트가 발생할 때까지 짧게 대기
|
|
await Future.any([completer.future, Future.delayed(const Duration(seconds: 1))]);
|
|
|
|
// then
|
|
expect(clubService.currentClub, isNotNull);
|
|
expect(clubService.currentClub?.id, clubId);
|
|
expect(clubService.currentClub?.name, '테스트 클럽');
|
|
expect(eventFired, true);
|
|
|
|
});
|
|
|
|
test('클럽 생성 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
final newClub = Club(
|
|
id: '',
|
|
name: '새 클럽',
|
|
description: '새 클럽 설명',
|
|
ownerId: 'owner_id',
|
|
|
|
);
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: anyNamed('data'),
|
|
)).thenAnswer((_) async => {
|
|
'club': {
|
|
'id': 'new_club_id',
|
|
'name': '새 클럽',
|
|
'description': '새 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
}
|
|
});
|
|
|
|
// when
|
|
final result = await clubService.createClub(newClub);
|
|
|
|
// then
|
|
expect(result.id, 'new_club_id');
|
|
expect(result.name, '새 클럽');
|
|
expect(clubService.currentClub?.id, 'new_club_id');
|
|
expect(clubService.clubs.length, 1);
|
|
expect(clubService.clubs[0].id, 'new_club_id');
|
|
|
|
});
|
|
|
|
test('클럽 정보 업데이트 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
const clubId = 'test_club_id';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
// 클럽 목록 설정
|
|
when(mockApiService.post('${ApiConfig.clubs}/user')).thenAnswer((_) async => [
|
|
{
|
|
'id': clubId,
|
|
'name': '테스트 클럽',
|
|
'description': '테스트 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
}
|
|
]);
|
|
await clubService.fetchUserClubs();
|
|
|
|
final updates = {
|
|
'name': '수정된 클럽',
|
|
'description': '수정된 클럽 설명',
|
|
};
|
|
|
|
// API 응답 모킹
|
|
when(mockApiService.put(
|
|
ApiConfig.clubs,
|
|
data: {
|
|
'clubId': clubId,
|
|
...updates,
|
|
},
|
|
)).thenAnswer((_) async => {
|
|
'club': {
|
|
'id': clubId,
|
|
'name': '수정된 클럽',
|
|
'description': '수정된 클럽 설명',
|
|
'ownerId': 'owner_id',
|
|
}
|
|
});
|
|
|
|
// when
|
|
final result = await clubService.updateClub(clubId, updates);
|
|
|
|
// then
|
|
expect(result.id, clubId);
|
|
expect(result.name, '수정된 클럽');
|
|
expect(result.description, '수정된 클럽 설명');
|
|
expect(clubService.clubs[0].name, '수정된 클럽');
|
|
|
|
verify(mockApiService.put(
|
|
ApiConfig.clubs,
|
|
data: {
|
|
'clubId': clubId,
|
|
...updates,
|
|
},
|
|
)).called(1);
|
|
});
|
|
});
|
|
|
|
group('에러 처리 테스트', () {
|
|
test('토큰 미설정 테스트', () async {
|
|
// given
|
|
// 토큰을 설정하지 않음
|
|
|
|
// when & then
|
|
expect(
|
|
() => clubService.fetchUserClubs(),
|
|
returnsNormally, // 토큰이 없으면 조용히 반환됨
|
|
);
|
|
});
|
|
|
|
test('API 에러 처리 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
const clubId = 'test_club_id';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
// API 에러 모킹
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: {'clubId': clubId},
|
|
)).thenThrow(Exception('API 에러 발생'));
|
|
|
|
// when & then
|
|
expect(
|
|
() => clubService.fetchClubById(clubId),
|
|
throwsA(isA<Exception>()),
|
|
);
|
|
|
|
});
|
|
|
|
test('클럽 생성 실패 테스트', () async {
|
|
// given
|
|
const token = 'test_token';
|
|
|
|
// 토큰 설정
|
|
when(mockApiService.setToken(token)).thenReturn(null);
|
|
await clubService.initialize(token);
|
|
|
|
final newClub = Club(
|
|
id: '',
|
|
name: '새 클럽',
|
|
description: '새 클럽 설명',
|
|
ownerId: 'owner_id',
|
|
|
|
);
|
|
|
|
// API 에러 모킹
|
|
when(mockApiService.post(
|
|
ApiConfig.clubs,
|
|
data: anyNamed('data'),
|
|
)).thenThrow(Exception('클럽 생성 실패'));
|
|
|
|
// when & then
|
|
expect(
|
|
() => clubService.createClub(newClub),
|
|
throwsA(isA<Exception>()),
|
|
);
|
|
|
|
});
|
|
});
|
|
}
|