Files
bowlingManager/mobile/test/screens/club/events_screen_import_test.dart
T

104 lines
3.8 KiB
Dart

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:lanebow/screens/club/events_screen.dart';
import 'package:lanebow/services/auth_service.dart';
import 'package:lanebow/services/club_service.dart';
import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/models/event_model.dart';
import 'package:lanebow/services/api_service.dart';
// Stub AuthService: 항상 토큰을 제공해 _loadEvents 내 initialize(token!) 경로가 실패하지 않도록 함
class StubAuthService extends AuthService {
@override
String? get token => 'test-token';
}
// Stub EventService: 네트워크 호출 없이 createEventsFromFile만 성공 처리
class StubEventService extends EventService {
StubEventService() : super.forTest(ApiService());
@override
Future<List<Event>> createEventsFromFile(List<Map<String, dynamic>> eventsData) async {
// 입력된 맵을 Event로 변환하여 반환 (필수 필드만 셋업)
final List<Event> created = [];
for (var i = 0; i < eventsData.length; i++) {
final e = eventsData[i];
created.add(Event(
id: 'e$i',
clubId: (e['clubId']?.toString() ?? 'club-1'),
title: (e['title']?.toString() ?? 'Untitled'),
startDate: DateTime.tryParse(e['startDate']?.toString() ?? '') ?? DateTime(2025, 1, 1),
endDate: null,
location: e['location']?.toString(),
type: e['type']?.toString(),
status: e['status']?.toString(),
maxParticipants: null,
currentParticipants: null,
gameCount: null,
participantFee: null,
registrationDeadline: null,
publicHash: null,
accessPassword: null,
isActive: true,
));
}
return created;
}
}
void main() {
group('EventsScreen 파일 업로드 플로우', () {
testWidgets('CSV 바이트 주입으로 성공 플로우 및 결과 다이얼로그 표시/닫기', (tester) async {
final auth = StubAuthService();
final club = ClubService.forTest(ApiService()); // 호출되지 않지만 타입 만족
final event = StubEventService();
await tester.pumpWidget(
MultiProvider(
providers: [
ChangeNotifierProvider<AuthService>.value(value: auth),
ChangeNotifierProvider<ClubService>.value(value: club),
ChangeNotifierProvider<EventService>.value(value: event),
],
child: const MaterialApp(home: EventsScreen()),
),
);
await tester.pump();
// CSV 본문 구성: 2 유효, 1 무효(title 누락)
const csv = 'title,startDate,endDate,description,location,status,type,maxParticipants\n'
'Match A,2025-10-01,,,,,,\n'
',2025-10-02,,,,,,\n'
'Match B,2025-10-03,,,,,,\n';
final bytes = Uint8List.fromList(csv.codeUnits);
// 테스트 전용 훅으로 임포트 실행
final stateFinder = find.byType(EventsScreen);
expect(stateFinder, findsOneWidget);
final state = tester.state(stateFinder);
await (state as dynamic).importFromBytesForTest('sample.csv', bytes);
// 결과 다이얼로그 표시 확인
await tester.pumpAndSettle(const Duration(milliseconds: 300));
expect(find.text('파일 처리 결과'), findsOneWidget);
expect(find.textContaining('생성된 이벤트:'), findsOneWidget);
expect(find.textContaining('유효하지 않은 행:'), findsOneWidget);
// 닫기 눌러 닫힘 확인
final closeBtn = find.text('닫기');
expect(closeBtn, findsOneWidget);
await tester.tap(closeBtn);
await tester.pumpAndSettle();
// 다이얼로그 사라짐
expect(find.text('파일 처리 결과'), findsNothing);
});
});
}