216 lines
7.6 KiB
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);
|
|
});
|
|
}
|
|
}
|