feat(watch): clôture lot #91 - fréquence cardiaque live, notifications de séance et finitions montre
Consolide le lot applicatif watch companion validé : - télémétrie fréquence cardiaque live remontée montre -> téléphone (collecteur watch, adapter Wear Data Layer, persistance Drift, propagation aux écrans historique/programme/profil/exécution) - notifications de séance en arrière-plan côté téléphone (service foreground de statut + passerelle applicative) - finitions montre : chrono d'étape, score d'étape, retrait du bouton "lancer une séance", thème, icônes et polices watch_app Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
76
test/infrastructure/remote/http_api_client_test.dart
Normal file
76
test/infrastructure/remote/http_api_client_test.dart
Normal file
@ -0,0 +1,76 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gametime/application/application.dart';
|
||||
import 'package:gametime/infrastructure/remote/remote.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/testing.dart';
|
||||
|
||||
void main() {
|
||||
test(
|
||||
'defaultBaseUrl keeps localhost outside Android without env override',
|
||||
() {
|
||||
expect(
|
||||
HttpApiClient.defaultBaseUrlFor(isAndroid: false),
|
||||
'http://localhost:8080',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test('defaultBaseUrl uses Android emulator host without env override', () {
|
||||
expect(
|
||||
HttpApiClient.defaultBaseUrlFor(isAndroid: true),
|
||||
'http://10.0.2.2:8080',
|
||||
);
|
||||
});
|
||||
|
||||
test('defaultBaseUrl keeps env override on Android', () {
|
||||
expect(
|
||||
HttpApiClient.defaultBaseUrlFor(
|
||||
isAndroid: true,
|
||||
configuredBaseUrl: ' http://192.168.1.42:8080 ',
|
||||
),
|
||||
'http://192.168.1.42:8080',
|
||||
);
|
||||
});
|
||||
|
||||
test('postJson maps server errors to server failure', () async {
|
||||
final client = HttpApiClient(
|
||||
baseUrl: Uri.parse('http://api.example.test'),
|
||||
client: MockClient(
|
||||
(_) async => http.Response('{"error":"internal"}', 500),
|
||||
),
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
client.postJson('/auth/login'),
|
||||
throwsA(
|
||||
isA<RemoteAuthException>()
|
||||
.having(
|
||||
(error) => error.failure,
|
||||
'failure',
|
||||
RemoteAuthFailure.server,
|
||||
)
|
||||
.having((error) => error.message, 'message', 'internal'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('postJson maps transport failures to network failure', () async {
|
||||
final client = HttpApiClient(
|
||||
baseUrl: Uri.parse('http://api.example.test'),
|
||||
client: MockClient((_) async => throw http.ClientException('refused')),
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
client.postJson('/auth/login'),
|
||||
throwsA(
|
||||
isA<RemoteAuthException>()
|
||||
.having(
|
||||
(error) => error.failure,
|
||||
'failure',
|
||||
RemoteAuthFailure.network,
|
||||
)
|
||||
.having((error) => error.message, 'message', 'refused'),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user