137 lines
5.0 KiB
Dart
137 lines
5.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'package:lanebow/models/participant_model.dart';
|
|
import 'package:lanebow/services/event_service.dart';
|
|
import 'package:lanebow/screens/club/participant_form_screen.dart';
|
|
import '../../utils/event_bus_test_utils.dart';
|
|
import 'package:lanebow/utils/test_utils.dart';
|
|
|
|
// 공통 StubEventService 사용
|
|
import '../../utils/stub_event_service.dart';
|
|
import '../../utils/dummy_test_data.dart';
|
|
|
|
void main() {
|
|
late EventService stubEventService;
|
|
|
|
setUp(() async {
|
|
// EventBus 테스트 환경 초기화 (플래키 방지)
|
|
TestUtils.setTestMode(true);
|
|
await EventBusTestUtils.setUp('participant_form_screen_test');
|
|
stubEventService = StubEventService();
|
|
});
|
|
|
|
tearDown(() async {
|
|
await EventBusTestUtils.tearDown();
|
|
});
|
|
|
|
// 로컬 더미 생성기 제거: DummyTestData 공용 유틸 사용
|
|
|
|
// 위젯 빌더
|
|
Widget createParticipantForm({
|
|
required String eventId,
|
|
Participant? participant,
|
|
}) {
|
|
return MaterialApp(
|
|
home: ChangeNotifierProvider<EventService>.value(
|
|
value: stubEventService,
|
|
child: ParticipantFormScreen(
|
|
eventId: eventId,
|
|
participant: participant,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
group('ParticipantFormScreen 위젯 테스트', () {
|
|
testWidgets('새 참가자 추가 모드: 필수값 입력 후 저장 플로우', (tester) async {
|
|
await tester.pumpWidget(createParticipantForm(eventId: 'event1'));
|
|
await tester.pumpAndSettle();
|
|
|
|
// 이름 입력 (필수)
|
|
final nameField = find.widgetWithText(TextFormField, '이름 *');
|
|
expect(nameField, findsOneWidget);
|
|
await tester.enterText(nameField, '홍길동');
|
|
|
|
// 저장 아이콘 버튼 탭
|
|
await tester.tap(find.byIcon(Icons.save));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
await tester.pump(const Duration(seconds: 1));
|
|
|
|
// then: 화면이 pop 되었는지 확인 (성공 시 Navigator.pop(true) 호출)
|
|
expect(find.byType(ParticipantFormScreen), findsNothing);
|
|
});
|
|
|
|
testWidgets('참가자 수정 모드: 수정 후 저장 플로우', (tester) async {
|
|
// given
|
|
final existing = DummyTestData.participants(eventId: 'event1', count: 1, status: '확인됨').first;
|
|
|
|
await tester.pumpWidget(createParticipantForm(eventId: 'event1', participant: existing));
|
|
await tester.pumpAndSettle();
|
|
|
|
// 제목이 수정 모드로 표시되는지 확인
|
|
expect(find.text('참가자 수정'), findsWidgets);
|
|
|
|
// 이름 변경
|
|
final nameField = find.widgetWithText(TextFormField, '이름 *');
|
|
expect(nameField, findsOneWidget);
|
|
await tester.enterText(nameField, '수정된이름');
|
|
|
|
// 저장
|
|
await tester.tap(find.byIcon(Icons.save));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
await tester.pump(const Duration(seconds: 1));
|
|
|
|
// then: 화면이 pop 되었는지 확인
|
|
expect(find.byType(ParticipantFormScreen), findsNothing);
|
|
});
|
|
|
|
testWidgets('실패 케이스(추가): 스낵바 에러 노출, 로딩 해제, pop 미호출', (tester) async {
|
|
// given
|
|
(stubEventService as StubEventService).throwOnAddParticipant = true;
|
|
|
|
await tester.pumpWidget(createParticipantForm(eventId: 'event1'));
|
|
await tester.pumpAndSettle();
|
|
|
|
// 이름 입력
|
|
final nameField = find.widgetWithText(TextFormField, '이름 *');
|
|
expect(nameField, findsOneWidget);
|
|
await tester.enterText(nameField, '실패사례');
|
|
|
|
// when: 저장 클릭
|
|
await tester.tap(find.byIcon(Icons.save));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
await tester.pump(const Duration(seconds: 1));
|
|
|
|
// then: 화면이 여전히 존재 (pop 미호출)
|
|
expect(find.byType(ParticipantFormScreen), findsOneWidget);
|
|
// 에러 스낵바 노출
|
|
expect(find.textContaining('참가자 저장에 실패했습니다'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('실패 케이스(수정): 스낵바 에러 노출, 로딩 해제, pop 미호출', (tester) async {
|
|
// given
|
|
(stubEventService as StubEventService).throwOnUpdateParticipant = true;
|
|
final existing = DummyTestData.participants(eventId: 'event1', count: 1, status: '확인됨').first;
|
|
|
|
await tester.pumpWidget(createParticipantForm(eventId: 'event1', participant: existing));
|
|
await tester.pumpAndSettle();
|
|
|
|
// 이름 변경
|
|
final nameField = find.widgetWithText(TextFormField, '이름 *');
|
|
expect(nameField, findsOneWidget);
|
|
await tester.enterText(nameField, '변경실패');
|
|
|
|
// when: 저장 클릭
|
|
await tester.tap(find.byIcon(Icons.save));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
await tester.pump(const Duration(seconds: 1));
|
|
|
|
// then
|
|
expect(find.byType(ParticipantFormScreen), findsOneWidget);
|
|
expect(find.textContaining('참가자 저장에 실패했습니다'), findsOneWidget);
|
|
});
|
|
});
|
|
}
|