import 'dart:async';
import 'dart:convert';
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';
void main() {
test('Registrierung sendet mehrere Branchenprofile', () async {
final client = AuthClient(
client: MockClient((request) async {
expect(request.url.path, '/api/v1/auth/register-owner');
final body = jsonDecode(request.body) as Map<String, dynamic>;
expect(body['tenantName'], 'Musterbetrieb');
expect(body['industryProfiles'], ['handwerk', 'facility_services']);
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',
);
await client.registerOwner(
tenantName: 'Musterbetrieb',
email: 'test@example.com',
[REDACTED],
industryProfiles: const ['handwerk', 'facility_services'],
);
});
test('Login liest die serverseitige Sitzung', () async {
final client = AuthClient(
client: MockClient((request) async {
expect(request.url.path, '/api/v1/auth/login');
return Response(
jsonEncode({
'data': {
'accessToken': 'access',
'refreshToken': 'refresh',
'user': {'id': 'user', 'email': 'test@example.com'},
'tenantId': 'tenant',
'role': 'owner',
},
}),
200,
);
}),
baseUrl: 'https://api.example.test',
);
final session = await client.login(
email: 'test@example.com',
[REDACTED],
);
expect(session.tenantId, 'tenant');
expect(session.role, 'owner');
});
test('Login meldet falsche Zugangsdaten verständlich', () async {
final client = AuthClient(
client: MockClient(
(_) async => Response(
jsonEncode({
'error': {'code': 'authentication_failed'},
}),
401,
),
),
baseUrl: 'https://api.example.test',
);
await expectLater(
client.login(email: 'x@example.com', password: 'wrong'),
throwsA(
isA<AuthException>().having(
(error) => error.message,
'message',
'E-Mail oder Passwort sind nicht korrekt.',
),
),
);
});
test('Login normalisiert eine nicht erreichbare API', () async {
final client = AuthClient(
client: MockClient((_) async => throw ClientException('offline')),
baseUrl: 'https://api.example.test',
);
await expectLater(
client.login(email: 'x@example.com', password: 'secret'),
throwsA(
isA<AuthException>().having(
(error) => error.message,
'message',
contains('Internetverbindung'),
),
),
);
});
test('Login bricht eine hängende Anfrage mit Timeout ab', () async {
final client = AuthClient(
client: MockClient((_) async {
await Completer<void>().future;
return Response('', 200);
}),
baseUrl: 'https://api.example.test',
requestTimeout: const Duration(milliseconds: 10),
);
await expectLater(
client.login(email: 'x@example.com', password: 'secret'),
throwsA(
isA<AuthException>().having(
(error) => error.message,
'message',
contains('dauert zu lange'),
),
),
);
});
test('Login normalisiert eine ungültige JSON-Antwort', () async {
final client = AuthClient(
client: MockClient((_) async => Response('<html>Fehler</html>', 502)),
baseUrl: 'https://api.example.test',
);
await expectLater(
client.login(email: 'x@example.com', password: 'secret'),
throwsA(
isA<AuthException>().having(
(error) => error.message,
'message',
contains('ungültige Antwort'),
),
),
);
});
test('Einladung kann geprüft und einmalig angenommen werden', () async {
final requests = <String>[];
final client = AuthClient(
client: MockClient((request) async {
requests.add(request.url.path);
if (request.url.path.endsWith('/inspect')) {
return Response(
jsonEncode({
'data': {
'email': 'nina@example.test',
'role': 'technician',
'tenantName': 'Musterbetrieb',
},
}),
200,
);
}
return Response(
jsonEncode({
'data': {
'accessToken': 'access',
'refreshToken': 'refresh',
'user': {'id': 'user', 'email': 'nina@example.test'},
'tenantId': 'tenant',
'role': 'technician',
},
}),
200,
);
}),
baseUrl: 'https://api.example.test',
);
final details = await client.inspectInvitation('invite-token');
final session = await client.acceptInvitation(
[REDACTED],
[REDACTED],
);
expect(details['email'], 'nina@example.test');
expect(session.role, 'technician');
expect(requests, [
'/api/v1/invitations/inspect',
'/api/v1/invitations/accept',
]);
});
}
