import 'package:commons_core/commons_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tane/i18n/strings.g.dart'; import 'package:tane/state/peer_rating_cubit.dart'; import 'package:tane/ui/rating_sheet.dart'; /// In-memory [RatingTransport] (one live rating per pair). class FakeRatingTransport implements RatingTransport { FakeRatingTransport(this.selfId); final String selfId; final Map byRater = {}; @override Future rate({ required String subjectPubkey, required int stars, String comment = '', }) async => byRater[selfId] = Rating( rater: selfId, subject: subjectPubkey, stars: stars, ratedAt: DateTime(2026), comment: comment, ); @override Future retract({required String subjectPubkey}) async => byRater.remove(selfId); @override Future> ratingsOf(String subjectPubkey) async => List.of(byRater.values); @override Future myRatingOf(String subjectPubkey) async => byRater[selfId]; @override Future close() async {} } void main() { const me = 'me'; const peer = 'peer'; late FakeRatingTransport transport; late PeerRatingCubit cubit; setUp(() async { LocaleSettings.setLocaleSync(AppLocale.en); transport = FakeRatingTransport(me); cubit = PeerRatingCubit(transport, peerPubkey: peer, selfPubkey: me); await cubit.load(); }); tearDown(() => cubit.close()); Widget host() => TranslationProvider( child: MaterialApp( locale: AppLocale.en.flutterLocale, supportedLocales: AppLocaleUtils.supportedLocales, localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], home: Scaffold( body: Builder( builder: (context) => Center( child: TextButton( onPressed: () => showRatingSheet(context, cubit), child: const Text('open'), ), ), ), ), ), ); testWidgets('picking stars and saving publishes the rating', (tester) async { await tester.pumpWidget(host()); await tester.tap(find.text('open')); await tester.pumpAndSettle(); expect(find.text('Rate this person'), findsOneWidget); // Save is disabled until stars are picked. expect( tester.widget(find.byKey(const Key('rating.save'))).enabled, isFalse, ); await tester.tap(find.byKey(const Key('rating.star.4'))); await tester.pump(); await tester.enterText( find.byKey(const Key('rating.comment')), 'Great swap'); await tester.tap(find.byKey(const Key('rating.save'))); await tester.pumpAndSettle(); final mine = transport.byRater[me]!; expect(mine.stars, 4); expect(mine.comment, 'Great swap'); expect(find.text('Rating saved'), findsOneWidget); // snackbar }); testWidgets('opens pre-filled when you already rated; retract removes', (tester) async { await cubit.rate(3, comment: 'Fine'); await tester.pumpWidget(host()); await tester.tap(find.text('open')); await tester.pumpAndSettle(); expect(find.text('Edit your rating'), findsOneWidget); expect(find.text('Fine'), findsOneWidget); // comment pre-filled await tester.tap(find.byKey(const Key('rating.retract'))); await tester.pumpAndSettle(); expect(transport.byRater, isEmpty); }); }