From 460ef3c643fa76313a399afc0108518791e71446 Mon Sep 17 00:00:00 2001 From: littleGnAl Date: Mon, 14 Oct 2024 17:31:24 +0800 Subject: [PATCH] fix: Fix use incorrect length value in RtmClientImplOverride.publish/StreamChannelImpl.publishTopicMessage --- .../agora_rtm_client_impl_override.dart | 5 +- .../agora_stream_channel_impl_override.dart | 10 +- .../impl/agora_rtm_client_impl_override.dart | 22 -- .../agora_rtm_client_impl_override_test.dart | 49 ++++ ...ora_stream_channel_impl_override_test.dart | 49 ++++ .../integration_test_app/test/all_mocks.dart | 4 +- .../test/all_mocks.mocks.dart | 247 ++++++++++++++++++ .../test/fake_iris_method_channel.dart | 13 + 8 files changed, 370 insertions(+), 29 deletions(-) create mode 100644 test_shard/integration_test_app/test/agora_rtm_client_impl_override_test.dart create mode 100644 test_shard/integration_test_app/test/agora_stream_channel_impl_override_test.dart create mode 100644 test_shard/integration_test_app/test/fake_iris_method_channel.dart diff --git a/lib/src/bindings/agora_rtm_client_impl_override.dart b/lib/src/bindings/agora_rtm_client_impl_override.dart index a26a30a..e11ae29 100644 --- a/lib/src/bindings/agora_rtm_client_impl_override.dart +++ b/lib/src/bindings/agora_rtm_client_impl_override.dart @@ -228,10 +228,11 @@ class RtmClientImplOverride extends rtmc_binding.RtmClientImpl { required String message, required int length, required PublishOptions option}) async { + final messageUint8List = Uint8List.fromList(utf8.encode(message)); return publishBinaryMessage( channelName: channelName, - message: Uint8List.fromList(utf8.encode(message)), - length: length, + message: messageUint8List, + length: messageUint8List.length, option: option); } } diff --git a/lib/src/bindings/agora_stream_channel_impl_override.dart b/lib/src/bindings/agora_stream_channel_impl_override.dart index 81f2a7b..6e58f9b 100644 --- a/lib/src/bindings/agora_stream_channel_impl_override.dart +++ b/lib/src/bindings/agora_stream_channel_impl_override.dart @@ -44,10 +44,11 @@ class StreamChannelImpl extends sci_binding.StreamChannelImpl required String message, required int length, required TopicMessageOptions option}) async { + final messageUint8List = Uint8List.fromList(utf8.encode(message)); return publishBinaryMessage( topic: topic, - message: Uint8List.fromList(utf8.encode(message)), - length: length, + message: messageUint8List, + length: messageUint8List.length, option: option); } @@ -57,10 +58,11 @@ class StreamChannelImpl extends sci_binding.StreamChannelImpl required String message, required int length, required TopicMessageOptions option}) { + final messageUint8List = Uint8List.fromList(utf8.encode(message)); return publishBinaryMessage( topic: topic, - message: Uint8List.fromList(utf8.encode(message)), - length: length, + message: messageUint8List, + length: messageUint8List.length, option: option); } } diff --git a/lib/src/impl/agora_rtm_client_impl_override.dart b/lib/src/impl/agora_rtm_client_impl_override.dart index eb9fb46..ada31be 100644 --- a/lib/src/impl/agora_rtm_client_impl_override.dart +++ b/lib/src/impl/agora_rtm_client_impl_override.dart @@ -222,17 +222,6 @@ class RtmClientImplOverride extends rtm_client_impl.RtmClientImpl { String channelName, String message, {RtmChannelType channelType = RtmChannelType.message, String? customType}) async { - // final option = PublishOptions( - // channelType: channelType, - // messageType: RtmMessageType.string, - // customType: customType); - // final requestId = await nativeBindingRtmClientImpl.publish( - // channelName: channelName, - // message: message, - // length: message.length, - // option: option); - // return rtmResultHandler.request(requestId); - final option = PublishOptions( channelType: channelType, messageType: RtmMessageType.string, @@ -260,17 +249,6 @@ class RtmClientImplOverride extends rtm_client_impl.RtmClientImpl { String channelName, Uint8List message, {RtmChannelType channelType = RtmChannelType.message, String? customType}) async { - // final option = PublishOptions( - // channelType: channelType, - // messageType: RtmMessageType.binary, - // customType: customType); - // final requestId = await nativeBindingRtmClientImpl.publishBinaryMessage( - // channelName: channelName, - // message: message, - // length: message.length, - // option: option); - // return rtmResultHandler.request(requestId); - final option = PublishOptions( channelType: channelType, messageType: RtmMessageType.binary, diff --git a/test_shard/integration_test_app/test/agora_rtm_client_impl_override_test.dart b/test_shard/integration_test_app/test/agora_rtm_client_impl_override_test.dart new file mode 100644 index 0000000..43c9807 --- /dev/null +++ b/test_shard/integration_test_app/test/agora_rtm_client_impl_override_test.dart @@ -0,0 +1,49 @@ +import 'dart:convert'; +import 'dart:typed_data' show Uint8List; + +import 'package:agora_rtm/agora_rtm.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:agora_rtm/src/bindings/agora_rtm_client_impl_override.dart' + as agora_rtm_client_impl; + +import 'fake_iris_method_channel.dart'; + +void main() { + test('RtmClientImplOverride.publish', () { + FakeIrisMethodChannel irisMethodChannel = FakeIrisMethodChannel(); + agora_rtm_client_impl.RtmClientImplOverride rtmClientImplOverride = + agora_rtm_client_impl.RtmClientImplOverride.create(irisMethodChannel); + const message = 'hello'; + final messageUint8List = Uint8List.fromList(utf8.encode(message)); + + rtmClientImplOverride.publish( + channelName: '123', + message: message, + length: 5, + option: const PublishOptions()); + + final methodCall = irisMethodChannel.methodCallQueue[0]; + final paramsMap = jsonDecode(methodCall.params); + expect(paramsMap['length'], messageUint8List.length); + expect(methodCall.buffers![0], messageUint8List); + }); + + test('RtmClientImplOverride.publishBinaryMessage', () { + FakeIrisMethodChannel irisMethodChannel = FakeIrisMethodChannel(); + agora_rtm_client_impl.RtmClientImplOverride rtmClientImplOverride = + agora_rtm_client_impl.RtmClientImplOverride.create(irisMethodChannel); + const message = 'hello'; + final messageUint8List = Uint8List.fromList(utf8.encode(message)); + + rtmClientImplOverride.publishBinaryMessage( + channelName: '123', + message: messageUint8List, + length: messageUint8List.length, + option: const PublishOptions()); + + final methodCall = irisMethodChannel.methodCallQueue[0]; + final paramsMap = jsonDecode(methodCall.params); + expect(paramsMap['length'], messageUint8List.length); + expect(methodCall.buffers![0], messageUint8List); + }); +} diff --git a/test_shard/integration_test_app/test/agora_stream_channel_impl_override_test.dart b/test_shard/integration_test_app/test/agora_stream_channel_impl_override_test.dart new file mode 100644 index 0000000..48f9831 --- /dev/null +++ b/test_shard/integration_test_app/test/agora_stream_channel_impl_override_test.dart @@ -0,0 +1,49 @@ +import 'dart:convert'; +import 'dart:typed_data' show Uint8List; + +import 'package:agora_rtm/agora_rtm.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:agora_rtm/src/bindings/agora_stream_channel_impl_override.dart' + as agora_stream_channel_impl; + +import 'fake_iris_method_channel.dart'; + +void main() { + test('StreamChannelImpl.publishTopicMessage', () { + FakeIrisMethodChannel irisMethodChannel = FakeIrisMethodChannel(); + agora_stream_channel_impl.StreamChannelImpl streamChannelImpl = + agora_stream_channel_impl.StreamChannelImpl(irisMethodChannel, '123'); + const message = 'hello'; + final messageUint8List = Uint8List.fromList(utf8.encode(message)); + + streamChannelImpl.publishTopicMessage( + topic: '123', + message: message, + length: 5, + option: const TopicMessageOptions()); + + final methodCall = irisMethodChannel.methodCallQueue[0]; + final paramsMap = jsonDecode(methodCall.params); + expect(paramsMap['length'], messageUint8List.length); + expect(methodCall.buffers![0], messageUint8List); + }); + + test('StreamChannelImpl.publishBinaryMessage', () { + FakeIrisMethodChannel irisMethodChannel = FakeIrisMethodChannel(); + agora_stream_channel_impl.StreamChannelImpl streamChannelImpl = + agora_stream_channel_impl.StreamChannelImpl(irisMethodChannel, '123'); + const message = 'hello'; + final messageUint8List = Uint8List.fromList(utf8.encode(message)); + + streamChannelImpl.publishBinaryMessage( + topic: '123', + message: messageUint8List, + length: messageUint8List.length, + option: const TopicMessageOptions()); + + final methodCall = irisMethodChannel.methodCallQueue[0]; + final paramsMap = jsonDecode(methodCall.params); + expect(paramsMap['length'], messageUint8List.length); + expect(methodCall.buffers![0], messageUint8List); + }); +} diff --git a/test_shard/integration_test_app/test/all_mocks.dart b/test_shard/integration_test_app/test/all_mocks.dart index 87de7b8..bfc3927 100644 --- a/test_shard/integration_test_app/test/all_mocks.dart +++ b/test_shard/integration_test_app/test/all_mocks.dart @@ -14,14 +14,16 @@ import 'package:agora_rtm/src/bindings/gen/agora_stream_channel_impl.dart' import 'package:agora_rtm/src/impl/rtm_result_handler_impl.dart'; +import 'package:iris_method_channel/iris_method_channel.dart'; + @GenerateNiceMocks([ MockSpec(), MockSpec(), MockSpec(), MockSpec(), MockSpec(), - // RtmResultHandlerImpl MockSpec(), + MockSpec(), ]) // ignore: unused_import import 'all_mocks.mocks.dart'; diff --git a/test_shard/integration_test_app/test/all_mocks.mocks.dart b/test_shard/integration_test_app/test/all_mocks.mocks.dart index dd39e58..1722a5f 100644 --- a/test_shard/integration_test_app/test/all_mocks.mocks.dart +++ b/test_shard/integration_test_app/test/all_mocks.mocks.dart @@ -5,6 +5,7 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i8; import 'dart:typed_data' as _i13; +import 'dart:ui' as _i15; import 'package:agora_rtm/src/agora_rtm_base.dart' as _i12; import 'package:agora_rtm/src/agora_rtm_client.dart' as _i11; @@ -125,6 +126,37 @@ class _FakeFuture_8 extends _i1.SmartFake implements _i8.Future { ); } +class _FakeScopedObjects_9 extends _i1.SmartFake implements _i3.ScopedObjects { + _FakeScopedObjects_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCallApiResult_10 extends _i1.SmartFake implements _i3.CallApiResult { + _FakeCallApiResult_10( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIrisMethodChannelInternal_11 extends _i1.SmartFake + implements _i3.IrisMethodChannelInternal { + _FakeIrisMethodChannelInternal_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [RtmClientImplOverride]. /// /// See the documentation for Mockito's code generation for more information. @@ -2250,3 +2282,218 @@ class MockRtmResultHandlerImpl extends _i1.Mock returnValueForMissingStub: null, ); } + +/// A class which mocks [IrisMethodChannel]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIrisMethodChannel extends _i1.Mock implements _i3.IrisMethodChannel { + @override + _i3.ScopedObjects get scopedEventHandlers => (super.noSuchMethod( + Invocation.getter(#scopedEventHandlers), + returnValue: _FakeScopedObjects_9( + this, + Invocation.getter(#scopedEventHandlers), + ), + returnValueForMissingStub: _FakeScopedObjects_9( + this, + Invocation.getter(#scopedEventHandlers), + ), + ) as _i3.ScopedObjects); + + @override + _i8.Future<_i3.InitilizationResult?> initilize( + List<_i3.InitilizationArgProvider>? args) => + (super.noSuchMethod( + Invocation.method( + #initilize, + [args], + ), + returnValue: _i8.Future<_i3.InitilizationResult?>.value(), + returnValueForMissingStub: _i8.Future<_i3.InitilizationResult?>.value(), + ) as _i8.Future<_i3.InitilizationResult?>); + + @override + _i8.Future<_i3.CallApiResult> invokeMethod(_i3.IrisMethodCall? methodCall) => + (super.noSuchMethod( + Invocation.method( + #invokeMethod, + [methodCall], + ), + returnValue: _i8.Future<_i3.CallApiResult>.value(_FakeCallApiResult_10( + this, + Invocation.method( + #invokeMethod, + [methodCall], + ), + )), + returnValueForMissingStub: + _i8.Future<_i3.CallApiResult>.value(_FakeCallApiResult_10( + this, + Invocation.method( + #invokeMethod, + [methodCall], + ), + )), + ) as _i8.Future<_i3.CallApiResult>); + + @override + _i8.Future> invokeMethodList( + List<_i3.IrisMethodCall>? methodCalls) => + (super.noSuchMethod( + Invocation.method( + #invokeMethodList, + [methodCalls], + ), + returnValue: + _i8.Future>.value(<_i3.CallApiResult>[]), + returnValueForMissingStub: + _i8.Future>.value(<_i3.CallApiResult>[]), + ) as _i8.Future>); + + @override + _i8.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future<_i3.CallApiResult> registerEventHandler( + _i3.ScopedEvent? scopedEvent, + String? params, + ) => + (super.noSuchMethod( + Invocation.method( + #registerEventHandler, + [ + scopedEvent, + params, + ], + ), + returnValue: _i8.Future<_i3.CallApiResult>.value(_FakeCallApiResult_10( + this, + Invocation.method( + #registerEventHandler, + [ + scopedEvent, + params, + ], + ), + )), + returnValueForMissingStub: + _i8.Future<_i3.CallApiResult>.value(_FakeCallApiResult_10( + this, + Invocation.method( + #registerEventHandler, + [ + scopedEvent, + params, + ], + ), + )), + ) as _i8.Future<_i3.CallApiResult>); + + @override + _i8.Future<_i3.CallApiResult> unregisterEventHandler( + _i3.ScopedEvent? scopedEvent, + String? params, + ) => + (super.noSuchMethod( + Invocation.method( + #unregisterEventHandler, + [ + scopedEvent, + params, + ], + ), + returnValue: _i8.Future<_i3.CallApiResult>.value(_FakeCallApiResult_10( + this, + Invocation.method( + #unregisterEventHandler, + [ + scopedEvent, + params, + ], + ), + )), + returnValueForMissingStub: + _i8.Future<_i3.CallApiResult>.value(_FakeCallApiResult_10( + this, + Invocation.method( + #unregisterEventHandler, + [ + scopedEvent, + params, + ], + ), + )), + ) as _i8.Future<_i3.CallApiResult>); + + @override + _i8.Future unregisterEventHandlers(_i3.TypedScopedKey? scopedKey) => + (super.noSuchMethod( + Invocation.method( + #unregisterEventHandlers, + [scopedKey], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + int getApiEngineHandle() => (super.noSuchMethod( + Invocation.method( + #getApiEngineHandle, + [], + ), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + _i15.VoidCallback addHotRestartListener(_i3.HotRestartListener? listener) => + (super.noSuchMethod( + Invocation.method( + #addHotRestartListener, + [listener], + ), + returnValue: () {}, + returnValueForMissingStub: () {}, + ) as _i15.VoidCallback); + + @override + void removeHotRestartListener(_i3.HotRestartListener? listener) => + super.noSuchMethod( + Invocation.method( + #removeHotRestartListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + _i3.IrisMethodChannelInternal getIrisMethodChannelInternal() => + (super.noSuchMethod( + Invocation.method( + #getIrisMethodChannelInternal, + [], + ), + returnValue: _FakeIrisMethodChannelInternal_11( + this, + Invocation.method( + #getIrisMethodChannelInternal, + [], + ), + ), + returnValueForMissingStub: _FakeIrisMethodChannelInternal_11( + this, + Invocation.method( + #getIrisMethodChannelInternal, + [], + ), + ), + ) as _i3.IrisMethodChannelInternal); +} diff --git a/test_shard/integration_test_app/test/fake_iris_method_channel.dart b/test_shard/integration_test_app/test/fake_iris_method_channel.dart new file mode 100644 index 0000000..de978b1 --- /dev/null +++ b/test_shard/integration_test_app/test/fake_iris_method_channel.dart @@ -0,0 +1,13 @@ +import 'package:mockito/mockito.dart'; +import 'package:iris_method_channel/iris_method_channel.dart'; + +class FakeIrisMethodChannel extends Fake implements IrisMethodChannel { + final List methodCallQueue = []; + + @override + Future invokeMethod(IrisMethodCall methodCall) async { + methodCallQueue.add(methodCall); + return CallApiResult( + irisReturnCode: 0, data: {'result': 0, 'requestId': 1}); + } +}