import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tasq/models/office.dart'; import 'package:tasq/widgets/multi_select_picker.dart'; void main() { testWidgets( 'SearchableMultiSelectDropdown: search / select-all / chips update', (WidgetTester tester) async { final offices = [ Office(id: 'o1', name: 'HQ'), Office(id: 'o2', name: 'Branch'), Office(id: 'o3', name: 'Remote'), ]; // Host state for selected IDs List selected = ['o1']; await tester.pumpWidget( MaterialApp( home: Scaffold( body: StatefulBuilder( builder: (context, setState) { return Padding( padding: const EdgeInsets.all(16.0), child: MultiSelectPicker( label: 'Offices', items: offices, selectedIds: selected, getId: (o) => o.id, getLabel: (o) => o.name, onChanged: (ids) => setState(() => selected = ids), ), ); }, ), ), ), ); // Initially the selected chip for 'HQ' must be visible expect(find.text('HQ'), findsOneWidget); expect(selected, equals(['o1'])); // Open dropdown dialog await tester.tap(find.text('Select')); await tester.pumpAndSettle(); // Dialog title present expect(find.text('Select Offices'), findsOneWidget); // All items are visible in the list initially expect(find.widgetWithText(CheckboxListTile, 'HQ'), findsOneWidget); expect(find.widgetWithText(CheckboxListTile, 'Branch'), findsOneWidget); expect(find.widgetWithText(CheckboxListTile, 'Remote'), findsOneWidget); // Search for 'Branch' -> only Branch should remain in the list final searchField = find.descendant( of: find.byType(AlertDialog), matching: find.byType(TextField), ); expect(searchField, findsOneWidget); await tester.enterText(searchField, 'Branch'); await tester.pumpAndSettle(); expect(find.widgetWithText(CheckboxListTile, 'Branch'), findsOneWidget); expect(find.widgetWithText(CheckboxListTile, 'HQ'), findsNothing); expect(find.widgetWithText(CheckboxListTile, 'Remote'), findsNothing); // Clear search, then use Select All await tester.enterText(searchField, ''); await tester.pumpAndSettle(); await tester.tap(find.widgetWithText(CheckboxListTile, 'Select All')); await tester.pumpAndSettle(); // Press Done to apply selection await tester.tap(find.text('Done')); await tester.pumpAndSettle(); // Now all chips should be present and selected list updated expect(find.text('HQ'), findsOneWidget); expect(find.text('Branch'), findsOneWidget); expect(find.text('Remote'), findsOneWidget); expect(selected.toSet(), equals({'o1', 'o2', 'o3'})); // Re-open dialog and uncheck 'HQ' await tester.tap(find.text('Select')); await tester.pumpAndSettle(); await tester.tap(find.widgetWithText(CheckboxListTile, 'HQ')); await tester.pumpAndSettle(); await tester.tap(find.text('Done')); await tester.pumpAndSettle(); // HQ chip should be removed, others remain expect(find.text('HQ'), findsNothing); expect(find.text('Branch'), findsOneWidget); expect(find.text('Remote'), findsOneWidget); expect(selected.toSet(), equals({'o2', 'o3'})); }, ); }