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/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'; // 모킹 클래스 생성 @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 { // SharedPreferences 모킹 SharedPreferences.setMockInitialValues({ ApiConfig.clubIdKey: testClubId, }); // API 서비스 모킹 mockApiService = MockApiService(); // EventService 초기화 (테스트용 생성자 사용) eventService = EventService.forTest(mockApiService); // 토큰 설정 await eventService.initialize(testToken); // 클럽 ID 설정 eventService.setClubId(testClubId); }); 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.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.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); }); }); }