import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';
import 'package:machweis/core/auth/auth_client.dart';
import 'package:machweis/core/auth/auth_store.dart';
import 'package:machweis/features/auth/presentation/welcome_screen.dart';
class _MemoryAuthTokenStorage implements AuthTokenStorage {
String? accessToken;
String? refreshToken;
@override
Future<void> deleteTokens() async {
accessToken = null;
refreshToken = null;
}
@override
Future<String?> readRefreshToken() async => refreshToken;
@override
Future<void> writeTokens({
required String accessToken,
required String refreshToken,
}) async {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
}
}
void main() {
testWidgets(
'Tippen auf Anmelden zeigt vor dem HTTP-Aufruf einen Ladezustand',
(tester) async {
final response = Completer<Response>();
final store = AuthStore(
client: AuthClient(
client: MockClient((_) => response.future),
baseUrl: 'https://api.example.test',
),
storage: _MemoryAuthTokenStorage(),
);
await tester.pumpWidget(
MaterialApp(home: WelcomeScreen(authStore: store)),
);
await tester.tap(find.text('Demo starten'));
await tester.pump();
await tester.enterText(
find.widgetWithText(TextField, 'E-Mail'),
'test@example.com',
);
await tester.enterText(
find.widgetWithText(TextField, 'Passwort'),
'secret',
);
await tester.tap(find.text('Anmelden'));
await tester.pump();
expect(find.text('Anmeldung läuft …'), findsOneWidget);
response.complete(
Response(
jsonEncode({
'data': {
'accessToken': 'access',
'refreshToken': 'refresh',
'user': {'id': 'user', 'email': 'test@example.com'},
'tenantId': 'tenant',
'role': 'owner',
},
}),
200,
),
);
await tester.pumpAndSettle();
expect(store.status, AuthStatus.signedIn);
},
);
testWidgets('Loginfehler wird im Formular sichtbar angezeigt', (
tester,
) async {
final store = AuthStore(
client: AuthClient(
client: MockClient(
(_) async => Response(
jsonEncode({
'error': {'code': 'authentication_failed'},
}),
401,
),
),
baseUrl: 'https://api.example.test',
),
storage: _MemoryAuthTokenStorage(),
);
await tester.pumpWidget(MaterialApp(home: WelcomeScreen(authStore: store)));
await tester.tap(find.text('Demo starten'));
await tester.pump();
await tester.tap(find.text('Anmelden'));
await tester.pumpAndSettle();
expect(
find.text('E-Mail oder Passwort sind nicht korrekt.'),
findsOneWidget,
);
expect(store.status, AuthStatus.signedOut);
});
testWidgets('Betriebsregistrierung verlangt und sendet Mehrfachauswahl', (
tester,
) async {
Map<String, dynamic>? requestBody;
final store = AuthStore(
client: AuthClient(
client: MockClient((request) async {
requestBody = jsonDecode(request.body) as Map<String, dynamic>;
return Response(
jsonEncode({
'data': {
'accessToken': 'access',
'refreshToken': 'refresh',
'user': {'id': 'user', 'email': 'test@example.com'},
'tenantId': 'tenant',
'role': 'owner',
},
}),
201,
);
}),
baseUrl: 'https://api.example.test',
),
storage: _MemoryAuthTokenStorage(),
);
await tester.pumpWidget(MaterialApp(home: WelcomeScreen(authStore: store)));
await tester.tap(find.text('Demo starten'));
await tester.pump();
await tester.tap(find.text('Neuen Betrieb anlegen'));
await tester.pump();
await tester.enterText(
find.widgetWithText(TextField, 'Name des Betriebs'),
'Musterbetrieb',
);
await tester.enterText(
find.widgetWithText(TextField, 'E-Mail'),
'test@example.com',
);
await tester.enterText(
find.widgetWithText(TextField, 'Passwort'),
'sicheres-passwort',
);
final registerButton = find.widgetWithText(FilledButton, 'Betrieb anlegen');
await tester.ensureVisible(registerButton);
await tester.tap(registerButton);
await tester.pump();
expect(
find.text('Wähle mindestens ein Branchenprofil aus.'),
findsOneWidget,
);
expect(requestBody, isNull);
await tester.ensureVisible(find.text('Handwerk'));
await tester.tap(find.text('Handwerk'));
await tester.tap(find.text('Facility Services'));
await tester.ensureVisible(registerButton);
await tester.tap(registerButton);
await tester.pumpAndSettle();
expect(requestBody?['industryProfiles'], ['handwerk', 'facility_services']);
expect(store.status, AuthStatus.signedIn);
});
}
