-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8cbc4dc
commit deb4d79
Showing
6 changed files
with
99 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,30 @@ | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:flutter_template/core/di/di_provider.dart'; | ||
import 'package:flutter_template/core/repository/session_repository.dart'; | ||
import 'package:flutter_template/core/source/auth_remote_source.dart'; | ||
import 'package:flutter_template/core/source/project_remote_source.dart'; | ||
import 'package:flutter_template/main.dart' as app; | ||
import 'package:flutter_template/ui/router/app_router.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
|
||
import 'repository_mocks.dart'; | ||
|
||
Future<void> commonSetup( | ||
MockSessionRepository mockSessionRepository, | ||
AppRouter appRouter, | ||
) async { | ||
Future<void> commonSetup({ | ||
required MockAuthRemoteSource mockAuthRemoteSource, | ||
required MockProjectRemoteSource mockProjectRemoteSource, | ||
}) async { | ||
await app.initSdks(); | ||
|
||
DiProvider.instance.unregister<SessionRepository>(); | ||
DiProvider.instance.unregister<AppRouter>(); | ||
DiProvider.instance.unregister<AuthRemoteSource>(); | ||
DiProvider.instance.unregister<ProjectRemoteSource>(); | ||
|
||
DiProvider.instance.registerSingleton<AuthRemoteSource>(mockAuthRemoteSource); | ||
DiProvider.instance | ||
.registerSingleton<SessionRepository>(mockSessionRepository); | ||
DiProvider.instance.registerSingleton<AppRouter>(appRouter); | ||
.registerSingleton<ProjectRemoteSource>(mockProjectRemoteSource); | ||
} | ||
|
||
extension WidgetTesterExtension on WidgetTester { | ||
BuildContext contextOfType<T extends Widget>() { | ||
final finder = find.byType(T); | ||
expect(finder, findsOneWidget); | ||
return element(finder); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
import 'package:flutter_template/core/repository/session_repository.dart'; | ||
import 'package:flutter_template/core/source/auth_remote_source.dart'; | ||
import 'package:flutter_template/core/source/project_remote_source.dart'; | ||
import 'package:mocktail/mocktail.dart'; | ||
|
||
class MockSessionRepository extends Mock implements SessionRepository {} | ||
class MockProjectRemoteSource extends Mock implements ProjectRemoteSource {} | ||
|
||
class MockAuthRemoteSource extends Mock implements AuthRemoteSource {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,93 @@ | ||
import 'dart:async'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_template/core/common/network_exceptions.dart'; | ||
import 'package:flutter_template/core/di/di_provider.dart'; | ||
import 'package:flutter_template/core/model/authentication_status.dart'; | ||
import 'package:flutter_template/core/model/service/auth_models.dart'; | ||
import 'package:flutter_template/core/model/user.dart'; | ||
import 'package:flutter_template/main.dart' as app; | ||
import 'package:flutter_template/ui/extensions/context_extensions.dart'; | ||
import 'package:flutter_template/ui/router/app_router.dart'; | ||
import 'package:flutter_template/ui/section/error_handler/global_event_handler_cubit.dart'; | ||
import 'package:flutter_template/ui/signin/signin_screen.dart'; | ||
import 'package:flutter_template/ui/welcome/welcome_screen.dart'; | ||
import 'package:mocktail/mocktail.dart'; | ||
import 'package:integration_test/integration_test.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:rxdart/rxdart.dart'; | ||
import 'package:mocktail/mocktail.dart'; | ||
|
||
import '../common/general_helpers.dart'; | ||
import '../common/repository_mocks.dart'; | ||
|
||
void main() { | ||
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); | ||
|
||
late MockSessionRepository mockSessionRepository; | ||
late AppRouter appRouter; | ||
late BuildContext context; | ||
late StreamController<AuthenticationStatus> statusController; | ||
late MockAuthRemoteSource mockAuthRemoteSource; | ||
late MockProjectRemoteSource mockProjectRemoteSource; | ||
|
||
setUp(() async { | ||
mockSessionRepository = MockSessionRepository(); | ||
statusController = BehaviorSubject() | ||
..add(AuthenticationStatus.unauthenticated); | ||
when(() => mockSessionRepository.status) | ||
.thenAnswer((_) => statusController.stream); | ||
appRouter = AppRouter(mockSessionRepository); | ||
await commonSetup(mockSessionRepository, appRouter); | ||
mockAuthRemoteSource = MockAuthRemoteSource(); | ||
mockProjectRemoteSource = MockProjectRemoteSource(); | ||
await commonSetup( | ||
mockAuthRemoteSource: mockAuthRemoteSource, | ||
mockProjectRemoteSource: mockProjectRemoteSource, | ||
); | ||
}); | ||
|
||
tearDown(() { | ||
DiProvider.instance.reset(); | ||
statusController.close(); | ||
}); | ||
group('SignIn screen tests', () { | ||
const email = "[email protected]"; | ||
const password = "test"; | ||
|
||
testWidgets('SignIn with wrong credentials', (WidgetTester tester) async { | ||
mockSignInUser(false, mockSessionRepository, statusController); | ||
await Future.delayed(const Duration(seconds: 2)); | ||
when(() => mockAuthRemoteSource.signIn(email, password)).thenAnswer( | ||
(_) => Future.error( | ||
const NetworkException.unauthorizedRequest("Unauthorized"), | ||
), | ||
); | ||
|
||
await tester.pumpWidget(const app.MyApp()); | ||
await tester.pumpAndSettle(); | ||
context = tester.element(find.byType(SignInScreen)); | ||
|
||
final context = tester.contextOfType<SignInScreen>(); | ||
await tester.enterText( | ||
find.widgetWithText(TextField, context.localizations.mail), | ||
'[email protected]', | ||
email, | ||
); | ||
await tester.enterText( | ||
find.widgetWithText(TextField, context.localizations.password), | ||
'1234', | ||
password, | ||
); | ||
await tester.tap( | ||
find.widgetWithText(TextButton, context.localizations.sign_in), | ||
); | ||
await tester | ||
.tap(find.widgetWithText(TextButton, context.localizations.sign_in)); | ||
await tester.pumpAndSettle(); | ||
expect(find.byType(AlertDialog), findsOneWidget); | ||
}); | ||
testWidgets('SignIn with correct credentials', (WidgetTester tester) async { | ||
mockSignInUser(true, mockSessionRepository, statusController); | ||
await Future.delayed(const Duration(seconds: 2)); | ||
when(() => mockAuthRemoteSource.signIn(email, password)).thenAnswer( | ||
(_) => Future.value( | ||
SignInResponse( | ||
accessToken: "testing-token", | ||
user: User(email: "[email protected]"), | ||
), | ||
), | ||
); | ||
when(() => mockProjectRemoteSource.getProjects()) | ||
.thenAnswer((_) => Future.value([])); | ||
|
||
await tester.pumpWidget(const app.MyApp()); | ||
await tester.pumpAndSettle(); | ||
context = tester.element(find.byType(SignInScreen)); | ||
|
||
final context = tester.contextOfType<SignInScreen>(); | ||
await tester.enterText( | ||
find.widgetWithText(TextField, context.localizations.mail), | ||
'[email protected]', | ||
email, | ||
); | ||
await tester.enterText( | ||
find.widgetWithText(TextField, context.localizations.password), | ||
'xmartlabs', | ||
password, | ||
); | ||
await tester | ||
.tap(find.widgetWithText(TextButton, context.localizations.sign_in)); | ||
await tester.pumpAndSettle(); | ||
await Future.delayed(const Duration(seconds: 2)); | ||
expect(find.byType(WelcomeScreen), findsOneWidget); | ||
}); | ||
}); | ||
} | ||
|
||
void mockSignInUser( | ||
bool correctCredentials, | ||
MockSessionRepository mockSessionRepository, | ||
StreamController<AuthenticationStatus> statusController, | ||
) => | ||
when( | ||
() => mockSessionRepository.signInUser( | ||
email: '[email protected]', | ||
password: correctCredentials ? 'xmartlabs' : '1234', | ||
), | ||
).thenAnswer( | ||
correctCredentials | ||
? (_) async { | ||
statusController.add(AuthenticationStatus.authenticated); | ||
} | ||
: (_) => Future.error( | ||
const UnknownError('Ops! Something went wrong'), | ||
), | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test/signin_test.dart --flavor dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import 'package:integration_test/integration_test_driver.dart'; | ||
|
||
Future<void> main() => integrationDriver(); |