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

187 lines
6.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sxchnge_app/auth/validation.dart';
import 'package:sxchnge_app/main.dart';
import 'package:sxchnge_app/generated/i18n/app_localizations_en.dart';
Future<void> openApp(
WidgetTester tester, {
Size size = const Size(390, 844),
double scale = 1,
}) async {
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1;
tester.platformDispatcher.textScaleFactorTestValue = scale;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
addTearDown(tester.platformDispatcher.clearTextScaleFactorTestValue);
await tester.pumpWidget(const SxchngeApp());
await tester.pumpAndSettle();
}
Future<void> submit(WidgetTester tester) async {
final button = find.byKey(const ValueKey('submit'));
await tester.ensureVisible(button);
await tester.tap(button);
await tester.pumpAndSettle();
}
void main() {
final l = AppLocalizationsEn();
test(
'validation rejects malformed email and mismatched signup passwords',
() {
for (final email in ['', 'user', 'user@', 'user @example.com']) {
expect(AuthValidation.email(email, l), isNotNull);
}
expect(AuthValidation.email(' user+tag@example.com ', l), isNull);
expect(AuthValidation.password('short', l, signUp: true), isNotNull);
expect(AuthValidation.password('short', l, signUp: false), isNull);
expect(
AuthValidation.confirmation('different', 'password', l),
isNotNull,
);
expect(AuthValidation.name(' ', l), isNotNull);
},
);
testWidgets(
'login validates, toggles password, and submits with the keyboard',
(tester) async {
await openApp(tester);
await submit(tester);
expect(find.text('Enter your email address.'), findsOneWidget);
expect(find.text('Enter your password.'), findsOneWidget);
expect(
tester.testTextInput.log.where(
(call) => call.method == 'TextInput.finishAutofillContext',
),
isEmpty,
);
await tester.enterText(
find.byKey(const ValueKey('email')),
'test@example.com',
);
await tester.enterText(
find.byKey(const ValueKey('password')),
'example-password',
);
await tester.tap(find.byTooltip('Show password'));
await tester.pump();
expect(
tester
.widget<TextField>(
find.descendant(
of: find.byKey(const ValueKey('password')),
matching: find.byType(TextField),
),
)
.obscureText,
isFalse,
);
await tester.testTextInput.receiveAction(TextInputAction.done);
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('preview-result')), findsOneWidget);
expect(
tester.testTextInput.log,
contains(
isMethodCall('TextInput.finishAutofillContext', arguments: true),
),
);
expect(tester.takeException(), isNull);
},
);
testWidgets(
'signup validates confirmation and clears credentials when switching',
(tester) async {
await openApp(tester);
await tester.tap(find.text('Sign up'));
await tester.pumpAndSettle();
await tester.enterText(find.byKey(const ValueKey('name')), 'Alex');
await tester.enterText(
find.byKey(const ValueKey('email')),
'alex@example.com',
);
await tester.enterText(
find.byKey(const ValueKey('password')),
'example-password',
);
await tester.enterText(
find.byKey(const ValueKey('confirmation')),
'different',
);
await submit(tester);
expect(find.text('Passwords do not match.'), findsOneWidget);
expect(
tester.testTextInput.log,
isNot(
contains(
isMethodCall('TextInput.finishAutofillContext', arguments: true),
),
),
);
await tester.enterText(
find.byKey(const ValueKey('confirmation')),
'example-password',
);
await submit(tester);
expect(find.byKey(const ValueKey('verification-sent')), findsOneWidget);
expect(
tester.testTextInput.log,
contains(
isMethodCall('TextInput.finishAutofillContext', arguments: true),
),
);
await tester.ensureVisible(
find.byKey(const ValueKey('demo-confirmation')),
);
await tester.tap(find.byKey(const ValueKey('demo-confirmation')));
await tester.pumpAndSettle();
expect(
find.byKey(const ValueKey('verification-verified')),
findsOneWidget,
);
await tester.ensureVisible(find.text('Continue to login'));
await tester.tap(find.text('Continue to login'));
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('confirmation')), findsNothing);
expect(find.text('example-password'), findsNothing);
expect(find.byKey(const ValueKey('preview-result')), findsNothing);
expect(tester.takeException(), isNull);
},
);
testWidgets('resizing preserves the selected mode and entered values', (
tester,
) async {
await openApp(tester, size: const Size(1440, 1000));
await tester.tap(find.text('Sign up'));
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(const ValueKey('email')),
'alex@example.com',
);
tester.view.physicalSize = const Size(390, 844);
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('name')), findsOneWidget);
expect(find.text('alex@example.com'), findsOneWidget);
expect(tester.takeException(), isNull);
});
for (final size in [const Size(320, 740), const Size(1440, 1000)]) {
testWidgets('both modes fit $size at 200% text scale', (tester) async {
await openApp(tester, size: size, scale: 2);
expect(tester.takeException(), isNull);
await tester.ensureVisible(find.text('Sign up'));
await tester.tap(find.text('Sign up'));
await tester.pumpAndSettle();
await submit(tester);
expect(tester.takeException(), isNull);
});
}
}