Files
bowlingManager/mobile/test/services/event_service_test.dart
T
2025-08-12 03:28:08 +09:00

408 lines
12 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/services/api_service.dart';
import 'package:lanebow/services/event_bus.dart';
import 'package:lanebow/models/event_model.dart';
import 'package:lanebow/models/participant_model.dart';
import 'package:lanebow/models/score_model.dart';
import 'package:lanebow/config/api_config.dart';
import 'package:lanebow/utils/test_utils.dart';
// 모킹 클래스 생성
@GenerateMocks([ApiService])
import 'event_service_test.mocks.dart';
void main() {
late EventService eventService;
late MockApiService mockApiService;
final testToken = 'test_token';
final testClubId = 'test_club_id';
// 테스트 이벤트 데이터
final testEvent = {
'id': 'test_event_id',
'clubId': 'test_club_id',
'title': '테스트 이벤트',
'description': '테스트 설명',
'type': 'regular',
'status': 'upcoming',
'startDate': DateTime.now().toIso8601String(),
'endDate': DateTime.now().add(const Duration(hours: 2)).toIso8601String(),
'location': '테스트 장소',
'maxParticipants': 20,
'gameCount': 3,
'entryFee': 10000,
'registrationDeadline': DateTime.now().add(const Duration(days: 1)).toIso8601String(),
'isActive': true,
};
// 테스트 참가자 데이터
final testParticipant = {
'id': 'test_participant_id',
'eventId': 'test_event_id',
'memberId': 'test_member_id',
'name': '테스트 참가자',
'status': 'confirmed',
'paymentStatus': 'paid',
'registrationDate': DateTime.now().toIso8601String(),
};
// 테스트 점수 데이터
final testScore = {
'id': 'test_score_id',
'eventId': 'test_event_id',
'participantId': 'test_participant_id',
'participantName': '테스트 참가자',
'games': [180, 200, 220],
'handicap': 10,
'total': 610,
'average': 203.33,
};
setUp(() async {
// 테스트 모드 강제 설정
TestUtils.setTestMode(true);
// 테스트별 고유 ID 생성 및 설정
final testId = 'event_service_test_${DateTime.now().millisecondsSinceEpoch}';
EventBus.setCurrentTestId(testId);
// EventBus 완전 초기화
EventBus().reset();
// SharedPreferences 모킹
SharedPreferences.setMockInitialValues({
ApiConfig.clubIdKey: testClubId,
});
// API 서비스 모킹
mockApiService = MockApiService();
// EventService 초기화 (테스트용 생성자 사용)
eventService = EventService.forTest(mockApiService);
// 토큰 설정
await eventService.initialize(testToken);
// 클럽 ID 설정
eventService.setClubId(testClubId);
});
tearDown(() {
// 테스트 종료 후 EventBus 초기화
EventBus().reset();
// 테스트에서 생성된 EventService 정리
eventService.dispose();
// 테스트 ID 초기화
EventBus.clearCurrentTestId();
// 테스트 모드 해제
TestUtils.setTestMode(false);
});
group('EventService 테스트', () {
test('initialize 메서드가 토큰을 설정해야 함', () async {
// given
// setUp에서 이미 initialize 호출됨
// then
verify(mockApiService.setToken(testToken)).called(1);
});
test('fetchClubEvents 메서드가 이벤트 목록을 가져와야 함', () async {
// given
final testEvents = [testEvent];
when(mockApiService.post(
'${ApiConfig.clubs}/events',
data: {'clubId': testClubId},
)).thenAnswer((_) async => testEvents);
// when
await eventService.fetchClubEvents();
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events',
data: {'clubId': testClubId},
)).called(1);
expect(eventService.events.length, 1);
expect(eventService.events[0].id, 'test_event_id');
expect(eventService.events[0].title, '테스트 이벤트');
});
test('fetchEventById 메서드가 특정 이벤트를 가져와야 함', () async {
// given
final eventId = 'test_event_id';
when(mockApiService.post(
'${ApiConfig.clubs}/events/detail',
data: {'eventId': eventId},
)).thenAnswer((_) async => {'event': testEvent});
// when
final result = await eventService.fetchEventById(eventId);
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events/detail',
data: {'eventId': eventId},
)).called(1);
expect(result.id, 'test_event_id');
expect(result.title, '테스트 이벤트');
});
test('createEvent 메서드가 새 이벤트를 생성해야 함', () async {
// given
final newEventData = {
'clubId': testClubId,
'title': '새 이벤트',
'startDate': DateTime.now().toIso8601String(),
};
when(mockApiService.post(
'${ApiConfig.clubs}/events',
data: newEventData,
)).thenAnswer((_) async => {'event': testEvent});
// when
final result = await eventService.createEvent(newEventData);
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events',
data: newEventData,
)).called(1);
expect(result.id, 'test_event_id');
expect(eventService.events.length, 1);
});
test('updateEvent 메서드가 이벤트를 업데이트해야 함', () async {
// given
final eventId = 'test_event_id';
final updates = {'title': '업데이트된 이벤트'};
final updatedEvent = Map<String, dynamic>.from(testEvent);
updatedEvent['title'] = '업데이트된 이벤트';
// 이벤트 목록에 테스트 이벤트 추가
when(mockApiService.post(
'${ApiConfig.clubs}/events',
data: {'clubId': testClubId},
)).thenAnswer((_) async => [testEvent]);
await eventService.fetchClubEvents();
when(mockApiService.put(
'${ApiConfig.clubs}/events/$eventId',
data: updates,
)).thenAnswer((_) async => {'event': updatedEvent});
// when
final result = await eventService.updateEvent(eventId, updates);
// then
verify(mockApiService.put(
'${ApiConfig.clubs}/events/$eventId',
data: updates,
)).called(1);
expect(result.title, '업데이트된 이벤트');
expect(eventService.events[0].title, '업데이트된 이벤트');
});
test('deleteEvent 메서드가 이벤트를 삭제해야 함', () async {
// given
final eventId = 'test_event_id';
// 이벤트 목록에 테스트 이벤트 추가
when(mockApiService.post(
'${ApiConfig.clubs}/events',
data: {'clubId': testClubId},
)).thenAnswer((_) async => [testEvent]);
await eventService.fetchClubEvents();
when(mockApiService.delete(
'${ApiConfig.clubs}/events/$eventId',
)).thenAnswer((_) async => {});
// when
final result = await eventService.deleteEvent(eventId);
// then
verify(mockApiService.delete(
'${ApiConfig.clubs}/events/$eventId',
)).called(1);
expect(result, true);
expect(eventService.events.length, 0);
});
test('fetchEventParticipants 메서드가 참가자 목록을 가져와야 함', () async {
// given
final eventId = 'test_event_id';
final testParticipants = [testParticipant];
when(mockApiService.post(
'${ApiConfig.clubs}/events/participants',
data: {'eventId': eventId},
)).thenAnswer((_) async => {'participants': testParticipants});
// when
final result = await eventService.fetchEventParticipants(eventId);
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events/participants',
data: {'eventId': eventId},
)).called(1);
expect(result.length, 1);
expect(result[0].id, 'test_participant_id');
expect(result[0].name, '테스트 참가자');
});
test('addParticipant 메서드가 참가자를 추가해야 함', () async {
// given
final eventId = 'test_event_id';
final participantData = {
'memberId': 'test_member_id',
'status': 'confirmed',
};
when(mockApiService.post(
'${ApiConfig.clubs}/events/$eventId/participants',
data: participantData,
)).thenAnswer((_) async => {'participant': testParticipant});
// when
final result = await eventService.addParticipant(eventId, participantData);
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events/$eventId/participants',
data: participantData,
)).called(1);
expect(result.id, 'test_participant_id');
expect(eventService.participants.length, 1);
});
test('updateParticipant 메서드가 참가자 정보를 업데이트해야 함', () async {
// given
final eventId = 'test_event_id';
final participantId = 'test_participant_id';
final updates = {'status': 'cancelled'};
final updatedParticipant = Map<String, dynamic>.from(testParticipant);
updatedParticipant['status'] = 'cancelled';
// 참가자 목록에 테스트 참가자 추가
when(mockApiService.post(
'${ApiConfig.clubs}/events/participants',
data: {'eventId': eventId},
)).thenAnswer((_) async => {'participants': [testParticipant]});
await eventService.fetchEventParticipants(eventId);
when(mockApiService.put(
'${ApiConfig.clubs}/events/$eventId/participants/$participantId',
data: updates,
)).thenAnswer((_) async => {'participant': updatedParticipant});
// when
final result = await eventService.updateParticipant(eventId, participantId, updates);
// then
verify(mockApiService.put(
'${ApiConfig.clubs}/events/$eventId/participants/$participantId',
data: updates,
)).called(1);
expect(result.status, 'cancelled');
expect(eventService.participants[0].status, 'cancelled');
});
test('removeParticipant 메서드가 참가자를 삭제해야 함', () async {
// given
final eventId = 'test_event_id';
final participantId = 'test_participant_id';
// 참가자 목록에 테스트 참가자 추가
when(mockApiService.post(
'${ApiConfig.clubs}/events/participants',
data: {'eventId': eventId},
)).thenAnswer((_) async => {'participants': [testParticipant]});
await eventService.fetchEventParticipants(eventId);
when(mockApiService.delete(
'${ApiConfig.clubs}/events/$eventId/participants/$participantId',
)).thenAnswer((_) async => {});
// when
final result = await eventService.removeParticipant(eventId, participantId);
// then
verify(mockApiService.delete(
'${ApiConfig.clubs}/events/$eventId/participants/$participantId',
)).called(1);
expect(result, true);
expect(eventService.participants.length, 0);
});
test('fetchEventScores 메서드가 점수 목록을 가져와야 함', () async {
// given
final eventId = 'test_event_id';
final testScores = [testScore];
when(mockApiService.post(
'${ApiConfig.clubs}/events/scores',
data: {'eventId': eventId},
)).thenAnswer((_) async => {'scores': testScores});
// when
final result = await eventService.fetchEventScores(eventId);
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events/scores',
data: {'eventId': eventId},
)).called(1);
expect(result.length, 1);
expect(result[0].id, 'test_score_id');
expect(result[0].participantName, '테스트 참가자');
});
test('addScore 메서드가 점수를 추가해야 함', () async {
// given
final eventId = 'test_event_id';
final scoreData = {
'participantId': 'test_participant_id',
'games': [180, 200, 220],
'handicap': 10,
};
when(mockApiService.post(
'${ApiConfig.clubs}/events/$eventId/scores',
data: scoreData,
)).thenAnswer((_) async => {'score': testScore});
// when
final result = await eventService.addScore(eventId, scoreData);
// then
verify(mockApiService.post(
'${ApiConfig.clubs}/events/$eventId/scores',
data: scoreData,
)).called(1);
expect(result.id, 'test_score_id');
expect(eventService.scores.length, 1);
});
});
}