import 'package:lanebow/services/event_service.dart'; import 'package:lanebow/models/participant_model.dart'; import 'package:lanebow/models/score_model.dart'; import 'package:lanebow/models/event_model.dart'; import 'package:lanebow/models/team_model.dart'; /// 테스트 공통 StubEventService /// - 네트워크/인증 의존성을 제거 /// - 각 메서드별 실패 시뮬레이션 플래그 제공 class StubEventService extends EventService { bool throwOnAddParticipant = false; bool throwOnUpdateParticipant = false; bool throwOnAddScore = false; bool throwOnUpdateScore = false; bool throwOnCloneEvent = false; bool throwOnCreateEvent = false; // Observability for tests bool lastCloneCalled = false; String? lastClonedEventId; Map? lastCreatedEventData; // Seeded events for tests List _seededEvents = []; set seededEvents(List events) => _seededEvents = List.from(events); @override List get events => List.from(_seededEvents); @override Future addParticipant(String eventId, Map data) async { if (throwOnAddParticipant) { throw Exception('의도한 실패(addParticipant)'); } return Participant( id: 'stub_p', memberId: (data['memberId'] ?? 'stub_member').toString(), name: (data['name'] ?? '이름없음').toString(), eventId: eventId, ); } @override Future cloneEvent(String eventId, {String? newName}) async { if (throwOnCloneEvent) { throw Exception('의도한 실패(cloneEvent)'); } lastCloneCalled = true; lastClonedEventId = eventId; final now = DateTime.now(); final e = Event( id: 'cloned_$eventId', clubId: 'club1', title: (newName ?? '복사본'), startDate: now, status: 'draft', isActive: true, ); // 목록 변경 알림만 수행 notifyListeners(); return e; } @override Future createEvent(Map eventData) async { if (throwOnCreateEvent) { throw Exception('의도한 실패(createEvent)'); } lastCreatedEventData = Map.from(eventData); final now = DateTime.now(); final e = Event( id: 'new_event', clubId: (eventData['clubId'] ?? 'club1') as String, title: (eventData['title'] ?? '제목없음') as String, description: eventData['description'] as String?, location: eventData['location'] as String?, startDate: DateTime.tryParse(eventData['startDate'] as String? ?? '') ?? now, endDate: (eventData['endDate'] != null) ? DateTime.tryParse(eventData['endDate'] as String) : null, status: (eventData['status'] ?? 'draft') as String, publicHash: eventData['publicHash'] as String?, accessPassword: eventData['accessPassword'] as String?, gameCount: eventData['gameCount'] as int?, participantFee: (eventData['participantFee'] as num?)?.toDouble(), maxParticipants: eventData['maxParticipants'] as int?, isActive: true, ); notifyListeners(); return e; } @override Future updateParticipant(String eventId, String participantId, Map data) async { if (throwOnUpdateParticipant) { throw Exception('의도한 실패(updateParticipant)'); } return Participant( id: participantId, memberId: (data['memberId'] ?? 'stub_member').toString(), name: (data['name'] ?? '이름없음').toString(), eventId: eventId, ); } @override Future addScore(String eventId, Map scoreData) async { if (throwOnAddScore) { throw Exception('의도한 실패(addScore)'); } return Score( id: 'stub_score', memberId: (scoreData['memberId'] ?? 'member1').toString(), eventId: eventId, clubId: 'club1', frames: (scoreData['frames'] as List?)?.cast() ?? const [], totalScore: (scoreData['totalScore'] as int?) ?? 0, handicap: scoreData['handicap'] as int?, date: DateTime.now(), notes: scoreData['notes'] as String?, ); } @override Future updateScore(String eventId, String scoreId, Map scoreData) async { if (throwOnUpdateScore) { throw Exception('의도한 실패(updateScore)'); } return Score( id: scoreId, memberId: (scoreData['memberId'] ?? 'member1').toString(), eventId: eventId, clubId: 'club1', frames: (scoreData['frames'] as List?)?.cast() ?? const [], totalScore: (scoreData['totalScore'] as int?) ?? 0, handicap: scoreData['handicap'] as int?, date: DateTime.now(), notes: scoreData['notes'] as String?, ); } // --- Stubbed fetch methods to avoid network in widget tests --- @override Future fetchClubEvents() async { // simulate quick load without network notifyListeners(); } @override Future> fetchEventParticipants(String eventId) async { return []; } @override Future> fetchEventScores(String eventId) async { return []; } @override Future> fetchEventTeams(String eventId) async { return []; } @override Future fetchEventById(String eventId) async { return Event( id: eventId, clubId: 'club1', title: '원본', startDate: DateTime.now(), status: 'active', isActive: true, ); } }