blob: 3aab6e8ff6e0392ba689ac56f23c0676fcde0f33 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:mockito/mockito.dart';
class TestHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return createMockImageHttpClient(context);
}
}
MockHttpClient createMockImageHttpClient(SecurityContext? _) {
final MockHttpClient client = MockHttpClient();
final MockHttpClientRequest request = MockHttpClientRequest();
final MockHttpClientResponse response = MockHttpClientResponse();
final MockHttpHeaders headers = MockHttpHeaders();
final List<int> transparentImage = getTestImageData();
when(client.getUrl(any))
.thenAnswer((_) => Future<MockHttpClientRequest>.value(request));
when(request.headers).thenReturn(headers);
when(request.close())
.thenAnswer((_) => Future<MockHttpClientResponse>.value(response));
when(client.autoUncompress = any).thenAnswer((_) => null);
when(response.contentLength).thenReturn(transparentImage.length);
when(response.statusCode).thenReturn(HttpStatus.ok);
when(response.compressionState)
.thenReturn(HttpClientResponseCompressionState.notCompressed);
// Define an image stream that streams the mock test image for all
// image tests that request an image.
StreamSubscription<List<int>> imageStream(Invocation invocation) {
final void Function(List<int>)? onData = invocation.positionalArguments[0];
final void Function()? onDone = invocation.namedArguments[#onDone];
final void Function(Object, [StackTrace?])? onError =
invocation.namedArguments[#onError];
final bool? cancelOnError = invocation.namedArguments[#cancelOnError];
return Stream<List<int>>.fromIterable(<List<int>>[transparentImage]).listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
}
when(response.listen(any,
onError: anyNamed('onError'),
onDone: anyNamed('onDone'),
cancelOnError: anyNamed('cancelOnError')))
.thenAnswer(imageStream);
return client;
}
// This string represents the hexidecial bytes of a transparent image. A
// string is used to make the visual representation of the data compact. A
// List<int> of the same data requires over 60 lines in a source file with
// each element in the array on a single line.
const String _imageBytesAsString = '''
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
''';
// Convert the string representing the hexidecimal bytes in the image into
// a list of integers that can be consumed as image data in a stream.
final List<int> _transparentImage = const LineSplitter()
.convert(_imageBytesAsString.replaceAllMapped(
RegExp(r' *0x([A-F0-9]{2}),? *\n? *'), (Match m) => '${m[1]}\n'))
.map<int>((String b) => int.parse(b, radix: 16))
.toList();
List<int> getTestImageData() {
return _transparentImage;
}
/// Define the "fake" data types to be used in mock data type definitions. These
/// fake data types are important in the definition of the return values of the
/// properties and methods of the mock data types for null safety.
// ignore: avoid_implementing_value_types
class _FakeDuration extends Fake implements Duration {}
class _FakeHttpClientRequest extends Fake implements HttpClientRequest {}
class _FakeUri extends Fake implements Uri {}
class _FakeHttpHeaders extends Fake implements HttpHeaders {}
class _FakeHttpClientResponse extends Fake implements HttpClientResponse {}
class _FakeSocket extends Fake implements Socket {}
class _FakeStreamSubscription<T> extends Fake
implements StreamSubscription<T> {}
/// A class which mocks [HttpClient].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpClient extends Mock implements HttpClient {
MockHttpClient() {
throwOnMissingStub(this);
}
@override
Duration get idleTimeout =>
super.noSuchMethod(Invocation.getter(#idleTimeout),
returnValue: _FakeDuration()) as Duration;
@override
set idleTimeout(Duration? idleTimeout) =>
super.noSuchMethod(Invocation.setter(#idleTimeout, idleTimeout));
@override
bool get autoUncompress =>
super.noSuchMethod(Invocation.getter(#autoUncompress), returnValue: false)
as bool;
@override
set autoUncompress(bool? autoUncompress) =>
super.noSuchMethod(Invocation.setter(#autoUncompress, autoUncompress));
@override
Future<HttpClientRequest> open(
String? method, String? host, int? port, String? path) =>
super.noSuchMethod(
Invocation.method(#open, <Object?>[method, host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> openUrl(String? method, Uri? url) =>
super.noSuchMethod(Invocation.method(#openUrl, <Object?>[method, url]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> get(String? host, int? port, String? path) =>
super.noSuchMethod(Invocation.method(#get, <Object?>[host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> getUrl(Uri? url) => super.noSuchMethod(
Invocation.method(#getUrl, <Object?>[url]),
returnValue:
Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> post(String? host, int? port, String? path) =>
super.noSuchMethod(Invocation.method(#post, <Object?>[host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> postUrl(Uri? url) => super.noSuchMethod(
Invocation.method(#postUrl, <Object?>[url]),
returnValue:
Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> put(String? host, int? port, String? path) =>
super.noSuchMethod(Invocation.method(#put, <Object?>[host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> putUrl(Uri? url) => super.noSuchMethod(
Invocation.method(#putUrl, <Object?>[url]),
returnValue:
Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> delete(String? host, int? port, String? path) =>
super.noSuchMethod(
Invocation.method(#delete, <Object?>[host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> deleteUrl(Uri? url) => super.noSuchMethod(
Invocation.method(#deleteUrl, <Object?>[url]),
returnValue:
Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> patch(String? host, int? port, String? path) =>
super.noSuchMethod(Invocation.method(#patch, <Object?>[host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> patchUrl(Uri? url) => super.noSuchMethod(
Invocation.method(#patchUrl, <Object?>[url]),
returnValue:
Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> head(String? host, int? port, String? path) =>
super.noSuchMethod(Invocation.method(#head, <Object?>[host, port, path]),
returnValue: Future<_FakeHttpClientRequest>.value(
_FakeHttpClientRequest())) as Future<HttpClientRequest>;
@override
Future<HttpClientRequest> headUrl(Uri? url) => super.noSuchMethod(
Invocation.method(#headUrl, <Object?>[url]),
returnValue:
Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
as Future<HttpClientRequest>;
@override
void addCredentials(
Uri? url, String? realm, HttpClientCredentials? credentials) =>
super.noSuchMethod(Invocation.method(
#addCredentials, <Object?>[url, realm, credentials]));
@override
void addProxyCredentials(String? host, int? port, String? realm,
HttpClientCredentials? credentials) =>
super.noSuchMethod(Invocation.method(
#addProxyCredentials, <Object?>[host, port, realm, credentials]));
@override
void close({bool? force = false}) => super.noSuchMethod(
Invocation.method(#close, <Object?>[], <Symbol, Object?>{#force: force}));
}
/// A class which mocks [HttpClientRequest].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpClientRequest extends Mock implements HttpClientRequest {
MockHttpClientRequest() {
throwOnMissingStub(this);
}
@override
bool get persistentConnection =>
super.noSuchMethod(Invocation.getter(#persistentConnection),
returnValue: false) as bool;
@override
set persistentConnection(bool? persistentConnection) => super.noSuchMethod(
Invocation.setter(#persistentConnection, persistentConnection));
@override
bool get followRedirects => super
.noSuchMethod(Invocation.getter(#followRedirects), returnValue: false)
as bool;
@override
set followRedirects(bool? followRedirects) =>
super.noSuchMethod(Invocation.setter(#followRedirects, followRedirects));
@override
int get maxRedirects =>
super.noSuchMethod(Invocation.getter(#maxRedirects), returnValue: 0)
as int;
@override
set maxRedirects(int? maxRedirects) =>
super.noSuchMethod(Invocation.setter(#maxRedirects, maxRedirects));
@override
int get contentLength =>
super.noSuchMethod(Invocation.getter(#contentLength), returnValue: 0)
as int;
@override
set contentLength(int? contentLength) =>
super.noSuchMethod(Invocation.setter(#contentLength, contentLength));
@override
bool get bufferOutput =>
super.noSuchMethod(Invocation.getter(#bufferOutput), returnValue: false)
as bool;
@override
set bufferOutput(bool? bufferOutput) =>
super.noSuchMethod(Invocation.setter(#bufferOutput, bufferOutput));
@override
String get method =>
super.noSuchMethod(Invocation.getter(#method), returnValue: '') as String;
@override
Uri get uri =>
super.noSuchMethod(Invocation.getter(#uri), returnValue: _FakeUri())
as Uri;
@override
HttpHeaders get headers => super.noSuchMethod(Invocation.getter(#headers),
returnValue: _FakeHttpHeaders()) as HttpHeaders;
@override
List<Cookie> get cookies =>
super.noSuchMethod(Invocation.getter(#cookies), returnValue: <Cookie>[])
as List<Cookie>;
@override
Future<HttpClientResponse> get done => super.noSuchMethod(
Invocation.getter(#done),
returnValue:
Future<_FakeHttpClientResponse>.value(_FakeHttpClientResponse()))
as Future<HttpClientResponse>;
@override
Future<HttpClientResponse> close() => super.noSuchMethod(
Invocation.method(#close, <Object?>[]),
returnValue:
Future<_FakeHttpClientResponse>.value(_FakeHttpClientResponse()))
as Future<HttpClientResponse>;
}
/// A class which mocks [HttpClientResponse].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpClientResponse extends Mock implements HttpClientResponse {
MockHttpClientResponse() {
throwOnMissingStub(this);
}
// Include an override method for the inherited listen method. This method
// intercepts HttpClientResponse listen calls to return a mock image.
@override
StreamSubscription<List<int>> listen(void Function(List<int> event)? onData,
{Function? onError, void Function()? onDone, bool? cancelOnError}) =>
super.noSuchMethod(
Invocation.method(
#listen,
<Object?>[onData],
<Symbol, Object?>{
#onError: onError,
#onDone: onDone,
#cancelOnError: cancelOnError
},
),
returnValue: _FakeStreamSubscription<List<int>>());
@override
int get statusCode =>
super.noSuchMethod(Invocation.getter(#statusCode), returnValue: 0) as int;
@override
String get reasonPhrase =>
super.noSuchMethod(Invocation.getter(#reasonPhrase), returnValue: '')
as String;
@override
int get contentLength =>
super.noSuchMethod(Invocation.getter(#contentLength), returnValue: 0)
as int;
@override
HttpClientResponseCompressionState get compressionState =>
super.noSuchMethod(Invocation.getter(#compressionState),
returnValue: HttpClientResponseCompressionState.notCompressed)
as HttpClientResponseCompressionState;
@override
bool get persistentConnection =>
super.noSuchMethod(Invocation.getter(#persistentConnection),
returnValue: false) as bool;
@override
bool get isRedirect =>
super.noSuchMethod(Invocation.getter(#isRedirect), returnValue: false)
as bool;
@override
List<RedirectInfo> get redirects =>
super.noSuchMethod(Invocation.getter(#redirects),
returnValue: <RedirectInfo>[]) as List<RedirectInfo>;
@override
HttpHeaders get headers => super.noSuchMethod(Invocation.getter(#headers),
returnValue: _FakeHttpHeaders()) as HttpHeaders;
@override
List<Cookie> get cookies =>
super.noSuchMethod(Invocation.getter(#cookies), returnValue: <Cookie>[])
as List<Cookie>;
@override
Future<HttpClientResponse> redirect(
[String? method, Uri? url, bool? followLoops]) =>
super.noSuchMethod(
Invocation.method(#redirect, <Object?>[method, url, followLoops]),
returnValue: Future<_FakeHttpClientResponse>.value(
_FakeHttpClientResponse())) as Future<HttpClientResponse>;
@override
Future<Socket> detachSocket() => super.noSuchMethod(
Invocation.method(#detachSocket, <Object?>[]),
returnValue: Future<_FakeSocket>.value(_FakeSocket())) as Future<Socket>;
}
/// A class which mocks [HttpHeaders].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpHeaders extends Mock implements HttpHeaders {
MockHttpHeaders() {
throwOnMissingStub(this);
}
@override
int get contentLength =>
super.noSuchMethod(Invocation.getter(#contentLength), returnValue: 0)
as int;
@override
set contentLength(int? contentLength) =>
super.noSuchMethod(Invocation.setter(#contentLength, contentLength));
@override
bool get persistentConnection =>
super.noSuchMethod(Invocation.getter(#persistentConnection),
returnValue: false) as bool;
@override
set persistentConnection(bool? persistentConnection) => super.noSuchMethod(
Invocation.setter(#persistentConnection, persistentConnection));
@override
bool get chunkedTransferEncoding =>
super.noSuchMethod(Invocation.getter(#chunkedTransferEncoding),
returnValue: false) as bool;
@override
set chunkedTransferEncoding(bool? chunkedTransferEncoding) =>
super.noSuchMethod(
Invocation.setter(#chunkedTransferEncoding, chunkedTransferEncoding));
@override
List<String>? operator [](String? name) =>
super.noSuchMethod(Invocation.method(#[], <Object?>[name]))
as List<String>?;
@override
String? value(String? name) =>
super.noSuchMethod(Invocation.method(#value, <Object?>[name])) as String?;
@override
void add(String? name, Object? value, {bool? preserveHeaderCase = false}) =>
super.noSuchMethod(Invocation.method(#add, <Object?>[name, value],
<Symbol, Object?>{#preserveHeaderCase: preserveHeaderCase}));
@override
void set(String? name, Object? value, {bool? preserveHeaderCase = false}) =>
super.noSuchMethod(Invocation.method(#set, <Object?>[name, value],
<Symbol, Object?>{#preserveHeaderCase: preserveHeaderCase}));
@override
void remove(String? name, Object? value) =>
super.noSuchMethod(Invocation.method(#remove, <Object?>[name, value]));
@override
void removeAll(String? name) =>
super.noSuchMethod(Invocation.method(#removeAll, <Object?>[name]));
@override
void forEach(void Function(String, List<String>)? action) =>
super.noSuchMethod(Invocation.method(#forEach, <Object?>[action]));
@override
void noFolding(String? name) =>
super.noSuchMethod(Invocation.method(#noFolding, <Object?>[name]));
}