import 'package:flutter_test/flutter_test.dart'; import 'package:halkyon_app/halkyon_app.dart'; import 'package:halkyon_app/testing.dart'; import 'package:material_ui/material_ui.dart'; /// Keeps what was copied, without the system's clipboard and its timer. class _Clipboard() implements SecretClipboard { final copied = []; @override Future copy(String text) async => copied.add(text); } void main() { late TestAppDependencies dependencies; late _Clipboard clipboard; setUp(() { dependencies = TestAppDependencies(); clipboard = _Clipboard(); }); Future show(WidgetTester tester) async { tester.view.physicalSize = const Size(1000, 1800); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); await tester.pumpWidget( testApp( Scaffold( body: SingleChildScrollView( child: AgentsSection(clipboard: clipboard), ), ), dependencies: dependencies, ), ); await tester.pumpAndSettle(); } Future make(WidgetTester tester, String handle) async { await tester.tap(find.text('Make an agent')); await tester.pumpAndSettle(); await tester.enterText(find.byType(TextField).first, 'Claude'); await tester.enterText(find.byType(TextField).last, handle); await tester.pump(); await tester.tap(find.widgetWithText(FilledButton, 'Make')); await tester.pumpAndSettle(); } testWidgets('nothing where the instance offers no agents', (tester) async { dependencies.agentGateway.isOffered = false; await show(tester); expect(find.text('Agents'), findsNothing); }); testWidgets('makes an agent and shows its token once, to copy', ( tester, ) async { await show(tester); expect(find.text('No agents yet.'), findsOneWidget); await make(tester, 'claude_bot'); expect(find.text('Token for @claude_bot'), findsOneWidget); expect(find.text('TOKEN-1'), findsOneWidget); await tester.tap(find.text('Copy token')); await tester.pump(); expect(clipboard.copied, ['TOKEN-1']); await tester.tap(find.text('Done')); await tester.pumpAndSettle(); expect(find.text('TOKEN-1'), findsNothing); expect(find.text('Claude'), findsOneWidget); expect(find.text('@claude_bot · never signed in'), findsOneWidget); }); testWidgets('a handle someone has is said so in the dialog', (tester) async { dependencies.agentGateway.taken.add('claude_bot'); await show(tester); await make(tester, 'claude_bot'); expect(find.text('Someone else has this handle.'), findsOneWidget); expect(find.byType(AlertDialog), findsOneWidget); expect(dependencies.agentGateway.agents, isEmpty); }); testWidgets('takes a token back and deletes, each once confirmed', ( tester, ) async { await show(tester); await make(tester, 'claude_bot'); await tester.tap(find.text('Done')); await tester.pumpAndSettle(); await tester.tap(find.byTooltip('Options for @claude_bot')); await tester.pumpAndSettle(); await tester.tap(find.text('Take back token')); await tester.pumpAndSettle(); expect(find.text("Take back @claude_bot's token?"), findsOneWidget); await tester.tap(find.widgetWithText(FilledButton, 'Take back token')); await tester.pumpAndSettle(); expect(find.text('@claude_bot · no token'), findsOneWidget); await tester.tap(find.byTooltip('Options for @claude_bot')); await tester.pumpAndSettle(); await tester.tap(find.text('Delete')); await tester.pumpAndSettle(); expect(find.text('Delete @claude_bot?'), findsOneWidget); await tester.tap(find.widgetWithText(FilledButton, 'Delete')); await tester.pumpAndSettle(); expect(find.text('No agents yet.'), findsOneWidget); expect(dependencies.agentGateway.agents, isEmpty); }); }