104 lines
3.8 KiB
Dart
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);
|
|
});
|
|
});
|
|
}
|