Files
sxchnge/frontend/app/test/verification_test.dart
T

134 lines
4.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:sxchnge_auth/sxchnge_auth.dart';
import 'package:sxchnge_app/main.dart';
import 'package:sxchnge_app/providers/locale.dart';
class RecoveringService implements VerificationService {
int sends = 0;
int confirmations = 0;
@override
Future<VerificationResult> send({
required String email,
required String locale,
}) async {
if (++sends == 1) throw StateError('private error');
return const VerificationResult(isSimulated: true);
}
@override
Future<VerificationResult> confirm({required String token}) async {
if (++confirmations == 1) throw StateError('private error');
return const VerificationResult(isSimulated: true);
}
}
Future<void> openVerification(
WidgetTester tester,
String route, {
VerificationService service = const DummyVerificationService(
delay: Duration.zero,
),
}) async {
tester.platformDispatcher.defaultRouteNameTestValue = route;
addTearDown(tester.platformDispatcher.clearDefaultRouteNameTestValue);
await tester.pumpWidget(SxchngeApp(verificationService: service));
await tester.pumpAndSettle();
}
void main() {
for (final scenario in {
'demo-valid': 'verified',
'demo-expired': 'expired',
'wrong': 'invalid',
'': 'invalid',
'demo-internal': 'error',
}.entries) {
testWidgets(
'confirmation link resolves ${scenario.key} as ${scenario.value}',
(tester) async {
await openVerification(tester, '/verify-email?token=${scenario.key}');
expect(
find.byKey(ValueKey('verification-${scenario.value}')),
findsOneWidget,
);
expect(find.textContaining('DEMO'), findsOneWidget);
expect(tester.takeException(), isNull);
},
);
}
testWidgets('internal confirmation error can retry without entering email', (
tester,
) async {
final service = RecoveringService();
await openVerification(
tester,
'/verify-email?token=opaque',
service: service,
);
expect(find.text('private error'), findsNothing);
final retry = find.byKey(const ValueKey('verification-retry'));
await tester.ensureVisible(retry);
await tester.tap(retry);
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('verification-verified')), findsOneWidget);
expect(service.confirmations, 2);
});
testWidgets(
'request validates email, reports send error and resends successfully',
(tester) async {
final service = RecoveringService();
await openVerification(tester, '/verification-sent', service: service);
final resend = find.byKey(const ValueKey('verification-resend'));
await tester.ensureVisible(resend);
await tester.tap(resend);
await tester.pumpAndSettle();
expect(find.text('Enter your email address.'), findsOneWidget);
expect(service.sends, 0);
await tester.enterText(
find.byKey(const ValueKey('verification-email')),
'alex@example.com',
);
await tester.ensureVisible(resend);
await tester.tap(resend);
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('verification-error')), findsOneWidget);
await tester.ensureVisible(resend);
await tester.tap(resend);
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('verification-sent')), findsOneWidget);
expect(service.sends, 2);
},
);
for (final route in [
'/verification-sent',
'/verify-email?token=demo-valid',
'/verify-email?token=demo-expired',
'/verify-email?token=bad',
'/verify-email?token=demo-internal',
]) {
testWidgets('$route fits narrow viewport at 200% in EN and RU', (
tester,
) async {
tester.view.physicalSize = const Size(320, 740);
tester.view.devicePixelRatio = 1;
tester.platformDispatcher.textScaleFactorTestValue = 2;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
addTearDown(tester.platformDispatcher.clearTextScaleFactorTestValue);
await openVerification(tester, route);
expect(tester.takeException(), isNull);
final element = tester.element(find.byType(Scaffold).first);
await element.read<LocaleProvider>().setLocale(const Locale('ru'));
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('locale-selector')), findsNothing);
expect(tester.takeException(), isNull);
});
}
}