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/score_model.dart'; import 'package:lanebow/models/team_model.dart'; import 'package:lanebow/screens/club/tabs/teams_tab.dart'; void main() { group('TeamsTab 드래그앤드롭 이동 콜백 테스트', () { testWidgets('DragTarget onAccept 시 onMoveParticipant가 올바른 인자로 호출된다', (tester) async { // given: 두 팀과 참가자 목록 final event = Event( id: 'ev1', clubId: 'c1', title: 'E', type: 'team', status: 'draft', startDate: DateTime.now(), isActive: true, ); final participants = [ Participant(id: 'p1', eventId: 'ev1', memberId: 'm1', name: 'A'), Participant(id: 'p2', eventId: 'ev1', memberId: 'm2', name: 'B'), ]; final teams = [ Team(id: 't1', eventId: 'ev1', name: 'A', memberIds: ['m1']), Team(id: 't2', eventId: 'ev1', name: 'B', memberIds: ['m2']), ]; Map? captured; await tester.pumpWidget( MaterialApp( home: Scaffold( body: TeamsTab( event: event, isLoading: false, teams: teams, participants: participants, scores: const [], teamGenerationMethod: 1, teamSizeController: TextEditingController(text: '4'), teamCountController: TextEditingController(text: '2'), unassignedParticipants: const [], onChangeTeamGenerationMethod: (_) {}, onGenerateTeams: () {}, onSaveTeams: () {}, onRemoveFromTeam: (_, __) {}, onShowParticipantSelectionDialog: (_) {}, onShowTeamSelectionDialog: (_) {}, calculateTeamAverage: (_) => 0, onShareEvent: () {}, onMoveParticipant: (p, from, to, toIndex) { captured = { 'p': p, 'from': from, 'to': to, 'toIndex': toIndex, }; }, ), ), ), ); await tester.pumpAndSettle(); // when: 두 번째 팀 카드의 DragTarget을 찾아 onAccept를 직접 호출 // 첫 DragTarget은 리스트 첫 카드이므로, 두 번째를 선택하여 from(A) -> to(B) 시나리오로 검증 final dragTargets = find.byType(DragTarget); expect(dragTargets, findsWidgets); final dragTargetWidget = tester.widget>>(dragTargets.at(1)); final onAccept = dragTargetWidget.onAccept; expect(onAccept, isNotNull); // LongPressDraggable가 전달하는 데이터 포맷을 재현 final data = { 'participant': participants.firstWhere((e) => e.memberId == 'm1'), 'fromTeam': teams.first, }; onAccept!.call(data); // then: 콜백 인자 검증 expect(captured, isNotNull); expect((captured!['p'] as Participant).id, 'p1'); expect((captured!['from'] as Team).id, 't1'); expect((captured!['to'] as Team).id, 't2'); // toIndex는 대상 팀 현재 길이(=1) 끝에 삽입 expect(captured!['toIndex'], 1); }); }); }