Files
IKAR/test/message_status_size_screen_test.dart

216 lines
7.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:ikar/core/config/app_message_status_size.dart';
import 'package:ikar/core/utils/haptics.dart';
import 'package:ikar/frontend/screens/profile/customization_section.dart';
import 'package:ikar/frontend/screens/profile/message_status_size_screen.dart';
import 'package:ikar/l10n/app_localizations.dart';
import 'package:ikar/main.dart' show api;
import 'package:shared_preferences/shared_preferences.dart';
final _slider = find.byKey(const ValueKey('message-status-size-slider'));
final _percent = find.byKey(const ValueKey('message-status-size-percent'));
Future<void> _pump(
WidgetTester tester, {
Widget home = const MessageStatusSizeScreen(),
Brightness brightness = Brightness.light,
Size size = const Size(360, 800),
double textScale = 1,
}) async {
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
await tester.pumpWidget(
MaterialApp(
locale: const Locale('ru'),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: brightness,
),
),
builder: (context, child) => MediaQuery(
data: MediaQuery.of(
context,
).copyWith(textScaler: TextScaler.linear(textScale)),
child: child!,
),
home: home,
),
);
await tester.pump();
}
Future<void> _finishAnimations(WidgetTester tester) async {
// The first frame lays out the expanded content and starts AnimatedSize.
await tester.pump();
await tester.pump(const Duration(milliseconds: 600));
await tester.pump();
}
void _expectPreviewSize(WidgetTester tester, double scale) {
for (final status in ['sent', 'delivered', 'read']) {
final receipt = find.byKey(ValueKey('message-status-preview-$status'));
final icon = tester.widget<Icon>(
find.descendant(of: receipt, matching: find.byType(Icon)),
);
expect(icon.size, closeTo(14 * scale, 0.000001), reason: status);
}
}
void main() {
late bool hapticsEnabled;
late bool fatalHitTestWarnings;
setUpAll(() => api.state);
setUp(() {
SharedPreferences.setMockInitialValues({});
AppMessageStatusSize.current.value = AppMessageStatusSize.defaultScale;
hapticsEnabled = Haptics.enabled;
Haptics.enabled = false;
fatalHitTestWarnings = WidgetController.hitTestWarningShouldBeFatal;
WidgetController.hitTestWarningShouldBeFatal = true;
});
tearDown(() {
AppMessageStatusSize.current.value = AppMessageStatusSize.defaultScale;
Haptics.enabled = hapticsEnabled;
WidgetController.hitTestWarningShouldBeFatal = fatalHitTestWarnings;
});
testWidgets('Russian customization opens the continuous size slider', (
tester,
) async {
await _pump(
tester,
home: const Scaffold(
body: SingleChildScrollView(child: CustomizationSection()),
),
);
expect(find.text('Галочки сообщений'), findsNothing);
await tester.tap(find.text('Кастомизация'));
await _finishAnimations(tester);
await tester.tap(find.text('Галочки сообщений'));
await _finishAnimations(tester);
expect(find.byType(MessageStatusSizeScreen), findsOneWidget);
final slider = tester.widget<Slider>(_slider);
expect(slider.min, 1.0);
expect(slider.max, 1.5);
expect(slider.divisions, isNull);
expect(slider.value, 1.0);
expect(tester.widget<Text>(_percent).data, '100%');
expect(find.text('Отправлено'), findsOneWidget);
expect(find.text('Доставлено'), findsOneWidget);
expect(find.text('Прочитано'), findsOneWidget);
_expectPreviewSize(tester, 1.0);
expect(
tester
.widget<TextButton>(find.widgetWithText(TextButton, 'Сбросить'))
.onPressed,
isNull,
);
expect(tester.takeException(), isNull);
});
testWidgets('drag updates previews and release saves before the debounce', (
tester,
) async {
await _pump(tester);
final prefs = await SharedPreferences.getInstance();
final rect = tester.getRect(_slider);
final gesture = await tester.startGesture(rect.center);
await gesture.moveTo(rect.center + Offset(rect.width * 0.08, 0));
await tester.pump();
final intermediate = AppMessageStatusSize.current.value;
expect(intermediate, greaterThan(1.0));
expect(intermediate, lessThan(1.5));
expect(tester.widget<Slider>(_slider).value, intermediate);
expect(
tester.widget<Text>(_percent).data,
'${(intermediate * 100).round()}%',
);
_expectPreviewSize(tester, intermediate);
expect(prefs.getDouble(AppMessageStatusSize.prefKey), isNull);
await gesture.up();
await tester.pump();
expect(prefs.getDouble(AppMessageStatusSize.prefKey), intermediate);
await tester.drag(_slider, const Offset(2000, 0));
await tester.pump();
expect(AppMessageStatusSize.current.value, 1.5);
expect(prefs.getDouble(AppMessageStatusSize.prefKey), 1.5);
expect(tester.widget<Text>(_percent).data, '150%');
_expectPreviewSize(tester, 1.5);
await tester.tap(find.widgetWithText(TextButton, 'Сбросить'));
await tester.pump();
expect(AppMessageStatusSize.current.value, 1.0);
expect(prefs.getDouble(AppMessageStatusSize.prefKey), 1.0);
expect(tester.widget<Slider>(_slider).value, 1.0);
_expectPreviewSize(tester, 1.0);
expect(tester.takeException(), isNull);
});
testWidgets('leaving the screen flushes a size and reopening restores it', (
tester,
) async {
await _pump(
tester,
home: const Scaffold(
body: SingleChildScrollView(child: CustomizationSection()),
),
);
await tester.tap(find.text('Кастомизация'));
await _finishAnimations(tester);
await tester.tap(find.text('Галочки сообщений'));
await _finishAnimations(tester);
tester.widget<Slider>(_slider).onChanged!(1.237);
await tester.pump();
Navigator.of(tester.element(find.byType(MessageStatusSizeScreen))).pop();
await _finishAnimations(tester);
final prefs = await SharedPreferences.getInstance();
expect(prefs.getDouble(AppMessageStatusSize.prefKey), 1.237);
AppMessageStatusSize.current.value = AppMessageStatusSize.defaultScale;
expect(await AppMessageStatusSize.load(), 1.237);
await tester.tap(find.text('Галочки сообщений'));
await _finishAnimations(tester);
expect(tester.widget<Slider>(_slider).value, 1.237);
expect(tester.widget<Text>(_percent).data, '124%');
_expectPreviewSize(tester, 1.237);
expect(tester.takeException(), isNull);
});
for (final brightness in Brightness.values) {
testWidgets('maximum size fits a small phone in ${brightness.name}', (
tester,
) async {
AppMessageStatusSize.current.value = AppMessageStatusSize.maxScale;
await _pump(
tester,
brightness: brightness,
size: const Size(320, 568),
textScale: 1.3,
);
_expectPreviewSize(tester, 1.5);
expect(tester.widget<Text>(_percent).data, '150%');
expect(tester.takeException(), isNull);
await tester.ensureVisible(find.widgetWithText(TextButton, 'Сбросить'));
await tester.pump();
await tester.tap(find.widgetWithText(TextButton, 'Сбросить'));
await tester.pump();
expect(AppMessageStatusSize.current.value, 1.0);
expect(tester.takeException(), isNull);
});
}
}