import 'package:flutter_test/flutter_test.dart'; import 'package:marianum_mobile/push/chat_thread_store.dart'; import 'package:marianum_mobile/push/push_actions.dart'; void main() { group('PushActions.finishReply', () { const token = 'chat1'; final thread = [ const ThreadMessage(nid: 1, sender: 'Max', text: 'Hi', timestampMs: 1), const ThreadMessage(nid: 2, sender: 'Max', text: 'Da?', timestampMs: 2), ]; test( 'successful reply removes the notification via chat cleanup', () async { var cleanups = 0; var renders = 0; var cancels = 0; await PushActions.finishReply( chatToken: token, sent: true, cleanupChat: (t) async { expect(t, token); cleanups++; }, loadThread: (_) async => thread, renderSilent: (_, _) async => renders++, cancelNotification: (_) async => cancels++, ); expect(cleanups, 1); expect(renders, 0); expect(cancels, 0); }, ); test('failed reply re-renders the unchanged thread exactly once', () async { var cleanups = 0; var renders = 0; List? rendered; await PushActions.finishReply( chatToken: token, sent: false, cleanupChat: (_) async => cleanups++, loadThread: (_) async => thread, renderSilent: (t, messages) async { expect(t, token); renders++; rendered = messages; }, cancelNotification: (_) async => fail('must not cancel'), ); expect(cleanups, 0); expect(renders, 1); // History unchanged — same messages, no self entry appended. expect(rendered!.map((m) => m.nid), [1, 2]); }); test( 'failed reply with empty history cancels to stop the spinner', () async { var cancels = 0; await PushActions.finishReply( chatToken: token, sent: false, cleanupChat: (_) async => fail('must not cleanup'), loadThread: (_) async => const [], renderSilent: (_, _) async => fail('nothing to render'), cancelNotification: (_) async => cancels++, ); expect(cancels, 1); }, ); }); }