233 lines
7.6 KiB
Dart
233 lines
7.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.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/config/app_message_status_size.dart';
|
|
import 'package:ikar/frontend/widgets/message_bubble.dart';
|
|
import 'package:ikar/frontend/widgets/message_status_icon.dart';
|
|
import 'package:ikar/frontend/widgets/text_with_meta.dart';
|
|
import 'package:ikar/l10n/app_localizations.dart';
|
|
|
|
void main() {
|
|
setUp(() => AppMessageStatusSize.current.value = 1);
|
|
tearDown(() => AppMessageStatusSize.current.value = 1);
|
|
|
|
testWidgets('receipt icons retain their base size and resize live', (
|
|
tester,
|
|
) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Scaffold(
|
|
body: Row(
|
|
children: [
|
|
MessageStatusIcon(icon: Symbols.check, size: 12),
|
|
MessageStatusIcon(icon: Symbols.done, size: 13),
|
|
MessageStatusIcon(icon: Symbols.done_all, size: 14),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
void expectSizes(double scale) {
|
|
for (final (icon, baseSize) in [
|
|
(Symbols.check, 12.0),
|
|
(Symbols.done, 13.0),
|
|
(Symbols.done_all, 14.0),
|
|
]) {
|
|
final finder = find.byIcon(icon);
|
|
expect(tester.widget<Icon>(finder).size, baseSize * scale);
|
|
expect(tester.getSize(finder), Size.square(baseSize * scale));
|
|
}
|
|
}
|
|
|
|
expectSizes(1);
|
|
AppMessageStatusSize.current.value = 1.237;
|
|
await tester.pump();
|
|
expectSizes(1.237);
|
|
AppMessageStatusSize.current.value = 1.5;
|
|
await tester.pump();
|
|
expectSizes(1.5);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('error and pending icons keep their size', (tester) async {
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Scaffold(
|
|
body: Row(
|
|
children: [
|
|
MessageStatusIcon(icon: Symbols.error, size: 14),
|
|
MessageStatusIcon(icon: Symbols.schedule, size: 14),
|
|
Icon(Symbols.check, size: 14),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
AppMessageStatusSize.current.value = 1.5;
|
|
await tester.pump();
|
|
|
|
for (final icon in [Symbols.error, Symbols.schedule, Symbols.check]) {
|
|
final finder = find.byIcon(icon);
|
|
expect(tester.widget<Icon>(finder).size, 14);
|
|
expect(tester.getSize(finder), const Size.square(14));
|
|
}
|
|
});
|
|
|
|
for (final text in ['Hi', 'A longer message that fills several lines']) {
|
|
testWidgets('enlarged receipts remain inside text metadata: $text', (
|
|
tester,
|
|
) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: ConstrainedBox(
|
|
constraints: const BoxConstraints(maxWidth: 140),
|
|
child: TextWithMeta(
|
|
key: const ValueKey('text-with-meta'),
|
|
text: Text(text, style: const TextStyle(fontSize: 16)),
|
|
meta: const Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text('12:34', style: TextStyle(fontSize: 10)),
|
|
SizedBox(width: 4),
|
|
MessageStatusIcon(icon: Symbols.done_all, size: 14),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
AppMessageStatusSize.current.value = 1.5;
|
|
await tester.pump();
|
|
|
|
final parent = tester.getRect(
|
|
find.byKey(const ValueKey('text-with-meta')),
|
|
);
|
|
final icon = tester.getRect(find.byIcon(Symbols.done_all));
|
|
expect(icon.size, const Size.square(21));
|
|
expect(icon.left, greaterThanOrEqualTo(parent.left));
|
|
expect(icon.top, greaterThanOrEqualTo(parent.top));
|
|
expect(icon.right, lessThanOrEqualTo(parent.right));
|
|
expect(icon.bottom, lessThanOrEqualTo(parent.bottom));
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
}
|
|
|
|
testWidgets('padded receipts fit the final line of a multiline caption', (
|
|
tester,
|
|
) async {
|
|
const caption = 'First line\nHi';
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Align(
|
|
alignment: Alignment.topLeft,
|
|
child: ConstrainedBox(
|
|
constraints: const BoxConstraints(maxWidth: 200),
|
|
child: TextWithMeta(
|
|
key: const ValueKey('caption-with-meta'),
|
|
fillWidth: true,
|
|
text: const Text(
|
|
caption,
|
|
style: TextStyle(fontSize: 16, height: 1.3),
|
|
),
|
|
meta: const Padding(
|
|
key: ValueKey('caption-meta'),
|
|
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 2),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text('12:34', style: TextStyle(fontSize: 10)),
|
|
SizedBox(width: 4),
|
|
MessageStatusIcon(icon: Symbols.done_all, size: 14),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
AppMessageStatusSize.current.value = 1.5;
|
|
await tester.pump();
|
|
|
|
final paragraph = tester.renderObject<RenderParagraph>(find.text(caption));
|
|
final caret = paragraph.getOffsetForCaret(
|
|
TextPosition(offset: caption.length),
|
|
Rect.zero,
|
|
);
|
|
final finalLineTop = paragraph.localToGlobal(caret).dy;
|
|
final text = tester.getRect(find.text(caption));
|
|
final parent = tester.getRect(
|
|
find.byKey(const ValueKey('caption-with-meta')),
|
|
);
|
|
final meta = tester.getRect(find.byKey(const ValueKey('caption-meta')));
|
|
|
|
expect(caret.dy, greaterThan(0));
|
|
expect(caret.dx + 8 + meta.width, lessThanOrEqualTo(parent.width));
|
|
expect(meta.height, 25);
|
|
expect(meta.top, greaterThanOrEqualTo(finalLineTop - 0.01));
|
|
expect(meta.top, lessThan(text.bottom));
|
|
expect(meta.bottom, lessThanOrEqualTo(parent.bottom));
|
|
expect(
|
|
tester.getSize(find.byIcon(Symbols.done_all)),
|
|
const Size.square(21),
|
|
);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('an existing own message receives scale and read updates', (
|
|
tester,
|
|
) async {
|
|
final readTime = ValueNotifier<int>(0);
|
|
addTearDown(readTime.dispose);
|
|
final message = CachedMessage(
|
|
id: 'status-scale-test',
|
|
accountId: 1,
|
|
chatId: 2,
|
|
senderId: 1,
|
|
text: 'Hi',
|
|
time: 1000,
|
|
status: 'sent',
|
|
);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
locale: const Locale('ru'),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Scaffold(
|
|
body: Align(
|
|
alignment: Alignment.topRight,
|
|
child: MessageBubble(
|
|
message: message,
|
|
isMe: true,
|
|
myId: 1,
|
|
chatType: 'DIALOG',
|
|
otherReadTime: readTime,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
expect(tester.widget<Icon>(find.byIcon(Symbols.check)).size, 14);
|
|
|
|
AppMessageStatusSize.current.value = 1.5;
|
|
await tester.pump();
|
|
expect(tester.widget<Icon>(find.byIcon(Symbols.check)).size, 21);
|
|
|
|
readTime.value = message.time;
|
|
await tester.pump();
|
|
expect(find.byIcon(Symbols.check), findsNothing);
|
|
expect(tester.widget<Icon>(find.byIcon(Symbols.done_all)).size, 21);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
}
|