@@ -38,10 +38,6 @@ import 'package:stream_chat/src/core/models/member.dart';
|
||||
/// [LogRecord] as the only parameter.
|
||||
typedef LogHandlerFunction = void Function(LogRecord record);
|
||||
|
||||
/// A function which can be used to request a Stream Chat API token from your
|
||||
/// own backend server. Function requires a single [userId].
|
||||
typedef TokenProvider = Future<String> Function(String userId);
|
||||
|
||||
final _levelEmojiMapper = {
|
||||
Level.INFO: 'ℹ️',
|
||||
Level.WARNING: '⚠️',
|
||||
@@ -583,7 +579,6 @@ class StreamChatClient {
|
||||
}
|
||||
|
||||
logger.info('Query channel start');
|
||||
print('Query Channel Started : ${DateTime.now()}');
|
||||
final res = await _chatApi.channel.queryChannels(
|
||||
filter: filter,
|
||||
sort: sort,
|
||||
@@ -594,7 +589,6 @@ class StreamChatClient {
|
||||
messageLimit: messageLimit,
|
||||
paginationParams: paginationParams,
|
||||
);
|
||||
print('Query Channel Completed : ${DateTime.now()}');
|
||||
|
||||
if (res.channels.isEmpty && paginationParams.offset == 0) {
|
||||
logger.warning('''
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:stream_chat/src/core/api/responses.dart';
|
||||
import 'package:stream_chat/src/core/http/stream_http_client.dart';
|
||||
import 'package:stream_chat/src/core/util/extension.dart';
|
||||
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
||||
|
||||
/// Class responsible for uploading images and files to a given channel
|
||||
@@ -70,29 +69,10 @@ class StreamAttachmentFileUploader implements AttachmentFileUploader {
|
||||
ProgressCallback? onSendProgress,
|
||||
CancelToken? cancelToken,
|
||||
}) async {
|
||||
final filename = file.path?.split('/').last ?? file.name;
|
||||
final mimeType = filename?.mimeType;
|
||||
|
||||
MultipartFile? multiPartFile;
|
||||
if (file.path != null) {
|
||||
multiPartFile = await MultipartFile.fromFile(
|
||||
file.path!,
|
||||
filename: filename,
|
||||
contentType: mimeType,
|
||||
);
|
||||
} else if (file.bytes != null) {
|
||||
multiPartFile = MultipartFile.fromBytes(
|
||||
file.bytes!,
|
||||
filename: filename,
|
||||
contentType: mimeType,
|
||||
);
|
||||
}
|
||||
|
||||
final response = await _client.post(
|
||||
final multiPartFile = await file.toMultipartFile();
|
||||
final response = await _client.postFile(
|
||||
'/channels/$channelType/$channelId/image',
|
||||
data: FormData.fromMap({
|
||||
'file': multiPartFile,
|
||||
}),
|
||||
multiPartFile,
|
||||
onSendProgress: onSendProgress,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
@@ -107,29 +87,10 @@ class StreamAttachmentFileUploader implements AttachmentFileUploader {
|
||||
ProgressCallback? onSendProgress,
|
||||
CancelToken? cancelToken,
|
||||
}) async {
|
||||
final filename = file.path?.split('/').last ?? file.name;
|
||||
final mimeType = filename?.mimeType;
|
||||
|
||||
MultipartFile? multiPartFile;
|
||||
if (file.path != null) {
|
||||
multiPartFile = await MultipartFile.fromFile(
|
||||
file.path!,
|
||||
filename: filename,
|
||||
contentType: mimeType,
|
||||
);
|
||||
} else if (file.bytes != null) {
|
||||
multiPartFile = MultipartFile.fromBytes(
|
||||
file.bytes!,
|
||||
filename: filename,
|
||||
contentType: mimeType,
|
||||
);
|
||||
}
|
||||
|
||||
final response = await _client.post(
|
||||
final multiPartFile = await file.toMultipartFile();
|
||||
final response = await _client.postFile(
|
||||
'/channels/$channelType/$channelId/file',
|
||||
data: FormData.fromMap({
|
||||
'file': multiPartFile,
|
||||
}),
|
||||
multiPartFile,
|
||||
onSendProgress: onSendProgress,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
|
||||
@@ -59,7 +59,6 @@ class ChannelApi {
|
||||
bool presence = false,
|
||||
PaginationParams paginationParams = const PaginationParams(),
|
||||
}) async {
|
||||
print('Query Channel Started 2 : ${DateTime.now()}');
|
||||
final response = await _client.get(
|
||||
'/channels',
|
||||
queryParameters: {
|
||||
@@ -80,7 +79,6 @@ class ChannelApi {
|
||||
})
|
||||
},
|
||||
);
|
||||
print('Query Channel Completed 2 : ${DateTime.now()}');
|
||||
return QueryChannelsResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ enum PushProvider {
|
||||
apn
|
||||
}
|
||||
|
||||
extension on PushProvider {
|
||||
/// Helper extension for [PushProvider]
|
||||
extension PushProviderX on PushProvider {
|
||||
/// Returns the string notion for [PushProvider].
|
||||
String get name => {
|
||||
PushProvider.apn: 'apn',
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dio/dio.dart' show MultipartFile;
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:stream_chat/src/core/platform_detector/platform_detector.dart';
|
||||
import 'package:stream_chat/src/core/util/extension.dart';
|
||||
|
||||
part 'attachment_file.freezed.dart';
|
||||
|
||||
part 'attachment_file.g.dart';
|
||||
|
||||
/// Union class to hold various [UploadState] of a attachment.
|
||||
@@ -58,14 +62,18 @@ String? _toString(Uint8List? bytes) {
|
||||
@JsonSerializable()
|
||||
class AttachmentFile {
|
||||
/// Creates a new [AttachmentFile] instance.
|
||||
const AttachmentFile({
|
||||
AttachmentFile({
|
||||
required this.size,
|
||||
this.path,
|
||||
this.name,
|
||||
this.bytes,
|
||||
}) : assert(
|
||||
}) : assert(
|
||||
path != null || bytes != null,
|
||||
'Either path or bytes should be != null',
|
||||
),
|
||||
assert(
|
||||
!CurrentPlatform.isWeb || bytes != null,
|
||||
'File by path is not supported in web, Please provide bytes',
|
||||
);
|
||||
|
||||
/// Create a new instance from a json
|
||||
@@ -95,4 +103,27 @@ class AttachmentFile {
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$AttachmentFileToJson(this);
|
||||
|
||||
/// Converts this into a [MultipartFile]
|
||||
Future<MultipartFile> toMultipartFile() async {
|
||||
final filename = path?.split('/').last ?? name;
|
||||
final mimeType = filename?.mimeType;
|
||||
|
||||
late MultipartFile multiPartFile;
|
||||
|
||||
if (CurrentPlatform.isWeb) {
|
||||
multiPartFile = MultipartFile.fromBytes(
|
||||
bytes!,
|
||||
filename: filename,
|
||||
contentType: mimeType,
|
||||
);
|
||||
} else {
|
||||
multiPartFile = await MultipartFile.fromFile(
|
||||
path!,
|
||||
filename: filename,
|
||||
contentType: mimeType,
|
||||
);
|
||||
}
|
||||
return multiPartFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
%PDF-1.7
|
||||
%µí®û
|
||||
3 0 obj
|
||||
<< /Length 4 0 R >>
|
||||
stream
|
||||
/DeviceRGB cs /DeviceRGB CS
|
||||
0 0 0.972549 SC
|
||||
21.68 194 136.64 26 re
|
||||
10 10 m 20 20 l S
|
||||
BT
|
||||
/F0 24 Tf
|
||||
25.68 200 Td
|
||||
(Hello World!) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
4 0 obj
|
||||
132
|
||||
endobj
|
||||
5 0 obj
|
||||
<< /Type /Font /Subtype /Type1 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >>
|
||||
endobj
|
||||
6 0 obj
|
||||
<< /Type /Page
|
||||
/Parent 2 0 R
|
||||
/Resources << /Font << /F0 5 0 R >> >>
|
||||
/MediaBox [ 0 0 180 240 ]
|
||||
/Contents 3 0 R
|
||||
>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<< /Type /Pages
|
||||
/Count 1
|
||||
/Kids [ 6 0 R ]
|
||||
>>
|
||||
endobj
|
||||
1 0 obj
|
||||
<< /Type /Catalog
|
||||
/Pages 2 0 R
|
||||
>>
|
||||
endobj
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000522 00000 n
|
||||
0000000457 00000 n
|
||||
0000000015 00000 n
|
||||
0000000199 00000 n
|
||||
0000000218 00000 n
|
||||
0000000317 00000 n
|
||||
trailer
|
||||
<< /Size 7
|
||||
/Root 1 0 R
|
||||
>>
|
||||
startxref
|
||||
574
|
||||
%%EOF
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1,136 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/attachment_file_uploader.dart';
|
||||
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../fakes.dart';
|
||||
import '../../matchers.dart';
|
||||
import '../../mocks.dart';
|
||||
import '../../utils.dart';
|
||||
|
||||
void main() {
|
||||
late final client = MockHttpClient();
|
||||
late StreamAttachmentFileUploader fileUploader;
|
||||
|
||||
setUp(() {
|
||||
fileUploader = StreamAttachmentFileUploader(client);
|
||||
registerFallbackValue<MultipartFile>(FakeMultiPartFile());
|
||||
});
|
||||
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
test('sendImage', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
const path = '/channels/$channelType/$channelId/image';
|
||||
final file = assetFile('test_image.jpeg');
|
||||
final attachmentFile = AttachmentFile(
|
||||
size: 333,
|
||||
path: file.path,
|
||||
bytes: file.readAsBytesSync(),
|
||||
);
|
||||
final multipartFile = await attachmentFile.toMultipartFile();
|
||||
|
||||
when(() => client.postFile(
|
||||
path,
|
||||
any(that: isSameMultipartFileAs(multipartFile)),
|
||||
)).thenAnswer((_) async => successResponse(path, data: {
|
||||
'file': 'test-file-url',
|
||||
}));
|
||||
|
||||
final res = await fileUploader.sendImage(
|
||||
attachmentFile,
|
||||
channelId,
|
||||
channelType,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.file, isNotNull);
|
||||
expect(res.file, isNotEmpty);
|
||||
|
||||
verify(() => client.postFile(
|
||||
path,
|
||||
any(that: isSameMultipartFileAs(multipartFile)),
|
||||
)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('sendFile', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
const path = '/channels/$channelType/$channelId/file';
|
||||
final file = assetFile('example.pdf');
|
||||
final attachmentFile = AttachmentFile(
|
||||
size: 333,
|
||||
path: file.path,
|
||||
bytes: file.readAsBytesSync(),
|
||||
);
|
||||
final multipartFile = await attachmentFile.toMultipartFile();
|
||||
|
||||
when(() => client.postFile(
|
||||
path,
|
||||
any(that: isSameMultipartFileAs(multipartFile)),
|
||||
)).thenAnswer((_) async => successResponse(path, data: {
|
||||
'file': 'test-file-url',
|
||||
}));
|
||||
|
||||
final res = await fileUploader.sendFile(
|
||||
attachmentFile,
|
||||
channelId,
|
||||
channelType,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.file, isNotNull);
|
||||
expect(res.file, isNotEmpty);
|
||||
|
||||
verify(() => client.postFile(
|
||||
path,
|
||||
any(that: isSameMultipartFileAs(multipartFile)),
|
||||
)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('deleteImage', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const path = '/channels/$channelType/$channelId/image';
|
||||
|
||||
const url = 'test-image-url';
|
||||
|
||||
when(() => client.delete(path, queryParameters: {'url': url})).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await fileUploader.deleteImage(url, channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.delete(path, queryParameters: {'url': url})).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('deleteFile', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const path = '/channels/$channelType/$channelId/file';
|
||||
|
||||
const url = 'test-file-url';
|
||||
|
||||
when(() => client.delete(path, queryParameters: {'url': url})).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await fileUploader.deleteFile(url, channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.delete(path, queryParameters: {'url': url})).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/channel_api.dart';
|
||||
import 'package:stream_chat/src/core/models/channel_model.dart';
|
||||
import 'package:stream_chat/src/core/models/channel_state.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
String _getChannelUrl(String channelId, String channelType) =>
|
||||
'/channels/$channelType/$channelId';
|
||||
|
||||
ChannelState _generateChannelState(
|
||||
String channelId,
|
||||
String channelType,
|
||||
) {
|
||||
final channel = ChannelModel(id: channelId, type: channelType);
|
||||
final messages = List.generate(
|
||||
3,
|
||||
(index) => Message(
|
||||
id: 'test-message-id-$index',
|
||||
text: 'test-message-text-$index',
|
||||
),
|
||||
);
|
||||
final members = List.generate(
|
||||
3,
|
||||
(index) => Member(userId: 'test-user-id-$index'),
|
||||
);
|
||||
final reads = List.generate(
|
||||
3,
|
||||
(index) => Read(
|
||||
lastRead: DateTime.now(),
|
||||
user: User(id: 'test-user-id-$index'),
|
||||
),
|
||||
);
|
||||
final watchers = List.generate(
|
||||
3,
|
||||
(index) => User(id: 'test-user-id-$index'),
|
||||
);
|
||||
final state = ChannelState(
|
||||
channel: channel,
|
||||
messages: messages,
|
||||
pinnedMessages: messages,
|
||||
members: members,
|
||||
read: reads,
|
||||
watchers: watchers,
|
||||
watcherCount: watchers.length,
|
||||
);
|
||||
return state;
|
||||
}
|
||||
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late ChannelApi channelApi;
|
||||
|
||||
setUp(() {
|
||||
channelApi = ChannelApi(client);
|
||||
});
|
||||
|
||||
test('queryChannel', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const channelData = <String, Object>{'name': 'test-channel'};
|
||||
const messagePagination = PaginationParams();
|
||||
const membersPagination = PaginationParams();
|
||||
const watchersPagination = PaginationParams();
|
||||
|
||||
const channelPath = '/channels/$channelType/$channelId';
|
||||
const path = '$channelPath/query';
|
||||
|
||||
final channelState = _generateChannelState(channelId, channelType);
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(
|
||||
path,
|
||||
data: channelState.toJson(),
|
||||
));
|
||||
|
||||
final res = await channelApi.queryChannel(
|
||||
channelType,
|
||||
channelId: channelId,
|
||||
channelData: channelData,
|
||||
messagesPagination: messagePagination,
|
||||
membersPagination: membersPagination,
|
||||
watchersPagination: watchersPagination,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.messages.length, channelState.messages.length);
|
||||
expect(res.pinnedMessages.length, channelState.pinnedMessages.length);
|
||||
expect(res.members.length, channelState.members.length);
|
||||
expect(res.read.length, channelState.read.length);
|
||||
expect(res.watchers.length, channelState.watchers.length);
|
||||
expect(res.watcherCount, channelState.watcherCount);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('queryChannels', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
final filter = Filter.in_('cid', const ['test-cid']);
|
||||
const sort = [SortOption<ChannelModel>('test-field')];
|
||||
const memberLimit = 33;
|
||||
const messageLimit = 33;
|
||||
|
||||
const path = '/channels';
|
||||
|
||||
final channelState = _generateChannelState(channelId, channelType);
|
||||
when(() => client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(
|
||||
path,
|
||||
data: {
|
||||
'channels': [channelState.toJson()]
|
||||
},
|
||||
));
|
||||
|
||||
final res = await channelApi.queryChannels(
|
||||
filter: filter,
|
||||
sort: sort,
|
||||
memberLimit: memberLimit,
|
||||
messageLimit: messageLimit,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channels, isNotEmpty);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('markAllRead', () async {
|
||||
const path = 'channels/read';
|
||||
when(() => client.post(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.markAllRead();
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('updateChannel', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const data = {'name': 'test-channel-name'};
|
||||
final message = Message(id: 'test-message-id', text: 'channel-updated');
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
final channelModel = ChannelModel(
|
||||
id: channelId,
|
||||
type: channelType,
|
||||
extraData: data,
|
||||
);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.updateChannel(
|
||||
channelId,
|
||||
channelType,
|
||||
data,
|
||||
message: message,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channel.cid, channelModel.cid);
|
||||
expect(res.message?.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('updateChannelPartial', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const data = {'name': 'test-channel-name'};
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
final channelModel = ChannelModel(
|
||||
id: channelId,
|
||||
type: channelType,
|
||||
extraData: data,
|
||||
);
|
||||
|
||||
when(() => client.patch(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.updateChannelPartial(
|
||||
channelId,
|
||||
channelType,
|
||||
data,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.patch(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('acceptChannelInvite', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
final message = Message(id: 'test-message-id', text: 'channel-accepted');
|
||||
|
||||
final channelModel = ChannelModel(id: channelId, type: channelType);
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.acceptChannelInvite(
|
||||
channelId,
|
||||
channelType,
|
||||
message: message,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channel.cid, channelModel.cid);
|
||||
expect(res.message?.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('rejectChannelInvite', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
final message = Message(id: 'test-message-id', text: 'channel-rejected');
|
||||
|
||||
final channelModel = ChannelModel(id: channelId, type: channelType);
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.rejectChannelInvite(
|
||||
channelId,
|
||||
channelType,
|
||||
message: message,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channel.cid, channelModel.cid);
|
||||
expect(res.message?.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('inviteChannelMembers', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const memberIds = ['test-member-id-1', 'test-member-id-2'];
|
||||
final channelModel = ChannelModel(id: channelId, type: channelType);
|
||||
final message = Message(id: 'test-message-id', text: 'members-invited');
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.inviteChannelMembers(
|
||||
channelId,
|
||||
channelType,
|
||||
memberIds,
|
||||
message: message,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channel.cid, channelModel.cid);
|
||||
expect(res.message?.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('addMembers', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const memberIds = ['test-member-id-1', 'test-member-id-2'];
|
||||
final channelModel = ChannelModel(id: channelId, type: channelType);
|
||||
final message = Message(id: 'test-message-id', text: 'members-added');
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.addMembers(
|
||||
channelId,
|
||||
channelType,
|
||||
memberIds,
|
||||
message: message,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channel.cid, channelModel.cid);
|
||||
expect(res.message?.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('removeMembers', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const memberIds = ['test-member-id-1', 'test-member-id-2'];
|
||||
final channelModel = ChannelModel(id: channelId, type: channelType);
|
||||
final message = Message(id: 'test-message-id', text: 'members-removed');
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'channel': channelModel.toJson(),
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await channelApi.removeMembers(
|
||||
channelId,
|
||||
channelType,
|
||||
memberIds,
|
||||
message: message,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.channel.cid, channelModel.cid);
|
||||
expect(res.message?.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('sendEvent', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
final event = Event(type: 'event.test');
|
||||
|
||||
final path = '${_getChannelUrl(channelId, channelType)}/event';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.sendEvent(channelId, channelType, event);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('deleteChannel', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
final path = _getChannelUrl(channelId, channelType);
|
||||
|
||||
when(() => client.delete(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.deleteChannel(channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.delete(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('truncateChannel', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
final path = '${_getChannelUrl(channelId, channelType)}/truncate';
|
||||
|
||||
when(() => client.post(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.truncateChannel(channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('hideChannel', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
final path = '${_getChannelUrl(channelId, channelType)}/hide';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.hideChannel(channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('showChannel', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
final path = '${_getChannelUrl(channelId, channelType)}/show';
|
||||
|
||||
when(() => client.post(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.showChannel(channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('markRead', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const messageId = 'test-message-id';
|
||||
|
||||
final path = '${_getChannelUrl(channelId, channelType)}/read';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.markRead(
|
||||
channelId,
|
||||
channelType,
|
||||
messageId: messageId,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('stopWatching', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
|
||||
final path = '${_getChannelUrl(channelId, channelType)}/stop-watching';
|
||||
|
||||
when(() => client.post(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await channelApi.stopWatching(channelId, channelType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/device_api.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late DeviceApi deviceApi;
|
||||
|
||||
setUp(() {
|
||||
deviceApi = DeviceApi(client);
|
||||
});
|
||||
|
||||
test('addDevice', () async {
|
||||
const deviceId = 'test-device-id';
|
||||
const pushProvider = PushProvider.firebase;
|
||||
|
||||
const path = '/devices';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await deviceApi.addDevice(deviceId, pushProvider);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('getDevices', () async {
|
||||
const path = '/devices';
|
||||
|
||||
final devices = List.generate(
|
||||
3,
|
||||
(index) => Device(
|
||||
id: 'test-device-id-$index',
|
||||
pushProvider: PushProvider.firebase.name,
|
||||
),
|
||||
);
|
||||
|
||||
when(() => client.get(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: {
|
||||
'devices': [...devices.map((it) => it.toJson())]
|
||||
}),
|
||||
);
|
||||
|
||||
final res = await deviceApi.getDevices();
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.devices.length, devices.length);
|
||||
|
||||
verify(() => client.get(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('removeDevice', () async {
|
||||
const deviceId = 'test-device-id';
|
||||
|
||||
const path = '/devices';
|
||||
|
||||
when(
|
||||
() => client.delete(path, queryParameters: any(named: 'queryParameters')),
|
||||
).thenAnswer((_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await deviceApi.removeDevice(deviceId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(
|
||||
() => client.delete(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/general_api.dart';
|
||||
import 'package:stream_chat/src/core/api/requests.dart';
|
||||
import 'package:stream_chat/src/core/models/channel_model.dart';
|
||||
import 'package:stream_chat/src/core/models/event.dart';
|
||||
import 'package:stream_chat/src/core/models/filter.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late GeneralApi generalApi;
|
||||
|
||||
setUp(() {
|
||||
generalApi = GeneralApi(client);
|
||||
});
|
||||
|
||||
test('sync', () async {
|
||||
const cids = ['test-cid-1', 'test-cid-2', 'test-cid-3'];
|
||||
final lastSyncAt = DateTime.now();
|
||||
|
||||
const path = '/sync';
|
||||
|
||||
final events =
|
||||
List.generate(3, (index) => Event(type: 'test-event-type-$index'));
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'events': [...events.map((it) => it.toJson())]
|
||||
}));
|
||||
|
||||
final res = await generalApi.sync(cids, lastSyncAt);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
group('searchMessages', () {
|
||||
test(
|
||||
'should throw if `query` and `messageFilters` is not provided',
|
||||
() async {
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
try {
|
||||
await generalApi.searchMessages(filter);
|
||||
} catch (e) {
|
||||
expect(e, isA<ArgumentError>());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should throw if `query` and `messageFilters` both are provided',
|
||||
() async {
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
const query = 'test-query';
|
||||
final messageFilter = Filter.query('key', 'text');
|
||||
try {
|
||||
await generalApi.searchMessages(
|
||||
filter,
|
||||
query: query,
|
||||
messageFilters: messageFilter,
|
||||
);
|
||||
} catch (e) {
|
||||
expect(e, isA<ArgumentError>());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test('should run successfully with `query`', () async {
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
const query = 'test-query';
|
||||
const sort = [SortOption<ChannelModel>('test-field')];
|
||||
const pagination = PaginationParams();
|
||||
|
||||
const path = '/search';
|
||||
|
||||
when(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).thenAnswer((_) async => successResponse(path, data: {'results': []}));
|
||||
|
||||
final res = await generalApi.searchMessages(
|
||||
filter,
|
||||
query: query,
|
||||
sort: sort,
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.results, isEmpty);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('should run successfully with `messageFilter`', () async {
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
const sort = [SortOption<ChannelModel>('test-field')];
|
||||
final messageFilter = Filter.query('key', 'text');
|
||||
const pagination = PaginationParams();
|
||||
|
||||
const path = '/search';
|
||||
|
||||
when(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).thenAnswer((_) async => successResponse(path, data: {'results': []}));
|
||||
|
||||
final res = await generalApi.searchMessages(
|
||||
filter,
|
||||
messageFilters: messageFilter,
|
||||
sort: sort,
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.results, isEmpty);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
});
|
||||
|
||||
group('queryMembers', () {
|
||||
test('with `channelId`', () async {
|
||||
const channelType = 'test-channel-type';
|
||||
const channelId = 'test-channel-id';
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
const pagination = PaginationParams();
|
||||
const sort = [SortOption('test-field')];
|
||||
|
||||
const path = '/members';
|
||||
|
||||
final members = List.generate(
|
||||
3,
|
||||
(index) => Member(userId: 'test-user-id=$index'),
|
||||
);
|
||||
|
||||
when(() =>
|
||||
client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'members': [...members.map((it) => it.toJson())]
|
||||
}));
|
||||
|
||||
final res = await generalApi.queryMembers(
|
||||
channelType,
|
||||
channelId: channelId,
|
||||
filter: filter,
|
||||
pagination: pagination,
|
||||
sort: sort,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.members.length, members.length);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('with `members`', () async {
|
||||
const channelType = 'test-channel-type';
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
const pagination = PaginationParams();
|
||||
const sort = [SortOption('test-field')];
|
||||
|
||||
const path = '/members';
|
||||
|
||||
final members = List.generate(
|
||||
3,
|
||||
(index) => Member(userId: 'test-user-id=$index'),
|
||||
);
|
||||
|
||||
when(() =>
|
||||
client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'members': [...members.map((it) => it.toJson())]
|
||||
}));
|
||||
|
||||
final res = await generalApi.queryMembers(
|
||||
channelType,
|
||||
filter: filter,
|
||||
pagination: pagination,
|
||||
sort: sort,
|
||||
members: members,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.members.length, members.length);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/guest_api.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late GuestApi guestApi;
|
||||
|
||||
setUp(() {
|
||||
guestApi = GuestApi(client);
|
||||
});
|
||||
|
||||
test('getGuestUser', () async {
|
||||
const accessToken = 'test-guest-token';
|
||||
final user = User(id: 'test-user-id');
|
||||
|
||||
const path = '/guest';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'access_token': accessToken,
|
||||
'user': user.toJson(),
|
||||
}));
|
||||
|
||||
final res = await guestApi.getGuestUser(user);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.accessToken, accessToken);
|
||||
expect(res.user.id, user.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/message_api.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late MessageApi messageApi;
|
||||
|
||||
setUp(() {
|
||||
messageApi = MessageApi(client);
|
||||
});
|
||||
|
||||
test('sendMessage', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
final message = Message(id: 'test-message-id', text: 'test-message-text');
|
||||
|
||||
const path = '/channels/$channelType/$channelId/message';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'message': message.toJson(),
|
||||
}));
|
||||
|
||||
final res = await messageApi.sendMessage(channelId, channelType, message);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.message.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('getMessagesById', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const messageIds = ['test-message-id-1', 'test-message-id-2'];
|
||||
|
||||
const path = '/channels/$channelType/$channelId/messages';
|
||||
|
||||
final messages = List.generate(
|
||||
3,
|
||||
(index) => Message(id: 'test-message-id-$index'),
|
||||
);
|
||||
|
||||
when(() => client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'messages': [...messages.map((it) => it.toJson())],
|
||||
}));
|
||||
|
||||
final res = await messageApi.getMessagesById(
|
||||
channelId,
|
||||
channelType,
|
||||
messageIds,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.messages.length, messages.length);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('getMessage', () async {
|
||||
const messageId = 'test-message-id';
|
||||
|
||||
const path = '/messages/$messageId';
|
||||
|
||||
final message = Message(id: messageId);
|
||||
|
||||
when(() => client.get(path)).thenAnswer((_) async =>
|
||||
successResponse(path, data: {'message': message.toJson()}));
|
||||
|
||||
final res = await messageApi.getMessage(messageId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.message.id, messageId);
|
||||
|
||||
verify(() => client.get(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('updateMessage', () async {
|
||||
final message = Message(id: 'test-message-id');
|
||||
|
||||
final path = '/messages/${message.id}';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: {'message': message.toJson()}),
|
||||
);
|
||||
|
||||
final res = await messageApi.updateMessage(message);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.message.id, message.id);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('deleteMessage', () async {
|
||||
const messageId = 'test-message-id';
|
||||
|
||||
const path = '/messages/$messageId';
|
||||
|
||||
when(() => client.delete(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}),
|
||||
);
|
||||
|
||||
final res = await messageApi.deleteMessage(messageId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.delete(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('sendAction', () async {
|
||||
const channelId = 'test-channel-id';
|
||||
const channelType = 'test-channel-type';
|
||||
const messageId = 'test-message-id';
|
||||
const formData = {'test-key': 'test-data'};
|
||||
|
||||
const path = '/messages/$messageId/action';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await messageApi.sendAction(
|
||||
channelId,
|
||||
channelType,
|
||||
messageId,
|
||||
formData,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('sendReaction', () async {
|
||||
const messageId = 'test-message-id';
|
||||
const reactionType = 'test-reaction-type';
|
||||
const extraData = {'test-key': 'test-data'};
|
||||
|
||||
const path = '/messages/$messageId/reaction';
|
||||
|
||||
final message = Message(id: messageId);
|
||||
final reaction = Reaction(type: reactionType, messageId: messageId);
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'message': message.toJson(),
|
||||
'reaction': reaction.toJson(),
|
||||
}));
|
||||
|
||||
final res = await messageApi.sendReaction(
|
||||
messageId,
|
||||
reactionType,
|
||||
extraData: extraData,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.message.id, messageId);
|
||||
expect(res.reaction.messageId, messageId);
|
||||
expect(res.reaction.type, reactionType);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('deleteReaction', () async {
|
||||
const messageId = 'test-message-id';
|
||||
const reactionType = 'test-reaction-type';
|
||||
|
||||
const path = '/messages/$messageId/reaction/$reactionType';
|
||||
|
||||
when(() => client.delete(path)).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await messageApi.deleteReaction(messageId, reactionType);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.delete(path)).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('getReactions', () async {
|
||||
const messageId = 'test-message-id';
|
||||
const options = PaginationParams();
|
||||
|
||||
const path = '/messages/$messageId/reactions';
|
||||
|
||||
final reactions = List.generate(
|
||||
3,
|
||||
(index) => Reaction(
|
||||
type: 'test-reaction-type-$index',
|
||||
messageId: messageId,
|
||||
),
|
||||
);
|
||||
|
||||
when(() => client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'reactions': [...reactions.map((it) => it.toJson())]
|
||||
}));
|
||||
|
||||
final res = await messageApi.getReactions(messageId, options);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.reactions.length, reactions.length);
|
||||
expect(res.reactions.every((it) => it.messageId == messageId), isTrue);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('translateMessage', () async {
|
||||
const messageId = 'test-message-id';
|
||||
const messageText = 'hello';
|
||||
const language = 'hi'; // Hindi
|
||||
final message = Message(id: messageId, text: messageText);
|
||||
|
||||
final path = '/messages/${message.id}/translate';
|
||||
|
||||
const translatedMessageText = 'नमस्ते';
|
||||
final translatedMessage = TranslatedMessage(const {
|
||||
language: translatedMessageText,
|
||||
});
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'message': translatedMessage.toJson(),
|
||||
}));
|
||||
|
||||
final res = await messageApi.translateMessage(messageId, language);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.message.i18n?.containsKey(language), isTrue);
|
||||
expect(res.message.i18n?[language], translatedMessageText);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('getReplies', () async {
|
||||
const parentId = 'test-parent-id';
|
||||
const options = PaginationParams();
|
||||
|
||||
const path = '/messages/$parentId/replies';
|
||||
|
||||
final messages = List.generate(
|
||||
3,
|
||||
(index) => Message(
|
||||
id: 'test-message-id-$index',
|
||||
parentId: parentId,
|
||||
),
|
||||
);
|
||||
|
||||
when(() => client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'messages': [...messages.map((it) => it.toJson())]
|
||||
}));
|
||||
|
||||
final res = await messageApi.getReplies(parentId, options);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.messages.length, messages.length);
|
||||
expect(res.messages.every((it) => it.parentId == parentId), isTrue);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/moderation_api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late ModerationApi moderationApi;
|
||||
|
||||
setUp(() {
|
||||
moderationApi = ModerationApi(client);
|
||||
});
|
||||
|
||||
test('muteUser', () async {
|
||||
const userId = 'test-user-id';
|
||||
|
||||
const path = '/moderation/mute';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.muteUser(userId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('unmuteUser', () async {
|
||||
const userId = 'test-user-id';
|
||||
|
||||
const path = '/moderation/unmute';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.unmuteUser(userId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('muteChannel', () async {
|
||||
const channelCid = 'test-channel-cid';
|
||||
const expiration = Duration(days: 3);
|
||||
|
||||
const path = '/moderation/mute/channel';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.muteChannel(
|
||||
channelCid,
|
||||
expiration: expiration,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('unmuteChannel', () async {
|
||||
const channelCid = 'test-channel-cid';
|
||||
|
||||
const path = '/moderation/unmute/channel';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.unmuteChannel(channelCid);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('flagMessage', () async {
|
||||
const messageId = 'test-message-id';
|
||||
|
||||
const path = '/moderation/flag';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.flagMessage(messageId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('unflagMessage', () async {
|
||||
const messageId = 'test-message-id';
|
||||
|
||||
const path = '/moderation/unflag';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.unflagMessage(messageId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('flagUser', () async {
|
||||
const userId = 'test-message-id';
|
||||
|
||||
const path = '/moderation/flag';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.flagUser(userId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('unflagUser', () async {
|
||||
const userId = 'test-message-id';
|
||||
|
||||
const path = '/moderation/unflag';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.unflagUser(userId);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('banUser', () async {
|
||||
const targetUserId = 'test-target-user-id';
|
||||
const options = {'key': 'value'};
|
||||
|
||||
const path = '/moderation/ban';
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.banUser(targetUserId, options: options);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('unbanUser', () async {
|
||||
const targetUserId = 'test-target-user-id';
|
||||
const options = {'key': 'value'};
|
||||
|
||||
const path = '/moderation/ban';
|
||||
|
||||
when(
|
||||
() => client.delete(path, queryParameters: any(named: 'queryParameters')),
|
||||
).thenAnswer((_) async => successResponse(path, data: <String, dynamic>{}));
|
||||
|
||||
final res = await moderationApi.unbanUser(targetUserId, options: options);
|
||||
|
||||
expect(res, isNotNull);
|
||||
|
||||
verify(
|
||||
() => client.delete(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import 'package:stream_chat/src/core/api/stream_chat_api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
const apiKey = 'test-api-key';
|
||||
late final client = MockHttpClient();
|
||||
late StreamChatApi streamChatApi;
|
||||
|
||||
setUp(() {
|
||||
streamChatApi = StreamChatApi(
|
||||
apiKey,
|
||||
client: client,
|
||||
);
|
||||
});
|
||||
|
||||
test('`.user`', () {
|
||||
expect(streamChatApi.user, isNotNull);
|
||||
});
|
||||
|
||||
test('`.guest`', () {
|
||||
expect(streamChatApi.guest, isNotNull);
|
||||
});
|
||||
|
||||
test('`.message`', () {
|
||||
expect(streamChatApi.message, isNotNull);
|
||||
});
|
||||
|
||||
test('`.channel`', () {
|
||||
expect(streamChatApi.channel, isNotNull);
|
||||
});
|
||||
|
||||
test('`.device`', () {
|
||||
expect(streamChatApi.device, isNotNull);
|
||||
});
|
||||
|
||||
test('`.moderation`', () {
|
||||
expect(streamChatApi.moderation, isNotNull);
|
||||
});
|
||||
|
||||
test('`.general`', () {
|
||||
expect(streamChatApi.general, isNotNull);
|
||||
});
|
||||
|
||||
test('`.fileUploader`', () {
|
||||
expect(streamChatApi.fileUploader, isNotNull);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/requests.dart';
|
||||
import 'package:stream_chat/src/core/api/user_api.dart';
|
||||
import 'package:stream_chat/src/core/models/filter.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
Response successResponse(String path, {Object? data}) => Response(
|
||||
data: data,
|
||||
requestOptions: RequestOptions(path: path),
|
||||
statusCode: 200,
|
||||
);
|
||||
|
||||
late final client = MockHttpClient();
|
||||
late UserApi userApi;
|
||||
|
||||
setUp(() {
|
||||
userApi = UserApi(client);
|
||||
});
|
||||
|
||||
test('queryUsers', () async {
|
||||
const presence = true;
|
||||
final filter = Filter.in_('cid', const ['test-cid-1', 'test-cid-2']);
|
||||
const sort = [SortOption('test-field')];
|
||||
const pagination = PaginationParams();
|
||||
|
||||
const path = '/users';
|
||||
|
||||
final users = List.generate(3, (index) => User(id: 'test-user-id-$index'));
|
||||
|
||||
when(() => client.get(path, queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => successResponse(path, data: {
|
||||
'users': [...users.map((it) => it.toJson())]
|
||||
}));
|
||||
|
||||
final res = await userApi.queryUsers(
|
||||
presence: presence,
|
||||
filter: filter,
|
||||
sort: sort,
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.users.length, users.length);
|
||||
|
||||
verify(
|
||||
() => client.get(path, queryParameters: any(named: 'queryParameters')),
|
||||
).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
|
||||
test('updateUsers', () async {
|
||||
final users = List.generate(3, (index) => User(id: 'test-user-id-$index'));
|
||||
|
||||
const path = '/users';
|
||||
|
||||
final updatedUsers = {for (final user in users) user.id: user};
|
||||
|
||||
when(() => client.post(path, data: any(named: 'data'))).thenAnswer(
|
||||
(_) async => successResponse(path, data: {
|
||||
'users': updatedUsers
|
||||
.map((key, value) => MapEntry(key, value.toJson()))
|
||||
}));
|
||||
|
||||
final res = await userApi.updateUsers(users);
|
||||
|
||||
expect(res, isNotNull);
|
||||
expect(res.users.length, updatedUsers.length);
|
||||
|
||||
verify(() => client.post(path, data: any(named: 'data'))).called(1);
|
||||
verifyNoMoreInteractions(client);
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,18 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/channel_api.dart';
|
||||
import 'package:stream_chat/src/core/api/device_api.dart';
|
||||
import 'package:stream_chat/src/core/api/general_api.dart';
|
||||
import 'package:stream_chat/src/core/api/message_api.dart';
|
||||
import 'package:stream_chat/src/core/api/moderation_api.dart';
|
||||
import 'package:stream_chat/src/core/api/stream_chat_api.dart';
|
||||
import 'package:stream_chat/src/core/api/user_api.dart';
|
||||
import 'package:stream_chat/src/core/api/guest_api.dart';
|
||||
import 'package:stream_chat/src/core/http/token.dart';
|
||||
import 'package:stream_chat/src/core/http/token_manager.dart';
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
|
||||
import 'mocks.dart';
|
||||
|
||||
class FakeTokenManager extends Fake implements TokenManager {
|
||||
final token = Token.development('test-user-id');
|
||||
@@ -25,3 +37,48 @@ class FakeTokenManager extends Fake implements TokenManager {
|
||||
@override
|
||||
void reset() {}
|
||||
}
|
||||
|
||||
class FakeMultiPartFile extends Fake implements MultipartFile {}
|
||||
|
||||
class FakeChatApi extends Fake implements StreamChatApi {
|
||||
UserApi? _user;
|
||||
|
||||
@override
|
||||
UserApi get user => _user ??= MockUserApi();
|
||||
|
||||
GuestApi? _guest;
|
||||
|
||||
@override
|
||||
GuestApi get guest => _guest ??= MockGuestApi();
|
||||
|
||||
MessageApi? _message;
|
||||
|
||||
@override
|
||||
MessageApi get message => _message ??= MockMessageApi();
|
||||
|
||||
ChannelApi? _channel;
|
||||
|
||||
@override
|
||||
ChannelApi get channel => _channel ??= MockChannelApi();
|
||||
|
||||
DeviceApi? _device;
|
||||
|
||||
@override
|
||||
DeviceApi get device => _device ??= MockDeviceApi();
|
||||
|
||||
ModerationApi? _moderation;
|
||||
|
||||
@override
|
||||
ModerationApi get moderation => _moderation ??= MockModerationApi();
|
||||
|
||||
GeneralApi? _general;
|
||||
|
||||
@override
|
||||
GeneralApi get general => _general ??= MockGeneralApi();
|
||||
|
||||
AttachmentFileUploader? _fileUploader;
|
||||
|
||||
@override
|
||||
AttachmentFileUploader get fileUploader =>
|
||||
_fileUploader ??= MockAttachmentFileUploader();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:dio/dio.dart' show MultipartFile;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
Matcher isSameMultipartFileAs(MultipartFile targetFile) =>
|
||||
_IsSameMultipartFileAs(targetFile: targetFile);
|
||||
|
||||
class _IsSameMultipartFileAs extends Matcher {
|
||||
const _IsSameMultipartFileAs({required this.targetFile});
|
||||
|
||||
final MultipartFile targetFile;
|
||||
|
||||
@override
|
||||
Description describe(Description description) =>
|
||||
description.add('is same multipartFile as $targetFile');
|
||||
|
||||
@override
|
||||
bool matches(covariant MultipartFile file, Map matchState) =>
|
||||
file.length == targetFile.length;
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:stream_chat/src/core/api/attachment_file_uploader.dart';
|
||||
import 'package:stream_chat/src/core/api/channel_api.dart';
|
||||
import 'package:stream_chat/src/core/api/device_api.dart';
|
||||
import 'package:stream_chat/src/core/api/general_api.dart';
|
||||
import 'package:stream_chat/src/core/api/guest_api.dart';
|
||||
import 'package:stream_chat/src/core/api/message_api.dart';
|
||||
import 'package:stream_chat/src/core/api/moderation_api.dart';
|
||||
import 'package:stream_chat/src/core/api/user_api.dart';
|
||||
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
||||
import 'package:stream_chat/src/core/http/stream_http_client.dart';
|
||||
import 'package:stream_chat/src/core/http/token_manager.dart';
|
||||
@@ -32,3 +40,20 @@ class MockHttpClient extends Mock implements StreamHttpClient {}
|
||||
class MockTokenManager extends Mock implements TokenManager {}
|
||||
|
||||
class MockConnectionIdManager extends Mock implements ConnectionIdManager {}
|
||||
|
||||
class MockUserApi extends Mock implements UserApi {}
|
||||
|
||||
class MockGuestApi extends Mock implements GuestApi {}
|
||||
|
||||
class MockMessageApi extends Mock implements MessageApi {}
|
||||
|
||||
class MockChannelApi extends Mock implements ChannelApi {}
|
||||
|
||||
class MockDeviceApi extends Mock implements DeviceApi {}
|
||||
|
||||
class MockModerationApi extends Mock implements ModerationApi {}
|
||||
|
||||
class MockGeneralApi extends Mock implements GeneralApi {}
|
||||
|
||||
class MockAttachmentFileUploader extends Mock
|
||||
implements AttachmentFileUploader {}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'dart:io';
|
||||
|
||||
File assetFile(String name) {
|
||||
final dir = currentDirectory.path;
|
||||
return File('$dir/test/assets/$name');
|
||||
}
|
||||
|
||||
// https://github.com/flutter/flutter/issues/20907
|
||||
Directory get currentDirectory {
|
||||
var directory = Directory.current;
|
||||
if (directory.path.endsWith('/test')) {
|
||||
directory = directory.parent;
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
Reference in New Issue
Block a user