diff --git a/packages/stream_chat/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/stream_chat/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16..919434a6 100644 --- a/packages/stream_chat/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/stream_chat/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/packages/stream_chat/example/lib/main.dart b/packages/stream_chat/example/lib/main.dart index 2d0a529f..d13dda4c 100644 --- a/packages/stream_chat/example/lib/main.dart +++ b/packages/stream_chat/example/lib/main.dart @@ -2,12 +2,9 @@ import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; Future main() async { - /// Create a new instance of [StreamChatClient] passing the apikey obtained from your - /// project dashboard. - final client = StreamChatClient( - 'b67pax5b2wdq', - logLevel: Level.INFO, - ); + /// Create a new instance of [StreamChatClient] + /// by passing the apikey obtained from your project dashboard. + final client = StreamChatClient('b67pax5b2wdq', logLevel: Level.INFO); /// Set the current user. In a production scenario, this should be done using /// a backend to generate a user token using our server SDK. @@ -21,7 +18,7 @@ Future main() async { 'https://getstream.io/random_png/?id=cool-shadow-7&name=Cool+shadow', }, ), - 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1zaGFkb3ctNyJ9.gkOlCRb1qgy4joHPaxFwPOdXcGvSPvp6QY0S4mpRkVo', + '''eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1zaGFkb3ctNyJ9.gkOlCRb1qgy4joHPaxFwPOdXcGvSPvp6QY0S4mpRkVo''', ); /// Creates a channel using the type `messaging` and `godevs`. @@ -44,15 +41,16 @@ Future main() async { /// Example using Stream's Low Level Dart client. class StreamExample extends StatelessWidget { - /// To initialize this example, an instance of [client] and [channel] is required. + /// To initialize this example, an instance of + /// [client] and [channel] is required. const StreamExample({ Key key, @required this.client, @required this.channel, }) : super(key: key); - /// Instance of [StreamChatClient] we created earlier. This contains information about - /// our application and connection state. + /// Instance of [StreamChatClient] we created earlier. + /// This contains information about our application and connection state. final StreamChatClient client; /// The channel we'd like to observe and participate. @@ -104,8 +102,8 @@ class HomeScreen extends StatelessWidget { } return const Center( child: SizedBox( - width: 100.0, - height: 100.0, + width: 100, + height: 100, child: CircularProgressIndicator(), ), ); @@ -180,7 +178,7 @@ class _MessageViewState extends State { return Align( alignment: Alignment.centerRight, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8), child: Text(item.text), ), ); @@ -188,7 +186,7 @@ class _MessageViewState extends State { return Align( alignment: Alignment.centerLeft, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8), child: Text(item.text), ), ); @@ -197,7 +195,7 @@ class _MessageViewState extends State { ), ), Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8), child: Row( children: [ Expanded( @@ -245,7 +243,8 @@ class _MessageViewState extends State { } } -/// Helper extension for quickly retrieving the current user id from a [StreamChatClient]. +/// Helper extension for quickly retrieving +/// the current user id from a [StreamChatClient]. extension on StreamChatClient { String get uid => state.user.id; } diff --git a/packages/stream_chat/example/pubspec.yaml b/packages/stream_chat/example/pubspec.yaml index 2a8b7eb2..2d010ab6 100644 --- a/packages/stream_chat/example/pubspec.yaml +++ b/packages/stream_chat/example/pubspec.yaml @@ -1,21 +1,22 @@ name: example description: A new Flutter project. -publish_to: 'none' +publish_to: "none" version: 1.0.0+1 environment: sdk: ">=2.7.0 <3.0.0" dependencies: + cupertino_icons: ^1.0.0 flutter: sdk: flutter - cupertino_icons: ^1.0.0 - stream_chat: + stream_chat: path: ../ dev_dependencies: flutter_test: sdk: flutter + flutter: - uses-material-design: true \ No newline at end of file + uses-material-design: true diff --git a/packages/stream_chat/lib/src/api/channel.dart b/packages/stream_chat/lib/src/api/channel.dart index b424f6f1..aeacaf7d 100644 --- a/packages/stream_chat/lib/src/api/channel.dart +++ b/packages/stream_chat/lib/src/api/channel.dart @@ -352,7 +352,7 @@ class Channel { state?.addMessage(response.message); return response; } catch (error) { - if (error is DioError && error.type != DioErrorType.RESPONSE) { + if (error is DioError && error.type != DioErrorType.response) { state?.retryQueue?.add([message]); } rethrow; @@ -405,7 +405,7 @@ class Channel { )); return response; } catch (error) { - if (error is DioError && error.type != DioErrorType.RESPONSE) { + if (error is DioError && error.type != DioErrorType.response) { state?.retryQueue?.add([message]); } rethrow; @@ -446,7 +446,7 @@ class Channel { return response; } catch (error) { - if (error is DioError && error.type != DioErrorType.RESPONSE) { + if (error is DioError && error.type != DioErrorType.response) { state?.retryQueue?.add([message]); } rethrow; diff --git a/packages/stream_chat/lib/src/api/retry_queue.dart b/packages/stream_chat/lib/src/api/retry_queue.dart index ac0e14d7..1049e0e9 100644 --- a/packages/stream_chat/lib/src/api/retry_queue.dart +++ b/packages/stream_chat/lib/src/api/retry_queue.dart @@ -74,7 +74,7 @@ class RetryQueue { } catch (error) { ApiError apiError; if (error is DioError) { - if (error.type == DioErrorType.RESPONSE) { + if (error.type == DioErrorType.response) { _messageQueue.remove(message); return; } diff --git a/packages/stream_chat/lib/src/client.dart b/packages/stream_chat/lib/src/client.dart index 8b9d3a75..f46ba178 100644 --- a/packages/stream_chat/lib/src/client.dart +++ b/packages/stream_chat/lib/src/client.dart @@ -252,7 +252,7 @@ class StreamChatClient { this.httpClient.options.connectTimeout = connectTimeout.inMilliseconds; this.httpClient.interceptors.add( InterceptorsWrapper( - onRequest: (options) async { + onRequest: (options, handler) async { options.queryParameters.addAll(_commonQueryParams); options.headers.addAll(_httpHeaders); @@ -280,15 +280,17 @@ class StreamChatClient { data: $stringData '''); - - return options; + handler.next(options); }, onError: _tokenExpiredInterceptor, ), ); } - Future _tokenExpiredInterceptor(DioError err) async { + Future _tokenExpiredInterceptor( + DioError err, + ErrorInterceptorHandler handler, + ) async { final apiError = ApiError( err.response?.data, err.response?.statusCode, @@ -312,17 +314,35 @@ class StreamChatClient { await connectUser(User(id: userId), newToken); try { - return await httpClient.request( - err.request.path, - cancelToken: err.request.cancelToken, - data: err.request.data, - onReceiveProgress: err.request.onReceiveProgress, - onSendProgress: err.request.onSendProgress, - queryParameters: err.request.queryParameters, - options: err.request, + handler.resolve( + await httpClient.request( + err.requestOptions.path, + cancelToken: err.requestOptions.cancelToken, + data: err.requestOptions.data, + onReceiveProgress: err.requestOptions.onReceiveProgress, + onSendProgress: err.requestOptions.onSendProgress, + queryParameters: err.requestOptions.queryParameters, + options: Options( + method: err.requestOptions.method, + sendTimeout: err.requestOptions.sendTimeout, + receiveTimeout: err.requestOptions.receiveTimeout, + extra: err.requestOptions.extra, + headers: err.requestOptions.headers, + responseType: err.requestOptions.responseType, + contentType: err.requestOptions.contentType, + validateStatus: err.requestOptions.validateStatus, + receiveDataWhenStatusError: + err.requestOptions.receiveDataWhenStatusError, + followRedirects: err.requestOptions.followRedirects, + maxRedirects: err.requestOptions.maxRedirects, + requestEncoder: err.requestOptions.requestEncoder, + responseDecoder: err.requestOptions.responseDecoder, + listFormat: err.requestOptions.listFormat, + ), + ), ); } catch (err) { - return err; + handler.reject(err); } } } @@ -784,7 +804,7 @@ class StreamChatClient { } Object _parseError(DioError error) { - if (error.type == DioErrorType.RESPONSE) { + if (error.type == DioErrorType.response) { final apiError = ApiError(error.response?.data, error.response?.statusCode); logger.severe('apiError: ${apiError.toString()}'); @@ -931,7 +951,7 @@ class StreamChatClient { _connectCompleter = Completer(); _anonymous = true; - final uuid = Uuid(); + const uuid = Uuid(); state.user = OwnUser(id: uuid.v4()); return connect().then((event) { diff --git a/packages/stream_chat/lib/src/models/attachment.dart b/packages/stream_chat/lib/src/models/attachment.dart index de5149db..551d70e4 100644 --- a/packages/stream_chat/lib/src/models/attachment.dart +++ b/packages/stream_chat/lib/src/models/attachment.dart @@ -35,7 +35,7 @@ class Attachment { this.extraData, this.file, UploadState uploadState, - }) : id = id ?? Uuid().v4(), + }) : id = id ?? const Uuid().v4(), title = title ?? file?.name, localUri = file?.path != null ? Uri.parse(file.path) : null { this.uploadState = uploadState ?? diff --git a/packages/stream_chat/lib/src/models/message.dart b/packages/stream_chat/lib/src/models/message.dart index a89324a7..de441dff 100644 --- a/packages/stream_chat/lib/src/models/message.dart +++ b/packages/stream_chat/lib/src/models/message.dart @@ -73,7 +73,7 @@ class Message { this.deletedAt, this.status = MessageSendingStatus.sent, this.skipPush, - }) : id = id ?? Uuid().v4(), + }) : id = id ?? const Uuid().v4(), pinExpires = pinExpires?.toUtc(); /// Create a new instance from a json diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 05023530..74310a86 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -9,22 +9,22 @@ environment: sdk: ">=2.7.0 <3.0.0" dependencies: - async: ^2.4.2 - collection: ^1.14.13 - dio: ^3.0.10 - freezed_annotation: ^0.12.0 - http_parser: ^3.1.4 - json_annotation: ^3.0.1 - logging: ^0.11.4 - meta: ^1.2.4 - mime: ^0.9.7 - rxdart: ^0.25.0 - uuid: ^2.2.2 - web_socket_channel: ^1.2.0 + async: ^2.5.0 + collection: ^1.15.0 + dio: ">=4.0.0-prev3 <4.0.0" + freezed_annotation: ^0.14.0 + http_parser: ^4.0.0 + json_annotation: ^4.0.0 + logging: ^1.0.0 + meta: ^1.3.0 + mime: ^1.0.0 + rxdart: ^0.26.0 + uuid: ^3.0.0 + web_socket_channel: ^2.0.0 dev_dependencies: build_runner: ^1.10.0 - freezed: ^0.12.7 - json_serializable: ^3.3.0 - mockito: ^4.1.1 - test: ^1.15.7 + freezed: ^0.14.0 + json_serializable: ^4.0.0 + mocktail: ^0.1.0 + test: ^1.16.0 diff --git a/packages/stream_chat/test/src/api/channel_test.dart b/packages/stream_chat/test/src/api/channel_test.dart index 755a3f3b..ae4d5296 100644 --- a/packages/stream_chat/test/src/api/channel_test.dart +++ b/packages/stream_chat/test/src/api/channel_test.dart @@ -1,6 +1,6 @@ import 'package:dio/dio.dart'; import 'package:dio/native_imp.dart'; -import 'package:mockito/mockito.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:stream_chat/src/api/requests.dart'; import 'package:stream_chat/src/client.dart'; import 'package:stream_chat/src/event_type.dart'; @@ -14,6 +14,8 @@ import 'package:stream_chat/stream_chat.dart'; class MockDio extends Mock implements DioForNative {} +class FakeRequestOptions extends Fake implements RequestOptions {} + class MockAttachmentUploader extends Mock implements AttachmentFileUploader {} class MockHttpClientAdapter extends Mock implements HttpClientAdapter {} @@ -24,8 +26,8 @@ void main() { test('sendMessage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -33,28 +35,34 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging', id: 'testid'); - final message = Message( - text: 'hey', - id: 'test', - ); + final message = Message(text: 'hey', id: 'test'); - when(mockDio.post('/channels/messaging/testid/message', data: { - 'message': message.toJson(), - })).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/message', + data: {'message': message.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.sendMessage(message); - verify( + verify(() => mockDio.post('/channels/messaging/testid/message', data: { - 'message': message.toJson(), - })).called(1); + 'message': message.toJson(), + })).called(1); }); test('markRead', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -64,29 +72,40 @@ void main() { final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( + when(() => mockDio.post( + any(), + data: any(named: 'data'), + )).thenAnswer((_) async => Response( data: '{}', statusCode: 200, + requestOptions: FakeRequestOptions(), )); await channelClient.watch(); - when(mockDio.post('/channels/messaging/testid/read', data: {})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/read', + data: {}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.markRead(); - verify(mockDio.post('/channels/messaging/testid/read', + verify(() => mockDio.post('/channels/messaging/testid/read', data: {})).called(1); }); test('getReplies', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -94,24 +113,28 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging', id: 'testid'); - final pagination = PaginationParams(); + const pagination = PaginationParams(); - when(mockDio.get('/messages/messageid/replies', - queryParameters: pagination.toJson())) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when(() => mockDio.get('/messages/messageid/replies', + queryParameters: pagination.toJson())).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.getReplies('messageid', pagination); - verify(mockDio.get('/messages/messageid/replies', - queryParameters: pagination.toJson())) - .called(1); + verify(() => mockDio.get('/messages/messageid/replies', + queryParameters: pagination.toJson())).called(1); }); test('sendAction', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -120,39 +143,46 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when(() => mockDio.post( + any(), + data: any(named: 'data'), + )).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); - final Map data = {'test': true}; + final data = {'test': true}; - when(mockDio.post('/messages/messageid/action', data: { - 'id': 'testid', - 'type': 'messaging', - 'form_data': data, - 'message_id': 'messageid', - })).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when(() => mockDio.post('/messages/messageid/action', data: { + 'id': 'testid', + 'type': 'messaging', + 'form_data': data, + 'message_id': 'messageid', + })).thenAnswer((_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + )); await channelClient.sendAction(Message(id: 'messageid'), data); - verify(mockDio.post('/messages/messageid/action', data: { - 'id': 'testid', - 'type': 'messaging', - 'form_data': data, - 'message_id': 'messageid', - })).called(1); + verify(() => mockDio.post('/messages/messageid/action', data: { + 'id': 'testid', + 'type': 'messaging', + 'form_data': data, + 'message_id': 'messageid', + })).called(1); }); test('getMessagesById', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -162,13 +192,18 @@ void main() { final channelClient = client.channel('messaging', id: 'testid'); final messageIds = ['a', 'b']; - when(mockDio.get('/channels/messaging/testid/messages', - queryParameters: {'ids': messageIds.join(',')})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when(() => mockDio.get('/channels/messaging/testid/messages', + queryParameters: {'ids': messageIds.join(',')})).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.getMessagesById(messageIds); - verify(mockDio.get('/channels/messaging/testid/messages', + verify(() => mockDio.get('/channels/messaging/testid/messages', queryParameters: {'ids': messageIds.join(',')})).called(1); }); @@ -176,12 +211,12 @@ void main() { final mockDio = MockDio(); final mockUploader = MockAttachmentUploader(); - final file = AttachmentFile(path: 'filePath/fileName.pdf'); - final channelId = 'testId'; - final channelType = 'messaging'; + const file = AttachmentFile(path: 'filePath/fileName.pdf'); + const channelId = 'testId'; + const channelType = 'messaging'; - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -191,24 +226,25 @@ void main() { ); final channelClient = client.channel(channelType, id: channelId); - when(mockUploader.sendFile(file, channelId, channelType)) + when(() => mockUploader.sendFile(file, channelId, channelType)) .thenAnswer((_) async => SendFileResponse()); await channelClient.sendFile(file); - verify(mockUploader.sendFile(file, channelId, channelType)).called(1); + verify(() => mockUploader.sendFile(file, channelId, channelType)) + .called(1); }); test('sendImage', () async { final mockDio = MockDio(); final mockUploader = MockAttachmentUploader(); - final image = AttachmentFile(path: 'imagePath/imageName.jpeg'); - final channelId = 'testId'; - final channelType = 'messaging'; + const image = AttachmentFile(path: 'imagePath/imageName.jpeg'); + const channelId = 'testId'; + const channelType = 'messaging'; - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -218,19 +254,20 @@ void main() { ); final channelClient = client.channel(channelType, id: channelId); - when(mockUploader.sendImage(image, channelId, channelType)) + when(() => mockUploader.sendImage(image, channelId, channelType)) .thenAnswer((_) async => SendImageResponse()); await channelClient.sendImage(image); - verify(mockUploader.sendImage(image, channelId, channelType)).called(1); + verify(() => mockUploader.sendImage(image, channelId, channelType)) + .called(1); }); test('deleteFile', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -238,23 +275,32 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging', id: 'testid'); - final url = 'url'; + const url = 'url'; - when(mockDio.delete('/channels/messaging/testid/file', - queryParameters: {'url': url})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.delete( + '/channels/messaging/testid/file', + queryParameters: {'url': url}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.deleteFile(url); - verify(mockDio.delete('/channels/messaging/testid/file', + verify(() => mockDio.delete('/channels/messaging/testid/file', queryParameters: {'url': url})).called(1); }); test('deleteImage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -262,15 +308,24 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging', id: 'testid'); - final url = 'url'; + const url = 'url'; - when(mockDio.delete('/channels/messaging/testid/image', - queryParameters: {'url': url})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.delete( + '/channels/messaging/testid/image', + queryParameters: {'url': url}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.deleteImage(url); - verify(mockDio.delete('/channels/messaging/testid/image', + verify(() => mockDio.delete('/channels/messaging/testid/image', queryParameters: {'url': url})).called(1); }); @@ -290,60 +345,68 @@ void main() { test('should be pinned successfully', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', httpClient: mockDio, tokenProvider: (_) async => '', ); - final channelClient = client.channel('messaging', id: 'testid'); + final message = Message(text: 'Hello', id: 'test'); - final message = Message( - text: 'Hello', - id: 'test', + when( + () => mockDio.post( + '/messages/${message.id}', + data: anything, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post( - '/messages/${message.id}', - data: anything, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await channelClient.pinMessage(message, 30); - verify(mockDio.post('/messages/${message.id}', data: anything)) + verify(() => + mockDio.post('/messages/${message.id}', data: anything)) .called(1); }); test('should be unpinned successfully', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', httpClient: mockDio, tokenProvider: (_) async => '', ); - final channelClient = client.channel('messaging', id: 'testid'); + final message = Message(text: 'Hello', id: 'test'); - final message = Message( - text: 'Hello', - id: 'test', + when( + () => mockDio.post( + '/messages/${message.id}', + data: anything, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post( - '/messages/${message.id}', - data: anything, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await channelClient.unpinMessage(message); - verify(mockDio.post('/messages/${message.id}', data: anything)) + verify(() => + mockDio.post('/messages/${message.id}', data: anything)) .called(1); }); }); @@ -351,8 +414,8 @@ void main() { test('sendEvent', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -361,32 +424,46 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when( + () => mockDio.post( + any(), + data: any(named: 'data'), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); final event = Event(type: EventType.any); - when(mockDio.post('/channels/messaging/testid/event', - data: {'event': event.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/event', + data: {'event': event.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.sendEvent(event); - verify(mockDio.post('/channels/messaging/testid/event', + verify(() => mockDio.post('/channels/messaging/testid/event', data: {'event': event.toJson()})).called(1); }); test('keyStroke', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -395,32 +472,46 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when( + () => mockDio.post( + any(), + data: any(named: 'data'), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); final event = Event(type: EventType.typingStart); - when(mockDio.post('/channels/messaging/testid/event', - data: {'event': event.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/event', + data: {'event': event.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.keyStroke(); - verify(mockDio.post('/channels/messaging/testid/event', + verify(() => mockDio.post('/channels/messaging/testid/event', data: {'event': event.toJson()})).called(1); }); test('stopTyping', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -429,24 +520,36 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when(() => mockDio.post( + any(), + data: any(named: 'data'), + )).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); final event = Event(type: EventType.typingStop); - when(mockDio.post('/channels/messaging/testid/event', - data: {'event': event.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/event', + data: {'event': event.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.stopTyping(); - verify(mockDio.post('/channels/messaging/testid/event', + verify(() => mockDio.post('/channels/messaging/testid/event', data: {'event': event.toJson()})).called(1); }); @@ -454,8 +557,8 @@ void main() { test('sendReaction', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -464,17 +567,25 @@ void main() { )..state.user = OwnUser(id: 'test-id'); final channelClient = client.channel('messaging', id: 'testid'); - final reactionType = 'test'; + const reactionType = 'test'; - when(mockDio.post( - '/messages/messageid/reaction', - data: { - 'reaction': { - 'type': reactionType, + when( + () => mockDio.post( + '/messages/messageid/reaction', + data: { + 'reaction': { + 'type': reactionType, + }, + 'enforce_unique': false, }, - 'enforce_unique': false, - }, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.sendReaction( Message( @@ -487,19 +598,20 @@ void main() { reactionType, ); - verify(mockDio.post('/messages/messageid/reaction', data: { - 'reaction': { - 'type': reactionType, - }, - 'enforce_unique': false, - })).called(1); + verify( + () => mockDio.post('/messages/messageid/reaction', data: { + 'reaction': { + 'type': reactionType, + }, + 'enforce_unique': false, + })).called(1); }); test('deleteReaction', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -509,8 +621,15 @@ void main() { final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.delete('/messages/messageid/reaction/test')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.delete('/messages/messageid/reaction/test'), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.deleteReaction( Message( @@ -523,15 +642,16 @@ void main() { Reaction(type: 'test'), ); - verify(mockDio.delete('/messages/messageid/reaction/test')) + verify(() => + mockDio.delete('/messages/messageid/reaction/test')) .called(1); }); test('getReactions', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -539,17 +659,25 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging', id: 'testid'); - final pagination = PaginationParams(); + const pagination = PaginationParams(); - when(mockDio.get('/messages/messageid/reactions', - queryParameters: pagination.toJson())) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.get( + '/messages/messageid/reactions', + queryParameters: pagination.toJson(), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.getReactions('messageid', pagination); - verify(mockDio.get('/messages/messageid/reactions', - queryParameters: pagination.toJson())) - .called(1); + verify(() => mockDio.get('/messages/messageid/reactions', + queryParameters: pagination.toJson())).called(1); }); }); @@ -557,8 +685,8 @@ void main() { test('addMembers', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -569,13 +697,22 @@ void main() { final members = ['vishal']; final message = Message(text: 'test'); - when(mockDio.post('/channels/messaging/testid', - data: {'add_members': members, 'message': message.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid', + data: {'add_members': members, 'message': message.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.addMembers(members, message); - verify(mockDio.post('/channels/messaging/testid', + verify(() => mockDio.post('/channels/messaging/testid', data: {'add_members': members, 'message': message.toJson()})) .called(1); }); @@ -583,8 +720,8 @@ void main() { test('acceptInvite', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -594,13 +731,22 @@ void main() { final channelClient = client.channel('messaging', id: 'testid'); final message = Message(text: 'test'); - when(mockDio.post('/channels/messaging/testid', - data: {'accept_invite': true, 'message': message.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid', + data: {'accept_invite': true, 'message': message.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.acceptInvite(message); - verify(mockDio.post('/channels/messaging/testid', + verify(() => mockDio.post('/channels/messaging/testid', data: {'accept_invite': true, 'message': message.toJson()})) .called(1); }); @@ -609,8 +755,8 @@ void main() { test('without id', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -618,15 +764,16 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging'); - final Map options = { + final options = { 'watch': true, 'state': false, 'presence': true, }; - when(mockDio.post('/channels/messaging/query', data: options)) - .thenAnswer((_) async { - return Response(data: r''' + when(() => mockDio.post('/channels/messaging/query', + data: options)).thenAnswer( + (_) async => Response( + data: r''' { "channel": { "id": "!members-0LOcD0mZtTan60zHobLmELjdndXsonnBVNzZnB5mTt0", @@ -912,14 +1059,16 @@ void main() { } ] } - ''', statusCode: 200); - }); + ''', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); final response = await channelClient.query(options: options); - verify(mockDio.post('/channels/messaging/query', - data: options)) - .called(1); + verify(() => mockDio.post('/channels/messaging/query', + data: options)).called(1); expect(channelClient.id, response.channel.id); expect(channelClient.cid, response.channel.cid); }); @@ -927,8 +1076,8 @@ void main() { test('with id', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -936,13 +1085,12 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging', id: 'testid'); - final Map options = { - 'state': false, - }; + final options = {'state': false}; - when(mockDio.post('/channels/messaging/testid/query', - data: options)) - .thenAnswer((_) async => Response(data: r''' + when(() => mockDio.post('/channels/messaging/testid/query', + data: options)).thenAnswer( + (_) async => Response( + data: r''' { "channel": { "id": "!members-0LOcD0mZtTan60zHobLmELjdndXsonnBVNzZnB5mTt0", @@ -1228,21 +1376,24 @@ void main() { } ] } - ''', statusCode: 200)); + ''', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.query(options: options); - verify(mockDio.post('/channels/messaging/testid/query', - data: options)) - .called(1); + verify(() => mockDio.post('/channels/messaging/testid/query', + data: options)).called(1); }); }); test('create', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1250,14 +1401,16 @@ void main() { tokenProvider: (_) async => '', ); final channelClient = client.channel('messaging'); - final Map options = { + final options = { 'watch': false, 'state': false, 'presence': false, }; - when(mockDio.post('/channels/messaging/query', data: options)) - .thenAnswer((_) async => Response(data: r''' + when(() => mockDio.post('/channels/messaging/query', + data: options)).thenAnswer( + (_) async => Response( + data: r''' { "channel": { "id": "!members-0LOcD0mZtTan60zHobLmELjdndXsonnBVNzZnB5mTt0", @@ -1543,12 +1696,16 @@ void main() { } ] } - ''', statusCode: 200)); + ''', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); final response = await channelClient.create(); - verify(mockDio.post('/channels/messaging/query', data: options)) - .called(1); + verify(() => mockDio.post('/channels/messaging/query', + data: options)).called(1); expect(channelClient.id, response.channel.id); expect(channelClient.cid, response.channel.cid); }); @@ -1556,8 +1713,8 @@ void main() { test('watch', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1571,8 +1728,10 @@ void main() { 'presence': true, }; - when(mockDio.post('/channels/messaging/query', data: options)) - .thenAnswer((_) async => Response(data: r''' + when(() => mockDio.post('/channels/messaging/query', + data: options)).thenAnswer( + (_) async => Response( + data: r''' { "channel": { "id": "!members-0LOcD0mZtTan60zHobLmELjdndXsonnBVNzZnB5mTt0", @@ -1858,12 +2017,16 @@ void main() { } ] } - ''', statusCode: 200)); + ''', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); final response = await channelClient.watch({'presence': true}); - verify(mockDio.post('/channels/messaging/query', data: options)) - .called(1); + verify(() => mockDio.post('/channels/messaging/query', + data: options)).called(1); expect(channelClient.id, response.channel.id); expect(channelClient.cid, response.channel.cid); }); @@ -1871,8 +2034,8 @@ void main() { test('stopWatching', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1881,24 +2044,32 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - '/channels/messaging/testid/stop-watching', - data: {}, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/stop-watching', + data: {}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.stopWatching(); - verify(mockDio.post( - '/channels/messaging/testid/stop-watching', - data: {}, - )).called(1); + verify(() => mockDio.post( + '/channels/messaging/testid/stop-watching', + data: {}, + )).called(1); }); test('update', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1908,24 +2079,37 @@ void main() { final channelClient = client.channel('messaging', id: 'testid'); final message = Message(text: 'test'); - when(mockDio.post('/channels/messaging/testid', data: { - 'message': message.toJson(), - 'data': {'test': true}, - })).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid', + data: { + 'message': message.toJson(), + 'data': {'test': true}, + }, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.update({'test': true}, message); - verify(mockDio.post('/channels/messaging/testid', data: { - 'message': message.toJson(), - 'data': {'test': true}, - })).called(1); + verify( + () => mockDio.post('/channels/messaging/testid', data: { + 'message': message.toJson(), + 'data': {'test': true}, + }), + ).called(1); }); test('delete', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1934,19 +2118,27 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.delete('/channels/messaging/testid')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.delete('/channels/messaging/testid'), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.delete(); - verify(mockDio.delete('/channels/messaging/testid')).called(1); + verify(() => mockDio.delete('/channels/messaging/testid')) + .called(1); }); test('truncate', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1955,20 +2147,28 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post('/channels/messaging/testid/truncate')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post('/channels/messaging/testid/truncate'), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.truncate(); - verify(mockDio.post('/channels/messaging/testid/truncate')) + verify(() => + mockDio.post('/channels/messaging/testid/truncate')) .called(1); }); test('rejectInvite', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1978,13 +2178,22 @@ void main() { final channelClient = client.channel('messaging', id: 'testid'); final message = Message(text: 'test'); - when(mockDio.post('/channels/messaging/testid', - data: {'reject_invite': true, 'message': message.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid', + data: {'reject_invite': true, 'message': message.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.rejectInvite(message); - verify(mockDio.post('/channels/messaging/testid', + verify(() => mockDio.post('/channels/messaging/testid', data: {'reject_invite': true, 'message': message.toJson()})) .called(1); }); @@ -1992,8 +2201,8 @@ void main() { test('inviteMembers', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -2004,21 +2213,30 @@ void main() { final members = ['vishal']; final message = Message(text: 'test'); - when(mockDio.post('/channels/messaging/testid', - data: {'invites': members, 'message': message.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid', + data: {'invites': members, 'message': message.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.inviteMembers(members, message); - verify(mockDio.post('/channels/messaging/testid', + verify(() => mockDio.post('/channels/messaging/testid', data: {'invites': members, 'message': message.toJson()})).called(1); }); test('removeMembers', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -2029,13 +2247,22 @@ void main() { final members = ['vishal']; final message = Message(text: 'test'); - when(mockDio.post('/channels/messaging/testid', - data: {'remove_members': members, 'message': message.toJson()})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid', + data: {'remove_members': members, 'message': message.toJson()}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.removeMembers(members, message); - verify(mockDio.post('/channels/messaging/testid', + verify(() => mockDio.post('/channels/messaging/testid', data: {'remove_members': members, 'message': message.toJson()})) .called(1); }); @@ -2043,8 +2270,8 @@ void main() { test('hide', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -2053,30 +2280,44 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when( + () => mockDio.post( + any(), + data: any(named: 'data'), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); - when(mockDio.post('/channels/messaging/testid/hide', - data: {'clear_history': true})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/channels/messaging/testid/hide', + data: {'clear_history': true}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.hide(clearHistory: true); - verify(mockDio.post('/channels/messaging/testid/hide', + verify(() => mockDio.post('/channels/messaging/testid/hide', data: {'clear_history': true})).called(1); }); test('show', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -2085,29 +2326,41 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when( + () => mockDio.post( + any(), + data: any(named: 'data'), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); - when(mockDio.post('/channels/messaging/testid/show')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post('/channels/messaging/testid/show'), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.show(); - verify(mockDio.post('/channels/messaging/testid/show')) + verify(() => mockDio.post('/channels/messaging/testid/show')) .called(1); }); test('banUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -2116,38 +2369,51 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when( + () => mockDio.post( + any(), + data: any(named: 'data'), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); - when(mockDio.post('/moderation/ban', data: { - 'test': true, - 'target_user_id': 'test-id', - 'type': 'messaging', - 'id': 'testid', - })).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post('/moderation/ban', data: { + 'test': true, + 'target_user_id': 'test-id', + 'type': 'messaging', + 'id': 'testid', + }), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); - final Map options = {'test': true}; + final options = {'test': true}; await channelClient.banUser('test-id', options); - verify(mockDio.post('/moderation/ban', data: { - 'test': true, - 'target_user_id': 'test-id', - 'type': 'messaging', - 'id': 'testid', - })).called(1); + verify(() => mockDio.post('/moderation/ban', data: { + 'test': true, + 'target_user_id': 'test-id', + 'type': 'messaging', + 'id': 'testid', + })).called(1); }); test('unbanUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -2156,28 +2422,46 @@ void main() { ); final channelClient = client.channel('messaging', id: 'testid'); - when(mockDio.post( - any, - data: anyNamed('data'), - )).thenAnswer((_) async => Response( - data: '{}', - statusCode: 200, - )); + when( + () => mockDio.post( + any(), + data: any(named: 'data'), + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.watch(); - when(mockDio.delete('/moderation/ban', queryParameters: { - 'target_user_id': 'test-id', - 'type': 'messaging', - 'id': 'testid', - })).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.delete( + '/moderation/ban', + queryParameters: { + 'target_user_id': 'test-id', + 'type': 'messaging', + 'id': 'testid', + }, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.unbanUser('test-id'); - verify(mockDio.delete('/moderation/ban', queryParameters: { - 'target_user_id': 'test-id', - 'type': 'messaging', - 'id': 'testid', - })).called(1); + verify( + () => mockDio.delete('/moderation/ban', queryParameters: { + 'target_user_id': 'test-id', + 'type': 'messaging', + 'id': 'testid', + }), + ).called(1); }); }); }); diff --git a/packages/stream_chat/test/src/api/requests_test.dart b/packages/stream_chat/test/src/api/requests_test.dart index de8ddaf8..1e46fee0 100644 --- a/packages/stream_chat/test/src/api/requests_test.dart +++ b/packages/stream_chat/test/src/api/requests_test.dart @@ -4,13 +4,13 @@ import 'package:stream_chat/stream_chat.dart'; void main() { group('src/api/requests', () { test('SortOption', () { - final option = SortOption('name'); + const option = SortOption('name'); final j = option.toJson(); expect(j, {'field': 'name', 'direction': -1}); }); test('PaginationParams', () { - final option = PaginationParams(); + const option = PaginationParams(); final j = option.toJson(); expect(j, {'limit': 10, 'offset': 0}); }); diff --git a/packages/stream_chat/test/src/api/responses_test.dart b/packages/stream_chat/test/src/api/responses_test.dart index 8c7b57e5..ad81aeff 100644 --- a/packages/stream_chat/test/src/api/responses_test.dart +++ b/packages/stream_chat/test/src/api/responses_test.dart @@ -3284,7 +3284,7 @@ void main() { }); test('QueryReactionsResponse', () { - const jsonExample = r''' + const jsonExample = ''' {"reactions": [{"message_id": "4637f7e4-a06b-42db-ba5a-8d8270dd926f","user_id": "c1c9b454-2bcc-402d-8bb0-2f3706ce1680","user": {"id": "c1c9b454-2bcc-402d-8bb0-2f3706ce1680","role": "user","created_at": "2020-01-28T22:17:30.83015Z","updated_at": "2020-01-28T22:17:31.19435Z","banned": false,"online": false,"image": "https://randomuser.me/api/portraits/women/2.jpg","name": "Mia Denys"},"type": "love","score": 1,"created_at": "2020-01-28T22:17:31.128376Z","updated_at": "2020-01-28T22:17:31.128376Z"}]} '''; final response = @@ -3402,31 +3402,31 @@ void main() { test('ListDevicesResponse', () { const jsonExample = - r'''{"devices":[{"push_provider":"firebase","id":"test"}],"duration":"0.35ms"}'''; + '''{"devices":[{"push_provider":"firebase","id":"test"}],"duration":"0.35ms"}'''; final response = ListDevicesResponse.fromJson(json.decode(jsonExample)); expect(response.devices, isA>()); }); test('SendFileResponse', () { - const jsonExample = r'''{"file": "file-url","duration":"0.35ms"}'''; + const jsonExample = '''{"file": "file-url","duration":"0.35ms"}'''; final response = SendFileResponse.fromJson(json.decode(jsonExample)); expect(response.file, isA()); }); test('SendImageResponse', () { - const jsonExample = r'''{"file": "file-url","duration":"0.35ms"}'''; + const jsonExample = '''{"file": "file-url","duration":"0.35ms"}'''; final response = SendImageResponse.fromJson(json.decode(jsonExample)); expect(response.file, isA()); }); test('SendImageResponse', () { - const jsonExample = r'''{"file": "file-url","duration":"0.35ms"}'''; + const jsonExample = '''{"file": "file-url","duration":"0.35ms"}'''; final response = SendImageResponse.fromJson(json.decode(jsonExample)); expect(response.file, isA()); }); test('EmptyResponse', () { - const jsonExample = r'''{"file": "file-url","duration":"0.35ms"}'''; + const jsonExample = '''{"file": "file-url","duration":"0.35ms"}'''; final response = EmptyResponse.fromJson(json.decode(jsonExample)); expect(response.duration, isA()); }); @@ -3481,8 +3481,7 @@ void main() { }); test('UpdateUsersResponse', () { - const jsonExample = - r'''{"users": {"bbb19d9a-ee50-45bc-84e5-0584e79d0c9e":{ + const jsonExample = '''{"users": {"bbb19d9a-ee50-45bc-84e5-0584e79d0c9e":{ "id": "bbb19d9a-ee50-45bc-84e5-0584e79d0c9e", "role": "user", "created_at": "2020-01-28T22:17:30.826259Z", @@ -3498,7 +3497,7 @@ void main() { test('ConnectGuestUserResponse', () { const jsonExample = - r'{"user":{"id":"guest-ac612aee-25fe-49fb-b1af-969e41f452a0-wild-breeze-7","role":"guest","created_at":"2020-02-03T10:19:01.538434Z","updated_at":"2020-02-03T10:19:01.539543Z","banned":false,"online":false},"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZ3Vlc3QtYWM2MTJhZWUtMjVmZS00OWZiLWIxYWYtOTY5ZTQxZjQ1MmEwLXdpbGQtYnJlZXplLTcifQ.mmoFGu7oJjpFsp7nFN78UbIpO7gowbuIbyoppsuvbXA","duration":"4.66ms"}'; + '''{"user":{"id":"guest-ac612aee-25fe-49fb-b1af-969e41f452a0-wild-breeze-7","role":"guest","created_at":"2020-02-03T10:19:01.538434Z","updated_at":"2020-02-03T10:19:01.539543Z","banned":false,"online":false},"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZ3Vlc3QtYWM2MTJhZWUtMjVmZS00OWZiLWIxYWYtOTY5ZTQxZjQ1MmEwLXdpbGQtYnJlZXplLTcifQ.mmoFGu7oJjpFsp7nFN78UbIpO7gowbuIbyoppsuvbXA","duration":"4.66ms"}'''; final response = ConnectGuestUserResponse.fromJson(json.decode(jsonExample)); expect(response.user, isA()); diff --git a/packages/stream_chat/test/src/api/web_socket_stub_test.dart b/packages/stream_chat/test/src/api/web_socket_stub_test.dart new file mode 100644 index 00000000..7f5bf4b1 --- /dev/null +++ b/packages/stream_chat/test/src/api/web_socket_stub_test.dart @@ -0,0 +1,11 @@ +import 'package:test/test.dart'; +import 'package:stream_chat/src/api/web_socket_channel_stub.dart'; + +void main() { + test('src/api/web_socket_stub_test', () { + expect( + () => connectWebSocket('fakeurl'), + throwsA(isA()), + ); + }); +} diff --git a/packages/stream_chat/test/src/api/websocket_test.dart b/packages/stream_chat/test/src/api/websocket_test.dart index 238cc850..e14903e2 100644 --- a/packages/stream_chat/test/src/api/websocket_test.dart +++ b/packages/stream_chat/test/src/api/websocket_test.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:logging/logging.dart'; -import 'package:mockito/mockito.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:stream_chat/src/api/connection_status.dart'; import 'package:stream_chat/src/api/websocket.dart'; import 'package:stream_chat/src/models/event.dart'; @@ -19,7 +19,7 @@ class Functions { }) => null; - void handleFunc(Event event) => null; + void handleFunc(Event event) {} } class MockFunctions extends Mock implements Functions {} @@ -28,35 +28,35 @@ class MockWSChannel extends Mock implements WebSocketChannel {} class MockWSSink extends Mock implements WebSocketSink {} +class FakeEvent extends Fake implements Event {} + void main() { group('src/api/websocket', () { + setUpAll(() { + registerFallbackValue(FakeEvent()); + }); + test('should connect with correct parameters', () async { final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - final ws = WebSocket( baseUrl: 'baseurl', user: User(id: 'testid'), logger: Logger('ws'), connectParams: {'test': 'true'}, connectPayload: {'payload': 'test'}, - handler: (e) { - print(e); - }, + handler: print, connectFunc: connectFunc, ); - final mockWSChannel = MockWSChannel(); - final streamController = StreamController.broadcast(); - const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.sink).thenAnswer((_) => MockWSSink()); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.sink).thenAnswer((_) => MockWSSink()); + when(() => mockWSChannel.stream).thenAnswer( + (_) => streamController.stream, + ); final timer = Timer.periodic( const Duration(milliseconds: 100), @@ -65,7 +65,7 @@ void main() { await ws.connect(); - verify(connectFunc(computedUrl)).called(1); + verify(() => connectFunc(computedUrl)).called(1); expect(ws.connectionStatus, ConnectionStatus.connected); await streamController.close(); @@ -76,7 +76,6 @@ void main() { test('should connect with correct parameters and handle events', () async { final handleFunc = MockFunctions().handleFunc; final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - final ws = WebSocket( baseUrl: 'baseurl', user: User(id: 'testid'), @@ -86,27 +85,21 @@ void main() { handler: handleFunc, connectFunc: connectFunc, ); - final mockWSChannel = MockWSChannel(); - - final StreamController streamController = - StreamController.broadcast(); - - final computedUrl = + final streamController = StreamController.broadcast(); + const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.sink).thenAnswer((_) => MockWSSink()); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.sink).thenAnswer((_) => MockWSSink()); + when(() => mockWSChannel.stream).thenAnswer((_) => streamController.stream); final connect = ws.connect().then((_) { streamController.sink.add('{}'); - return Future.delayed(Duration(milliseconds: 200)); + return Future.delayed(const Duration(milliseconds: 200)); }).then((value) { - verify(connectFunc(computedUrl)).called(1); - verify(handleFunc(any)).called(greaterThan(0)); + verify(() => connectFunc(computedUrl)).called(1); + verify(() => handleFunc(any())).called(greaterThan(0)); return streamController.close(); }); @@ -118,9 +111,7 @@ void main() { test('should close correctly the controller', () async { final handleFunc = MockFunctions().handleFunc; - final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - final ws = WebSocket( baseUrl: 'baseurl', user: User(id: 'testid'), @@ -130,27 +121,21 @@ void main() { handler: handleFunc, connectFunc: connectFunc, ); - final mockWSChannel = MockWSChannel(); - - final StreamController streamController = - StreamController.broadcast(); - - final computedUrl = + final streamController = StreamController.broadcast(); + const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.sink).thenAnswer((_) => MockWSSink()); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.sink).thenAnswer((_) => MockWSSink()); + when(() => mockWSChannel.stream).thenAnswer((_) => streamController.stream); final connect = ws.connect().then((_) { streamController.sink.add('{}'); - return Future.delayed(Duration(milliseconds: 200)); + return Future.delayed(const Duration(milliseconds: 200)); }).then((value) { - verify(connectFunc(computedUrl)).called(1); - verify(handleFunc(any)).called(greaterThan(0)); + verify(() => connectFunc(computedUrl)).called(1); + verify(() => handleFunc(any())).called(greaterThan(0)); return streamController.close(); }); @@ -159,6 +144,7 @@ void main() { return connect; }); + test('should close correctly the controller while connecting', () async { final handleFunc = MockFunctions().handleFunc; @@ -198,9 +184,7 @@ void main() { test('should run correctly health check', () async { final handleFunc = MockFunctions().handleFunc; - final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - final ws = WebSocket( baseUrl: 'baseurl', user: User(id: 'testid'), @@ -210,32 +194,27 @@ void main() { handler: handleFunc, connectFunc: connectFunc, ); - final mockWSChannel = MockWSChannel(); final mockWSSink = MockWSSink(); - - final StreamController streamController = - StreamController.broadcast(); - - final computedUrl = + final streamController = StreamController.broadcast(); + const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); - when(mockWSChannel.sink).thenReturn(mockWSSink); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.stream).thenAnswer((_) => streamController.stream); + when(() => mockWSChannel.sink).thenReturn(mockWSSink); final timer = Timer.periodic( - Duration(milliseconds: 1000), + const Duration(milliseconds: 1000), (_) => streamController.sink.add('{}'), ); final connect = ws.connect().then((_) { streamController.sink.add('{}'); - return Future.delayed(Duration(milliseconds: 200)); + return Future.delayed(const Duration(milliseconds: 200)); }).then((value) async { - verify(mockWSSink.add("{'type': 'health.check'}")).called(greaterThan(0)); + verify(() => mockWSSink.add("{'type': 'health.check'}")) + .called(greaterThan(0)); timer.cancel(); await streamController.close(); @@ -249,9 +228,7 @@ void main() { test('should run correctly reconnection check', () async { final handleFunc = MockFunctions().handleFunc; - final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - Logger.root.level = Level.ALL; final ws = WebSocket( baseUrl: 'baseurl', @@ -262,34 +239,28 @@ void main() { handler: handleFunc, connectFunc: connectFunc, reconnectionMonitorTimeout: 1, - reconnectionMonitorInterval: 1, ); - final mockWSChannel = MockWSChannel(); final mockWSSink = MockWSSink(); - - StreamController streamController = - StreamController.broadcast(); - - final computedUrl = + var streamController = StreamController.broadcast(); + const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); - when(mockWSChannel.sink).thenReturn(mockWSSink); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.stream).thenAnswer((_) => streamController.stream); + when(() => mockWSChannel.sink).thenReturn(mockWSSink); final connect = ws.connect().then((_) { streamController.sink.add('{}'); streamController.close(); streamController = StreamController.broadcast(); streamController.sink.add('{}'); - return Future.delayed(Duration(milliseconds: 200)); + return Future.delayed(const Duration(milliseconds: 200)); }).then((value) async { - verify(mockWSSink.add("{'type': 'health.check'}")).called(greaterThan(0)); + verify(() => mockWSSink.add("{'type': 'health.check'}")) + .called(greaterThan(0)); - verify(connectFunc(computedUrl)).called(2); + verify(() => connectFunc(computedUrl)).called(2); await streamController.close(); return mockWSSink.close(); @@ -302,9 +273,7 @@ void main() { test('should close correctly the controller', () async { final handleFunc = MockFunctions().handleFunc; - final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - final ws = WebSocket( baseUrl: 'baseurl', user: User(id: 'testid'), @@ -314,28 +283,22 @@ void main() { handler: handleFunc, connectFunc: connectFunc, ); - final mockWSChannel = MockWSChannel(); final mockWSSink = MockWSSink(); - - final StreamController streamController = - StreamController.broadcast(); - - final computedUrl = + final streamController = StreamController.broadcast(); + const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); - when(mockWSChannel.sink).thenReturn(mockWSSink); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.stream).thenAnswer((_) => streamController.stream); + when(() => mockWSChannel.sink).thenReturn(mockWSSink); final connect = ws.connect().then((_) { streamController.sink.add('{}'); - return Future.delayed(Duration(milliseconds: 200)); + return Future.delayed(const Duration(milliseconds: 200)); }).then((value) async { await ws.disconnect(); - verify(mockWSSink.close()).called(greaterThan(0)); + verify(mockWSSink.close).called(greaterThan(0)); await streamController.close(); await mockWSSink.close(); @@ -348,41 +311,34 @@ void main() { test('should throw an error', () async { final ConnectWebSocket connectFunc = MockFunctions().connectFunc; - final ws = WebSocket( baseUrl: 'baseurl', user: User(id: 'testid'), logger: Logger('ws'), connectParams: {'test': 'true'}, connectPayload: {'payload': 'test'}, - handler: (e) { - print(e); - }, + handler: print, connectFunc: connectFunc, ); - final mockWSChannel = MockWSChannel(); - final streamController = StreamController.broadcast(); - - final computedUrl = + const computedUrl = 'wss://baseurl/connect?test=true&json=%7B%22payload%22%3A%22test%22%2C%22user_details%22%3A%7B%22id%22%3A%22testid%22%7D%7D'; - when(connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); - when(mockWSChannel.sink).thenAnswer((_) => MockWSSink()); - when(mockWSChannel.stream).thenAnswer((_) { - return streamController.stream; - }); + when(() => connectFunc(computedUrl)).thenAnswer((_) => mockWSChannel); + when(() => mockWSChannel.sink).thenAnswer((_) => MockWSSink()); + when(() => mockWSChannel.stream).thenAnswer((_) => streamController.stream); Future.delayed( - Duration(milliseconds: 1000), + const Duration(milliseconds: 1000), () => streamController.sink.addError('test error'), ); try { expect(await ws.connect(), throwsA(isA())); } catch (e) { - verify(connectFunc(computedUrl)).called(greaterThanOrEqualTo(1)); + verify(() => connectFunc(computedUrl)).called(greaterThanOrEqualTo(1)); + streamController.close(); } }); } diff --git a/packages/stream_chat/test/src/client_test.dart b/packages/stream_chat/test/src/client_test.dart index 21b9d09b..6ae8ee3e 100644 --- a/packages/stream_chat/test/src/client_test.dart +++ b/packages/stream_chat/test/src/client_test.dart @@ -1,10 +1,11 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:typed_data'; import 'package:dio/dio.dart'; import 'package:dio/native_imp.dart'; import 'package:logging/logging.dart'; -import 'package:mockito/mockito.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:stream_chat/src/api/requests.dart'; import 'package:stream_chat/src/client.dart'; import 'package:stream_chat/src/exceptions.dart'; @@ -15,6 +16,8 @@ import 'package:test/test.dart'; class MockDio extends Mock implements DioForNative {} +class FakeRequestOptions extends Fake implements RequestOptions {} + class MockHttpClientAdapter extends Mock implements HttpClientAdapter {} class Functions { @@ -25,10 +28,16 @@ class MockFunctions extends Mock implements Functions {} void main() { group('src/client', () { - group('constructor', () { - final List log = []; + setUpAll(() { + registerFallbackValue(FakeRequestOptions()); + registerFallbackValue>(const Stream.empty()); + registerFallbackValue>(Future.value()); + }); - overridePrint(testFn()) => () { + group('constructor', () { + final log = []; + + dynamic overridePrint(testFn()) => () { log.clear(); final spec = ZoneSpecification(print: (_, __, ___, String msg) { // Add to log instead of printing to stdout @@ -37,9 +46,7 @@ void main() { return Zone.current.fork(specification: spec).run(testFn); }; - tearDown(() { - log.clear(); - }); + tearDown(log.clear); test('should create the object correctly', () { final client = StreamChatClient('api-key'); @@ -52,14 +59,14 @@ void main() { }); test('should create the object correctly', overridePrint(() { - final LogHandlerFunction logHandler = (LogRecord record) { + void logHandler(LogRecord record) { print(record.message); - }; + } final client = StreamChatClient( 'api-key', - connectTimeout: Duration(seconds: 10), - receiveTimeout: Duration(seconds: 12), + connectTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 12), logLevel: Level.INFO, baseURL: 'test.com', logHandlerFunction: logHandler, @@ -74,13 +81,15 @@ void main() { client.logger.warning('test'); client.logger.config('test config'); - expect([log[log.length - 2], log[log.length - 1]], - ['instantiating new client', 'test']); + expect( + [log[log.length - 2], log[log.length - 1]], + ['instantiating new client', 'test'], + ); })); test('Channel', () { final client = StreamChatClient('test'); - final Map data = {'test': 1}; + final data = {'test': 1}; final channelClient = client.channel('type', id: 'id', extraData: data); expect(channelClient.type, 'type'); expect(channelClient.id, 'id'); @@ -91,71 +100,73 @@ void main() { test('should pass right default parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final queryParams = { 'payload': json.encode({ - "filter_conditions": null, - "sort": null, - "state": true, - "watch": true, - "presence": false, - "limit": 10, - "offset": 0, + 'filter_conditions': null, + 'sort': null, + 'state': true, + 'watch': true, + 'presence': false, + 'limit': 10, + 'offset': 0, }), }; - when(mockDio.get('/channels', queryParameters: queryParams)) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.get('/channels', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.queryChannelsOnline(filter: null, waitForConnect: false); - verify(mockDio.get('/channels', queryParameters: queryParams)) + verify(() => + mockDio.get('/channels', queryParameters: queryParams)) .called(1); }); test('should pass right parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final queryFilter = { - "id": { - "\$in": ["test"], + 'id': { + '\$in': ['test'], }, }; final sortOptions = >[]; - final options = {"state": false, "watch": false, "presence": true}; - final paginationParams = PaginationParams( - limit: 10, - offset: 2, - ); + final options = {'state': false, 'watch': false, 'presence': true}; + const paginationParams = PaginationParams(offset: 2); final queryParams = { 'payload': json.encode({ - "filter_conditions": queryFilter, - "sort": sortOptions, + 'filter_conditions': queryFilter, + 'sort': sortOptions, } ..addAll(options) ..addAll(paginationParams.toJson())), }; - when(mockDio.get('/channels', queryParameters: queryParams)) - .thenAnswer((_) async { - return Response(data: '{"channels":[]}', statusCode: 200); - }); + when( + () => mockDio.get('/channels', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{"channels":[]}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.queryChannelsOnline( filter: queryFilter, @@ -165,7 +176,8 @@ void main() { waitForConnect: false, ); - verify(mockDio.get('/channels', queryParameters: queryParams)) + verify(() => + mockDio.get('/channels', queryParameters: queryParams)) .called(1); }); }); @@ -174,22 +186,16 @@ void main() { test('should pass right default parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final filter = { 'cid': { r'$in': ['messaging:testId'] } }; - const query = 'hello'; - final queryParams = { 'payload': json.encode({ 'filter_conditions': filter, @@ -197,34 +203,37 @@ void main() { }), }; - when(mockDio.get('/search', queryParameters: queryParams)) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.get('/search', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.search(filter, query: query); - verify(mockDio.get('/search', queryParameters: queryParams)) + verify(() => + mockDio.get('/search', queryParameters: queryParams)) .called(1); }); test('should pass right parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final filters = { - "id": { - "\$in": ["test"], + 'id': { + '\$in': ['test'], }, }; - final sortOptions = [SortOption('name')]; - final query = 'query'; - + const sortOptions = [SortOption('name')]; + const query = 'query'; final queryParams = { 'payload': json.encode({ 'filter_conditions': filters, @@ -235,18 +244,26 @@ void main() { }), }; - when(mockDio.get('/search', queryParameters: queryParams)) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.get('/search', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.search( filters, sort: sortOptions, query: query, - paginationParams: PaginationParams(), + paginationParams: const PaginationParams(), ); - verify(mockDio.get('/search', queryParameters: queryParams)) - .called(1); + verify( + () => mockDio.get('/search', queryParameters: queryParams), + ).called(1); }); }); @@ -254,23 +271,28 @@ void main() { test('addDevice', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post('/devices', data: { + 'id': 'test-id', + 'push_provider': 'firebase', + }), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/devices', data: { - 'id': 'test-id', - 'push_provider': 'firebase', - })).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.addDevice('test-id', PushProvider.firebase); verify( - mockDio.post( + () => mockDio.post( '/devices', data: {'id': 'test-id', 'push_provider': 'firebase'}, ), @@ -280,41 +302,53 @@ void main() { test('getDevices', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when(() => mockDio.get('/devices')).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.get('/devices')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.getDevices(); - verify(mockDio.get('/devices')).called(1); + verify(() => mockDio.get('/devices')).called(1); }); test('removeDevice', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.delete( + '/devices', + queryParameters: {'id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio - .delete('/devices', queryParameters: {'id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.removeDevice('test-id'); - verify(mockDio.delete('/devices', - queryParameters: {'id': 'test-id'})).called(1); + verify( + () => mockDio.delete( + '/devices', + queryParameters: {'id': 'test-id'}, + ), + ).called(1); }); }); @@ -324,7 +358,7 @@ void main() { expect( token, - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidGVzdCJ9.devtoken', + '''eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidGVzdCJ9.devtoken''', ); }); @@ -332,62 +366,68 @@ void main() { test('should pass right default parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final queryParams = { 'payload': json.encode({ - "filter_conditions": {}, - "sort": null, - "presence": false, + 'filter_conditions': {}, + 'sort': null, + 'presence': false, }), }; - when(mockDio.get('/users', queryParameters: queryParams)) - .thenAnswer( - (_) async => Response(data: '{"users":[]}', statusCode: 200)); + when( + () => mockDio.get('/users', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{"users":[]}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.queryUsers(); - verify(mockDio.get('/users', queryParameters: queryParams)) - .called(1); + verify( + () => mockDio.get( + '/users', + queryParameters: queryParams, + ), + ).called(1); }); test('should pass right parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); - - final Map queryFilter = { - "id": { - "\$in": ["test"], + final client = StreamChatClient('api-key', httpClient: mockDio); + final queryFilter = { + 'id': { + '\$in': ['test'], }, }; - final List sortOptions = []; - final options = {"presence": true}; - - final Map queryParams = { + const sortOptions = []; + final options = {'presence': true}; + final queryParams = { 'payload': json.encode({ - "filter_conditions": queryFilter, - "sort": sortOptions, + 'filter_conditions': queryFilter, + 'sort': sortOptions, }..addAll(options)), }; - when(mockDio.get('/users', queryParameters: queryParams)) - .thenAnswer((_) async { - return Response(data: '{"users":[]}', statusCode: 200); - }); + when( + () => mockDio.get('/users', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{"users":[]}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.queryUsers( filter: queryFilter, @@ -395,7 +435,8 @@ void main() { options: options, ); - verify(mockDio.get('/users', queryParameters: queryParams)) + verify(() => + mockDio.get('/users', queryParameters: queryParams)) .called(1); }); }); @@ -404,34 +445,37 @@ void main() { test('connectUser should throw exception', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/flag', + data: {'target_user_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/flag', - data: {'target_user_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.flagUser('test-id'); - verify(mockDio.post('/moderation/flag', + verify(() => mockDio.post('/moderation/flag', data: {'target_user_id': 'test-id'})).called(1); }); test('flagUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + final client = StreamChatClient('api-key', httpClient: mockDio); expect(() => client.connectUserWithProvider(User(id: 'test-id')), throwsA(isA())); @@ -440,60 +484,62 @@ void main() { test('unflagUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/unflag', + data: {'target_user_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/unflag', - data: {'target_user_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.unflagUser('test-id'); - verify(mockDio.post('/moderation/unflag', + verify(() => mockDio.post('/moderation/unflag', data: {'target_user_id': 'test-id'})).called(1); }); test('updateUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final user = User(id: 'test-id'); - final data = { 'users': {user.id: user.toJson()}, }; - when(mockDio.post('/users', data: data)) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when(() => mockDio.post('/users', data: data)).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.updateUser(user); - verify(mockDio.post('/users', data: data)).called(1); + verify(() => mockDio.post('/users', data: data)).called(1); }); test('updateUsers', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); - - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + final client = StreamChatClient('api-key', httpClient: mockDio); final user = User(id: 'test-id'); final user2 = User(id: 'test-id2'); @@ -504,53 +550,70 @@ void main() { }, }; - when(mockDio.post('/users', data: data)) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when(() => mockDio.post('/users', data: data)).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.updateUsers([user, user2]); - verify(mockDio.post('/users', data: data)).called(1); + verify(() => mockDio.post('/users', data: data)).called(1); }); test('banUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/ban', + data: {'test': true, 'target_user_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/ban', - data: {'test': true, 'target_user_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.banUser('test-id', {'test': true}); - verify(mockDio.post('/moderation/ban', + verify(() => mockDio.post('/moderation/ban', data: {'test': true, 'target_user_id': 'test-id'})).called(1); }); test('unbanUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.delete( + '/moderation/ban', + queryParameters: {'test': true, 'target_user_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.delete('/moderation/ban', - queryParameters: {'test': true, 'target_user_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.unbanUser('test-id', {'test': true}); - verify(mockDio.delete('/moderation/ban', + verify(() => mockDio.delete('/moderation/ban', queryParameters: {'test': true, 'target_user_id': 'test-id'})) .called(1); }); @@ -558,42 +621,54 @@ void main() { test('muteUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/mute', + data: {'target_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/mute', - data: {'target_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.muteUser('test-id'); - verify(mockDio.post('/moderation/mute', + verify(() => mockDio.post('/moderation/mute', data: {'target_id': 'test-id'})).called(1); }); test('unmuteUser', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/unmute', + data: {'target_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/unmute', - data: {'target_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.unmuteUser('test-id'); - verify(mockDio.post('/moderation/unmute', + verify(() => mockDio.post('/moderation/unmute', data: {'target_id': 'test-id'})).called(1); }); }); @@ -602,131 +677,148 @@ void main() { test('flagMessage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/flag', + data: {'target_message_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/flag', - data: {'target_message_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.flagMessage('test-id'); - verify(mockDio.post('/moderation/flag', + verify(() => mockDio.post('/moderation/flag', data: {'target_message_id': 'test-id'})).called(1); }); test('unflagMessage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when( + () => mockDio.post( + '/moderation/unflag', + data: {'target_message_id': 'test-id'}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/moderation/unflag', - data: {'target_message_id': 'test-id'})) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.unflagMessage('test-id'); - verify(mockDio.post('/moderation/unflag', + verify(() => mockDio.post('/moderation/unflag', data: {'target_message_id': 'test-id'})).called(1); }); test('updateMessage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + final message = Message(id: 'test', updatedAt: DateTime.now()); + + when( + () => mockDio.post( + '/messages/${message.id}', + data: {'message': anything}, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - final message = Message( - id: 'test', - updatedAt: DateTime.now(), - ); - - when(mockDio.post( - '/messages/${message.id}', - data: {'message': anything}, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.updateMessage(message); - verify(mockDio.post('/messages/${message.id}', + verify(() => mockDio.post('/messages/${message.id}', data: {'message': anything})).called(1); }); test('deleteMessage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + const messageId = 'test'; + + when(() => mockDio.delete('/messages/$messageId')).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - final messageId = 'test'; - - when(mockDio.delete('/messages/$messageId')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.deleteMessage(Message(id: messageId)); - verify(mockDio.delete('/messages/$messageId')).called(1); + verify(() => mockDio.delete('/messages/$messageId')).called(1); }); test('getMessage', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + const messageId = 'test'; + + when(() => mockDio.get('/messages/$messageId')).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - final messageId = 'test'; - - when(mockDio.get('/messages/$messageId')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.getMessage(messageId); - verify(mockDio.get('/messages/$messageId')).called(1); + verify(() => mockDio.get('/messages/$messageId')).called(1); }); test('markAllRead', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + + when(() => mockDio.post('/channels/read')).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - when(mockDio.post('/channels/read')) - .thenAnswer((_) async => Response(data: '{}', statusCode: 200)); - await client.markAllRead(); - verify(mockDio.post('/channels/read')).called(1); + verify(() => mockDio.post('/channels/read')).called(1); }); }); @@ -735,43 +827,53 @@ void main() { test('should put the correct parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + final queryParams = {'test': 1}; + + when( + () => mockDio.get('/test', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - final Map queryParams = { - 'test': 1, - }; - - when(mockDio.get('/test', queryParameters: queryParams)) - .thenAnswer((_) async { - return Response(data: '{}', statusCode: 200); - }); - await client.get('/test', queryParameters: queryParams); - verify(mockDio.get('/test', queryParameters: queryParams)) + verify(() => + mockDio.get('/test', queryParameters: queryParams)) .called(1); }); test('should catch the error', () async { - final dioHttp = Dio(); - final mockHttpClientAdapter = MockHttpClientAdapter(); - dioHttp.httpClientAdapter = mockHttpClientAdapter; + final mockDio = MockDio(); - final client = StreamChatClient( - 'api-key', - httpClient: dioHttp, + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + + final client = StreamChatClient('api-key', httpClient: mockDio); + + when(() => mockDio.get(any())).thenThrow( + DioError( + type: DioErrorType.response, + response: Response( + data: 'test error', + statusCode: 400, + requestOptions: FakeRequestOptions(), + ), + requestOptions: FakeRequestOptions(), + ), ); - when(mockHttpClientAdapter.fetch(any, any, any)).thenAnswer( - (_) async => ResponseBody.fromString('test error', 400)); - - expect(client.get('/test'), throwsA(ApiError('test error', 400))); + expect( + client.get('/test'), + throwsA(ApiError('test error', 400)), + ); }); }); @@ -779,40 +881,48 @@ void main() { test('should put the correct parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + + final client = StreamChatClient('api-key', httpClient: mockDio); + final data = {'test': 1}; + + when(() => mockDio.post('/test', data: data)).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); + + await client.post('/test', data: data); + + verify(() => mockDio.post('/test', data: data)).called(1); + }); + + test('should catch the error', () async { + final mockDio = MockDio(); + + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', httpClient: mockDio, ); - final Map data = { - 'test': 1, - }; - - when(mockDio.post('/test', data: data)).thenAnswer((_) async { - return Response(data: '{}', statusCode: 200); - }); - - await client.post('/test', data: data); - - verify(mockDio.post('/test', data: data)).called(1); - }); - - test('should catch the error', () async { - final dioHttp = Dio(); - final mockHttpClientAdapter = MockHttpClientAdapter(); - dioHttp.httpClientAdapter = mockHttpClientAdapter; - - final client = StreamChatClient( - 'api-key', - httpClient: dioHttp, + when(() => mockDio.post(any())).thenThrow( + DioError( + type: DioErrorType.response, + response: Response( + data: 'test error', + statusCode: 400, + requestOptions: FakeRequestOptions(), + ), + requestOptions: FakeRequestOptions(), + ), ); - when(mockHttpClientAdapter.fetch(any, any, any)).thenAnswer( - (_) async => ResponseBody.fromString('test error', 400)); - expect(client.post('/test'), throwsA(ApiError('test error', 400))); }); }); @@ -821,40 +931,45 @@ void main() { test('should put the correct parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, + final client = StreamChatClient('api-key', httpClient: mockDio); + final data = {'test': 1}; + + when(() => mockDio.put('/test', data: data)).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), ); - final Map data = { - 'test': 1, - }; - - when(mockDio.put('/test', data: data)).thenAnswer((_) async { - return Response(data: '{}', statusCode: 200); - }); - await client.put('/test', data: data); - verify(mockDio.put('/test', data: data)).called(1); + verify(() => mockDio.put('/test', data: data)).called(1); }); test('should catch the error', () async { - final dioHttp = Dio(); - final mockHttpClientAdapter = MockHttpClientAdapter(); - dioHttp.httpClientAdapter = mockHttpClientAdapter; + final mockDio = MockDio(); - final client = StreamChatClient( - 'api-key', - httpClient: dioHttp, + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + + final client = StreamChatClient('api-key', httpClient: mockDio); + + when(() => mockDio.put(any())).thenThrow( + DioError( + type: DioErrorType.response, + response: Response( + data: 'test error', + statusCode: 400, + requestOptions: FakeRequestOptions(), + ), + requestOptions: FakeRequestOptions(), + ), ); - when(mockHttpClientAdapter.fetch(any, any, any)).thenAnswer( - (_) async => ResponseBody.fromString('test error', 400)); - expect(client.put('/test'), throwsA(ApiError('test error', 400))); }); }); @@ -863,41 +978,48 @@ void main() { test('should put the correct parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); - final client = StreamChatClient( - 'api-key', - httpClient: mockDio, - ); + final client = StreamChatClient('api-key', httpClient: mockDio); - final Map data = { + final data = { 'test': 1, }; - when(mockDio.patch('/test', data: data)) - .thenAnswer((_) async { - return Response(data: '{}', statusCode: 200); - }); + when(() => mockDio.patch('/test', data: data)).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.patch('/test', data: data); - verify(mockDio.patch('/test', data: data)).called(1); + verify(() => mockDio.patch('/test', data: data)).called(1); }); test('should catch the error', () async { - final dioHttp = Dio(); - final mockHttpClientAdapter = MockHttpClientAdapter(); - dioHttp.httpClientAdapter = mockHttpClientAdapter; + final mockDio = MockDio(); - final client = StreamChatClient( - 'api-key', - httpClient: dioHttp, + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + + final client = StreamChatClient('api-key', httpClient: mockDio); + + when(() => mockDio.patch(any())).thenThrow( + DioError( + type: DioErrorType.response, + response: Response( + data: 'test error', + statusCode: 400, + requestOptions: FakeRequestOptions(), + ), + requestOptions: FakeRequestOptions(), + ), ); - when(mockHttpClientAdapter.fetch(any, any, any)).thenAnswer( - (_) async => ResponseBody.fromString('test error', 400)); - expect(client.patch('/test'), throwsA(ApiError('test error', 400))); }); }); @@ -906,42 +1028,55 @@ void main() { test('should put the correct parameters', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', httpClient: mockDio, ); - final Map queryParams = { + final queryParams = { 'test': 1, }; - when(mockDio.delete('/test', queryParameters: queryParams)) - .thenAnswer((_) async { - return Response(data: '{}', statusCode: 200); - }); + when( + () => mockDio.delete('/test', queryParameters: queryParams), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.delete('/test', queryParameters: queryParams); - verify(mockDio.delete('/test', queryParameters: queryParams)) + verify(() => + mockDio.delete('/test', queryParameters: queryParams)) .called(1); }); test('should catch the error', () async { - final dioHttp = Dio(); - final mockHttpClientAdapter = MockHttpClientAdapter(); - dioHttp.httpClientAdapter = mockHttpClientAdapter; + final mockDio = MockDio(); - final client = StreamChatClient( - 'api-key', - httpClient: dioHttp, + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); + + final client = StreamChatClient('api-key', httpClient: mockDio); + + when(() => mockDio.delete(any())).thenThrow( + DioError( + type: DioErrorType.response, + response: Response( + data: 'test error', + statusCode: 400, + requestOptions: FakeRequestOptions(), + ), + requestOptions: FakeRequestOptions(), + ), ); - when(mockHttpClientAdapter.fetch(any, any, any)).thenAnswer( - (_) async => ResponseBody.fromString('test error', 400)); - expect(client.delete('/test'), throwsA(ApiError('test error', 400))); }); }); @@ -949,8 +1084,8 @@ void main() { group('pin message', () { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -966,33 +1101,48 @@ void main() { }); test('should complete successfully', () async { - final timeout = 30; + const timeout = 30; final message = Message(text: 'Hello'); - when(mockDio.post( - '/messages/${message.id}', - data: anything, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/messages/${message.id}', + data: anything, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.pinMessage(message, timeout); - verify(mockDio.post('/messages/${message.id}', + verify(() => mockDio.post('/messages/${message.id}', data: {'message': anything})).called(1); }); test('should unpin message successfully', () async { final message = Message(text: 'Hello'); - when(mockDio.post( - '/messages/${message.id}', - data: anything, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.post( + '/messages/${message.id}', + data: anything, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await client.unpinMessage(message); - verify(mockDio.post('/messages/${message.id}', - data: anything)) - .called(1); + verify(() => mockDio.post('/messages/${message.id}', + data: anything)).called(1); }); }); }); @@ -1001,8 +1151,8 @@ void main() { test('should update channel', () async { final mockDio = MockDio(); - when(mockDio.options).thenReturn(BaseOptions()); - when(mockDio.interceptors).thenReturn(Interceptors()); + when(() => mockDio.options).thenReturn(BaseOptions()); + when(() => mockDio.interceptors).thenReturn(Interceptors()); final client = StreamChatClient( 'api-key', @@ -1012,20 +1162,30 @@ void main() { final channelClient = client.channel('type', id: 'id', extraData: {'name': 'init'}); - var update = { + const update = { 'set': {'name': 'demo'} }; - when(mockDio.patch( - '/channels/${channelClient.type}/${channelClient.id}', - data: update, - )).thenAnswer((_) async => Response(data: '{}', statusCode: 200)); + when( + () => mockDio.patch( + '/channels/${channelClient.type}/${channelClient.id}', + data: update, + ), + ).thenAnswer( + (_) async => Response( + data: '{}', + statusCode: 200, + requestOptions: FakeRequestOptions(), + ), + ); await channelClient.updatePartial(update); - verify(mockDio.patch( - '/channels/${channelClient.type}/${channelClient.id}', - data: update)) - .called(1); + verify( + () => mockDio.patch( + '/channels/${channelClient.type}/${channelClient.id}', + data: update, + ), + ).called(1); }); }); }); diff --git a/packages/stream_chat/test/src/models/action_test.dart b/packages/stream_chat/test/src/models/action_test.dart index 4859fcbe..5d142953 100644 --- a/packages/stream_chat/test/src/models/action_test.dart +++ b/packages/stream_chat/test/src/models/action_test.dart @@ -5,7 +5,7 @@ import 'package:stream_chat/src/models/action.dart'; void main() { group('src/models/action', () { - const jsonExample = r'''{ + const jsonExample = '''{ "name": "name", "style": "style", "text": "text", diff --git a/packages/stream_chat/test/src/models/attachment_test.dart b/packages/stream_chat/test/src/models/attachment_test.dart index b15458ad..3124ddd2 100644 --- a/packages/stream_chat/test/src/models/attachment_test.dart +++ b/packages/stream_chat/test/src/models/attachment_test.dart @@ -1,12 +1,12 @@ +import 'dart:convert'; import 'package:stream_chat/src/models/attachment.dart'; import 'package:stream_chat/src/models/action.dart'; -import 'dart:convert'; import 'package:test/test.dart'; void main() { group('src/models/attachment', () { - const jsonExample = r'''{ + const jsonExample = '''{ "type": "giphy", "title": "awesome", "title_link": "https://giphy.com/gifs/nrkp3-dance-happy-3o7TKnCdBx5cMg0qti", @@ -38,22 +38,27 @@ void main() { test('should parse json correctly', () { final attachment = Attachment.fromJson(json.decode(jsonExample)); - expect(attachment.type, "giphy"); - expect(attachment.title, "awesome"); - expect(attachment.titleLink, - "https://giphy.com/gifs/nrkp3-dance-happy-3o7TKnCdBx5cMg0qti"); - expect(attachment.thumbUrl, - "https://media0.giphy.com/media/3o7TKnCdBx5cMg0qti/giphy.gif"); + expect(attachment.type, 'giphy'); + expect(attachment.title, 'awesome'); + expect( + attachment.titleLink, + 'https://giphy.com/gifs/nrkp3-dance-happy-3o7TKnCdBx5cMg0qti', + ); + expect( + attachment.thumbUrl, + 'https://media0.giphy.com/media/3o7TKnCdBx5cMg0qti/giphy.gif', + ); expect(attachment.actions, hasLength(3)); expect(attachment.actions[0], isA()); }); test('should serialize to json correctly', () { final channel = Attachment( - type: "image", - title: "soo", - titleLink: - "https://giphy.com/gifs/nrkp3-dance-happy-3o7TKnCdBx5cMg0qti"); + type: 'image', + title: 'soo', + titleLink: + 'https://giphy.com/gifs/nrkp3-dance-happy-3o7TKnCdBx5cMg0qti', + ); expect( channel.toJson(), diff --git a/packages/stream_chat/test/src/models/channel_state_test.dart b/packages/stream_chat/test/src/models/channel_state_test.dart index 0a14cb76..c2d69b2b 100644 --- a/packages/stream_chat/test/src/models/channel_state_test.dart +++ b/packages/stream_chat/test/src/models/channel_state_test.dart @@ -10,7 +10,7 @@ import 'package:stream_chat/stream_chat.dart'; void main() { group('src/models/channel_state', () { - const jsonExample = r'''{ + const jsonExample = '''{ "channel": { "id": "dev", "type": "team", @@ -853,28 +853,32 @@ void main() { expect(channelState.channel.config.commands, hasLength(1)); expect(channelState.channel.config.commands[0], isA()); expect(channelState.channel.lastMessageAt, - DateTime.parse("2020-01-30T13:43:41.062362Z")); + DateTime.parse('2020-01-30T13:43:41.062362Z')); expect(channelState.channel.createdAt, - DateTime.parse("2019-04-03T18:43:33.213373Z")); + DateTime.parse('2019-04-03T18:43:33.213373Z')); expect(channelState.channel.updatedAt, - DateTime.parse("2019-04-03T18:43:33.213374Z")); + DateTime.parse('2019-04-03T18:43:33.213374Z')); expect(channelState.channel.createdBy, isA()); expect(channelState.channel.frozen, true); expect(channelState.channel.extraData['example'], 1); - expect(channelState.channel.extraData['name'], "#dev"); - expect(channelState.channel.extraData['image'], - "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png"); + expect(channelState.channel.extraData['name'], '#dev'); + expect( + channelState.channel.extraData['image'], + 'https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png', + ); expect(channelState.messages, hasLength(25)); expect(channelState.messages[0], isA()); expect(channelState.messages[0], isNotNull); - expect(channelState.messages[0].createdAt, - DateTime.parse("2020-01-29T03:23:02.843948Z")); + expect( + channelState.messages[0].createdAt, + DateTime.parse('2020-01-29T03:23:02.843948Z'), + ); expect(channelState.messages[0].user, isA()); expect(channelState.watcherCount, 5); }); test('should serialize to json correctly', () { - const toJsonExample = r''' + const toJsonExample = ''' { "channel": { "id": "dev", diff --git a/packages/stream_chat/test/src/models/channel_test.dart b/packages/stream_chat/test/src/models/channel_test.dart index 69b18197..9f6aa5b7 100644 --- a/packages/stream_chat/test/src/models/channel_test.dart +++ b/packages/stream_chat/test/src/models/channel_test.dart @@ -17,19 +17,19 @@ void main() { test('should parse json correctly', () { final channel = ChannelModel.fromJson(json.decode(jsonExample)); - expect(channel.id, equals("test")); - expect(channel.type, equals("livestream")); - expect(channel.cid, equals("test:livestream")); - expect(channel.extraData["cats"], equals(true)); - expect(channel.extraData["fruit"], equals(["bananas", "apples"])); + expect(channel.id, equals('test')); + expect(channel.type, equals('livestream')); + expect(channel.cid, equals('test:livestream')); + expect(channel.extraData['cats'], equals(true)); + expect(channel.extraData['fruit'], equals(['bananas', 'apples'])); }); test('should serialize to json correctly', () { final channel = ChannelModel( - type: "type", - id: "id", - cid: "a:a", - extraData: {"name": "cool"}, + type: 'type', + id: 'id', + cid: 'a:a', + extraData: {'name': 'cool'}, ); expect( @@ -40,10 +40,10 @@ void main() { test('should serialize to json correctly when frozen is provided', () { final channel = ChannelModel( - type: "type", - id: "id", - cid: "a:a", - extraData: {"name": "cool"}, + type: 'type', + id: 'id', + cid: 'a:a', + extraData: {'name': 'cool'}, frozen: false, ); diff --git a/packages/stream_chat/test/src/models/command_test.dart b/packages/stream_chat/test/src/models/command_test.dart index dc44f736..8fafd192 100644 --- a/packages/stream_chat/test/src/models/command_test.dart +++ b/packages/stream_chat/test/src/models/command_test.dart @@ -1,6 +1,6 @@ -import 'package:stream_chat/src/models/command.dart'; import 'dart:convert'; +import 'package:stream_chat/src/models/command.dart'; import 'package:test/test.dart'; void main() { @@ -30,9 +30,9 @@ void main() { expect( command.toJson(), { - "name": "giphy", - "description": "Post a random gif to the channel", - "args": "[text]", + 'name': 'giphy', + 'description': 'Post a random gif to the channel', + 'args': '[text]', }, ); }); diff --git a/packages/stream_chat/test/src/models/device_test.dart b/packages/stream_chat/test/src/models/device_test.dart index 3f8de16e..27a94982 100644 --- a/packages/stream_chat/test/src/models/device_test.dart +++ b/packages/stream_chat/test/src/models/device_test.dart @@ -5,7 +5,7 @@ import 'package:stream_chat/src/models/device.dart'; void main() { group('src/models/device', () { - const jsonExample = r'''{ + const jsonExample = '''{ "id": "device-id", "push_provider": "push-provider" }'''; diff --git a/packages/stream_chat/test/src/models/event_test.dart b/packages/stream_chat/test/src/models/event_test.dart index db99b01a..a7c669df 100644 --- a/packages/stream_chat/test/src/models/event_test.dart +++ b/packages/stream_chat/test/src/models/event_test.dart @@ -55,7 +55,7 @@ void main() { type: 'type', cid: 'cid', connectionId: 'connectionId', - createdAt: DateTime.parse("2020-01-29T03:22:47.63613Z"), + createdAt: DateTime.parse('2020-01-29T03:22:47.63613Z'), me: OwnUser(id: 'id2'), totalUnreadCount: 1, unreadChannels: 1, diff --git a/packages/stream_chat/test/src/models/member_test.dart b/packages/stream_chat/test/src/models/member_test.dart index 237f0030..25e1d78e 100644 --- a/packages/stream_chat/test/src/models/member_test.dart +++ b/packages/stream_chat/test/src/models/member_test.dart @@ -28,8 +28,8 @@ void main() { final member = Member.fromJson(json.decode(jsonExample)); expect(member.user, isA()); expect(member.role, 'member'); - expect(member.createdAt, DateTime.parse("2020-01-28T22:17:30.95443Z")); - expect(member.updatedAt, DateTime.parse("2020-01-28T22:17:30.95443Z")); + expect(member.createdAt, DateTime.parse('2020-01-28T22:17:30.95443Z')); + expect(member.updatedAt, DateTime.parse('2020-01-28T22:17:30.95443Z')); }); }); } diff --git a/packages/stream_chat/test/src/models/message_test.dart b/packages/stream_chat/test/src/models/message_test.dart index 3541b2c0..0898e902 100644 --- a/packages/stream_chat/test/src/models/message_test.dart +++ b/packages/stream_chat/test/src/models/message_test.dart @@ -76,10 +76,10 @@ void main() { test('should parse json correctly', () { final message = Message.fromJson(json.decode(jsonExample)); - expect(message.id, "4637f7e4-a06b-42db-ba5a-8d8270dd926f"); + expect(message.id, '4637f7e4-a06b-42db-ba5a-8d8270dd926f'); expect(message.text, - "https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA"); - expect(message.type, "regular"); + 'https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA'); + expect(message.type, 'regular'); expect(message.user, isA()); expect(message.silent, isA()); expect(message.attachments, isA>()); @@ -87,8 +87,8 @@ void main() { expect(message.ownReactions, isA>()); expect(message.reactionCounts, {'love': 1}); expect(message.reactionScores, {'love': 1}); - expect(message.createdAt, DateTime.parse("2020-01-28T22:17:31.107978Z")); - expect(message.updatedAt, DateTime.parse("2020-01-28T22:17:31.130506Z")); + expect(message.createdAt, DateTime.parse('2020-01-28T22:17:31.107978Z')); + expect(message.updatedAt, DateTime.parse('2020-01-28T22:17:31.130506Z')); expect(message.mentionedUsers, isA>()); expect(message.pinned, false); expect(message.pinnedAt, null); @@ -98,38 +98,37 @@ void main() { test('should serialize to json correctly', () { final message = Message( - id: "4637f7e4-a06b-42db-ba5a-8d8270dd926f", + id: '4637f7e4-a06b-42db-ba5a-8d8270dd926f', text: - "https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA", + 'https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA', silent: false, attachments: [ Attachment.fromJson({ - "type": "video", - "author_name": "GIPHY", - "title": "The Lion King Disney GIF - Find \u0026 Share on GIPHY", - "title_link": - "https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.gif", - "text": - "Discover \u0026 share this Lion King Live Action GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.", - "image_url": - "https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.gif", - "thumb_url": - "https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.gif", - "asset_url": - "https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.mp4", - "og_scrape_url": - "https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA" + 'type': 'video', + 'author_name': 'GIPHY', + 'title': 'The Lion King Disney GIF - Find \u0026 Share on GIPHY', + 'title_link': + 'https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.gif', + 'text': + '''Discover \u0026 share this Lion King Live Action GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.''', + 'image_url': + 'https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.gif', + 'thumb_url': + 'https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.gif', + 'asset_url': + 'https://media.giphy.com/media/5zvN79uTGfLMOVfQaA/giphy.mp4', + 'og_scrape_url': + 'https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA' }) ], showInChannel: true, parentId: 'parentId', extraData: {'hey': 'test'}, - status: MessageSendingStatus.sent, ); expect( message.toJson(), - json.decode(r''' + json.decode(''' { "id": "4637f7e4-a06b-42db-ba5a-8d8270dd926f", "text": "https://giphy.com/gifs/the-lion-king-live-action-5zvN79uTGfLMOVfQaA", diff --git a/packages/stream_chat/test/src/models/reaction_test.dart b/packages/stream_chat/test/src/models/reaction_test.dart index 8bc92081..2a1d5431 100644 --- a/packages/stream_chat/test/src/models/reaction_test.dart +++ b/packages/stream_chat/test/src/models/reaction_test.dart @@ -1,7 +1,7 @@ -import 'package:test/test.dart'; -import 'package:stream_chat/src/models/reaction.dart'; import 'dart:convert'; +import 'package:test/test.dart'; +import 'package:stream_chat/src/models/reaction.dart'; import 'package:stream_chat/src/models/user.dart'; void main() { @@ -30,13 +30,13 @@ void main() { test('should parse json correctly', () { final reaction = Reaction.fromJson(json.decode(jsonExample)); expect(reaction.messageId, '76cd8c82-b557-4e48-9d12-87995d3a0e04'); - expect(reaction.createdAt, DateTime.parse("2020-01-28T22:17:31.108742Z")); + expect(reaction.createdAt, DateTime.parse('2020-01-28T22:17:31.108742Z')); expect(reaction.type, 'wow'); expect( reaction.user.toJson(), - User.init("2de0297c-f3f2-489d-b930-ef77342edccf", extraData: { - "image": "https://randomuser.me/api/portraits/women/45.jpg", - "name": "Daisy Morgan" + User.init('2de0297c-f3f2-489d-b930-ef77342edccf', extraData: { + 'image': 'https://randomuser.me/api/portraits/women/45.jpg', + 'name': 'Daisy Morgan' }).toJson(), ); expect(reaction.score, 1); @@ -47,13 +47,13 @@ void main() { test('should serialize to json correctly', () { final reaction = Reaction( messageId: '76cd8c82-b557-4e48-9d12-87995d3a0e04', - createdAt: DateTime.parse("2020-01-28T22:17:31.108742Z"), + createdAt: DateTime.parse('2020-01-28T22:17:31.108742Z'), type: 'wow', - user: User.init("2de0297c-f3f2-489d-b930-ef77342edccf", extraData: { - "image": "https://randomuser.me/api/portraits/women/45.jpg", - "name": "Daisy Morgan" + user: User.init('2de0297c-f3f2-489d-b930-ef77342edccf', extraData: { + 'image': 'https://randomuser.me/api/portraits/women/45.jpg', + 'name': 'Daisy Morgan' }), - userId: "2de0297c-f3f2-489d-b930-ef77342edccf", + userId: '2de0297c-f3f2-489d-b930-ef77342edccf', extraData: {'bananas': 'yes'}, score: 1, ); @@ -61,10 +61,10 @@ void main() { expect( reaction.toJson(), { - "message_id": "76cd8c82-b557-4e48-9d12-87995d3a0e04", - "type": "wow", - "score": 1, - "bananas": 'yes', + 'message_id': '76cd8c82-b557-4e48-9d12-87995d3a0e04', + 'type': 'wow', + 'score': 1, + 'bananas': 'yes', }, ); }); diff --git a/packages/stream_chat/test/src/models/read_test.dart b/packages/stream_chat/test/src/models/read_test.dart index b15ce66a..9fd68b6a 100644 --- a/packages/stream_chat/test/src/models/read_test.dart +++ b/packages/stream_chat/test/src/models/read_test.dart @@ -31,8 +31,8 @@ void main() { ); expect(read.toJson(), { - "user": {"id": "bbb19d9a-ee50-45bc-84e5-0584e79d0c9e"}, - "last_read": "2020-01-28T22:17:30.966485Z", + 'user': {'id': 'bbb19d9a-ee50-45bc-84e5-0584e79d0c9e'}, + 'last_read': '2020-01-28T22:17:30.966485Z', 'unread_messages': 10, }); }); diff --git a/packages/stream_chat/test/src/models/user_test.dart b/packages/stream_chat/test/src/models/user_test.dart index 6100b218..0a307126 100644 --- a/packages/stream_chat/test/src/models/user_test.dart +++ b/packages/stream_chat/test/src/models/user_test.dart @@ -17,11 +17,13 @@ void main() { }); test('should serialize to json correctly', () { - final user = - User(id: 'bbb19d9a-ee50-45bc-84e5-0584e79d0c9e', role: "abc"); + final user = User( + id: 'bbb19d9a-ee50-45bc-84e5-0584e79d0c9e', + role: 'abc', + ); expect(user.toJson(), { - 'id': "bbb19d9a-ee50-45bc-84e5-0584e79d0c9e", + 'id': 'bbb19d9a-ee50-45bc-84e5-0584e79d0c9e', }); }); }); diff --git a/packages/stream_chat_flutter/lib/src/user_list_view.dart b/packages/stream_chat_flutter/lib/src/user_list_view.dart index d4bc2f72..416f7ba0 100644 --- a/packages/stream_chat_flutter/lib/src/user_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/user_list_view.dart @@ -208,7 +208,7 @@ class _UserListViewState extends State var message = error.toString(); if (error is DioError) { final dioError = error as DioError; - if (dioError.type == DioErrorType.RESPONSE) { + if (dioError.type == DioErrorType.response) { message = dioError.message; } else { message = 'Check your connection and retry'; diff --git a/packages/stream_chat_flutter/pubspec.yaml b/packages/stream_chat_flutter/pubspec.yaml index 37898bcf..d3e003dd 100644 --- a/packages/stream_chat_flutter/pubspec.yaml +++ b/packages/stream_chat_flutter/pubspec.yaml @@ -5,43 +5,47 @@ version: 1.5.1 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues +publish_to: none + environment: sdk: ">=2.7.0 <3.0.0" dependencies: flutter: sdk: flutter - stream_chat_flutter_core: ^1.5.0 + stream_chat_flutter_core: + path: ../stream_chat_flutter_core photo_view: ^0.11.0 - rxdart: ^0.25.0 + rxdart: ^0.26.0 scrollable_positioned_list: ^0.1.8 jiffy: ^3.0.1 - flutter_svg: ^0.19.3 + flutter_svg: ">=0.21.0-nullsafety.0 <0.21.0" flutter_portal: ^0.3.0 - cached_network_image: ^2.5.0 + cached_network_image: ">=3.0.0-nullsafety <3.0.0" shimmer: ^1.1.2 flutter_markdown: ^0.5.2 - url_launcher: ^5.7.10 + url_launcher: ^6.0.0 emojis: ^0.9.3 video_player: ^2.0.0 chewie: ^1.0.0 - file_picker: ^2.1.5 - image_picker: ^0.6.7+17 - flutter_keyboard_visibility: ^4.0.2 + file_picker: ^3.0.0 + image_picker: ^0.7.0 + flutter_keyboard_visibility: ^5.0.0 video_compress: ^2.1.1 visibility_detector: ^0.1.5 - meta: ^1.2.4 - lottie: ^0.7.0+1 + http_parser: ^4.0.0 + meta: ^1.3.0 + lottie: ^1.0.0 substring_highlight: ^0.1.2 flutter_slidable: ^0.5.7 image_gallery_saver: ^1.6.7 - share_plus: ^1.2.0 + share_plus: ^2.0.0 photo_manager: ^1.0.0 ezanimation: ^0.4.1 - synchronized: ^2.1.0 + synchronized: ^3.0.0 characters: ^1.0.0 - dio: ^3.0.10 - path_provider: ^1.6.27 + dio: ">=4.0.0-prev3 <4.0.0" + path_provider: ^2.0.0 video_thumbnail: ^0.2.5+1 @@ -60,4 +64,4 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^4.1.3 - pedantic: ^1.9.2 \ No newline at end of file + pedantic: ^1.9.2 diff --git a/packages/stream_chat_flutter_core/lib/src/stream_channel.dart b/packages/stream_chat_flutter_core/lib/src/stream_channel.dart index 8f86fca4..58a47d0a 100644 --- a/packages/stream_chat_flutter_core/lib/src/stream_channel.dart +++ b/packages/stream_chat_flutter_core/lib/src/stream_channel.dart @@ -350,7 +350,7 @@ class StreamChannelState extends State { var message = snapshot.error.toString(); if (snapshot.error is DioError) { final dioError = snapshot.error as DioError; - if (dioError.type == DioErrorType.RESPONSE) { + if (dioError.type == DioErrorType.response) { message = dioError.message; } else { message = 'Check your connection and retry'; diff --git a/packages/stream_chat_flutter_core/pubspec.yaml b/packages/stream_chat_flutter_core/pubspec.yaml index cf8f9b00..98190f2c 100644 --- a/packages/stream_chat_flutter_core/pubspec.yaml +++ b/packages/stream_chat_flutter_core/pubspec.yaml @@ -5,6 +5,8 @@ version: 1.5.0 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues +publish_to: none + environment: sdk: ">=2.7.0 <3.0.0" flutter: ">=1.17.0" @@ -12,7 +14,7 @@ environment: dependencies: flutter: sdk: flutter - rxdart: ^0.25.0 + rxdart: ^0.26.0 stream_chat: ^1.5.0 dependency_overrides: @@ -22,4 +24,6 @@ dependency_overrides: dev_dependencies: flutter_test: sdk: flutter - mockito: ^4.1.3 \ No newline at end of file + fake_async: ^1.1.0 + mockito: ^4.1.3 + diff --git a/packages/stream_chat_persistence/example/pubspec.yaml b/packages/stream_chat_persistence/example/pubspec.yaml index faa4fcd4..2586bea6 100644 --- a/packages/stream_chat_persistence/example/pubspec.yaml +++ b/packages/stream_chat_persistence/example/pubspec.yaml @@ -11,7 +11,8 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 - stream_chat: ^1.4.0 + stream_chat: + path: ../../stream_chat stream_chat_persistence: path: ../ diff --git a/packages/stream_chat_persistence/lib/src/dao/channel_dao.dart b/packages/stream_chat_persistence/lib/src/dao/channel_dao.dart index e75cead6..ce2e1db3 100644 --- a/packages/stream_chat_persistence/lib/src/dao/channel_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/channel_dao.dart @@ -19,10 +19,10 @@ class ChannelDao extends DatabaseAccessor (select(channels)..where((c) => c.cid.equals(cid))).join([ leftOuterJoin(users, channels.createdById.equalsExp(users.id)), ]).map((rows) { - final channel = rows.readTable(channels); - final createdBy = rows.readTable(users); + final channel = rows.readTableOrNull(channels); + final createdBy = rows.readTableOrNull(users); return channel.toChannelModel(createdBy: createdBy?.toUser()); - }).getSingle(); + }).getSingleOrNull(); /// Delete all channels by matching cid in [cids] /// diff --git a/packages/stream_chat_persistence/lib/src/dao/connection_event_dao.dart b/packages/stream_chat_persistence/lib/src/dao/connection_event_dao.dart index 50528bd2..e80a814c 100644 --- a/packages/stream_chat_persistence/lib/src/dao/connection_event_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/connection_event_dao.dart @@ -17,16 +17,16 @@ class ConnectionEventDao extends DatabaseAccessor /// Get the latest stored connection event Future get connectionEvent => select(connectionEvents) .map((eventEntity) => eventEntity.toEvent()) - .getSingle(); + .getSingleOrNull(); /// Get the latest stored lastSyncAt Future get lastSyncAt => - select(connectionEvents).getSingle().then((r) => r?.lastSyncAt); + select(connectionEvents).getSingleOrNull().then((r) => r?.lastSyncAt); /// Update stored connection event with latest data Future updateConnectionEvent(Event event) async => transaction(() async { - final connectionInfo = await select(connectionEvents).getSingle(); + final connectionInfo = await select(connectionEvents).getSingleOrNull(); await into(connectionEvents).insert( ConnectionEventEntity( id: 1, diff --git a/packages/stream_chat_persistence/lib/src/dao/message_dao.dart b/packages/stream_chat_persistence/lib/src/dao/message_dao.dart index 8d36b758..3b7f8c2f 100644 --- a/packages/stream_chat_persistence/lib/src/dao/message_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/message_dao.dart @@ -36,9 +36,9 @@ class MessageDao extends DatabaseAccessor (delete(messages)..where((tbl) => tbl.channelCid.isIn(cids))).go(); Future _messageFromJoinRow(TypedResult rows) async { - final userEntity = rows.readTable(_users); - final pinnedByEntity = rows.readTable(_pinnedByUsers); - final msgEntity = rows.readTable(messages); + final userEntity = rows.readTableOrNull(_users); + final pinnedByEntity = rows.readTableOrNull(_pinnedByUsers); + final msgEntity = rows.readTableOrNull(messages); final latestReactions = await _db.reactionDao.getReactions(msgEntity.id); final ownReactions = await _db.reactionDao.getReactionsByUserId( msgEntity.id, @@ -66,7 +66,7 @@ class MessageDao extends DatabaseAccessor ]) ..where(messages.id.equals(id))) .map(_messageFromJoinRow) - .getSingle(); + .getSingleOrNull(); /// Returns all the messages of a particular thread by matching /// [Messages.channelCid] with [cid] @@ -77,7 +77,7 @@ class MessageDao extends DatabaseAccessor messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)), ]) ..where(messages.channelCid.equals(cid)) - ..where(isNotNull(messages.parentId)) + ..where(messages.parentId.isNotNull()) ..orderBy([OrderingTerm.asc(messages.createdAt)])) .map(_messageFromJoinRow) .get()); @@ -93,7 +93,7 @@ class MessageDao extends DatabaseAccessor leftOuterJoin( _pinnedByUsers, messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)), ]) - ..where(isNotNull(messages.parentId)) + ..where(messages.parentId.isNotNull()) ..where(messages.parentId.equals(parentId)) ..orderBy([OrderingTerm.asc(messages.createdAt)])) .map(_messageFromJoinRow) @@ -136,7 +136,8 @@ class MessageDao extends DatabaseAccessor ]) ..where(messages.channelCid.equals(cid)) ..where( - isNull(messages.parentId) | messages.showInChannel.equals(true)) + messages.parentId.isNull() | messages.showInChannel.equals(true), + ) ..orderBy([OrderingTerm.asc(messages.createdAt)])) .map(_messageFromJoinRow) .get()); diff --git a/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart b/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart index 34ee4c28..4d56ba49 100644 --- a/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/pinned_message_dao.dart @@ -36,9 +36,9 @@ class PinnedMessageDao extends DatabaseAccessor (delete(pinnedMessages)..where((tbl) => tbl.channelCid.isIn(cids))).go(); Future _messageFromJoinRow(TypedResult rows) async { - final userEntity = rows.readTable(users); - final pinnedByEntity = rows.readTable(_pinnedByUsers); - final msgEntity = rows.readTable(pinnedMessages); + final userEntity = rows.readTableOrNull(users); + final pinnedByEntity = rows.readTableOrNull(_pinnedByUsers); + final msgEntity = rows.readTableOrNull(pinnedMessages); final latestReactions = await _db.reactionDao.getReactions(msgEntity.id); final ownReactions = await _db.reactionDao.getReactionsByUserId( msgEntity.id, @@ -66,7 +66,7 @@ class PinnedMessageDao extends DatabaseAccessor ]) ..where(pinnedMessages.id.equals(id))) .map(_messageFromJoinRow) - .getSingle(); + .getSingleOrNull(); /// Returns all the messages of a particular thread by matching /// [PinnedMessages.channelCid] with [cid] @@ -77,7 +77,7 @@ class PinnedMessageDao extends DatabaseAccessor pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)), ]) ..where(pinnedMessages.channelCid.equals(cid)) - ..where(isNotNull(pinnedMessages.parentId)) + ..where(pinnedMessages.parentId.isNotNull()) ..orderBy([OrderingTerm.asc(pinnedMessages.createdAt)])) .map(_messageFromJoinRow) .get()); @@ -93,7 +93,7 @@ class PinnedMessageDao extends DatabaseAccessor leftOuterJoin(_pinnedByUsers, pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)), ]) - ..where(isNotNull(pinnedMessages.parentId)) + ..where(pinnedMessages.parentId.isNotNull()) ..where(pinnedMessages.parentId.equals(parentId)) ..orderBy([OrderingTerm.asc(pinnedMessages.createdAt)])) .map(_messageFromJoinRow) @@ -135,7 +135,7 @@ class PinnedMessageDao extends DatabaseAccessor pinnedMessages.pinnedByUserId.equalsExp(_pinnedByUsers.id)), ]) ..where(pinnedMessages.channelCid.equals(cid)) - ..where(isNull(pinnedMessages.parentId) | + ..where(pinnedMessages.parentId.isNull() | pinnedMessages.showInChannel.equals(true)) ..orderBy([OrderingTerm.asc(pinnedMessages.createdAt)])) .map(_messageFromJoinRow) diff --git a/packages/stream_chat_persistence/lib/src/dao/reaction_dao.dart b/packages/stream_chat_persistence/lib/src/dao/reaction_dao.dart index ef06326a..a2a92b2e 100644 --- a/packages/stream_chat_persistence/lib/src/dao/reaction_dao.dart +++ b/packages/stream_chat_persistence/lib/src/dao/reaction_dao.dart @@ -23,8 +23,8 @@ class ReactionDao extends DatabaseAccessor ..where(reactions.messageId.equals(messageId)) ..orderBy([OrderingTerm.asc(reactions.createdAt)])) .map((rows) { - final userEntity = rows.readTable(users); - final reactionEntity = rows.readTable(reactions); + final userEntity = rows.readTableOrNull(users); + final reactionEntity = rows.readTableOrNull(reactions); return reactionEntity.toReaction(user: userEntity?.toUser()); }).get(); diff --git a/packages/stream_chat_persistence/pubspec.yaml b/packages/stream_chat_persistence/pubspec.yaml index f458bfe1..4e81ad51 100644 --- a/packages/stream_chat_persistence/pubspec.yaml +++ b/packages/stream_chat_persistence/pubspec.yaml @@ -5,20 +5,23 @@ version: 1.5.0 repository: https://github.com/GetStream/stream-chat-flutter issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues +publish_to: none + environment: sdk: ">=2.7.0 <3.0.0" dependencies: flutter: sdk: flutter - logging: ^0.11.4 - meta: ^1.2.4 - moor: ^3.4.0 - mutex: ^2.0.0 - path: ^1.7.0 - path_provider: ^1.6.27 + logging: ^1.0.0 + meta: ^1.3.0 + moor: ^4.2.0 + mutex: ^3.0.0 + path: ^1.8.0 + path_provider: ^2.0.0 sqlite3_flutter_libs: ^0.4.0+1 - stream_chat: ^1.5.0 + stream_chat: + path: ../stream_chat dependency_overrides: stream_chat: @@ -26,6 +29,7 @@ dependency_overrides: dev_dependencies: build_runner: ^1.11.0 - mockito: ^4.1.3 - moor_generator: ^3.4.1 - test: ^1.15.7 + mocktail: ^0.1.0 + moor_generator: ^4.2.0 + pedantic: ^1.11.0 + test: ^1.16.0 diff --git a/packages/stream_chat_persistence/test/mock_chat_database.dart b/packages/stream_chat_persistence/test/mock_chat_database.dart index a60bd39b..53a9a178 100644 --- a/packages/stream_chat_persistence/test/mock_chat_database.dart +++ b/packages/stream_chat_persistence/test/mock_chat_database.dart @@ -1,4 +1,4 @@ -import 'package:mockito/mockito.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:stream_chat_persistence/src/dao/dao.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; diff --git a/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart b/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart index 55a5113a..2d44ca15 100644 --- a/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart +++ b/packages/stream_chat_persistence/test/stream_chat_persistence_client_test.dart @@ -1,4 +1,4 @@ -import 'package:mockito/mockito.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_persistence/src/db/moor_chat_database.dart'; import 'package:stream_chat_persistence/src/stream_chat_persistence_client.dart'; @@ -84,121 +84,124 @@ void main() { const parentId = 'testParentId'; final replies = List.generate(3, (index) => Message(id: 'testId$index')); - when(mockDatabase.messageDao.getThreadMessagesByParentId(parentId)) + when(() => mockDatabase.messageDao.getThreadMessagesByParentId(parentId)) .thenAnswer((_) async => replies); final fetchedReplies = await client.getReplies(parentId); expect(fetchedReplies.length, replies.length); - verify(mockDatabase.messageDao.getThreadMessagesByParentId(parentId)) + verify(() => + mockDatabase.messageDao.getThreadMessagesByParentId(parentId)) .called(1); }); test('getConnectionInfo', () async { final event = Event(type: 'testEvent'); - when(mockDatabase.connectionEventDao.connectionEvent) + when(() => mockDatabase.connectionEventDao.connectionEvent) .thenAnswer((_) async => event); final fetchedEvent = await client.getConnectionInfo(); expect(fetchedEvent.type, event.type); - verify(mockDatabase.connectionEventDao.connectionEvent).called(1); + verify(() => mockDatabase.connectionEventDao.connectionEvent).called(1); }); test('getLastSyncAt', () async { final lastSync = DateTime.now(); - when(mockDatabase.connectionEventDao.lastSyncAt) + when(() => mockDatabase.connectionEventDao.lastSyncAt) .thenAnswer((_) async => lastSync); final fetchedLastSync = await client.getLastSyncAt(); expect(fetchedLastSync, isSameDateAs(lastSync)); - verify(mockDatabase.connectionEventDao.lastSyncAt).called(1); + verify(() => mockDatabase.connectionEventDao.lastSyncAt).called(1); }); test('updateConnectionInfo', () async { final event = Event(type: 'testEvent'); - when(mockDatabase.connectionEventDao.updateConnectionEvent(event)) + when(() => mockDatabase.connectionEventDao.updateConnectionEvent(event)) .thenAnswer((_) async { return; }); await client.updateConnectionInfo(event); - verify(mockDatabase.connectionEventDao.updateConnectionEvent(event)) + verify(() => mockDatabase.connectionEventDao.updateConnectionEvent(event)) .called(1); }); test('updateLastSyncAt', () async { final lastSync = DateTime.now(); - when(mockDatabase.connectionEventDao.updateLastSyncAt(lastSync)) + when(() => mockDatabase.connectionEventDao.updateLastSyncAt(lastSync)) .thenAnswer((_) { return; }); await client.updateLastSyncAt(lastSync); - verify(mockDatabase.connectionEventDao.updateLastSyncAt(lastSync)) + verify(() => mockDatabase.connectionEventDao.updateLastSyncAt(lastSync)) .called(1); }); test('getChannelCids', () async { final channelCids = List.generate(3, (index) => 'testCid$index'); - when(mockDatabase.channelDao.cids).thenAnswer((_) async => channelCids); + when(() => mockDatabase.channelDao.cids) + .thenAnswer((_) async => channelCids); final fetchedChannelCids = await client.getChannelCids(); expect(fetchedChannelCids.length, channelCids.length); - verify(mockDatabase.channelDao.cids).called(1); + verify(() => mockDatabase.channelDao.cids).called(1); }); test('getChannelByCid', () async { const cid = 'testCid'; final channelModel = ChannelModel(cid: cid); - when(mockDatabase.channelDao.getChannelByCid(cid)) + when(() => mockDatabase.channelDao.getChannelByCid(cid)) .thenAnswer((_) async => channelModel); final fetchedChannelModel = await client.getChannelByCid(cid); expect(fetchedChannelModel.cid, channelModel.cid); - verify(mockDatabase.channelDao.getChannelByCid(cid)).called(1); + verify(() => mockDatabase.channelDao.getChannelByCid(cid)).called(1); }); test('getMembersByCid', () async { const cid = 'testCid'; final members = List.generate(3, (index) => Member()); - when(mockDatabase.memberDao.getMembersByCid(cid)) + when(() => mockDatabase.memberDao.getMembersByCid(cid)) .thenAnswer((_) async => members); final fetchedMembers = await client.getMembersByCid(cid); expect(fetchedMembers.length, members.length); - verify(mockDatabase.memberDao.getMembersByCid(cid)).called(1); + verify(() => mockDatabase.memberDao.getMembersByCid(cid)).called(1); }); test('getReadsByCid', () async { const cid = 'testCid'; final reads = List.generate(3, (index) => Read()); - when(mockDatabase.readDao.getReadsByCid(cid)) + when(() => mockDatabase.readDao.getReadsByCid(cid)) .thenAnswer((_) async => reads); final fetchedReads = await client.getReadsByCid(cid); expect(fetchedReads.length, reads.length); - verify(mockDatabase.readDao.getReadsByCid(cid)).called(1); + verify(() => mockDatabase.readDao.getReadsByCid(cid)).called(1); }); test('getMessagesByCid', () async { const cid = 'testCid'; final messages = List.generate(3, (index) => Message()); - when(mockDatabase.messageDao.getMessagesByCid(cid)) + when(() => mockDatabase.messageDao.getMessagesByCid(cid)) .thenAnswer((_) async => messages); final fetchedMessages = await client.getMessagesByCid(cid); expect(fetchedMessages.length, messages.length); - verify(mockDatabase.messageDao.getMessagesByCid(cid)).called(1); + verify(() => mockDatabase.messageDao.getMessagesByCid(cid)).called(1); }); test('getPinnedMessagesByCid', () async { const cid = 'testCid'; final messages = List.generate(3, (index) => Message()); - when(mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) + when(() => mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) .thenAnswer((_) async => messages); final fetchedMessages = await client.getPinnedMessagesByCid(cid); expect(fetchedMessages.length, messages.length); - verify(mockDatabase.pinnedMessageDao.getMessagesByCid(cid)).called(1); + verify(() => mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) + .called(1); }); test('getChannelStateByCid', () async { @@ -208,15 +211,15 @@ void main() { final reads = List.generate(3, (index) => Read()); final channel = ChannelModel(cid: cid); - when(mockDatabase.memberDao.getMembersByCid(cid)) + when(() => mockDatabase.memberDao.getMembersByCid(cid)) .thenAnswer((_) async => members); - when(mockDatabase.readDao.getReadsByCid(cid)) + when(() => mockDatabase.readDao.getReadsByCid(cid)) .thenAnswer((_) async => reads); - when(mockDatabase.channelDao.getChannelByCid(cid)) + when(() => mockDatabase.channelDao.getChannelByCid(cid)) .thenAnswer((_) async => channel); - when(mockDatabase.messageDao.getMessagesByCid(cid)) + when(() => mockDatabase.messageDao.getMessagesByCid(cid)) .thenAnswer((_) async => messages); - when(mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) + when(() => mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) .thenAnswer((_) async => messages); final fetchedChannelState = await client.getChannelStateByCid(cid); @@ -226,11 +229,12 @@ void main() { expect(fetchedChannelState.read.length, reads.length); expect(fetchedChannelState.channel.cid, channel.cid); - verify(mockDatabase.memberDao.getMembersByCid(cid)).called(1); - verify(mockDatabase.readDao.getReadsByCid(cid)).called(1); - verify(mockDatabase.channelDao.getChannelByCid(cid)).called(1); - verify(mockDatabase.messageDao.getMessagesByCid(cid)).called(1); - verify(mockDatabase.pinnedMessageDao.getMessagesByCid(cid)).called(1); + verify(() => mockDatabase.memberDao.getMembersByCid(cid)).called(1); + verify(() => mockDatabase.readDao.getReadsByCid(cid)).called(1); + verify(() => mockDatabase.channelDao.getChannelByCid(cid)).called(1); + verify(() => mockDatabase.messageDao.getMessagesByCid(cid)).called(1); + verify(() => mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) + .called(1); }); test('getChannelStates', () async { @@ -252,17 +256,17 @@ void main() { ) .toList(growable: false); - when(mockDatabase.channelQueryDao.getChannels()) + when(() => mockDatabase.channelQueryDao.getChannels()) .thenAnswer((_) async => channels); - when(mockDatabase.memberDao.getMembersByCid(cid)) + when(() => mockDatabase.memberDao.getMembersByCid(cid)) .thenAnswer((_) async => members); - when(mockDatabase.readDao.getReadsByCid(cid)) + when(() => mockDatabase.readDao.getReadsByCid(cid)) .thenAnswer((_) async => reads); - when(mockDatabase.channelDao.getChannelByCid(cid)) + when(() => mockDatabase.channelDao.getChannelByCid(cid)) .thenAnswer((_) async => channel); - when(mockDatabase.messageDao.getMessagesByCid(cid)) + when(() => mockDatabase.messageDao.getMessagesByCid(cid)) .thenAnswer((_) async => messages); - when(mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) + when(() => mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) .thenAnswer((_) async => messages); final fetchedChannelStates = await client.getChannelStates(); @@ -278,151 +282,160 @@ void main() { expect(fetched.channel.cid, original.channel.cid); } - verify(mockDatabase.channelQueryDao.getChannels()).called(1); - verify(mockDatabase.memberDao.getMembersByCid(cid)).called(3); - verify(mockDatabase.readDao.getReadsByCid(cid)).called(3); - verify(mockDatabase.channelDao.getChannelByCid(cid)).called(3); - verify(mockDatabase.messageDao.getMessagesByCid(cid)).called(3); - verify(mockDatabase.pinnedMessageDao.getMessagesByCid(cid)).called(3); + verify(() => mockDatabase.channelQueryDao.getChannels()).called(1); + verify(() => mockDatabase.memberDao.getMembersByCid(cid)).called(3); + verify(() => mockDatabase.readDao.getReadsByCid(cid)).called(3); + verify(() => mockDatabase.channelDao.getChannelByCid(cid)).called(3); + verify(() => mockDatabase.messageDao.getMessagesByCid(cid)).called(3); + verify(() => mockDatabase.pinnedMessageDao.getMessagesByCid(cid)) + .called(3); }); test('updateChannelQueries', () async { const filter = {}; const cids = []; - when(mockDatabase.channelQueryDao.updateChannelQueries(filter, cids)) + when(() => + mockDatabase.channelQueryDao.updateChannelQueries(filter, cids)) .thenAnswer((realInvocation) async { return; }); await client.updateChannelQueries(filter, cids); - verify(mockDatabase.channelQueryDao.updateChannelQueries(filter, cids)) + verify(() => + mockDatabase.channelQueryDao.updateChannelQueries(filter, cids)) .called(1); }); test('deleteMessageById', () async { const messageId = 'testMessageId'; - when(mockDatabase.messageDao.deleteMessageByIds([messageId])) + when(() => mockDatabase.messageDao.deleteMessageByIds([messageId])) .thenAnswer((_) async { return; }); await client.deleteMessageById(messageId); - verify(mockDatabase.messageDao.deleteMessageByIds([messageId])).called(1); + verify(() => mockDatabase.messageDao.deleteMessageByIds([messageId])) + .called(1); }); test('deletePinnedMessageById', () async { const messageId = 'testMessageId'; - when(mockDatabase.pinnedMessageDao.deleteMessageByIds([messageId])) + when(() => mockDatabase.pinnedMessageDao.deleteMessageByIds([messageId])) .thenAnswer((_) async { return; }); await client.deletePinnedMessageById(messageId); - verify(mockDatabase.pinnedMessageDao.deleteMessageByIds([messageId])) + verify(() => + mockDatabase.pinnedMessageDao.deleteMessageByIds([messageId])) .called(1); }); test('deleteMessageByIds', () async { const messageIds = []; - when(mockDatabase.messageDao.deleteMessageByIds(messageIds)) + when(() => mockDatabase.messageDao.deleteMessageByIds(messageIds)) .thenAnswer((_) async { return; }); await client.deleteMessageByIds(messageIds); - verify(mockDatabase.messageDao.deleteMessageByIds(messageIds)).called(1); + verify(() => mockDatabase.messageDao.deleteMessageByIds(messageIds)) + .called(1); }); test('deletePinnedMessageByIds', () async { const messageIds = []; - when(mockDatabase.pinnedMessageDao.deleteMessageByIds(messageIds)) + when(() => mockDatabase.pinnedMessageDao.deleteMessageByIds(messageIds)) .thenAnswer((_) async { return; }); await client.deletePinnedMessageByIds(messageIds); - verify(mockDatabase.pinnedMessageDao.deleteMessageByIds(messageIds)) + verify(() => mockDatabase.pinnedMessageDao.deleteMessageByIds(messageIds)) .called(1); }); test('deleteMessageByCid', () async { const cid = 'testCid'; - when(mockDatabase.messageDao.deleteMessageByCids([cid])) + when(() => mockDatabase.messageDao.deleteMessageByCids([cid])) .thenAnswer((_) async { return; }); await client.deleteMessageByCid(cid); - verify(mockDatabase.messageDao.deleteMessageByCids([cid])).called(1); + verify(() => mockDatabase.messageDao.deleteMessageByCids([cid])) + .called(1); }); test('deletePinnedMessageByCid', () async { const cid = 'testCid'; - when(mockDatabase.pinnedMessageDao.deleteMessageByCids([cid])) + when(() => mockDatabase.pinnedMessageDao.deleteMessageByCids([cid])) .thenAnswer((_) async { return; }); await client.deletePinnedMessageByCid(cid); - verify(mockDatabase.pinnedMessageDao.deleteMessageByCids([cid])) + verify(() => mockDatabase.pinnedMessageDao.deleteMessageByCids([cid])) .called(1); }); test('deleteMessageByCids', () async { const cids = []; - when(mockDatabase.messageDao.deleteMessageByCids(cids)) + when(() => mockDatabase.messageDao.deleteMessageByCids(cids)) .thenAnswer((_) async { return; }); await client.deleteMessageByCids(cids); - verify(mockDatabase.messageDao.deleteMessageByCids(cids)).called(1); + verify(() => mockDatabase.messageDao.deleteMessageByCids(cids)).called(1); }); test('deletePinnedMessageByCids', () async { const cids = []; - when(mockDatabase.pinnedMessageDao.deleteMessageByCids(cids)) + when(() => mockDatabase.pinnedMessageDao.deleteMessageByCids(cids)) .thenAnswer((_) async { return; }); await client.deletePinnedMessageByCids(cids); - verify(mockDatabase.pinnedMessageDao.deleteMessageByCids(cids)).called(1); + verify(() => mockDatabase.pinnedMessageDao.deleteMessageByCids(cids)) + .called(1); }); test('deleteChannels', () async { const cids = []; - when(mockDatabase.channelDao.deleteChannelByCids(cids)) + when(() => mockDatabase.channelDao.deleteChannelByCids(cids)) .thenAnswer((_) async { return; }); await client.deleteChannels(cids); - verify(mockDatabase.channelDao.deleteChannelByCids(cids)).called(1); + verify(() => mockDatabase.channelDao.deleteChannelByCids(cids)).called(1); }); test('updateMessages', () async { const cid = 'testCid'; final messages = List.generate(3, (index) => Message()); - when(mockDatabase.messageDao.updateMessages(cid, messages)) + when(() => mockDatabase.messageDao.updateMessages(cid, messages)) .thenAnswer((_) async { return; }); await client.updateMessages(cid, messages); - verify(mockDatabase.messageDao.updateMessages(cid, messages)).called(1); + verify(() => mockDatabase.messageDao.updateMessages(cid, messages)) + .called(1); }); test('updatePinnedMessages', () async { const cid = 'testCid'; final messages = List.generate(3, (index) => Message()); - when(mockDatabase.pinnedMessageDao.updateMessages(cid, messages)) + when(() => mockDatabase.pinnedMessageDao.updateMessages(cid, messages)) .thenAnswer((_) async { return; }); await client.updatePinnedMessages(cid, messages); - verify(mockDatabase.pinnedMessageDao.updateMessages(cid, messages)) + verify(() => mockDatabase.pinnedMessageDao.updateMessages(cid, messages)) .called(1); }); @@ -441,7 +454,7 @@ void main() { ); }, ); - when(mockDatabase.messageDao.getThreadMessages(cid)) + when(() => mockDatabase.messageDao.getThreadMessages(cid)) .thenAnswer((realInvocation) async => messages); final fetchedThreads = await client.getChannelThreads(cid); @@ -452,85 +465,90 @@ void main() { expect(fetched.key, original.key); } - verify(mockDatabase.messageDao.getThreadMessages(cid)).called(1); + verify(() => mockDatabase.messageDao.getThreadMessages(cid)).called(1); }); test('updateChannels', () async { final channels = List.generate(3, (index) => ChannelModel()); - when(mockDatabase.channelDao.updateChannels(channels)) + when(() => mockDatabase.channelDao.updateChannels(channels)) .thenAnswer((_) async { return; }); await client.updateChannels(channels); - verify(mockDatabase.channelDao.updateChannels(channels)).called(1); + verify(() => mockDatabase.channelDao.updateChannels(channels)).called(1); }); test('updateMembers', () async { const cid = 'testCid'; final members = List.generate(3, (index) => Member()); - when(mockDatabase.memberDao.updateMembers(cid, members)) + when(() => mockDatabase.memberDao.updateMembers(cid, members)) .thenAnswer((_) async { return; }); await client.updateMembers(cid, members); - verify(mockDatabase.memberDao.updateMembers(cid, members)).called(1); + verify(() => mockDatabase.memberDao.updateMembers(cid, members)) + .called(1); }); test('updateReads', () async { const cid = 'testCid'; final reads = List.generate(3, (index) => Read()); - when(mockDatabase.readDao.updateReads(cid, reads)).thenAnswer((_) async { + when(() => mockDatabase.readDao.updateReads(cid, reads)) + .thenAnswer((_) async { return; }); await client.updateReads(cid, reads); - verify(mockDatabase.readDao.updateReads(cid, reads)).called(1); + verify(() => mockDatabase.readDao.updateReads(cid, reads)).called(1); }); test('updateUsers', () async { final users = List.generate(3, (index) => User()); - when(mockDatabase.userDao.updateUsers(users)).thenAnswer((_) async { + when(() => mockDatabase.userDao.updateUsers(users)).thenAnswer((_) async { return; }); await client.updateUsers(users); - verify(mockDatabase.userDao.updateUsers(users)).called(1); + verify(() => mockDatabase.userDao.updateUsers(users)).called(1); }); test('updateReactions', () async { final reactions = List.generate(3, (index) => Reaction()); - when(mockDatabase.reactionDao.updateReactions(reactions)) + when(() => mockDatabase.reactionDao.updateReactions(reactions)) .thenAnswer((_) async { return; }); await client.updateReactions(reactions); - verify(mockDatabase.reactionDao.updateReactions(reactions)).called(1); + verify(() => mockDatabase.reactionDao.updateReactions(reactions)) + .called(1); }); test('deleteReactionsByMessageId', () async { final messageIds = []; - when(mockDatabase.reactionDao.deleteReactionsByMessageIds(messageIds)) + when(() => + mockDatabase.reactionDao.deleteReactionsByMessageIds(messageIds)) .thenAnswer((_) async { return; }); await client.deleteReactionsByMessageId(messageIds); - verify(mockDatabase.reactionDao.deleteReactionsByMessageIds(messageIds)) + verify(() => + mockDatabase.reactionDao.deleteReactionsByMessageIds(messageIds)) .called(1); }); test('deleteMembersByCids', () async { final cids = []; - when(mockDatabase.memberDao.deleteMemberByCids(cids)) + when(() => mockDatabase.memberDao.deleteMemberByCids(cids)) .thenAnswer((_) async { return; }); await client.deleteMembersByCids(cids); - verify(mockDatabase.memberDao.deleteMemberByCids(cids)).called(1); + verify(() => mockDatabase.memberDao.deleteMemberByCids(cids)).called(1); }); tearDown(() async {