import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:network_app/features/auth/presentation/login_screen.dart'; import 'package:network_app/shared/providers/auth_provider.dart'; import 'package:network_app/shared/services/api_client.dart'; import 'package:mocktail/mocktail.dart'; class MockApiClient extends Mock implements ApiClient {} void main() { late MockApiClient mockApiClient; setUp(() { mockApiClient = MockApiClient(); }); Widget createTestWidget() { return ProviderScope( overrides: [ apiClientProvider.overrideWithValue(mockApiClient), ], child: MaterialApp( home: const LoginScreen(), ), ); } group('LoginScreen Widget Tests', () { testWidgets('renders login form', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); expect(find.text('Network App'), findsOneWidget); expect(find.text('Sign in to your account'), findsOneWidget); expect(find.byType(TextFormField), findsNWidgets(2)); expect(find.text('Sign In'), findsOneWidget); }); testWidgets('shows email field', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); expect(find.widgetWithText(TextFormField, 'Email'), findsOneWidget); }); testWidgets('shows password field', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); expect(find.widgetWithText(TextFormField, 'Password'), findsOneWidget); }); testWidgets('validates empty email', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); // Enter only password await tester.enterText( find.widgetWithText(TextFormField, 'Password'), 'password123', ); // Tap sign in await tester.tap(find.text('Sign In')); await tester.pumpAndSettle(); expect(find.text('Please enter your email'), findsOneWidget); }); testWidgets('validates invalid email format', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); await tester.enterText( find.widgetWithText(TextFormField, 'Email'), 'notanemail', ); await tester.enterText( find.widgetWithText(TextFormField, 'Password'), 'password123', ); await tester.tap(find.text('Sign In')); await tester.pumpAndSettle(); expect(find.text('Please enter a valid email'), findsOneWidget); }); testWidgets('validates empty password', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); await tester.enterText( find.widgetWithText(TextFormField, 'Email'), 'test@test.com', ); await tester.tap(find.text('Sign In')); await tester.pumpAndSettle(); expect(find.text('Please enter your password'), findsOneWidget); }); testWidgets('shows loading indicator when signing in', (tester) async { final completer = Completer>(); when(() => mockApiClient.getSession()).thenAnswer((_) async => null); when(() => mockApiClient.signIn( email: any(named: 'email'), password: any(named: 'password'), )).thenAnswer((_) => completer.future); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); await tester.enterText( find.widgetWithText(TextFormField, 'Email'), 'test@test.com', ); await tester.enterText( find.widgetWithText(TextFormField, 'Password'), 'password123', ); await tester.tap(find.text('Sign In')); await tester.pump(); expect(find.byType(CircularProgressIndicator), findsOneWidget); // Complete to cleanup completer.complete({'user': {'id': '1', 'email': 'test@test.com'}}); await tester.pumpAndSettle(); }); testWidgets('shows sign up link', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); expect(find.text("Don't have an account?"), findsOneWidget); expect(find.text('Sign Up'), findsOneWidget); }); testWidgets('shows error message on failed login', (tester) async { when(() => mockApiClient.getSession()).thenAnswer((_) async => null); when(() => mockApiClient.signIn( email: any(named: 'email'), password: any(named: 'password'), )).thenThrow(Exception('Invalid credentials')); await tester.pumpWidget(createTestWidget()); await tester.pumpAndSettle(); await tester.enterText( find.widgetWithText(TextFormField, 'Email'), 'test@test.com', ); await tester.enterText( find.widgetWithText(TextFormField, 'Password'), 'wrongpassword', ); await tester.tap(find.text('Sign In')); await tester.pumpAndSettle(); expect(find.text('Invalid email or password'), findsOneWidget); }); }); }