import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:go_router/go_router.dart'; import 'package:tane/app.dart' show materialLocaleFor; import 'package:tane/db/database.dart'; import 'package:tane/db/enums.dart'; import 'package:tane/i18n/strings.g.dart'; import 'package:tane/ui/plantares_screen.dart'; import '../support/test_support.dart'; /// The Plantares screen used to hide the data it stored: no date, no link to /// the seed. These pin the surfaced version — a named, dated, tappable /// commitment with an overdue nudge. void main() { late AppDatabase db; setUp(() => db = newTestDatabase()); tearDown(() => db.close()); testWidgets('a tile names the linked seed and flags an overdue return-by', (tester) async { final repo = newTestRepository(db); final vid = await repo.addQuickVariety(label: 'Tomate rosa'); await repo.createPlantare( direction: PlantareDirection.iReturn, varietyId: vid, counterparty: 'Ana', dueBy: DateTime(2000, 1, 1).millisecondsSinceEpoch, // long past → overdue ); await tester.pumpWidget( wrapScreen(repository: repo, child: const PlantaresScreen()), ); await tester.pump(); // let the Drift stream emit await tester.pump(const Duration(milliseconds: 100)); expect(find.textContaining('Tomate rosa'), findsOneWidget); expect(find.textContaining('Ana'), findsOneWidget); expect(find.textContaining('Return by'), findsOneWidget); expect(find.textContaining('overdue'), findsOneWidget); await disposeTree(tester); }); testWidgets('an open commitment with no due date shows no overdue flag', (tester) async { final repo = newTestRepository(db); final vid = await repo.addQuickVariety(label: 'Maíz'); await repo.createPlantare( direction: PlantareDirection.owedToMe, varietyId: vid, ); await tester.pumpWidget( wrapScreen(repository: repo, child: const PlantaresScreen()), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); expect(find.textContaining('overdue'), findsNothing); expect(find.textContaining('Return by'), findsNothing); await disposeTree(tester); }); testWidgets('a fully-signed bilateral pledge shows the "signed by both" badge', (tester) async { LocaleSettings.setLocaleSync(AppLocale.en); final repo = newTestRepository(db); await repo.createPlantare( direction: PlantareDirection.owedToMe, counterparty: 'Ana', pledgeId: 'p-1', debtorKey: 'dk', creditorKey: 'ck', debtorSignature: 'ds', creditorSignature: 'cs', remoteState: PlantareRemoteState.accepted, ); await tester.pumpWidget( wrapScreen(repository: repo, child: const PlantaresScreen()), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); expect(find.text('Signed by both'), findsOneWidget); // No accept/decline for a closed deal. expect(find.byKey(const Key('plantare.accept.')), findsNothing); await disposeTree(tester); }); testWidgets('a pending proposal shows the "awaiting signature" badge', (tester) async { LocaleSettings.setLocaleSync(AppLocale.en); final repo = newTestRepository(db); await repo.createPlantare( direction: PlantareDirection.iReturn, counterparty: 'Ben', pledgeId: 'p-2', debtorKey: 'dk', creditorKey: 'ck', creditorSignature: 'cs', // proposer (creditor) signed; I (debtor) haven't remoteState: PlantareRemoteState.proposed, ); await tester.pumpWidget( wrapScreen(repository: repo, child: const PlantaresScreen()), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); expect(find.text('Awaiting signature'), findsOneWidget); await disposeTree(tester); }); testWidgets('tapping a linked commitment opens its variety', (tester) async { final repo = newTestRepository(db); final vid = await repo.addQuickVariety(label: 'Judía'); await repo.createPlantare( direction: PlantareDirection.iReturn, varietyId: vid, ); LocaleSettings.setLocaleSync(AppLocale.en); final router = GoRouter( routes: [ GoRoute( path: '/', builder: (_, _) => const PlantaresScreen(), ), GoRoute( path: '/variety/:id', builder: (_, state) => Scaffold(body: Text('variety ${state.pathParameters['id']}')), ), ], ); await tester.pumpWidget( TranslationProvider( child: RepositoryProvider.value( value: repo, child: MaterialApp.router( routerConfig: router, locale: materialLocaleFor(AppLocale.en.flutterLocale), supportedLocales: AppLocaleUtils.supportedLocales, localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], ), ), ), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); await tester.tap(find.byType(ListTile).first); await tester.pumpAndSettle(); expect(find.text('variety $vid'), findsOneWidget); await disposeTree(tester); }); }