start quesitonnaire

This commit is contained in:
verboomp
2026-02-19 11:04:02 +01:00
parent 168fc986f2
commit 9b3446685a
47 changed files with 2456 additions and 97 deletions

View File

@@ -0,0 +1,200 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fotodocumentation/controller/login_controller.dart';
import 'package:fotodocumentation/dto/jwt_token_pair_dto.dart';
import 'package:fotodocumentation/pages/questionnaire/login/questionnaire_login_widget.dart';
import 'package:fotodocumentation/utils/di_container.dart';
import 'package:fotodocumentation/utils/global_router.dart';
import 'package:fotodocumentation/utils/login_credentials.dart';
import 'package:mockito/mockito.dart';
import '../../../testing/test_utils.dart';
import '../../../testing/test_utils.mocks.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
DiContainer.instance.initState();
late MockLoginController mockLoginController;
late MockLoginCredentials mockLoginCredentials;
setUp(() {
mockLoginController = MockLoginController();
mockLoginCredentials = MockLoginCredentials();
when(mockLoginCredentials.isLoggedIn).thenReturn(false);
DiContainer.instance.put(LoginController, mockLoginController);
DiContainer.instance.put(LoginCredentials, mockLoginCredentials);
});
group('LoginWidget', () {
testWidgets('displays login title', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
await pumpApp(tester, const QuestionaireLoginWidget());
await tester.pumpAndSettle();
// Verify the login title is displayed (German localization)
expect(find.byKey(const Key('login_title')), findsOneWidget);
});
testWidgets('displays username and password fields', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
await pumpApp(tester, const QuestionaireLoginWidget());
await tester.pumpAndSettle();
// Verify username field exists
expect(find.byKey(const Key("username")), findsOneWidget);
// Verify password field exists
expect(find.byKey(const Key("password")), findsOneWidget);
});
testWidgets('displays login button', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
await pumpApp(tester, const QuestionaireLoginWidget());
await tester.pumpAndSettle();
// Verify login button exists
expect(find.byKey(const Key("SubmitWidgetButton")), findsOneWidget);
});
testWidgets('can enter username and password', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
await pumpApp(tester, const QuestionaireLoginWidget());
await tester.pumpAndSettle();
// Enter username
await tester.enterText(find.byKey(const Key("username")), 'testuser');
await tester.pumpAndSettle();
// Enter password
await tester.enterText(find.byKey(const Key("password")), 'testpassword');
await tester.pumpAndSettle();
// Verify text was entered
expect(find.text('testuser'), findsOneWidget);
});
testWidgets('calls authenticate on login button tap', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
final jwtTokenPairDto = JwtTokenPairDto(
accessToken: 'test_access_token',
refreshToken: 'test_refresh_token',
);
when(mockLoginController.authenticate('testuser', 'testpassword'))
.thenAnswer((_) async => (jwtTokenPairDto: jwtTokenPairDto));
await pumpAppConfig(tester, GlobalRouter.pathFotoLogin);
await tester.pumpAndSettle();
// Enter credentials
await tester.enterText(find.byKey(const Key("username")), 'testuser');
await tester.enterText(find.byKey(const Key("password")), 'testpassword');
await tester.pumpAndSettle();
// Tap login button
await tester.tap(find.byKey(const Key("SubmitWidgetButton")));
await tester.pumpAndSettle();
// Verify authenticate was called with correct credentials
verify(mockLoginController.authenticate('testuser', 'testpassword')).called(1);
});
testWidgets('sets logged in on successful authentication', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
final jwtTokenPairDto = JwtTokenPairDto(
accessToken: 'test_access_token',
refreshToken: 'test_refresh_token',
);
when(mockLoginController.authenticate('testuser', 'testpassword'))
.thenAnswer((_) async => (jwtTokenPairDto: jwtTokenPairDto));
await pumpAppConfig(tester, GlobalRouter.pathFotoLogin);
await tester.pumpAndSettle();
// Enter credentials
await tester.enterText(find.byKey(const Key("username")), 'testuser');
await tester.enterText(find.byKey(const Key("password")), 'testpassword');
await tester.pumpAndSettle();
// Tap login button
await tester.tap(find.byKey(const Key("SubmitWidgetButton")));
await tester.pumpAndSettle();
// Verify setLoggedIn was called
verify(mockLoginCredentials.setLoggedIn(true)).called(1);
});
testWidgets('displays error message on failed authentication', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
when(mockLoginController.authenticate('testuser', 'wrongpassword'))
.thenAnswer((_) async => (jwtTokenPairDto: null));
await pumpAppConfig(tester, GlobalRouter.pathFotoLogin);
await tester.pumpAndSettle();
// Enter credentials
await tester.enterText(find.byKey(const Key("username")), 'testuser');
await tester.enterText(find.byKey(const Key("password")), 'wrongpassword');
await tester.pumpAndSettle();
// Tap login button
await tester.tap(find.byKey(const Key("SubmitWidgetButton")));
await tester.pumpAndSettle();
// Verify error message is displayed (German localization)
expect(find.text('Falscher Benutzername oder Passwort'), findsOneWidget);
});
testWidgets('does not call setLoggedIn on failed authentication', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
when(mockLoginController.authenticate('testuser', 'wrongpassword'))
.thenAnswer((_) async => (jwtTokenPairDto: null));
await pumpApp(tester, const QuestionaireLoginWidget());
await tester.pumpAndSettle();
// Enter credentials
await tester.enterText(find.byKey(const Key("username")), 'testuser');
await tester.enterText(find.byKey(const Key("password")), 'wrongpassword');
await tester.pumpAndSettle();
// Tap login button
await tester.tap(find.byKey(const Key("SubmitWidgetButton")));
await tester.pumpAndSettle();
// Verify setLoggedIn was NOT called
verifyNever(mockLoginCredentials.setLoggedIn(any));
});
testWidgets('password field obscures text', (WidgetTester tester) async {
setScreenSize(tester, 1024, 1024);
await pumpApp(tester, const QuestionaireLoginWidget());
await tester.pumpAndSettle();
// Find the EditableText descendant of the password field
// TextFormField wraps TextField which contains EditableText
final passwordFieldFinder = find.byKey(const Key("password"));
final editableTextFinder = find.descendant(
of: passwordFieldFinder,
matching: find.byType(EditableText),
);
final editableText = tester.widget<EditableText>(editableTextFinder);
// Verify obscureText is true
expect(editableText.obscureText, isTrue);
});
});
}