import 'package:commons_core/commons_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tane/services/message_store.dart'; import 'package:tane/services/unread_service.dart'; import 'package:tane/ui/unread_badge.dart'; import '../support/test_support.dart'; /// The badge is driven by [UnreadService]: it shows a count when there are /// unread messages and clears when they're read — live, over the service's /// `changes` stream. Injecting the service avoids the `getIt` lookup. The store /// reads are real async, so mutations run inside `runAsync`. void main() { late MessageStore store; late UnreadService unread; setUp(() { store = MessageStore(InMemorySecretStore()); unread = UnreadService(store, InMemorySecretStore()); }); tearDown(() => unread.dispose()); Widget host() => MaterialApp( home: Scaffold( body: UnreadBadge( peer: 'alice', service: unread, child: const Icon(Icons.chat_bubble), ), ), ); Future receive(int atMs) async { final m = PrivateMessage( fromPubkey: 'alice', text: 'hi', at: DateTime.fromMillisecondsSinceEpoch(atMs)); await store.append('alice', m); await unread.onMessageReceived('alice', m); } // Lets pending async (store reads + the widget's stream-driven refresh) // resolve in the real zone, then renders a frame. Future pumpRefresh(WidgetTester tester) async { for (var i = 0; i < 5; i++) { await tester.runAsync( () => Future.delayed(const Duration(milliseconds: 20))); await tester.pump(); } } testWidgets('shows an existing unread count on build', (tester) async { await tester.runAsync(() => receive(1000)); await tester.pumpWidget(host()); await pumpRefresh(tester); expect(find.text('1'), findsOneWidget); }); testWidgets('reacts to a new message and to being read', (tester) async { await tester.pumpWidget(host()); await pumpRefresh(tester); expect(find.text('1'), findsNothing); await tester.runAsync(() => receive(1000)); await pumpRefresh(tester); expect(find.text('1'), findsOneWidget); await tester.runAsync(() => unread.markRead('alice')); await pumpRefresh(tester); expect(find.text('1'), findsNothing); }); }