import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:mocktail/mocktail.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:mabea_app/api/api_client.dart'; class _MockClient extends Mock implements http.Client {} void main() { late _MockClient httpClient; late ApiClient apiClient; setUp(() { SharedPreferences.setMockInitialValues({}); httpClient = _MockClient(); apiClient = ApiClient(baseUrl: 'http://test.local/api/v1', httpClient: httpClient); }); group('login', () { test('speichert Token bei Erfolg', () async { when(() => httpClient.post( Uri.parse('http://test.local/api/v1/auth/login'), headers: any(named: 'headers'), body: any(named: 'body'), )).thenAnswer( (_) async => http.Response(jsonEncode({'access_token': 'abc-token'}), 200), ); final token = await apiClient.login('mitarbeiter1', 'test-passwort-123'); expect(token, 'abc-token'); expect(apiClient.istEingeloggt, isTrue); }); test('wirft ApiException bei falschem Passwort', () async { when(() => httpClient.post( Uri.parse('http://test.local/api/v1/auth/login'), headers: any(named: 'headers'), body: any(named: 'body'), )).thenAnswer( (_) async => http.Response(jsonEncode({'detail': 'falsch'}), 401), ); expect( () => apiClient.login('mitarbeiter1', 'falsch'), throwsA(isA().having((e) => e.status, 'status', 401)), ); }); }); group('request', () { test('sendet Bearer-Token, sobald eingeloggt', () async { when(() => httpClient.post( Uri.parse('http://test.local/api/v1/auth/login'), headers: any(named: 'headers'), body: any(named: 'body'), )).thenAnswer((_) async => http.Response(jsonEncode({'access_token': 'abc-token'}), 200)); await apiClient.login('mitarbeiter1', 'test-passwort-123'); when(() => httpClient.get( Uri.parse('http://test.local/api/v1/objekte'), headers: any(named: 'headers'), )).thenAnswer((_) async => http.Response(jsonEncode([]), 200)); await apiClient.request('/objekte'); final captured = verify(() => httpClient.get( Uri.parse('http://test.local/api/v1/objekte'), headers: captureAny(named: 'headers'), )).captured; final headers = captured.single as Map; expect(headers['Authorization'], 'Bearer abc-token'); }); test('wirft ApiException bei 4xx-Antwort', () async { when(() => httpClient.get( Uri.parse('http://test.local/api/v1/objekte/1'), headers: any(named: 'headers'), )).thenAnswer((_) async => http.Response(jsonEncode({'detail': 'nicht gefunden'}), 404)); expect( () => apiClient.request('/objekte/1'), throwsA(isA().having((e) => e.status, 'status', 404)), ); }); }); }