93 lines
2.8 KiB
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;
|
|
}
|