cyberhybridhub/server/test/helpers/mock_http_client.dart

93 lines
2.8 KiB
Dart

import 'dart:convert';
import 'package:http/http.dart' as http;
/// Records requests and returns canned responses for Alpaca client unit tests.
class MockHttpClient extends http.BaseClient {
MockHttpClient({Map<String, _MatchedResponse>? responses})
: _responses = responses ?? <String, _MatchedResponse>{};
final Map<String, _MatchedResponse> _responses;
final List<http.BaseRequest> requests = <http.BaseRequest>[];
/// Captured request bodies indexed by request order in [requests].
final List<String> capturedBodies = <String>[];
void whenGet(String pathSuffix, http.Response response) {
_responses[pathSuffix] = _MatchedResponse(method: 'GET', response: response);
}
void whenGetJson(String pathSuffix, Map<String, dynamic> body,
{int statusCode = 200}) {
whenGet(
pathSuffix,
http.Response(jsonEncode(body), statusCode, headers: <String, String>{
'content-type': 'application/json',
}),
);
}
void whenPost(String pathSuffix, http.Response response) {
_responses['POST:$pathSuffix'] =
_MatchedResponse(method: 'POST', response: response);
}
void whenPostJson(String pathSuffix, Map<String, dynamic> body,
{int statusCode = 200}) {
whenPost(
pathSuffix,
http.Response(jsonEncode(body), statusCode, headers: <String, String>{
'content-type': 'application/json',
}),
);
}
@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
requests.add(request);
final String body = await _readBody(request);
capturedBodies.add(body);
final String path = request.url.path;
final String method = request.method.toUpperCase();
for (final MapEntry<String, _MatchedResponse> entry in _responses.entries) {
final _MatchedResponse match = entry.value;
if (match.method != method) continue;
final String suffix = entry.key.startsWith('$method:')
? entry.key.substring(method.length + 1)
: entry.key;
if (path.endsWith(suffix) || request.url.toString().contains(suffix)) {
return http.StreamedResponse(
Stream<List<int>>.value(utf8.encode(match.response.body)),
match.response.statusCode,
headers: match.response.headers,
request: request,
);
}
}
return http.StreamedResponse(
Stream<List<int>>.value(utf8.encode('{}')),
404,
request: request,
);
}
Future<String> _readBody(http.BaseRequest request) async {
if (request is http.Request) {
return request.body;
}
final List<int> bytes = await request.finalize().toBytes();
return utf8.decode(bytes);
}
@override
void close() {}
}
class _MatchedResponse {
_MatchedResponse({required this.method, required this.response});
final String method;
final http.Response response;
}