import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:ikar/backend/modules/messages.dart'; import 'package:ikar/core/protocol/packet.dart'; import 'package:ikar/frontend/widgets/attachment/bubbles/bubble_context.dart'; const reason = 'Начать диалог не получится. Возможности профиля ограничены'; const original = CachedMessage( id: 'synthetic', accountId: 1, chatId: 2, senderId: 1, text: 'Synthetic text', time: 1, status: 'pending', payload: {'elements': >[]}, ); void main() { test( 'server rejection survives storage without changing message content', () { final failed = original.withSendFailure(const PacketError(reason)); final restored = CachedMessage.fromDbRow(failed.toDbRow()); expect(restored.sendFailure, reason); expect(restored.text, original.text); expect(restored.payload?['elements'], isEmpty); expect(restored.copyWith(status: 'sent').sendFailure, isNull); expect( original.withSendFailure(StateError('offline')).sendFailure, isNull, ); }, ); testWidgets('tapping the failed status shows the saved server reason', ( tester, ) async { final failed = original.withSendFailure(const PacketError(reason)); await tester.pumpWidget( MaterialApp( home: Scaffold( body: Builder( builder: (context) => Center( child: BubbleContext( context: context, cs: Theme.of(context).colorScheme, text: Colors.black, shape: BubbleShape.singleMiddle, contentType: MessageType.text, hasPhotoWithCaption: false, hasMultiplePhotosNoCaption: false, message: failed, isMe: true, myId: 1, chatType: 'DIALOG', ).statusIcon(), ), ), ), ), ); expect(find.text(reason), findsNothing); await tester.tap(find.byIcon(Symbols.error)); await tester.pump(); expect(find.text(reason), findsOneWidget); await tester.pump(const Duration(seconds: 3)); await tester.pumpAndSettle(); }); }