Files
bowlingManager/mobile/test/screens/club/team_generation_test.dart
T
2025-08-12 03:28:08 +09:00

283 lines
8.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lanebow/models/event_model.dart';
import 'package:lanebow/models/participant_model.dart';
import 'package:lanebow/models/team_model.dart';
import 'package:lanebow/services/event_service.dart';
import 'package:lanebow/services/event_bus.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'test_event_details_screen.dart';
// 이벤트 서비스 모킹을 위한 어노테이션
@GenerateMocks([EventService])
import 'team_generation_test.mocks.dart';
void main() {
late MockEventService mockEventService;
late Event testEvent;
// 테스트 설정
setUp(() {
// EventBus 초기화
EventBus().reset();
mockEventService = MockEventService();
// 테스트용 이벤트 데이터 생성
testEvent = Event(
id: '1',
clubId: '1',
title: '테스트 이벤트',
description: '테스트 설명',
type: '팀전',
status: '예정',
startDate: DateTime.now(),
endDate: DateTime.now().add(const Duration(hours: 3)),
location: '테스트 볼링장',
maxParticipants: 20,
gameCount: 3,
participantFee: 10000,
registrationDeadline: DateTime.now().add(const Duration(days: 1)),
publicHash: 'test123',
accessPassword: 'pass123',
isActive: true,
);
// 참가자 데이터 모킹
final testParticipants = [
Participant(
id: '1',
eventId: '1',
memberId: '1',
name: '참가자 1',
status: '확정',
isPaid: true,
registeredAt: DateTime.now(),
),
Participant(
id: '2',
eventId: '1',
memberId: '2',
name: '참가자 2',
status: '확정',
isPaid: true,
registeredAt: DateTime.now(),
),
Participant(
id: '3',
eventId: '1',
memberId: '3',
name: '참가자 3',
status: '확정',
isPaid: true,
registeredAt: DateTime.now(),
),
Participant(
id: '4',
eventId: '1',
memberId: '4',
name: '참가자 4',
status: '확정',
isPaid: true,
registeredAt: DateTime.now(),
),
Participant(
id: '5',
eventId: '1',
memberId: '5',
name: '참가자 5',
status: '확정',
isPaid: true,
registeredAt: DateTime.now(),
),
Participant(
id: '6',
eventId: '1',
memberId: '6',
name: '참가자 6',
status: '확정',
isPaid: true,
registeredAt: DateTime.now(),
),
];
when(mockEventService.fetchEventParticipants(any))
.thenAnswer((_) async => testParticipants);
when(mockEventService.fetchEventTeams(any))
.thenAnswer((_) async => <Team>[]);
});
tearDown(() {
// 테스트 종료 후 EventBus 초기화
EventBus().reset();
});
Widget createEventDetailsScreen() {
return MaterialApp(
home: ChangeNotifierProvider<EventService>.value(
value: mockEventService,
child: TestEventDetailsScreen(event: testEvent),
),
);
}
group('팀 생성 옵션 UI 테스트', () {
testWidgets('팀 생성 옵션이 올바르게 표시되어야 함', (WidgetTester tester) async {
// given
await tester.pumpWidget(createEventDetailsScreen());
await tester.pumpAndSettle();
// 팀 탭으로 이동
await tester.tap(find.text('팀').first);
await tester.pumpAndSettle();
// then
// 팀 생성 옵션 확인
expect(find.text('팀 생성 옵션'), findsOneWidget);
expect(find.text('팀 인원수로 나누기'), findsOneWidget);
expect(find.text('팀 개수로 나누기'), findsOneWidget);
// 라디오 버튼 확인
expect(find.byType(Radio<int>), findsNWidgets(2));
// 팀 생성 버튼 확인
expect(find.text('팀 생성하기'), findsOneWidget);
});
testWidgets('팀 인원수 옵션 선택 시 인원수 입력 필드가 표시되어야 함', (WidgetTester tester) async {
// given
await tester.pumpWidget(createEventDetailsScreen());
await tester.pumpAndSettle();
// 팀 탭으로 이동
await tester.tap(find.text('팀').first);
await tester.pumpAndSettle();
// when
// 팀 인원수로 나누기 라디오 버튼 선택
await tester.tap(find.text('팀 인원수로 나누기'));
await tester.pumpAndSettle();
// then
// 인원수 입력 필드 확인
expect(find.text('인원수:'), findsOneWidget);
expect(find.textContaining('총'), findsOneWidget);
});
testWidgets('팀 개수 옵션 선택 시 팀 수 입력 필드가 표시되어야 함', (WidgetTester tester) async {
// given
await tester.pumpWidget(createEventDetailsScreen());
await tester.pumpAndSettle();
// 팀 탭으로 이동
await tester.tap(find.text('팀').first);
await tester.pumpAndSettle();
// when
// 팀 개수로 나누기 라디오 버튼 선택
// 라디오 버튼을 찾아 탭
await tester.tap(find.byType(Radio<int>).at(1));
await tester.pumpAndSettle();
// then
// 팀 수 입력 필드 확인
// TextField 위젯이 있는지 확인
expect(find.byType(TextField), findsWidgets);
// 팀 수 라벨 확인
expect(find.text('팀 수:'), findsOneWidget);
// 참가자 수 확인
expect(find.textContaining('총'), findsOneWidget);
});
testWidgets('팀 생성 버튼 클릭 시 팀이 생성되어야 함', (WidgetTester tester) async {
// given
await tester.pumpWidget(createEventDetailsScreen());
await tester.pumpAndSettle();
// 팀 탭으로 이동
await tester.tap(find.text('팀').first);
await tester.pumpAndSettle();
// when
// 팀 생성 버튼 클릭
await tester.tap(find.text('팀 생성하기'));
await tester.pumpAndSettle();
// then
// 팀 생성 확인 메시지 확인
expect(find.byType(SnackBar), findsOneWidget);
expect(find.text('팀이 생성되었습니다'), findsOneWidget);
});
});
group('팀 에버리지/핸디캡 계산 및 표시 테스트', () {
testWidgets('팀 에버리지가 올바르게 계산되고 표시되어야 함', (WidgetTester tester) async {
// given
// 팀 데이터 모킹
final testTeams = [
Team(
id: '1',
eventId: '1',
name: 'A',
memberIds: ['1', '2', '3'],
),
];
when(mockEventService.fetchEventTeams(any))
.thenAnswer((_) async => testTeams);
await tester.pumpWidget(createEventDetailsScreen());
await tester.pumpAndSettle();
// 팀 탭으로 이동
await tester.tap(find.text('팀').first);
await tester.pumpAndSettle();
// then
// 팀 에버리지 표시 확인
expect(find.textContaining('팀 에버리지:'), findsOneWidget);
});
});
group('미배정 인원 표시 테스트', () {
testWidgets('미배정 참가자가 올바르게 표시되어야 함', (WidgetTester tester) async {
// given
// 팀 데이터 모킹 (일부 참가자만 배정)
final testTeams = [
Team(
id: '1',
eventId: '1',
name: 'A',
memberIds: ['1', '2', '3'],
),
];
when(mockEventService.fetchEventTeams(any))
.thenAnswer((_) async => testTeams);
await tester.pumpWidget(createEventDetailsScreen());
await tester.pumpAndSettle();
// 팀 탭으로 이동
await tester.tap(find.text('팀').first);
await tester.pumpAndSettle();
// then
// 미배정 참가자 섹션 확인
// 미배정 참가자 텍스트 확인 - Card 내부의 Text 위젯으로 표시됨
// 텍스트 스타일이 적용된 경우 정확한 텍스트 매칭이 어려울 수 있으므로 참가자 이름만 확인
// 미배정 참가자 섹션이 존재하는지 확인
expect(find.byType(Card), findsWidgets);
// 실제 구현에서 미배정 참가자 텍스트가 어떻게 표시되는지 확인
// 텍스트 스타일이 적용된 경우 정확한 텍스트 매칭이 어려울 수 있으므로 텍스트 타입으로 확인
expect(find.byType(Text), findsWidgets);
});
});
}