feat: Complete Phase 1 Authentication and setup Flutter project structure
- Completed authentication system with signup, login, password reset, and logout - Enhanced error handling and accessibility across all auth flows - Added comprehensive loading states and user feedback - Implemented confirmation dialogs for destructive actions - Setup complete Flutter project structure with proper configuration - Added planning documentation for Phase 2 household creation - All Phase 1 success criteria verified and complete
This commit is contained in:
144
test/integration_test/auth_flow_test.dart
Normal file
144
test/integration_test/auth_flow_test.dart
Normal file
@@ -0,0 +1,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:sage/main.dart' as app;
|
||||
import 'package:sage/core/router/app_router.dart';
|
||||
|
||||
/// Integration test for password reset flow
|
||||
///
|
||||
/// Tests the complete password reset journey:
|
||||
/// 1. Navigate to password reset from login
|
||||
/// 2. Request password reset
|
||||
/// 3. Handle deep link with token
|
||||
/// 4. Update password
|
||||
/// 5. Navigate back to login
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('Password Reset Flow', () {
|
||||
testWidgets('complete password reset flow works correctly', (WidgetTester tester) async {
|
||||
// Launch app
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Start from login screen (if not already there)
|
||||
// Navigate to password reset
|
||||
final forgotPasswordButton = find.text('Forgot Password?');
|
||||
expect(forgotPasswordButton, findsOneWidget);
|
||||
|
||||
await tester.tap(forgotPasswordButton);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Should be on reset password page
|
||||
expect(find.text('Reset Password'), findsOneWidget);
|
||||
expect(find.text('Forgot Password?'), findsOneWidget);
|
||||
|
||||
// Test deep linking by simulating URL with token
|
||||
// This would normally be triggered by email link
|
||||
final context = tester.element(find.byType(Scaffold));
|
||||
|
||||
// Navigate to reset password confirm with token
|
||||
GoRouter.of(context).go('/reset-password-confirm?token=test123&email=test@example.com');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Should be on reset password confirm page
|
||||
expect(find.text('Reset Password'), findsOneWidget);
|
||||
|
||||
// Navigate to update password with token
|
||||
GoRouter.of(context).go('/update-password?token=test123&email=test@example.com');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Should be on update password page
|
||||
expect(find.text('Update Password'), findsOneWidget);
|
||||
expect(find.text('Set New Password'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('password reset navigation from signup works', (WidgetTester tester) async {
|
||||
// Launch app
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Navigate to signup first
|
||||
final signupButton = find.text('Sign Up');
|
||||
if (signupButton.evaluate().isNotEmpty) {
|
||||
await tester.tap(signupButton);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
// Look for forgot password link on signup page
|
||||
final signupForgotPassword = find.text('Forgot Password?');
|
||||
expect(signupForgotPassword, findsOneWidget);
|
||||
|
||||
await tester.tap(signupForgotPassword);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Should navigate to reset password page
|
||||
expect(find.text('Reset Password'), findsOneWidget);
|
||||
expect(find.text('Forgot Password?'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('deep linking handles malformed URLs gracefully', (WidgetTester tester) async {
|
||||
// Launch app
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Test malformed reset URL
|
||||
final context = tester.element(find.byType(Scaffold));
|
||||
GoRouter.of(context).go('/reset-password-invalid');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Should show error page with option to request new reset
|
||||
expect(find.text('Page not found'), findsOneWidget);
|
||||
expect(find.text('Request New Reset Link'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('router extracts URL parameters correctly', (WidgetTester tester) async {
|
||||
// Launch app
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Navigate with URL parameters
|
||||
final context = tester.element(find.byType(Scaffold));
|
||||
GoRouter.of(context).go('/reset-password-confirm?token=abc123&email=user@example.com');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Extract parameters using router helper
|
||||
final params = AppRouter.extractQueryParameters(context);
|
||||
expect(params['token'], 'abc123');
|
||||
expect(params['email'], 'user@example.com');
|
||||
|
||||
// Test deep link handler
|
||||
final resetData = AppRouter.handlePasswordResetDeepLink(context);
|
||||
expect(resetData['token'], 'abc123');
|
||||
expect(resetData['email'], 'user@example.com');
|
||||
});
|
||||
});
|
||||
|
||||
group('Navigation Guards', () {
|
||||
testWidgets('password reset routes are accessible without auth', (WidgetTester tester) async {
|
||||
// Launch app
|
||||
app.main();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Test all password reset routes are accessible
|
||||
final context = tester.element(find.byType(Scaffold));
|
||||
|
||||
// Test /reset-password
|
||||
GoRouter.of(context).go('/reset-password');
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Reset Password'), findsOneWidget);
|
||||
|
||||
// Test /reset-password-confirm
|
||||
GoRouter.of(context).go('/reset-password-confirm');
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Reset Password'), findsOneWidget);
|
||||
|
||||
// Test /update-password
|
||||
GoRouter.of(context).go('/update-password');
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Update Password'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user