Merge pull request #1522 from GetStream/feat/interceptors

This commit is contained in:
Sahil Kumar
2023-05-05 18:13:21 +05:30
committed by GitHub
7 changed files with 112 additions and 45 deletions
+23
View File
@@ -10,6 +10,29 @@
- Expose `ChannelMute` class. [#1473](https://github.com/GetStream/stream-chat-flutter/issues/1473)
- Added synchronization to the `StreamChatClient.sync`
api. [#1392](https://github.com/GetStream/stream-chat-flutter/issues/1392)
- Added support for `StreamChatClient.chatApiInterceptors` to add custom interceptors to the API client.
[#1265](https://github.com/GetStream/stream-chat-flutter/issues/1265).
```dart
final client = StreamChatClient(
chatApiInterceptors: [
InterceptorsWrapper(
onRequest: (options, handler) {
// Do something before request is sent.
return handler.next(options);
},
onResponse: (response, handler) {
// Do something with response data
return handler.next(response);
},
onError: (DioError e, handler) {
// Do something with response error
return handler.next(e);
},
),
],
);
```
## 6.0.0
@@ -73,6 +73,7 @@ class StreamChatClient {
WebSocket? ws,
AttachmentFileUploaderProvider attachmentFileUploaderProvider =
StreamAttachmentFileUploader.new,
Iterable<Interceptor>? chatApiInterceptors,
}) {
logger.info('Initiating new StreamChatClient');
@@ -91,6 +92,7 @@ class StreamChatClient {
connectionIdManager: _connectionIdManager,
attachmentFileUploaderProvider: attachmentFileUploaderProvider,
logger: detachedLogger('🕸️'),
interceptors: chatApiInterceptors,
);
_ws = ws ??
@@ -1,3 +1,4 @@
import 'package:dio/dio.dart';
import 'package:logging/logging.dart';
import 'package:stream_chat/src/core/api/attachment_file_uploader.dart';
import 'package:stream_chat/src/core/api/call_api.dart';
@@ -26,6 +27,7 @@ class StreamChatApi {
AttachmentFileUploaderProvider attachmentFileUploaderProvider =
StreamAttachmentFileUploader.new,
Logger? logger,
Iterable<Interceptor>? interceptors,
}) : _fileUploaderProvider = attachmentFileUploaderProvider,
_client = client ??
StreamHttpClient(
@@ -34,6 +36,7 @@ class StreamChatApi {
tokenManager: tokenManager,
connectionIdManager: connectionIdManager,
logger: logger,
interceptors: interceptors,
);
final StreamHttpClient _client;
@@ -101,8 +101,7 @@ class LoggingInterceptor extends Interceptor {
options.data as Map?,
header: 'Body',
);
}
if (data is FormData) {
} else if (data is FormData) {
final formDataMap = <String, dynamic>{}
..addEntries(data.fields)
..addEntries(data.files);
@@ -163,7 +162,7 @@ class LoggingInterceptor extends Interceptor {
_logPrintResponse('');
_printResponse(_logPrintResponse, response);
_logPrintResponse('');
_logPrintResponse('');
_printLine(_logPrintResponse, '');
}
super.onResponse(response, handler);
}
@@ -25,6 +25,7 @@ class StreamHttpClient {
TokenManager? tokenManager,
ConnectionIdManager? connectionIdManager,
Logger? logger,
Iterable<Interceptor>? interceptors,
}) : _options = options ?? const StreamHttpClientOptions(),
httpClient = dio ?? Dio() {
httpClient
@@ -45,20 +46,25 @@ class StreamHttpClient {
if (tokenManager != null) AuthInterceptor(this, tokenManager),
if (connectionIdManager != null)
ConnectionIdInterceptor(connectionIdManager),
if (logger != null && logger.level != Level.OFF)
LoggingInterceptor(
requestHeader: true,
logPrint: (step, message) {
switch (step) {
case InterceptStep.request:
return logger.info(message);
case InterceptStep.response:
return logger.info(message);
case InterceptStep.error:
return logger.severe(message);
}
},
),
...interceptors ??
[
// Add a default logging interceptor if no interceptors are
// provided.
if (logger != null && logger.level != Level.OFF)
LoggingInterceptor(
requestHeader: true,
logPrint: (step, message) {
switch (step) {
case InterceptStep.request:
return logger.info(message);
case InterceptStep.response:
return logger.info(message);
case InterceptStep.error:
return logger.severe(message);
}
},
),
],
]);
}
@@ -3,6 +3,7 @@ library stream_chat;
export 'package:async/async.dart';
export 'package:dio/src/cancel_token.dart';
export 'package:dio/src/dio_error.dart';
export 'package:dio/src/dio_mixin.dart' show Interceptor, InterceptorsWrapper;
export 'package:dio/src/multipart_file.dart';
export 'package:dio/src/options.dart';
export 'package:dio/src/options.dart' show ProgressCallback;
@@ -19,6 +20,7 @@ export 'src/core/api/responses.dart';
export 'src/core/api/stream_chat_api.dart' show PushProvider;
export 'src/core/api/stream_chat_api.dart';
export 'src/core/error/error.dart';
export 'src/core/http/interceptor/logging_interceptor.dart';
export 'src/core/models/action.dart';
export 'src/core/models/attachment.dart';
export 'src/core/models/attachment_file.dart';
@@ -86,41 +86,73 @@ void main() {
},
);
test('loggingInterceptor should be added if logger is provided', () {
const apiKey = 'api-key';
final client = StreamHttpClient(
apiKey,
logger: Logger('test-logger'),
);
group('loggingInterceptor', () {
test('should be added if logger is provided', () {
const apiKey = 'api-key';
final client = StreamHttpClient(
apiKey,
logger: Logger('test-logger'),
);
expect(
client.httpClient.interceptors.whereType<LoggingInterceptor>().length,
1,
);
});
expect(
client.httpClient.interceptors.whereType<LoggingInterceptor>().length,
1,
);
});
test('loggingInterceptor should log requests', () async {
const apiKey = 'api-key';
final logger = MockLogger();
final client = StreamHttpClient(apiKey, logger: logger);
test('should not be added if logger.level is OFF', () {
const apiKey = 'api-key';
final client = StreamHttpClient(
apiKey,
logger: Logger.detached('test-logger')..level = Level.OFF,
);
try {
await client.get('path');
} catch (_) {}
expect(
client.httpClient.interceptors.whereType<LoggingInterceptor>().length,
0,
);
});
verify(() => logger.info(any())).called(greaterThan(0));
});
test('should not be added if `interceptors` are provided', () {
const apiKey = 'api-key';
final client = StreamHttpClient(
apiKey,
logger: Logger.detached('test-logger'),
interceptors: [
// Sample Interceptor.
InterceptorsWrapper(),
],
);
test('loggingInterceptor should log error', () async {
const apiKey = 'api-key';
final logger = MockLogger();
final client = StreamHttpClient(apiKey, logger: logger);
expect(
client.httpClient.interceptors.whereType<LoggingInterceptor>().length,
0,
);
});
try {
await client.get('path');
} catch (_) {}
test('should log requests', () async {
const apiKey = 'api-key';
final logger = MockLogger();
final client = StreamHttpClient(apiKey, logger: logger);
verify(() => logger.severe(any())).called(greaterThan(0));
try {
await client.get('path');
} catch (_) {}
verify(() => logger.info(any())).called(greaterThan(0));
});
test('should log error', () async {
const apiKey = 'api-key';
final logger = MockLogger();
final client = StreamHttpClient(apiKey, logger: logger);
try {
await client.get('path');
} catch (_) {}
verify(() => logger.severe(any())).called(greaterThan(0));
});
});
test('`.close` should close the dio client', () async {