From 08af795a3e66c9c77157321b29f6ea20ff354ac6 Mon Sep 17 00:00:00 2001 From: Are Date: Mon, 22 Nov 2021 11:30:19 +0100 Subject: [PATCH] Make v4.0.0 stable release (#72) feat: add PAM v3 support Adds PAM v3 support with grantToken and setToken. fix: change subscribe loop to no longer throw Subscribe loop no longer throws on unrecoverable failure, instead waits for restart. feat: add restore method to subscription After subscribe loop fails, call restore to restart it. fix: add more specific diagnostics Adds more diagnostics for network module. fix: change whenStarts to stream WhenStarts future no longer throws and is now based on a stream. fix: release resources on failure Networking should now release all resources after a failure. fix: Signature mismatch issue. Fixes issue of Signature mismatch with PAM enabled keysets. fix: Message decryption failure in subscribe. Fixes issue of message decryption with subscription. --- .pubnub.yml | 21 ++- acceptance_tests/bin/acceptance_tests.dart | 2 +- pubnub/CHANGELOG.md | 15 ++ pubnub/README.md | 3 +- pubnub/example/supervisor.dart | 18 +- pubnub/lib/src/core/core.dart | 2 +- .../lib/src/networking/meta/diagnostics.dart | 44 ----- .../meta/diagnostics/diagnostics.dart | 3 + .../src/networking/meta/diagnostics/html.dart | 45 +++++ .../src/networking/meta/diagnostics/io.dart | 141 +++++++++++++++ .../src/networking/meta/diagnostics/stub.dart | 31 ++++ pubnub/lib/src/networking/meta/meta.dart | 32 +--- pubnub/lib/src/networking/meta/strategy.dart | 2 +- .../src/networking/request_handler/io.dart | 44 ++--- pubnub/lib/src/subscribe/manager.dart | 4 + .../subscribe_loop/subscribe_loop.dart | 30 ++-- .../subscribe_loop/subscribe_loop_state.dart | 46 +++-- pubnub/lib/src/subscribe/subscription.dart | 5 + pubnub/pubspec.yaml | 2 +- pubnub/test/unit/dx/file_test.dart | 164 ------------------ pubnub/test/unit/dx/fixtures/files.dart | 105 ----------- pubnub/test/unit/dx/fixtures/history.dart | 158 ----------------- .../test/unit/dx/fixtures/message_action.dart | 102 ----------- pubnub/test/unit/dx/fixtures/pam.dart | 93 ---------- pubnub/test/unit/dx/fixtures/signal.dart | 3 - pubnub/test/unit/dx/history_test.dart | 160 ----------------- pubnub/test/unit/dx/message_action_test.dart | 144 --------------- .../dx/objects/channel_metadata_test.dart | 65 ------- .../dx/objects/fixtures/channel_metadata.dart | 63 ------- .../objects/fixtures/membership_metadata.dart | 98 ----------- .../dx/objects/fixtures/uuid_metadata.dart | 67 ------- .../dx/objects/membership_metadata_test.dart | 129 -------------- .../unit/dx/objects/uuid_metadata_test.dart | 85 --------- pubnub/test/unit/dx/pam_test.dart | 59 ------- pubnub/test/unit/dx/publish_test.dart | 35 ---- pubnub/test/unit/dx/push_test.dart | 136 +-------------- pubnub/test/unit/dx/signal_test.dart | 35 ---- pubnub/test/unit/dx/time_test.dart | 43 ----- pubnub/test/unit/dx/utils_test.dart | 6 +- pubnub/test/unit/net/fake_net.dart | 17 +- 40 files changed, 369 insertions(+), 1888 deletions(-) delete mode 100644 pubnub/lib/src/networking/meta/diagnostics.dart create mode 100644 pubnub/lib/src/networking/meta/diagnostics/diagnostics.dart create mode 100644 pubnub/lib/src/networking/meta/diagnostics/html.dart create mode 100644 pubnub/lib/src/networking/meta/diagnostics/io.dart create mode 100644 pubnub/lib/src/networking/meta/diagnostics/stub.dart delete mode 100644 pubnub/test/unit/dx/fixtures/history.dart delete mode 100644 pubnub/test/unit/dx/fixtures/message_action.dart delete mode 100644 pubnub/test/unit/dx/fixtures/pam.dart delete mode 100644 pubnub/test/unit/dx/fixtures/signal.dart delete mode 100644 pubnub/test/unit/dx/history_test.dart delete mode 100644 pubnub/test/unit/dx/objects/channel_metadata_test.dart delete mode 100644 pubnub/test/unit/dx/objects/fixtures/channel_metadata.dart delete mode 100644 pubnub/test/unit/dx/objects/fixtures/membership_metadata.dart delete mode 100644 pubnub/test/unit/dx/objects/fixtures/uuid_metadata.dart delete mode 100644 pubnub/test/unit/dx/objects/membership_metadata_test.dart delete mode 100644 pubnub/test/unit/dx/objects/uuid_metadata_test.dart delete mode 100644 pubnub/test/unit/dx/signal_test.dart delete mode 100644 pubnub/test/unit/dx/time_test.dart diff --git a/.pubnub.yml b/.pubnub.yml index 1f525904..c66851bd 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,5 +1,24 @@ --- changelog: + - date: 2021-11-22 + version: v4.0.0 + changes: + - type: feature + text: "Adds PAM v3 support with `grantToken` and `setToken`." + - type: feature + text: "After subscribe loop fails, call restore to restart it." + - type: bug + text: "Subscribe loop no longer throws on unrecoverable failure, instead waits for restart." + - type: bug + text: "Adds more diagnostics for network module." + - type: bug + text: "WhenStarts future no longer throws and is now based on a stream." + - type: bug + text: "Networking should now release all resources after a failure." + - type: bug + text: "Fixes issue of Signature mismatch with PAM enabled keysets." + - type: bug + text: "Fixes issue of message decryption with subscription." - changes: - @@ -351,7 +370,7 @@ supported-platforms: platforms: - "Dart SDK >=2.6.0 <3.0.0" version: "PubNub Dart SDK" -version: "3.1.0" +version: "4.0.0" sdks: - full-name: PubNub Dart SDK diff --git a/acceptance_tests/bin/acceptance_tests.dart b/acceptance_tests/bin/acceptance_tests.dart index dc51e489..9675e8df 100644 --- a/acceptance_tests/bin/acceptance_tests.dart +++ b/acceptance_tests/bin/acceptance_tests.dart @@ -15,7 +15,7 @@ Future main() async { featureFiles: env['FEATURES_PATH'] ?? '../../service-contract-mock/contract/features', logger: logger, - tags: 'not @skip', + tags: 'not @skip and not @na=dart and not @beta', ); var exitCode = 0; diff --git a/pubnub/CHANGELOG.md b/pubnub/CHANGELOG.md index a306e1a2..510296cf 100644 --- a/pubnub/CHANGELOG.md +++ b/pubnub/CHANGELOG.md @@ -1,3 +1,18 @@ +## v4.0.0 +November 22 2021 + +#### Added +- Adds PAM v3 support with `grantToken` and `setToken`. +- After subscribe loop fails, call restore to restart it. + +#### Fixed +- Subscribe loop no longer throws on unrecoverable failure, instead waits for restart. Fixed the following issues reported by [@willbryant](https://github.com/willbryant): [#63](https://github.com/pubnub/dart/issues/63). +- Adds more diagnostics for network module. Fixed the following issues reported by [@willbryant](https://github.com/willbryant): [#65](https://github.com/pubnub/dart/issues/65). +- WhenStarts future no longer throws and is now based on a stream. Fixed the following issues reported by [@willbryant](https://github.com/willbryant): [#64](https://github.com/pubnub/dart/issues/64). +- Networking should now release all resources after a failure. Fixed the following issues reported by [@aadil058](https://github.com/aadil058): [#62](https://github.com/pubnub/dart/issues/62). +- Fixes issue of Signature mismatch with PAM enabled keysets. Fixed the following issues reported by [@mahmoudsalah37](https://github.com/mahmoudsalah37): [#50](https://github.com/pubnub/dart/issues/50). +- Fixes issue of message decryption with subscription. Fixed the following issues reported by [@TabooSun](https://github.com/TabooSun): [#46](https://github.com/pubnub/dart/issues/46). + ## [v3.0.0](https://github.com/pubnub/dart/releases/tag/v3.0.0) October 8 2020 diff --git a/pubnub/README.md b/pubnub/README.md index 82971830..bfd3e1b2 100644 --- a/pubnub/README.md +++ b/pubnub/README.md @@ -14,7 +14,7 @@ To add the package to your Dart or Flutter project, add `pubnub` as a dependency ```yaml dependencies: - pubnub: ^1.0.0 + pubnub: ^4.0.0 ``` After adding the dependency to `pubspec.yaml`, run the `pub get` command in the root directory of your project (the same that the `pubspec.yaml` is in). @@ -27,6 +27,7 @@ If you want to use the latest, unreleased version of `pubnub`, you can add it to dependencies: pubnub: git: git://github.com/pubnub/dart.git + path: pubnub ``` ### Using a local copy of the repository diff --git a/pubnub/example/supervisor.dart b/pubnub/example/supervisor.dart index da5e3aa4..259d092d 100644 --- a/pubnub/example/supervisor.dart +++ b/pubnub/example/supervisor.dart @@ -3,7 +3,7 @@ import 'package:pubnub/logging.dart'; import 'package:pubnub/networking.dart'; void main() async { - var logger = StreamLogger.root('root', logLevel: Level.warning); + var logger = StreamLogger.root('root', logLevel: Level.all); // Subscribe to messages with a default printer logger.stream.listen( @@ -18,27 +18,27 @@ void main() async { ); print( - 'Network reconnection test. Please wait few seconds for further instructions...'); + '*\n*** Network reconnection test. Please wait few seconds for further instructions. You will see few diagnostic log lines in the meantime.\n*'); - var sub = pubnub.subscribe(channels: {'test2'}); + await provideLogger(logger, () async { + var sub = pubnub.subscribe(channels: {'test2'}); - await Future.delayed(Duration(seconds: 5)); + await Future.delayed(Duration(seconds: 5)); - print('Subscribed. Disconnect your network for few seconds.'); + print('*\n*** Subscribed. Disconnect your network for few seconds.\n*'); - await Future.delayed(Duration(seconds: 5)); + await Future.delayed(Duration(seconds: 5)); - await provideLogger(logger, () async { var f = pubnub.publish('test2', {'myMessage': 'it works!'}); print( - 'Now reconnect your network again! If everything goes well, you should see the message. You will see few diagnostic log lines in the meantime.'); + '*\n*** Now reconnect your network again! If everything goes well, you should see the message.\n*'); await f; var message = await sub.messages.first; - print(message.payload); + print('*\n*** ${message.payload}\n*'); await sub.dispose(); diff --git a/pubnub/lib/src/core/core.dart b/pubnub/lib/src/core/core.dart index fd2a4660..f624eae8 100644 --- a/pubnub/lib/src/core/core.dart +++ b/pubnub/lib/src/core/core.dart @@ -21,7 +21,7 @@ class Core { /// Internal module responsible for supervising. SupervisorModule supervisor = SupervisorModule(); - static String version = '3.1.0'; + static String version = '4.0.0'; Core( {Keyset? defaultKeyset, diff --git a/pubnub/lib/src/networking/meta/diagnostics.dart b/pubnub/lib/src/networking/meta/diagnostics.dart deleted file mode 100644 index 463758ac..00000000 --- a/pubnub/lib/src/networking/meta/diagnostics.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:pubnub/core.dart'; - -class HostIsDownDiagnostic extends Diagnostic { - final String? host; - final int? port; - - const HostIsDownDiagnostic(this.host, this.port); -} - -class HostLookupFailedDiagnostic extends Diagnostic { - final String? host; - - const HostLookupFailedDiagnostic(this.host); -} - -class UnknownHttpExceptionDiagnostic extends Diagnostic { - const UnknownHttpExceptionDiagnostic(); -} - -class TimeoutDiagnostic extends Diagnostic { - const TimeoutDiagnostic(); -} - -final Map netDiagnosticsMap = { - RegExp(r'^SocketException: OS Error: Software caused connection abort, errno = 103, address = ([a-zA-Z0-9\-\.]+), port = ([0-9]+)$'): - (match) => HostIsDownDiagnostic( - match?.group(1), int.tryParse(match?.group(2) ?? '')), - RegExp(r'^SocketException: Connection failed \(OS Error: Host is down, errno = 64\), address = ([a-zA-Z0-9\-\.]+), port = ([0-9]+)$'): - (match) => HostIsDownDiagnostic( - match?.group(1), int.tryParse(match?.group(2) ?? '')), - RegExp(r"^SocketException: Failed host lookup: '([a-zA-Z0-9\-\.]+)'"): - (match) => HostLookupFailedDiagnostic(match?.group(1)), - RegExp(r"^Failed host lookup: '([a-zA-Z0-9\-\.]+)'$"): (match) => - HostLookupFailedDiagnostic(match?.group(1)), - RegExp(r'^Connecting timed out'): (match) => UnknownHttpExceptionDiagnostic(), - RegExp(r'^HttpException: , uri ='): (match) => - UnknownHttpExceptionDiagnostic(), -}; - -class AccessDeniedDiagnostic extends Diagnostic { - Set affectedChannels = {}; - - AccessDeniedDiagnostic(); -} diff --git a/pubnub/lib/src/networking/meta/diagnostics/diagnostics.dart b/pubnub/lib/src/networking/meta/diagnostics/diagnostics.dart new file mode 100644 index 00000000..11d1d9ab --- /dev/null +++ b/pubnub/lib/src/networking/meta/diagnostics/diagnostics.dart @@ -0,0 +1,3 @@ +export 'stub.dart' + if (dart.library.io) 'io.dart' + if (dart.library.html) 'html.dart'; diff --git a/pubnub/lib/src/networking/meta/diagnostics/html.dart b/pubnub/lib/src/networking/meta/diagnostics/html.dart new file mode 100644 index 00000000..997bf86c --- /dev/null +++ b/pubnub/lib/src/networking/meta/diagnostics/html.dart @@ -0,0 +1,45 @@ +import 'package:pubnub/core.dart'; + +class HostIsDownDiagnostic extends Diagnostic { + final dynamic originalException; + + const HostIsDownDiagnostic(this.originalException); +} + +class HostLookupFailedDiagnostic extends Diagnostic { + final dynamic originalException; + + const HostLookupFailedDiagnostic(this.originalException); +} + +class UnknownHttpExceptionDiagnostic extends Diagnostic { + final dynamic originalException; + + const UnknownHttpExceptionDiagnostic(this.originalException); +} + +class TimeoutDiagnostic extends Diagnostic { + const TimeoutDiagnostic(); +} + +class AccessDeniedDiagnostic extends Diagnostic { + AccessDeniedDiagnostic(); +} + +Diagnostic? getNetworkDiagnostic(dynamic exception) { + if (exception is RequestOtherException) { + return UnknownHttpExceptionDiagnostic(exception); + } + + if (exception is RequestTimeoutException) { + return TimeoutDiagnostic(); + } + + if (exception is RequestFailureException) { + var request = exception.response; + + if (request.statusCode == 403) { + return AccessDeniedDiagnostic(); + } + } +} diff --git a/pubnub/lib/src/networking/meta/diagnostics/io.dart b/pubnub/lib/src/networking/meta/diagnostics/io.dart new file mode 100644 index 00000000..24b1f4c7 --- /dev/null +++ b/pubnub/lib/src/networking/meta/diagnostics/io.dart @@ -0,0 +1,141 @@ +import 'dart:io'; +import 'package:pubnub/core.dart'; + +class HostIsDownDiagnostic extends Diagnostic { + final dynamic originalException; + + const HostIsDownDiagnostic(this.originalException); +} + +class HostLookupFailedDiagnostic extends Diagnostic { + final dynamic originalException; + + const HostLookupFailedDiagnostic(this.originalException); +} + +class UnknownHttpExceptionDiagnostic extends Diagnostic { + final dynamic originalException; + + const UnknownHttpExceptionDiagnostic(this.originalException); +} + +class TimeoutDiagnostic extends Diagnostic { + const TimeoutDiagnostic(); +} + +class AccessDeniedDiagnostic extends Diagnostic { + const AccessDeniedDiagnostic(); +} + +Diagnostic? getNetworkDiagnostic(dynamic exception) { + if (exception is RequestOtherException) { + var originalException = exception.additionalData; + + if (originalException is SocketException) { + if (originalException.osError?.message == + 'nodename nor servname provided, or not known') { + return HostLookupFailedDiagnostic(originalException); + } + + var errno = _getErrorCode(originalException.osError?.errorCode); + + switch (errno) { + case _Errno.ECONNRESET: + case _Errno.ECONNABORTED: + case _Errno.ECONNREFUSED: + case _Errno.ETIMEOUT: + case _Errno.EHOSTUNREACH: + return HostIsDownDiagnostic(originalException); + case _Errno.EBADF: + case _Errno.ENETUNREACH: + case _Errno.unknown: + return UnknownHttpExceptionDiagnostic(originalException); + } + } + + if (originalException is HttpException || + originalException is HandshakeException) { + return UnknownHttpExceptionDiagnostic(originalException); + } + } + + if (exception is RequestTimeoutException) { + return TimeoutDiagnostic(); + } + + if (exception is RequestFailureException) { + var request = exception.response; + + if (request.statusCode == 403) { + return AccessDeniedDiagnostic(); + } + } +} + +enum _Errno { + unknown, + ECONNABORTED, + ECONNRESET, + ECONNREFUSED, + EHOSTUNREACH, + EBADF, + ETIMEOUT, + ENETUNREACH +} + +_Errno _getErrorCode(int? errno) { + if (errno == null) { + return _Errno.unknown; + } + + if (Platform.isLinux) { + return _linuxErrnoCodes[errno] ?? _Errno.unknown; + } else if (Platform.isWindows) { + return _winErrnoCodes[errno] ?? _Errno.unknown; + } else if (Platform.isMacOS || Platform.isIOS) { + return _macErrnoCodes[errno] ?? _Errno.unknown; + } else if (Platform.isAndroid) { + return _androidErrnoCodes[errno] ?? _Errno.unknown; + } else { + return _Errno.unknown; + } +} + +const _linuxErrnoCodes = { + 9: _Errno.EBADF, + 101: _Errno.ENETUNREACH, + 103: _Errno.ECONNABORTED, + 104: _Errno.ECONNRESET, + 110: _Errno.ETIMEOUT, + 111: _Errno.ECONNREFUSED, + 113: _Errno.EHOSTUNREACH, +}; + +const _winErrnoCodes = { + 9: _Errno.EBADF, + 106: _Errno.ECONNABORTED, + 107: _Errno.ECONNREFUSED, + 108: _Errno.ECONNRESET, + 110: _Errno.EHOSTUNREACH, + 118: _Errno.ENETUNREACH, + 138: _Errno.ETIMEOUT +}; + +const _macErrnoCodes = { + 9: _Errno.EBADF, + 51: _Errno.ENETUNREACH, + 53: _Errno.ECONNABORTED, + 54: _Errno.ECONNRESET, + 60: _Errno.ETIMEOUT, + 61: _Errno.ECONNREFUSED, + 65: _Errno.EHOSTUNREACH +}; + +const _androidErrnoCodes = { + 9: _Errno.EBADF, + 111: _Errno.ECONNREFUSED, + 113: _Errno.ECONNABORTED, + 114: _Errno.ENETUNREACH, + 116: _Errno.ETIMEOUT, + 118: _Errno.EHOSTUNREACH +}; diff --git a/pubnub/lib/src/networking/meta/diagnostics/stub.dart b/pubnub/lib/src/networking/meta/diagnostics/stub.dart new file mode 100644 index 00000000..dd8211f6 --- /dev/null +++ b/pubnub/lib/src/networking/meta/diagnostics/stub.dart @@ -0,0 +1,31 @@ +import 'package:pubnub/core.dart'; + +class HostIsDownDiagnostic extends Diagnostic { + final dynamic originalException; + + const HostIsDownDiagnostic(this.originalException); +} + +class HostLookupFailedDiagnostic extends Diagnostic { + final dynamic originalException; + + const HostLookupFailedDiagnostic(this.originalException); +} + +class UnknownHttpExceptionDiagnostic extends Diagnostic { + final dynamic originalException; + + const UnknownHttpExceptionDiagnostic(this.originalException); +} + +class TimeoutDiagnostic extends Diagnostic { + const TimeoutDiagnostic(); +} + +class AccessDeniedDiagnostic extends Diagnostic { + AccessDeniedDiagnostic(); +} + +Diagnostic? getNetworkDiagnostic(dynamic exception) { + throw UnimplementedError(); +} diff --git a/pubnub/lib/src/networking/meta/meta.dart b/pubnub/lib/src/networking/meta/meta.dart index dc904fee..76ae6745 100644 --- a/pubnub/lib/src/networking/meta/meta.dart +++ b/pubnub/lib/src/networking/meta/meta.dart @@ -1,32 +1,2 @@ -import 'package:pubnub/core.dart'; - -import 'diagnostics.dart'; - +export 'diagnostics/diagnostics.dart'; export 'strategy.dart'; - -Diagnostic? getNetworkDiagnostic(dynamic exception) { - if (exception is RequestOtherException) { - var otherException = exception.additionalData; - var message = otherException.toString(); - - return netDiagnosticsMap.entries.map((entry) { - return entry.key.hasMatch(message) - ? entry.value(entry.key.matchAsPrefix(message)) - : null; - }).firstWhere((element) => element != null, orElse: () => null); - } - - if (exception is RequestTimeoutException) { - return TimeoutDiagnostic(); - } - - if (exception is RequestFailureException) { - var request = exception.response; - - if (request.statusCode == 403) { - return AccessDeniedDiagnostic(); - } - } - - return null; -} diff --git a/pubnub/lib/src/networking/meta/strategy.dart b/pubnub/lib/src/networking/meta/strategy.dart index 79bed299..7ab67294 100644 --- a/pubnub/lib/src/networking/meta/strategy.dart +++ b/pubnub/lib/src/networking/meta/strategy.dart @@ -1,6 +1,6 @@ import 'package:pubnub/core.dart'; -import 'diagnostics.dart'; +import 'diagnostics/diagnostics.dart'; /// @nodoc class NetworkingStrategy extends Strategy { diff --git a/pubnub/lib/src/networking/request_handler/io.dart b/pubnub/lib/src/networking/request_handler/io.dart index 4915c86e..817fa4f7 100644 --- a/pubnub/lib/src/networking/request_handler/io.dart +++ b/pubnub/lib/src/networking/request_handler/io.dart @@ -48,36 +48,36 @@ class RequestHandler extends IRequestHandler { @override Future response(Request data) async { - _logger.info('($_id) Preparing request.'); + try { + _logger.info('($_id) Preparing request.'); - var headers = {...(data.headers ?? {})}; - var uri = prepareUri(_module.getOrigin(), data.uri ?? Uri()); - List? body; + var headers = {...(data.headers ?? {})}; + var uri = prepareUri(_module.getOrigin(), data.uri ?? Uri()); + List? body; - if (data.type == RequestType.file) { - var formData = FormData(); + if (data.type == RequestType.file) { + var formData = FormData(); - for (var entry in (data.body as Map).entries) { - if (entry.value is List) { - formData.addBytes(entry.key, entry.value); - } else { - formData.add(entry.key, entry.value); + for (var entry in (data.body as Map).entries) { + if (entry.value is List) { + formData.addBytes(entry.key, entry.value); + } else { + formData.add(entry.key, entry.value); + } } - } - headers['Content-Type'] = formData.contentType; - headers['Content-Length'] = formData.contentLength.toString(); - body = formData.body; - } else { - if (data.body != null) { - headers['Content-Type'] = 'application/json'; - body = utf8.encode(data.body.toString()); + headers['Content-Type'] = formData.contentType; + headers['Content-Length'] = formData.contentLength.toString(); + body = formData.body; + } else { + if (data.body != null) { + headers['Content-Type'] = 'application/json'; + body = utf8.encode(data.body.toString()); + } } - } - _logger.info('($_id) Starting request to "$uri"...'); + _logger.info('($_id) Starting request to "$uri"...'); - try { if (isCancelled) { throw await cancelReason; } diff --git a/pubnub/lib/src/subscribe/manager.dart b/pubnub/lib/src/subscribe/manager.dart index 5cb7d771..3bfa8cd0 100644 --- a/pubnub/lib/src/subscribe/manager.dart +++ b/pubnub/lib/src/subscribe/manager.dart @@ -72,4 +72,8 @@ class Manager { await subscription.cancel(); } } + + Future restore() async { + _loop.update((state) => state.clone(isErrored: false), skipCancel: false); + } } diff --git a/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop.dart b/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop.dart index 6b304709..970387b8 100644 --- a/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop.dart +++ b/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop.dart @@ -49,6 +49,8 @@ class SubscribeLoop { onCancel: () => update((state) => state.clone(isActive: false)), ); + _whenStartsController = StreamController.broadcast(); + var loopStream = _loop(); loopStream.listen((envelope) { @@ -64,8 +66,8 @@ class SubscribeLoop { late StreamController _messagesController; Stream get envelopes => _messagesController.stream; - Completer _whenStarts = Completer(); - Future get whenStarts => _whenStarts.future; + late StreamController _whenStartsController; + Future get whenStarts => _whenStartsController.stream.take(1).first; final StreamController _queueController = StreamController.broadcast(); @@ -74,7 +76,7 @@ class SubscribeLoop { var newState = callback(_state); _state = newState; - _logger.silly('State has been updated.'); + _logger.silly('State has been updated ($newState).'); if (skipCancel == false) { _queueController.add(CancelException()); @@ -106,9 +108,8 @@ class SubscribeLoop { channels: state.channels, channelGroups: state.channelGroups); - if (!_whenStarts.isCompleted && state.timetoken.value != BigInt.zero) { - _whenStarts.complete(); - _whenStarts = Completer(); + if (state.timetoken.value != BigInt.zero) { + _whenStartsController.add(null); } var response = @@ -139,6 +140,7 @@ class SubscribeLoop { } return Envelope.fromJson(object); }); + _logger.silly('Updating the state...'); tries = 0; @@ -165,10 +167,9 @@ class SubscribeLoop { if (diagnostic == null) { _logger.warning('No diagnostics found.'); - if (!_whenStarts.isCompleted) { - _whenStarts.completeError(Exception('subscribe failed')); - } - rethrow; + update((state) => state.clone(isErrored: true)); + yield* Stream.error(exception); + continue; } _logger.silly('Possible reason found: $diagnostic'); @@ -177,12 +178,17 @@ class SubscribeLoop { if (resolutions == null) { _logger.silly('No resolutions found.'); - rethrow; + + update((state) => state.clone(isErrored: true)); + yield* Stream.error(exception); + continue; } for (var resolution in resolutions) { if (resolution is FailResolution) { - rethrow; + update((state) => state.clone(isErrored: true)); + yield* Stream.error(exception); + continue; } else if (resolution is DelayResolution) { await Future.delayed(resolution.delay); } else if (resolution is RetryResolution) { diff --git a/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop_state.dart b/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop_state.dart index 4dcde9a9..02c306a5 100644 --- a/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop_state.dart +++ b/pubnub/lib/src/subscribe/subscribe_loop/subscribe_loop_state.dart @@ -2,16 +2,17 @@ import 'package:pubnub/core.dart'; /// @nodoc class SubscribeLoopState { - Keyset keyset; + final Keyset keyset; - Timetoken timetoken; - int? region; - Timetoken? customTimetoken; + final Timetoken timetoken; + final int? region; + final Timetoken? customTimetoken; - bool isActive; + final bool isActive; + final bool isErrored; - Set channels; - Set channelGroups; + final Set channels; + final Set channelGroups; SubscribeLoopState(this.keyset, {Timetoken? timetoken, @@ -19,11 +20,14 @@ class SubscribeLoopState { this.channels = const {}, this.channelGroups = const {}, this.isActive = false, + this.isErrored = false, this.customTimetoken}) : timetoken = timetoken ?? Timetoken(BigInt.zero); bool get shouldRun => - isActive && (channels.isNotEmpty || channelGroups.isNotEmpty); + isActive && + !isErrored && + (channels.isNotEmpty || channelGroups.isNotEmpty); SubscribeLoopState clone( {Timetoken? timetoken, @@ -31,21 +35,26 @@ class SubscribeLoopState { Set? channels, Set? channelGroups, bool? isActive, + bool? isErrored, Timetoken? customTimetoken}) => - SubscribeLoopState(keyset) - ..timetoken = timetoken ?? this.timetoken - ..region = region ?? this.region - ..channels = channels ?? this.channels - ..channelGroups = channelGroups ?? this.channelGroups - ..isActive = isActive ?? this.isActive - ..customTimetoken = timetoken == null + SubscribeLoopState( + keyset, + timetoken: timetoken ?? this.timetoken, + region: region ?? this.region, + channels: channels ?? this.channels, + channelGroups: channelGroups ?? this.channelGroups, + isActive: isActive ?? this.isActive, + isErrored: isErrored ?? this.isErrored, + customTimetoken: timetoken == null ? customTimetoken ?? this.customTimetoken - : customTimetoken; + : customTimetoken, + ); @override bool operator ==(Object other) { if (other is SubscribeLoopState) { return isActive == other.isActive && + isErrored == other.isErrored && timetoken.value == other.timetoken.value && region == other.region && channels.containsAll(other.channels) && @@ -56,4 +65,9 @@ class SubscribeLoopState { return false; } + + @override + String toString() { + return '${isActive ? 1 : 0}${isErrored ? 1 : 0}$region $timetoken $customTimetoken $channels $channelGroups'; + } } diff --git a/pubnub/lib/src/subscribe/subscription.dart b/pubnub/lib/src/subscribe/subscription.dart index eddf8936..0760446a 100644 --- a/pubnub/lib/src/subscribe/subscription.dart +++ b/pubnub/lib/src/subscribe/subscription.dart @@ -186,4 +186,9 @@ class Subscription { /// Alias for [pause]. void unsubscribe() => pause(); + + /// Restores the subscription and its shared, underlying subscribe loop after an exception. + Future restore() async { + await _manager.restore(); + } } diff --git a/pubnub/pubspec.yaml b/pubnub/pubspec.yaml index 3b45b231..aad4a780 100644 --- a/pubnub/pubspec.yaml +++ b/pubnub/pubspec.yaml @@ -1,6 +1,6 @@ name: pubnub description: PubNub SDK v5 for Dart lang (with Flutter support) that allows you to create real-time applications -version: 4.0.0-beta.0 +version: 4.0.0 homepage: https://www.pubnub.com/docs environment: diff --git a/pubnub/test/unit/dx/file_test.dart b/pubnub/test/unit/dx/file_test.dart index ab138fc6..8ba8c09f 100644 --- a/pubnub/test/unit/dx/file_test.dart +++ b/pubnub/test/unit/dx/file_test.dart @@ -5,9 +5,6 @@ import 'package:test/test.dart'; import 'package:pubnub/pubnub.dart'; import 'package:pubnub/core.dart'; -import 'package:pubnub/src/dx/files/files.dart'; -import 'package:pubnub/src/dx/_endpoints/files.dart'; - import '../net/fake_net.dart'; part 'fixtures/files.dart'; @@ -27,167 +24,6 @@ void main() { ); }); - test('#listFiles', () async { - when( - path: - 'v1/files/test/channels/channel/files?limit=10&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test', - method: 'GET', - ).then(status: 200, body: _listFilesSuccessResponse); - - var result = await pubnub.files.listFiles('channel', limit: 10); - expect(result, isA()); - expect(result.filesDetail, isA>()); - expect(result.next, isA()); - expect(result.count, equals(100)); - }); - - test('#publishFileMessage success', () async { - when( - path: _publishFileMessageUrl1, - method: 'GET', - ).then(status: 200, body: _publishFileMessageSuccessResponse); - var message = - FileMessage(FileInfo('some', 'cat_file.jpg'), message: 'msg'); - var result = await pubnub.files.publishFileMessage('channel', message); - expect(result, isA()); - }); - - test('#publishFileMessage withEncryption', () async { - when( - path: _publishFileMessageUrlEncryption, - method: 'GET', - ).then(status: 200, body: _publishFileMessageSuccessResponse); - var message = - FileMessage(FileInfo('some', 'cat_file.jpg'), message: 'msg'); - var result = await pubnub.files.publishFileMessage('channel', message, - cipherKey: CipherKey.fromUtf8('cipherKey')); - expect(result, isA()); - }); - - test('#publishFileMessage withEncryption defaultKeyset', () async { - pubnub = PubNub( - networking: FakeNetworkingModule(), - defaultKeyset: Keyset( - subscribeKey: 'test', - publishKey: 'test', - cipherKey: CipherKey.fromUtf8('cipherKey'), - uuid: UUID('test')), - crypto: CryptoModule( - defaultConfiguration: - CryptoConfiguration(useRandomInitializationVector: false), - )); - when( - path: _publishFileMessageUrlEncryption, - method: 'GET', - ).then(status: 200, body: _publishFileMessageSuccessResponse); - var message = - FileMessage(FileInfo('some', 'cat_file.jpg'), message: 'msg'); - var result = await pubnub.files.publishFileMessage('channel', message); - expect(result, isA()); - }); - - test('#publishFileMessage cipherKey precedence', () async { - pubnub = PubNub( - networking: FakeNetworkingModule(), - crypto: CryptoModule( - defaultConfiguration: - CryptoConfiguration(useRandomInitializationVector: false), - ), - defaultKeyset: Keyset( - subscribeKey: 'test', - publishKey: 'test', - cipherKey: CipherKey.fromUtf8('default_cipherKey'), - uuid: UUID('test'))); - when( - path: _publishFileMessageUrlEncryption, - method: 'GET', - ).then(status: 200, body: _publishFileMessageSuccessResponse); - var message = - FileMessage(FileInfo('some', 'cat_file.jpg'), message: 'msg'); - var result = await pubnub.files.publishFileMessage('channel', message, - cipherKey: CipherKey.fromUtf8('cipherKey')); - expect(result, isA()); - }); - - test('#publishFileMessage failure', () async { - when( - path: _publishFileMessageUrl1, - method: 'GET', - ).then(status: 200, body: _publishFileMessageFailureResponse); - var message = - FileMessage(FileInfo('some', 'cat_file.jpg'), message: 'msg'); - var result = await pubnub.files.publishFileMessage('channel', message); - expect(result, isA()); - expect(result.isError, equals(true)); - }); - - test('#DeleteFile', () async { - when( - path: - 'v1/files/test/channels/channel/files/5a3eb38c-483a-4b25-ac01-c4e20deba6d6/cat_file.jpg?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test', - method: 'DELETE', - ).then(status: 200, body: _deleteFileResponse); - - var result = await pubnub.files.deleteFile( - 'channel', '5a3eb38c-483a-4b25-ac01-c4e20deba6d6', 'cat_file.jpg'); - expect(result, isA()); - }); - test('#SendFile', () async { - when( - path: _generateFileUploadUrl, - method: 'POST', - body: '{"name":"cat_file.jpg"}') - .then(status: 200, body: _generateFileUploadUrlResponse); - - when( - path: 'https://pubnub-test-config.s3.amazonaws.com', - method: 'POST', - body: _sendFileResponse) - .then(status: 204, body: ''); - - when( - path: _publishFileMessageUrl2, - method: 'GET', - ).then(status: 200, body: _publishFileMessageSuccessResponse); - - var result = await pubnub.files.sendFile( - 'channel', 'cat_file.jpg', [0, 1, 2, 3], - fileMessage: 'msg', keyset: keyset); - expect(result, isA()); - }); - - test('#SendFile #FileMessagePublish retry', () async { - var keyset = - Keyset(subscribeKey: 'test', publishKey: 'test', uuid: UUID('test')); - when( - path: _generateFileUploadUrl, - method: 'POST', - body: '{"name":"cat_file.jpg"}') - .then(status: 200, body: _generateFileUploadUrlResponse); - when( - path: 'https://pubnub-test-config.s3.amazonaws.com', - method: 'POST', - body: _sendFileResponse) - .then(status: 204, body: ''); - when( - path: _publishFileMessageUrl2, - method: 'GET', - ).then(status: 400, body: _publishFileMessageFailureResponse); - var result = await pubnub.files.sendFile( - 'channel', 'cat_file.jpg', [0, 1, 2, 3], - fileMessage: 'msg', keyset: keyset); - expect(result, isA()); - expect(result.fileInfo, isNotNull); - }); - - test('#Download File', () async { - when(path: _downloadFileUrl, method: 'GET') - .then(status: 200, body: [01, 02]); - var result = await pubnub.files.downloadFile( - 'channel', '5a3eb38c-483a-4b25-ac01-c4e20deba6d6', 'cat_file.jpg'); - - expect(result, isA()); - }); test('#getFileUrl', () { var result = pubnub.files.getFileUrl('channel', 'fileId', 'fileName'); expect(result, isA()); diff --git a/pubnub/test/unit/dx/fixtures/files.dart b/pubnub/test/unit/dx/fixtures/files.dart index 83c9ce36..1845adec 100644 --- a/pubnub/test/unit/dx/fixtures/files.dart +++ b/pubnub/test/unit/dx/fixtures/files.dart @@ -1,109 +1,4 @@ part of '../file_test.dart'; -final _listFilesSuccessResponse = '''{ - "status": 200, - "data": [ - { - "name": "test_file.jpg", - "id": "5a3eb38c-483a-4b25-ac01-c4e20deba6d6", - "size": 203923, - "created": "2020-04-22T22:48:31Z" - } - ], - "next": "lnlngwonowgong", - "count": 100 -}'''; -final _publishFileMessageSuccessResponse = '[1, "Sent", "1"]'; - -final _publishFileMessageFailureResponse = '[0, "Invalid subscribe key", "1"]'; - -final _deleteFileResponse = ''' -{ - "status": 200 -}'''; - -final _generateFileUploadUrlResponse = ''' -{ - "status": 200, - "data": { - "id": "5a3eb38c-483a-4b25-ac01-c4e20deba6d6", - "name": "cat_file.jpg" - }, - "file_upload_request": { - "url": "https://pubnub-test-config.s3.amazonaws.com", - "method": "POST", - "expiration_date": "2020-04-03T22:44:47Z", - "form_fields": [ - { - "key": "tagging", - "value": "ObjectTTL1000" - }, - { - "key": "key", - "value": "file-upload/5a3eb38c-483a-4b25-ac01-c4e20deba6d6/test_image.jpg" - }, - { - "key": "Content-Type", - "value": "binary/octet-stream" - }, - { - "key": "X-Amz-Credential", - "value": "xxx/20200403/us-west-2/s3/aws4_request" - }, - { - "key": "X-Amz-Security-Token", - "value": "lgnwegn2mg202j4g0g2mg04g02gj2" - }, - { - "key": "X-Amz-Algorithm", - "value": "AWS4-HMAC-SHA256" - }, - { - "key": "X-Amz-Date", - "value": "20200403T212950Z" - }, - { - "key": "Policy", - "value": "CnsgImV4cGlyYXRpb24iOiAiMjAyMC0wNC0wM1QyMToy..." - }, - { - "key": "X-Amz-Signature", - "value": "1fbaad6738c6cd4c7eec2afe4cb2553a1e9cd2be690fdc2ecdc6e26f60a3781a" - } - ] - } -} -'''; - -final _sendFileResponse = ''' -{ - "tagging": "ObjectTTL1000", - "key": "file-upload/5a3eb38c-483a-4b25-ac01-c4e20deba6d6/test_image.jpg", - "Content-Type": "binary/octet-stream", - "X-Amz-Credential": "xxx/20200403/us-west-2/s3/aws4_request", - "X-Amz-Security-Token": "lgnwegn2mg202j4g0g2mg04g02gj2", - "X-Amz-Algorithm": "AWS4-HMAC-SHA256", - "X-Amz-Date": "20200403T212950Z", - "Policy": "CnsgImV4cGlyYXRpb24iOiAiMjAyMC0wNC0wM1QyMToy...", - "X-Amz-Signature": "1fbaad6738c6cd4c7eec2afe4cb2553a1e9cd2be690fdc2ecdc6e26f60a3781a", - "file": [0, 1, 2, 3] -} -'''; - -final _publishFileMessageUrl1 = - 'v1/files/publish-file/test/test/0/channel/0/%7B%22message%22:%22msg%22,%22file%22:%7B%22id%22:%22some%22,%22name%22:%22cat_file.jpg%22%7D%7D?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test'; - -final _publishFileMessageUrlEncryption = - 'v1/files/publish-file/test/test/0/channel/0/%22X3LuZh36Z3vi4HFJSxdqD7XN%2FTsyUiPBmDfVaRipvaYs8wQE6OOloLTjGSTnZXIb0knFDIr8jPniWrnUYtdoTQ==%22?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test'; - -final _publishFileMessageUrl2 = - 'v1/files/publish-file/test/test/0/channel/0/%7B%22message%22:%22msg%22,%22file%22:%7B%22id%22:%225a3eb38c-483a-4b25-ac01-c4e20deba6d6%22,%22name%22:%22cat_file.jpg%22,%22url%22:%22https:%2F%2Fps.pndsn.com%2Fv1%2Ffiles%2Ftest%2Fchannels%2Fchannel%2Ffiles%2F5a3eb38c-483a-4b25-ac01-c4e20deba6d6%2Fcat_file.jpg%3Fpnsdk=PubNub-Dart%252F1.4.2%22%7D%7D?pnsdk=PubNub-Dart%2F${PubNub.version}'; - -final _generateFileUploadUrl = - 'v1/files/test/channels/channel/generate-upload-url?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test'; - -final _downloadFileUrl = - 'https://ps.pndsn.com/v1/files/test/channels/channel/files/5a3eb38c-483a-4b25-ac01-c4e20deba6d6/cat_file.jpg?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test'; - final _getFileUrl = 'https://ps.pndsn.com/v1/files/test/channels/channel/files/fileId/fileName?pnsdk=PubNub-Dart%2F${PubNub.version}'; diff --git a/pubnub/test/unit/dx/fixtures/history.dart b/pubnub/test/unit/dx/fixtures/history.dart deleted file mode 100644 index 7c1967a9..00000000 --- a/pubnub/test/unit/dx/fixtures/history.dart +++ /dev/null @@ -1,158 +0,0 @@ -part of '../history_test.dart'; - -final _batchFetchMessagesSuccessResponse = '''{ - "error":false, - "status":200, - "error_message":"", - "channels":{"test-1":[{"message": 42, "timetoken": "1231231231231", "uuid": "test-uuid" }], "test-2": [{"message": 10, "timetoken": "1231231231231", "uuid": "test-uuid" }]} -}'''; - -final _batchCountMessagesSuccessResponse = '''{ - "error": false, - "status": 200, - "error_message": "", - "channels": {"test-1": 42, "test-2": 10} -}'''; - -final _batchFetchMessagesWithActionSuccessResponse = '''{ - "status": 200, - "error": false, - "error_message": "", - "channels": { - "demo-channel": [ - { - "message": "Hi", - "timetoken": "15610547826970040", - "uuid": "test-uuid", - "actions": { - "receipt": { - "read": [ - { - "uuid": "user-7", - "actionTimetoken": 15610547826970044 - } - ] - } - } - }, - { - "message": "Hello", - "timetoken": "15610547826970000", - "uuid": "test-uuid", - "actions": { - "reaction": { - "smiley_face": [ - { - "uuid": "user-456", - "actionTimetoken": 15610547826970050 - } - ], - "poop_pile": [ - { - "uuid": "user-789", - "actionTimetoken": 15610547826980050 - }, - { - "uuid": "user-567", - "actionTimetoken": 15610547826970000 - } - ] - } - } - } - ] - } -}'''; - -final _batchFetchMessagesWithActionsWithMore = '''{ - "status": 200, - "error": false, - "error_message": "", - "channels": { - "demo-channel": [ - { - "message": "Hi", - "timetoken": "15610547826970040", - "uuid": "test-uuid", - "actions": { - "receipt": { - "read": [ - { - "uuid": "user-7", - "actionTimetoken": 15610547826970044 - } - ] - } - } - }, - { - "message": "Hello", - "timetoken": "15610547826970000", - "uuid": "test-uuid", - "actions": { - "reaction": { - "smiley_face": [ - { - "uuid": "user-456", - "actionTimetoken": 15610547826970050 - } - ], - "poop_pile": [ - { - "uuid": "user-789", - "actionTimetoken": 15610547826980050 - }, - { - "uuid": "user-567", - "actionTimetoken": 15610547826970000 - } - ] - } - } - } - ] - }, - "more": { - "url": "/v1/history-with-actions/s/channel/c?start=15610547826970000&max=98", - "start": "15610547826970000", - "max": 98 - } -} -'''; - -final _batchFetchMessagesWithMetaSuccessResponse = '''{ - "status": 200, - "error": false, - "error_message": "", - "channels": { - "my_channel": [ - { - "message_type": null, - "message": "hello world", - "timetoken": "16048329933709932", - "meta": { - "hello": "world" - }, - "uuid": "test-uuid" - } - ] - } -} -'''; -final _batchFetchMessagesWithMetaEmptyString = '''{ - "status": 200, - "error": false, - "error_message": "", - "channels": { - "my_channel": [ - { - "message_type": null, - "message": "hello world", - "timetoken": "16048329933709932", - "meta": "", - "uuid": "test-uuid" - } - ] - } -} -'''; diff --git a/pubnub/test/unit/dx/fixtures/message_action.dart b/pubnub/test/unit/dx/fixtures/message_action.dart deleted file mode 100644 index 438e3e1e..00000000 --- a/pubnub/test/unit/dx/fixtures/message_action.dart +++ /dev/null @@ -1,102 +0,0 @@ -part of '../message_action_test.dart'; - -final _addMessageActionResponse = ''' -{ - "status": 200, - "data": { - "type": "reaction", - "value": "smiley_face", - "actionTimetoken": "15610547826970050", - "messageTimetoken": "15610547826969050", - "uuid": "terryterry69420" - } -}'''; - -final _addMessageActionBody = '{"type":"reaction","value":"smiley_face"}'; - -final _fetchMessageActionsResponse = ''' -{ - "status": 200, - "data": [ - { - "type": "reaction", - "value": "smiley_face", - "actionTimetoken": "15610547826970050", - "messageTimetoken": "15610547826969050", - "uuid": "terryterry69420" - } - ] -}'''; - -final _fetchMessageActionsResponseWithMoreField = ''' -{ - "status": 200, - "data": [ - { - "type": "reaction", - "value": "smiley_face", - "actionTimetoken": "15610547826970050", - "messageTimetoken": "15610547826969050", - "uuid": "terryterry69420" - } - ], - "more": { - "url": "v1/message-actions/test/channel/test?start=15610547826970050&end=15645905639093361&limit=2", - "start": "15610547826970050", - "end": "15645905639093361", - "limit": 2 - } -} -'''; - -final _deleteMessageActionResponse = ''' -{ - "status": 200, - "data": {} -}'''; - -final _failedToPublishErrorResponse = '''{ - "status": 207, - "data": { - "type": "reaction", - "value": "smiley_face", - "uuid": "user-456", - "actionTimetoken": 15610547826970050, - "messageTimetoken": 15610547826969050 - }, - "error": { - "message": "Stored but failed to publish message action.", - "source": "actions" - } -}'''; - -final _invalidParameterErrorResponse = '''{ - "status": 400, - "error": { - "source": "actions", - "message": "Request payload contained invalid input.", - "details": [ - { - "message": "Missing field", - "location": "value", - "locationType": "body" - } - ] - } -}'''; - -final _unauthorizeErrorResponse = '''{ - "status": 403, - "error": { - "source": "actions", - "message": "Supplied authorization key does not have the permissions required to perform this operation." - } -}'''; - -final _fetchMessageActionError = '''{ - "status": 400, - "error": { - "source": "actions", - "message": "Invalid Subkey" - } -}'''; diff --git a/pubnub/test/unit/dx/fixtures/pam.dart b/pubnub/test/unit/dx/fixtures/pam.dart deleted file mode 100644 index fbfde2eb..00000000 --- a/pubnub/test/unit/dx/fixtures/pam.dart +++ /dev/null @@ -1,93 +0,0 @@ -part of '../pam_test.dart'; - -final _grantRequest = MockRequest('GET', - 'v2/auth/grant/sub-key/test?pnsdk=PubNub-Dart%2F${PubNub.version}&auth=authKey&channel=my_channel&ttl=1440&uuid=test&m=0&r=1&w=0×tamp=1234567890&signature=v2.b03n4VbdzmcaTQ7my7n53FHx51G1JZRwzd16WKEUS2s'); - -final _grantWithUUIDRequest = MockRequest('GET', - 'v2/auth/grant/sub-key/test?pnsdk=PubNub-Dart%2F${PubNub.version}&auth=authKey&target-uuid=uuid1&ttl=1440&uuid=test&m=0&r=1&w=0×tamp=1234567890&signature=v2.lViScuTbVX_HUoA8zeR5vZuGswS5Tn9IaaBmOawow7o'); - -final _grantSuccessResponse = - MockResponse(statusCode: 200, headers: {}, body: ''' -{ - "status": 200, - "message": "Success", - "payload": { - "ttl": 1440, - "auths": { - "password": { - "r": 1, - "w": 0, - "m": 0, - "d": 0 - } - }, - "subscribe_key": "{subscribe-key}", - "level": "user", - "channel": "my_channel" - }, - "service": "Access Manager" -} -'''); - -final _grantWithUUIDSuccessResponse = - MockResponse(statusCode: 200, headers: {}, body: ''' -{ - "status":200, - "message":"Success", - "payload":{ - "uuids":{ - "uuid1":{ - "auths":{ - "myAuthKey":{ - "d":0, - "g":1, - "j":0, - "m":0, - "r":0, - "u":1, - "w":0 - } - } - } - }, - "subscribe_key":"mySubKey", - "ttl":300, - "level":"uuid" - }, - "service":"Access Manager" -} -'''); - -final _grantTokenRequest = MockRequest( - 'POST', - 'v3/pam/test/grant?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=test×tamp=1234567890&signature=v2.6idWWLsaFHCqICaw2eAXAXjlZokGe2x-heqmhYEp5Dg', - {}, - '{"ttl":1440,"permissions":{"resources":{"channels":{"inbox-jay":3},"groups":{},"uuids":{}},"patterns":{"channels":{},"groups":{},"uuids":{}},"meta":{"user-id":"jay@example.com","contains-unicode":"The 來 test."}}}'); - -final _grantTokenSuccessResponse = - MockResponse(statusCode: 200, headers: {}, body: '''{ - "status": 200, - "data": { - "message": "Success", - "token": "p0F2AkF0Gl6ZkldDdHRsGQWgQ3Jlc6REY2hhbqFpaW5ib3gtamF5A0NncnCgQ3VzcqBDc3BjoENwYXSkRGNoYW6gQ2dycKBDdXNyoENzcGOgRG1ldGGiZ3VzZXItaWRvamF5QGV4YW1wbGUuY29tcGNvbnRhaW5zLXVuaWNvZGVtVGhlIOS-hiB0ZXN0LkNzaWdYID3ahuVZSAmm-P4eR2KPay9KqahygKQbB9Uldx0LW2em" - }, - "service": "Access Manager" -}'''); - -final _grantTokenFailureResponse = - MockResponse(statusCode: 400, headers: {}, body: ''' -{ - "status": 400, - "error": { - "message": "Invalid ttl", - "source": "authz", - "details": [ - { - "message": "Valid range is 1 minute to 30 days.", - "location": "ttl", - "locationType": "body" - } - ] - }, - "service": "Access Manager" -}'''); diff --git a/pubnub/test/unit/dx/fixtures/signal.dart b/pubnub/test/unit/dx/fixtures/signal.dart deleted file mode 100644 index 7dd6a66e..00000000 --- a/pubnub/test/unit/dx/fixtures/signal.dart +++ /dev/null @@ -1,3 +0,0 @@ -part of '../signal_test.dart'; - -final _signalSuccessResponse = '[1, "Sent", "1"]'; diff --git a/pubnub/test/unit/dx/history_test.dart b/pubnub/test/unit/dx/history_test.dart deleted file mode 100644 index e37e98ec..00000000 --- a/pubnub/test/unit/dx/history_test.dart +++ /dev/null @@ -1,160 +0,0 @@ -import 'package:test/test.dart'; - -import 'package:pubnub/pubnub.dart'; -import 'package:pubnub/core.dart'; -import 'package:pubnub/src/dx/_endpoints/history.dart'; - -import '../net/fake_net.dart'; -part './fixtures/history.dart'; - -void main() { - late PubNub pubnub; - group('DX [history]', () { - setUp(() { - pubnub = PubNub( - defaultKeyset: Keyset( - subscribeKey: 'test', publishKey: 'test', uuid: UUID('test')), - networking: FakeNetworkingModule()); - }); - - test('.batch#fetchMessages correctly fetches messages', () async { - when( - path: - 'v3/history/sub-key/test/channel/test-1,test-2?max=10&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _batchFetchMessagesSuccessResponse); - - var result = - await pubnub.batch.fetchMessages({'test-1', 'test-2'}, count: 10); - - expect(result.channels['test-1'], isA>()); - expect(result.channels['test-1']!.length, equals(1)); - expect(result.channels['test-1']![0].message, equals(42)); - expect(result.channels['test-1']![0].uuid, equals('test-uuid')); - expect(result.channels['test-2'], isA>()); - expect(result.channels['test-2']!.length, equals(1)); - expect(result.channels['test-2']![0].message, equals(10)); - expect(result.channels['test-2']![0].uuid, equals('test-uuid')); - }); - - test('.batch#countMessages correctly fetches counts when passed in Set', - () async { - when( - method: 'GET', - path: - 'v3/history/sub-key/test/message-counts/test-1,test-2?timetoken=100&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - ).then(status: 200, body: _batchCountMessagesSuccessResponse); - - var result = await pubnub.batch.countMessages({'test-1', 'test-2'}, - timetoken: Timetoken(BigInt.from(100))); - - expect(result.channels['test-1'], equals(42)); - expect(result.channels['test-2'], equals(10)); - }); - - test('.batch#fetchMessagesWith Message Actions for multiple channels', - () async { - when( - path: - 'v3/history-with-actions/sub-key/test/channel/demo-channel?max=10&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _batchFetchMessagesWithActionsWithMore); - - expect( - pubnub.batch.fetchMessages({'demo-channel', 'channel_2'}, - includeMessageActions: true, count: 10), - throwsA(TypeMatcher())); - }); - test('.batch#fetchMessages with messageActions', () async { - when( - path: - 'v3/history-with-actions/sub-key/test/channel/demo-channel?max=10&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _batchFetchMessagesWithActionSuccessResponse); - - var result = await pubnub.batch.fetchMessages({'demo-channel'}, - includeMessageActions: true, count: 10); - - expect(result.channels['demo-channel'], - isA>()); - expect(result.channels['demo-channel']![0].actions, - isA>()); - expect(result.channels['demo-channel']![0].actions!['receipt']['read'], - isA()); - expect(result.channels['demo-channel']![0].timetoken, - equals(Timetoken(BigInt.from(15610547826970040)))); - }); - - test('.batch#fetchMessages with more messages', () async { - when( - path: - 'v3/history-with-actions/sub-key/test/channel/demo-channel?max=10&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _batchFetchMessagesWithActionsWithMore); - - var result = await pubnub.batch.fetchMessages({'demo-channel'}, - includeMessageActions: true, count: 10); - - expect(result.channels['demo-channel'], - isA>()); - expect(result.channels['demo-channel']!.length, equals(2)); - expect(result.channels['demo-channel']![1].actions!['reaction'].length, - equals(2)); - expect( - result.more!.url, - equals( - '/v1/history-with-actions/s/channel/c?start=15610547826970000&max=98')); - expect(result.more!.start, equals('15610547826970000')); - expect(result.more!.count, equals(98)); - }); - test('.batch#fetchMessages default count for single channel', () async { - when( - path: - '/v3/history/sub-key/test/channel/my_channel?max=100&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET') - .then(status: 200, body: _batchFetchMessagesSuccessResponse); - await pubnub.batch.fetchMessages({'my_channel'}); - }); - test('.batch#fetchMessages default count for multiple channel', () async { - when( - path: - '/v3/history/sub-key/test/channel/ch1,ch2?max=25&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET') - .then(status: 200, body: _batchFetchMessagesSuccessResponse); - await pubnub.batch.fetchMessages({'ch1', 'ch2'}); - }); - - test('.batch#fetchMessages with actions default count', () async { - when( - path: - '/v3/history-with-actions/sub-key/test/channel/ch1?max=25&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET') - .then( - status: 200, body: _batchFetchMessagesWithActionSuccessResponse); - await pubnub.batch.fetchMessages({'ch1'}, includeMessageActions: true); - }); - test('.batch#fetchMessages with include_meta', () async { - when( - path: - '/v3/history/sub-key/test/channel/my_channel?max=100&include_meta=true&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET') - .then(status: 200, body: _batchFetchMessagesWithMetaSuccessResponse); - var result = - await pubnub.batch.fetchMessages({'my_channel'}, includeMeta: true); - - expect(result.channels['my_channel']![0].meta!['hello'], equals('world')); - }); - - test('.batch#fetchMessages with include_meta and null meta value', - () async { - when( - path: - '/v3/history/sub-key/test/channel/my_channel?max=100&include_meta=true&include_message_type=true&include_uuid=true&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET') - .then(status: 200, body: _batchFetchMessagesWithMetaEmptyString); - var result = - await pubnub.batch.fetchMessages({'my_channel'}, includeMeta: true); - expect(result.channels['my_channel']![0].meta, equals(null)); - }); - }); -} diff --git a/pubnub/test/unit/dx/message_action_test.dart b/pubnub/test/unit/dx/message_action_test.dart index d808fc21..59eb524b 100644 --- a/pubnub/test/unit/dx/message_action_test.dart +++ b/pubnub/test/unit/dx/message_action_test.dart @@ -4,10 +4,8 @@ import 'package:pubnub/pubnub.dart'; import 'package:pubnub/core.dart'; import 'package:pubnub/src/dx/_utils/utils.dart'; -import 'package:pubnub/src/dx/_endpoints/message_action.dart'; import '../net/fake_net.dart'; -part './fixtures/message_action.dart'; void main() { late PubNub pubnub; @@ -63,97 +61,11 @@ void main() { throwsA(TypeMatcher())); }); - test('add message action should give valid response type', () async { - var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); - var actionValue = 'smiley_face'; - var actionType = 'reaction'; - when( - method: 'POST', - path: - 'v1/message-actions/test/channel/test/message/15610547826970050?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - body: _addMessageActionBody, - ).then(status: 200, body: _addMessageActionResponse); - expect( - await pubnub.addMessageAction( - type: actionType, - value: actionValue, - channel: 'test', - timetoken: messageTimetoken), - isA()); - }); - - test('add message action failed to publish response', () async { - var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); - var actionValue = 'smiley_face'; - var actionType = 'reaction'; - when( - method: 'POST', - path: - 'v1/message-actions/test/channel/test/message/15610547826970050?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - body: _addMessageActionBody, - ).then(status: 207, body: _failedToPublishErrorResponse); - - expect( - pubnub.addMessageAction( - type: actionType, - value: actionValue, - channel: 'test', - timetoken: messageTimetoken), - throwsA(TypeMatcher())); - }); - - test('add message action invalid parameter response (400)', () async { - var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); - var actionValue = 'smiley_face'; - var actionType = 'reaction'; - when( - method: 'POST', - path: - 'v1/message-actions/test/channel/test/message/15610547826970050?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - body: _addMessageActionBody, - ).then(status: 400, body: _invalidParameterErrorResponse); - expect( - pubnub.addMessageAction( - type: actionType, - value: actionValue, - channel: 'test', - timetoken: messageTimetoken), - throwsA(TypeMatcher())); - }); - test('add message action invalid parameter response (403)', () async { - var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); - var actionValue = 'smiley_face'; - var actionType = 'reaction'; - when( - method: 'POST', - path: - 'v1/message-actions/test/channel/test/message/15610547826970050?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - body: _addMessageActionBody, - ).then(status: 403, body: _unauthorizeErrorResponse); - expect( - pubnub.addMessageAction( - type: actionType, - value: actionValue, - channel: 'test', - timetoken: messageTimetoken), - throwsA(TypeMatcher())); - }); - test('fetch message action throws when channel is empty', () async { expect(pubnub.fetchMessageActions(''), throwsA(TypeMatcher())); }); - test('fetch message action returns valid response', () async { - when( - method: 'GET', - path: - 'v1/message-actions/test/channel/test?pnsdk=PubNub-Dart%2F${PubNub.version}&limit=100&uuid=test-uuid') - .then(status: 200, body: _fetchMessageActionsResponse); - - expect(await pubnub.fetchMessageActions('test'), - isA()); - }); test('fetch message actions throws if there is no available keyset', () async { pubnub.keysets.remove('default'); @@ -162,28 +74,6 @@ void main() { throwsA(TypeMatcher())); }); - test('fetch message action returns valid response with multiple page', - () async { - when( - method: 'GET', - path: - 'v1/message-actions/test/channel/test?pnsdk=PubNub-Dart%2F${PubNub.version}&limit=100&uuid=test-uuid', - ).then(status: 200, body: _fetchMessageActionsResponseWithMoreField); - var response = await pubnub.fetchMessageActions('test'); - expect(response.actions.length, 1); - expect(response.moreActions, isA()); - }); - - test('fetch message action returns Error', () async { - when( - method: 'GET', - path: - 'v1/message-actions/test/channel/test?pnsdk=PubNub-Dart%2F${PubNub.version}', - ).then(status: 400, body: _fetchMessageActionError); - - expect(pubnub.fetchMessageActions('test'), throwsA(anything)); - }); - test('delete message action throws when channel is empty', () async { var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); var channel = ''; @@ -208,39 +98,5 @@ void main() { actionTimetoken: actionTimetoken), throwsA(TypeMatcher())); }); - - test('delete message action returns valid response', () async { - var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); - var channel = 'test'; - var actionTimetoken = Timetoken(BigInt.from(15645905639093361)); - - when( - method: 'DELETE', - path: - 'v1/message-actions/test/channel/test/message/15610547826970050/action/15645905639093361?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - ).then(status: 200, body: _deleteMessageActionResponse); - - expect( - await pubnub.deleteMessageAction(channel, - messageTimetoken: messageTimetoken, - actionTimetoken: actionTimetoken), - isA()); - }); - - test('delete message action returns error response', () async { - var messageTimetoken = Timetoken(BigInt.from(15610547826970050)); - var channel = 'test'; - var actionTimetoken = Timetoken(BigInt.from(15645905639093361)); - when( - method: 'DELETE', - path: - 'v1/message-actions/test/channel/test/message/15610547826970050/action/15645905639093361?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - ).then(status: 403, body: _unauthorizeErrorResponse); - expect( - pubnub.deleteMessageAction(channel, - messageTimetoken: messageTimetoken, - actionTimetoken: actionTimetoken), - throwsA(TypeMatcher())); - }); }); } diff --git a/pubnub/test/unit/dx/objects/channel_metadata_test.dart b/pubnub/test/unit/dx/objects/channel_metadata_test.dart deleted file mode 100644 index 1619e422..00000000 --- a/pubnub/test/unit/dx/objects/channel_metadata_test.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:test/test.dart'; - -import 'package:pubnub/pubnub.dart'; -import 'package:pubnub/core.dart'; - -import '../../net/fake_net.dart'; -part 'fixtures/channel_metadata.dart'; - -void main() { - late PubNub pubnub; - group('DX [objectMetadata] [channel]', () { - setUp(() { - pubnub = PubNub( - defaultKeyset: Keyset( - subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('uuid-1')), - networking: FakeNetworkingModule()); - }); - - test('#getAllChannelMetadata()', () async { - when( - path: - 'v2/objects/demo/channels?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _getAllMetadataSuccessResponse); - var response = await pubnub.objects.getAllChannelMetadata(limit: 10); - expect(response, isA()); - expect(response.metadataList![0].id, 'my-channel'); - }); - - test('#getChannelMetadata()', () async { - when( - path: - 'v2/objects/demo/channels/my-channel?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _getMetadataSuccessResponse); - var response = await pubnub.objects.getChannelMetadata('my-channel'); - expect(response, isA()); - expect(response.metadata.id, 'my-channel'); - }); - - test('#setChannelMetadata()', () async { - var channelMetadataInput = ChannelMetadataInput( - name: 'My channel', description: 'A channel that is mine'); - when( - path: - 'v2/objects/demo/channels/my-channel?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _setChannelMetadataBody, - ).then(status: 200, body: _setChannelMetadataSuccessResponse); - var response = await pubnub.objects - .setChannelMetadata('my-channel', channelMetadataInput); - expect(response, isA()); - expect(response.metadata.id, 'my-channel'); - }); - test('#removeChannelMetadata()', () async { - when( - path: - 'v2/objects/demo/channels/my-channel?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'DELETE', - ).then(status: 200, body: _removeMetadataSuccessResponse); - var response = await pubnub.objects.removeChannelMetadata('my-channel'); - expect(response, isA()); - }); - }); -} diff --git a/pubnub/test/unit/dx/objects/fixtures/channel_metadata.dart b/pubnub/test/unit/dx/objects/fixtures/channel_metadata.dart deleted file mode 100644 index 9abdbd18..00000000 --- a/pubnub/test/unit/dx/objects/fixtures/channel_metadata.dart +++ /dev/null @@ -1,63 +0,0 @@ -part of '../channel_metadata_test.dart'; - -final _getAllMetadataSuccessResponse = '''{ - "status": 200, - "data": [ - { - "id": "my-channel", - "name": "My channel", - "description": "A channel that is mine", - "custom": null, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" - }, - { - "id": "main", - "name": "Main channel", - "description": "The main channel", - "custom": { - "public": true, - "motd": "Always check your spelling!" - }, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" - } - ], - "totalCount": 9, - "next": "MUIwQTAwMUItQkRBRC00NDkyLTgyMEMtODg2OUU1N0REMTNBCg==", - "prev": "M0FFODRENzMtNjY2Qy00RUExLTk4QzktNkY1Q0I2MUJFNDRCCg==" -} -'''; - -final _getMetadataSuccessResponse = '''{ - "status": 200, - "data": { - "id": "my-channel", - "name": "My channel", - "description": "A channel that is mine", - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" - } -} -'''; - -final _setChannelMetadataBody = - '{"name":"My channel","description":"A channel that is mine","custom":null}'; - -final _setChannelMetadataSuccessResponse = '''{ - "status": 200, - "data": { - "id": "my-channel", - "name": "My channel", - "description": "A channel that is mine", - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" - } -} -'''; - -final _removeMetadataSuccessResponse = '''{ - "status": 0, - "data": {} -} -'''; diff --git a/pubnub/test/unit/dx/objects/fixtures/membership_metadata.dart b/pubnub/test/unit/dx/objects/fixtures/membership_metadata.dart deleted file mode 100644 index 614a6ad6..00000000 --- a/pubnub/test/unit/dx/objects/fixtures/membership_metadata.dart +++ /dev/null @@ -1,98 +0,0 @@ -part of '../membership_metadata_test.dart'; - -final _membershipsMetadataSuccessResponse = '''{ - "status": 200, - "data": [ - { - "channel": { - "id": "my-channel", - "name": "My channel", - "description": "A channel that is mine", - "custom": null, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" - }, - "custom": { - "starred": false - }, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RUNDMDUwNjktNUYwRC00RTI0LUI1M0QtNUUzNkE2NkU0MEVFCg==" - }, - { - "channel": { - "id": "main", - "name": "Main channel", - "description": "The main channel", - "custom": { - "public": true, - "motd": "Always check your spelling!" - }, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" - }, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "RUNDMDUwNjktNUYwRC00RTI0LUI1M0QtNUUzNkE2NkU0MEVFCg==" - } - ], - "totalCount": 7, - "next": "RDIwQUIwM0MtNUM2Ni00ODQ5LUFGRjMtNDk1MzNDQzE3MUVCCg==", - "prev": "MzY5RjkzQUQtNTM0NS00QjM0LUI0M0MtNjNBQUFGODQ5MTk2Cg==" -}'''; -final _manageMemershipMetadataBody = - '{"set":[{"channel":{"id":"my-channel"},"custom":{"starred":false}}],"delete":[{"channel":{"id":"channel-1"}}]}'; - -final _setMemershipsMetadataBody = - '{"set":[{"channel":{"id":"my-channel"},"custom":{"starred":false}}]}'; - -final _removeMemershipsMetadataBody = - '{"delete":[{"channel":{"id":"channel-1"}}]}'; - -final _membersMetadataSuccessResponse = '''{ - "status": 200, - "data": [ - { - "uuid": { - "id": "uuid-1", - "name": "John Doe", - "externalId": null, - "profileUrl": null, - "email": "jack@twitter.com", - "custom": null, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg==" - }, - "custom": { - "role": "admin" - }, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" - }, - { - "uuid": { - "id": "uuid-2", - "name": "Bob Cat", - "externalId": null, - "profileUrl": null, - "email": "bobc@example.com", - "custom": { - "phone": "999-999-9999" - }, - "updated": "2019-02-21T03:29:00.173452", - "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" - }, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" - } - ], - "totalCount": 37, - "next": "RDIwQUIwM0MtNUM2Ni00ODQ5LUFGRjMtNDk1MzNDQzE3MUVCCg==", - "prev": "MzY5RjkzQUQtNTM0NS00QjM0LUI0M0MtNjNBQUFGODQ5MTk2Cg==" -}'''; - -final _manageMemersMetadataBody = - '{"set":[{"uuid":{"id":"uuid-1"},"custom":{"role":"admin"}}],"delete":[{"uuid":{"id":"uuid-1"}}]}'; - -final _setMembersMetadataBody = - '{"set":[{"uuid":{"id":"uuid-1"},"custom":{"role":"admin"}}]}'; - -final _removeMembersMetadataBody = '{"delete":[{"uuid":{"id":"uuid-2"}}]}'; diff --git a/pubnub/test/unit/dx/objects/fixtures/uuid_metadata.dart b/pubnub/test/unit/dx/objects/fixtures/uuid_metadata.dart deleted file mode 100644 index 918db508..00000000 --- a/pubnub/test/unit/dx/objects/fixtures/uuid_metadata.dart +++ /dev/null @@ -1,67 +0,0 @@ -part of '../uuid_metadata_test.dart'; - -final _getAllMetadataSuccessResponse = '''{ - "status": 200, - "data": [ - { - "id": "uuid-1", - "name": "John Doe", - "externalId": null, - "profileUrl": null, - "email": "jack@twitter.com", - "custom": null, - "updated": "2019-02-20T23:11:20.893755", - "eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg==" - }, - { - "id": "uuid-2", - "name": "Bob Cat", - "externalId": null, - "profileUrl": null, - "email": "bobc@example.com", - "custom": { - "phone": "999-999-9999" - }, - "updated": "2019-02-21T03:29:00.173452", - "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" - } - ] -} -'''; - -final _getMetadataSuccessResponse = '''{ - "status": 200, - "data": { - "id": "uuid-1", - "name": "John Doe", - "externalId": null, - "profileUrl": null, - "email": "jack@twitter.com", - "updated": "2019-02-20T23:11:20.893755", - "eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg==" - } -} -'''; - -final _setUuidMetadataBody = - '{"name":"John Doe","email":"jack@twitter.com","custom":null,"externalId":null,"profileUrl":null}'; - -final _setUuidMetadataSuccessResponse = '''{ - "status": 200, - "data": { - "id": "uuid-1", - "name": "John Doe", - "externalId": null, - "profileUrl": null, - "email": "jack@twitter.com", - "updated": "2019-02-20T23:11:20.893755", - "eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg==" - } -} -'''; - -final _removeMetadataSuccessResponse = '''{ - "status": 0, - "data": {} -} -'''; diff --git a/pubnub/test/unit/dx/objects/membership_metadata_test.dart b/pubnub/test/unit/dx/objects/membership_metadata_test.dart deleted file mode 100644 index b9854364..00000000 --- a/pubnub/test/unit/dx/objects/membership_metadata_test.dart +++ /dev/null @@ -1,129 +0,0 @@ -import 'package:test/test.dart'; - -import 'package:pubnub/pubnub.dart'; -import 'package:pubnub/core.dart'; - -import '../../net/fake_net.dart'; -part 'fixtures/membership_metadata.dart'; - -void main() { - late PubNub pubnub; - group('DX [objects] [membership]', () { - setUp(() { - pubnub = PubNub( - defaultKeyset: Keyset( - subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('uuid-1')), - networking: FakeNetworkingModule()); - }); - - test('#getMemberships()', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-2/channels?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _membershipsMetadataSuccessResponse); - var response = - await pubnub.objects.getMemberships(uuid: 'uuid-2', limit: 10); - expect(response, isA()); - expect(response.metadataList![0].channel.id, 'my-channel'); - }); - - test('#manageMemberships()', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-1/channels?count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _manageMemershipMetadataBody) - .then(status: 200, body: _membershipsMetadataSuccessResponse); - var setDataInput = [ - MembershipMetadataInput('my-channel', custom: {'starred': false}) - ]; - var response = - await pubnub.objects.manageMemberships(setDataInput, {'channel-1'}); - expect(response, isA()); - expect(response.metadataList![0].channel.id, 'my-channel'); - }); - - test('#setMemberships()', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-1/channels?count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _setMemershipsMetadataBody) - .then(status: 200, body: _membershipsMetadataSuccessResponse); - var setDataInput = [ - MembershipMetadataInput('my-channel', custom: {'starred': false}) - ]; - var response = await pubnub.objects.setMemberships(setDataInput); - expect(response, isA()); - expect(response.metadataList![0].channel.id, 'my-channel'); - }); - test('#removeMemberships()', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-1/channels?count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _removeMemershipsMetadataBody) - .then(status: 200, body: _membershipsMetadataSuccessResponse); - var response = await pubnub.objects.removeMemberships({'channel-1'}); - expect(response, isA()); - expect(response.metadataList![0].channel.id, 'my-channel'); - }); - - test('#getChannelMembers()', () async { - when( - path: - 'v2/objects/demo/channels/my-channel/uuids?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _membersMetadataSuccessResponse); - var response = - await pubnub.objects.getChannelMembers('my-channel', limit: 10); - expect(response, isA()); - expect(response.metadataList![0].uuid.id, 'uuid-1'); - }); - - test('#manageChannelMembers()', () async { - when( - path: - 'v2/objects/demo/channels/my-channel/uuids?count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _manageMemersMetadataBody) - .then(status: 200, body: _membersMetadataSuccessResponse); - var setDataInput = [ - ChannelMemberMetadataInput('uuid-1', custom: {'role': 'admin'}) - ]; - var response = await pubnub.objects - .manageChannelMembers('my-channel', setDataInput, {'uuid-1'}); - expect(response, isA()); - expect(response.metadataList![0].uuid.id, 'uuid-1'); - }); - - test('#setMembersMetadata()', () async { - when( - path: - 'v2/objects/demo/channels/my-channel/uuids?count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _setMembersMetadataBody, - ).then(status: 200, body: _membersMetadataSuccessResponse); - var setDataInput = [ - ChannelMemberMetadataInput('uuid-1', custom: {'role': 'admin'}) - ]; - var response = - await pubnub.objects.setChannelMembers('my-channel', setDataInput); - expect(response, isA()); - expect(response.metadataList![0].uuid.id, 'uuid-1'); - }); - test('#removeChannelMembers()', () async { - when( - path: - 'v2/objects/demo/channels/my-channel/uuids?count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _removeMembersMetadataBody) - .then(status: 200, body: _membersMetadataSuccessResponse); - var response = - await pubnub.objects.removeChannelMembers('my-channel', {'uuid-2'}); - expect(response, isA()); - expect(response.metadataList![0].uuid.id, 'uuid-1'); - }); - }); -} diff --git a/pubnub/test/unit/dx/objects/uuid_metadata_test.dart b/pubnub/test/unit/dx/objects/uuid_metadata_test.dart deleted file mode 100644 index 7af9b608..00000000 --- a/pubnub/test/unit/dx/objects/uuid_metadata_test.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:test/test.dart'; - -import 'package:pubnub/pubnub.dart'; -import 'package:pubnub/core.dart'; - -import '../../net/fake_net.dart'; -part 'fixtures/uuid_metadata.dart'; - -void main() { - late PubNub pubnub; - group('DX [objects] [uuid]', () { - setUp(() { - pubnub = PubNub( - defaultKeyset: Keyset( - subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('uuid-1')), - networking: FakeNetworkingModule()); - }); - test('#getAllUUIDMetadata()', () async { - when( - path: - 'v2/objects/demo/uuids?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _getAllMetadataSuccessResponse); - var response = await pubnub.objects.getAllUUIDMetadata(limit: 10); - expect(response, isA()); - expect(response.metadataList![0].id, 'uuid-1'); - }); - test('#getUUIDMetadata()', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-1?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _getMetadataSuccessResponse); - var response = await pubnub.objects.getUUIDMetadata(); - expect(response, isA()); - expect(response.metadata!.id, 'uuid-1'); - }); - test('#getUUIDMetadata() with explicitly provided uuid', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-2?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'GET', - ).then(status: 200, body: _getMetadataSuccessResponse); - var response = await pubnub.objects.getUUIDMetadata(uuid: 'uuid-2'); - expect(response, isA()); - expect(response.metadata!.id, 'uuid-1'); - }); - test('#setUUIDMetadata()', () async { - var uuidMetadataInput = - UuidMetadataInput(name: 'John Doe', email: 'jack@twitter.com'); - when( - path: - 'v2/objects/demo/uuids/uuid-1?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _setUuidMetadataBody, - ).then(status: 200, body: _setUuidMetadataSuccessResponse); - var response = await pubnub.objects.setUUIDMetadata(uuidMetadataInput); - expect(response, isA()); - expect(response.metadata.id, 'uuid-1'); - }); - test('#setUUIDMetadata() with explicitly provided uuid', () async { - var uuidMetadataInput = - UuidMetadataInput(name: 'John Doe', email: 'jack@twitter.com'); - when( - path: - 'v2/objects/demo/uuids/uuid-2?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'PATCH', - body: _setUuidMetadataBody, - ).then(status: 200, body: _setUuidMetadataSuccessResponse); - var response = await pubnub.objects - .setUUIDMetadata(uuidMetadataInput, uuid: 'uuid-2'); - expect(response, isA()); - expect(response.metadata.id, 'uuid-1'); - }); - test('#removeUUIDMetadata()', () async { - when( - path: - 'v2/objects/demo/uuids/uuid-1?pnsdk=PubNub-Dart%2F${PubNub.version}&uuid=uuid-1', - method: 'DELETE', - ).then(status: 200, body: _removeMetadataSuccessResponse); - var response = await pubnub.objects.removeUUIDMetadata(); - expect(response, isA()); - }); - }); -} diff --git a/pubnub/test/unit/dx/pam_test.dart b/pubnub/test/unit/dx/pam_test.dart index f1de70d8..fa87a982 100644 --- a/pubnub/test/unit/dx/pam_test.dart +++ b/pubnub/test/unit/dx/pam_test.dart @@ -3,12 +3,9 @@ import 'package:test/test.dart'; import 'package:pubnub/core.dart'; import 'package:pubnub/src/default.dart'; import 'package:pubnub/src/dx/_utils/utils.dart'; -import 'package:pubnub/src/dx/pam/pam.dart'; import '../net/fake_net.dart'; -part './fixtures/pam.dart'; - void main() { late PubNub pubnub; group('DX [PAM]', () { @@ -53,36 +50,6 @@ void main() { channelGroups: {'cg1'}, uuids: {'uuid1'}), throwsA(TypeMatcher())); }); - test('grant should return valid result', () async { - when(request: _grantRequest, method: '', path: '') - .then(response: _grantSuccessResponse, status: 200); - - var response = await pubnub.grant( - {'authKey'}, - channels: {'my_channel'}, - read: true, - write: false, - manage: false, - ttl: 1440, - ); - expect(response.message, equals('Success')); - }); - - test('grant should return valid result with uuid Permission', () async { - when(request: _grantWithUUIDRequest, method: '', path: '') - .then(response: _grantWithUUIDSuccessResponse, status: 200); - - var response = await pubnub.grant( - {'authKey'}, - uuids: {'uuid1'}, - read: true, - write: false, - manage: false, - ttl: 1440, - ); - expect(response.message, equals('Success')); - expect(response.permissions.first.uuid, equals('uuid1')); - }); test('requestToken.send throws when resources are empty', () async { var request = pubnub.requestToken(ttl: 1440, meta: { @@ -91,31 +58,5 @@ void main() { }); expect(request.send(), throwsA(TypeMatcher())); }); - test('requestToken.send should return valid result', () async { - when(request: _grantTokenRequest, method: '', path: '') - .then(response: _grantTokenSuccessResponse, status: 200); - - var request = pubnub.requestToken(ttl: 1440, meta: { - 'user-id': 'jay@example.com', - 'contains-unicode': 'The 來 test.' - }) - ..add(ResourceType.channel, name: 'inbox-jay', read: true, write: true); - - var response = await request.send(); - - expect(response, isA()); - }); - - test('requestToken.send returns error response', () async { - when(request: _grantTokenRequest, method: '', path: '') - .then(response: _grantTokenFailureResponse, status: 400); - var request = pubnub.requestToken(ttl: 1440, meta: { - 'user-id': 'jay@example.com', - 'contains-unicode': 'The 來 test.' - }) - ..add(ResourceType.channel, name: 'inbox-jay', read: true, write: true); - - expect(request.send(), throwsA(TypeMatcher())); - }); }); } diff --git a/pubnub/test/unit/dx/publish_test.dart b/pubnub/test/unit/dx/publish_test.dart index 77072cf0..968d16af 100644 --- a/pubnub/test/unit/dx/publish_test.dart +++ b/pubnub/test/unit/dx/publish_test.dart @@ -27,40 +27,5 @@ void main() { expect( pubnub?.publish('test', 42), throwsA(TypeMatcher())); }); - - test('publish returns PublishResult with correct data', () async { - when( - path: - 'publish/demo/demo/0/test/0/%7B%22hello%22:%22world%22%7D?uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET') - .then(status: 200, body: _publishSuccessResponse); - - var response = await pubnub?.publish('test', {'hello': 'world'}); - - expect(response?.isError, equals(false)); - expect(response?.description, equals('Sent')); - }); - - test('publish throws an exception when non-200 status code', () async { - when( - path: - 'publish/demo/demo/0/test/0/%7B%22hello%22:%22world%22%7D?uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 400, body: _publishFailureResponse); - - expect(pubnub?.publish('test', {'hello': 'world'}), - throwsA(TypeMatcher())); - }); - - test('#publish with meta', () async { - when( - path: - 'publish/demo/demo/0/test/0/%7B%22hello%22:%22world%22%7D?meta=%7B%22hello%22%3A%22world%22%7D&uuid=test&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _publishSuccessResponse); - var response = await pubnub - ?.publish('test', {'hello': 'world'}, meta: {'hello': 'world'}); - expect(response?.description, equals('Sent')); - }); }); } diff --git a/pubnub/test/unit/dx/push_test.dart b/pubnub/test/unit/dx/push_test.dart index eab693a8..35ae0989 100644 --- a/pubnub/test/unit/dx/push_test.dart +++ b/pubnub/test/unit/dx/push_test.dart @@ -29,18 +29,6 @@ void main() { throwsA(TypeMatcher())); }); - test('listPushChannels returns valid response for non apns2 gateway', - () async { - var deviceId = 'A332C23D'; - when( - path: - 'v1/push/sub-key/test/devices/A332C23D?uuid=test&type=gcm&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '["ch1", "ch2"]'); - var response = await pubnub.listPushChannels(deviceId, PushGateway.gcm); - expect(response, isA()); - }); - test( 'listPushChannels throws when topic is not provided with apns2 gateway', () async { @@ -49,37 +37,6 @@ void main() { throwsA(TypeMatcher())); }); - test( - 'listPushChannels should return valid response for apns2 with default development env', - () async { - var deviceId = 'A332C23D'; - var topic = 'topic'; - when( - path: - 'v2/push/sub-key/test/devices-apns2/A332C23D?uuid=test&environment=development&topic=topic&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '["ch1", "ch2"]'); - var response = await pubnub.listPushChannels(deviceId, PushGateway.apns2, - topic: topic); - expect(response, isA()); - }); - - test( - 'listPushChannels should return valid response for apns2 with mentioned development env', - () async { - var deviceId = 'A332C23D'; - var topic = 'topic'; - when( - path: - 'v2/push/sub-key/test/devices-apns2/A332C23D?uuid=test&environment=production&topic=topic&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '["ch1", "ch2"]'); - var response = await pubnub.listPushChannels(deviceId, PushGateway.apns2, - topic: topic, environment: Environment.production); - expect(response, isA()); - expect(response.channels[0] as String, isNotNull); - }); - test('addPushChannels throws if no keyset found', () async { pubnub.keysets.remove('default'); var deviceId = 'A332C23D'; @@ -95,54 +52,12 @@ void main() { throwsA(TypeMatcher())); }); - test('addPushChannels returns valid response', () async { - var deviceId = 'A332C23D'; - var channels = {'ch1', 'ch2'}; - when( - path: - 'v1/push/sub-key/test/devices/A332C23D?add=ch1%2Cch2&uuid=test&type=gcm&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1, "ch1", "ch2"]'); - var response = - await pubnub.addPushChannels(deviceId, PushGateway.gcm, channels); - expect(response, isA()); - }); - - test( - 'addPushChannels with fcm type should give call to backend with gcm type value', - () async { - var deviceId = 'A332C23D'; - var channels = {'ch1', 'ch2'}; - when( - path: - 'v1/push/sub-key/test/devices/A332C23D?add=ch1%2Cch2&uuid=test&type=gcm&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1, "ch1", "ch2"]'); - var response = - await pubnub.addPushChannels(deviceId, PushGateway.fcm, channels); - expect(response, isA()); - }); - test('addPushChannels throws when topic null with apns2', () { var deviceId = 'A332C23D'; var channels = {'ch1', 'ch2'}; expect(pubnub.addPushChannels(deviceId, PushGateway.apns2, channels), throwsA(TypeMatcher())); }); - test('addPushChannels returns valid response with apns2', () async { - var deviceId = 'A332C23D'; - var channels = {'ch1', 'ch2'}; - var topic = 'topic'; - when( - path: - 'v2/push/sub-key/test/devices-apns2/A332C23D?add=ch1%2Cch2&uuid=test&environment=production&topic=topic&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1,"ch1,ch2"]'); - var response = await pubnub.addPushChannels( - deviceId, PushGateway.apns2, channels, - topic: topic, environment: Environment.production); - expect(response, isA()); - }); test('removePushChannels throws if no keyset found', () async { pubnub.keysets.remove('default'); @@ -159,39 +74,12 @@ void main() { throwsA(TypeMatcher())); }); - test('removePushChannels returns valid response', () async { - var deviceId = 'A332C23D'; - var channels = {'ch1', 'ch2'}; - when( - path: - 'v1/push/sub-key/test/devices/A332C23D?remove=ch1%2Cch2&uuid=test&type=gcm&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1, "ch1", "ch2"]'); - var response = - await pubnub.removePushChannels(deviceId, PushGateway.gcm, channels); - expect(response, isA()); - }); - test('removePushChannels throws when topic null with apns2', () { var deviceId = 'A332C23D'; var channels = {'ch1', 'ch2'}; expect(pubnub.removePushChannels(deviceId, PushGateway.apns2, channels), throwsA(TypeMatcher())); }); - test('removePushChannels returns valid response with apns2', () async { - var deviceId = 'A332C23D'; - var channels = {'ch1', 'ch2'}; - var topic = 'topic'; - when( - path: - 'v2/push/sub-key/test/devices-apns2/A332C23D?remove=ch1%2Cch2&uuid=test&environment=production&topic=topic&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1, "ch1", "ch2"]'); - var response = await pubnub.removePushChannels( - deviceId, PushGateway.apns2, channels, - topic: topic, environment: Environment.production); - expect(response, isA()); - }); test('removeDevice throws if no keyset found', () async { pubnub.keysets.remove('default'); @@ -206,34 +94,12 @@ void main() { throwsA(TypeMatcher())); }); - test('removeDevice returns valid response', () async { - var deviceId = 'A332C23D'; - when( - path: - 'v1/push/sub-key/test/devices/A332C23D/remove?uuid=test&type=gcm&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1, "Device Removed"]'); - var response = await pubnub.removeDevice(deviceId, PushGateway.gcm); - expect(response, isA()); - }); - test('removeDevice throws when topic is null with apns2', () { var deviceId = 'A332C23D'; expect(pubnub.removeDevice(deviceId, PushGateway.apns2), throwsA(TypeMatcher())); }); - test('removeDevice returns valid response with apns2', () async { - var deviceId = 'A332C23D'; - var topic = 'topic'; - when( - path: - 'v2/push/sub-key/test/devices-apns2/A332C23D/remove?uuid=test&environment=production&topic=topic&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[1, "Device Removed"]'); - var response = await pubnub.removeDevice(deviceId, PushGateway.apns2, - topic: topic, environment: Environment.production); - expect(response, isA()); - }); + test('device should return an instance of Device', () { var deviceId = 'A332C23D'; var device = pubnub.device(deviceId); diff --git a/pubnub/test/unit/dx/signal_test.dart b/pubnub/test/unit/dx/signal_test.dart deleted file mode 100644 index 99722583..00000000 --- a/pubnub/test/unit/dx/signal_test.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:test/test.dart'; - -import 'package:pubnub/pubnub.dart'; -import 'package:pubnub/core.dart'; - -import '../net/fake_net.dart'; -part './fixtures/signal.dart'; - -void main() { - late PubNub pubnub; - group('DX [signal]', () { - setUp(() { - pubnub = PubNub(networking: FakeNetworkingModule()) - ..keysets.add( - 'default', - Keyset( - subscribeKey: 'demo', - uuid: UUID('test-uuid'), - publishKey: 'demo'), - useAsDefault: true); - }); - - test('signal successfully returns SignalResult', () async { - when( - path: - 'signal/demo/demo/0/test/0/%7B%22typing%22:true%7D?uuid=test-uuid&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _signalSuccessResponse); - - var response = await pubnub.signal('test', {'typing': true}); - - expect(response.isError, equals(false)); - }); - }); -} diff --git a/pubnub/test/unit/dx/time_test.dart b/pubnub/test/unit/dx/time_test.dart deleted file mode 100644 index a689e40d..00000000 --- a/pubnub/test/unit/dx/time_test.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:test/test.dart'; - -import 'package:pubnub/pubnub.dart'; -import 'package:pubnub/core.dart'; - -import '../net/fake_net.dart'; - -void main() { - group('DX [time]', () { - late PubNub pubnub; - - test('time successfully returns TimeResult', () async { - pubnub = PubNub( - defaultKeyset: Keyset( - subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('test')), - networking: FakeNetworkingModule()); - - when( - path: 'time/0?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[123]'); - - var response = await pubnub.time(); - - expect(response, isA()); - expect(response.value, isA()); - }); - - test('time successfully returns TimeResult without any keyset', () async { - pubnub = PubNub(networking: FakeNetworkingModule()); - - when( - path: 'time/0?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: '[123]'); - - var response = await pubnub.time(); - - expect(response, isA()); - expect(response.value, isA()); - }); - }); -} diff --git a/pubnub/test/unit/dx/utils_test.dart b/pubnub/test/unit/dx/utils_test.dart index cb9f2d19..8d28d4cd 100644 --- a/pubnub/test/unit/dx/utils_test.dart +++ b/pubnub/test/unit/dx/utils_test.dart @@ -1,3 +1,4 @@ +import 'package:pubnub/pubnub.dart'; import 'package:test/test.dart'; import 'package:pubnub/core.dart'; import 'package:pubnub/src/dx/_utils/utils.dart'; @@ -25,6 +26,9 @@ void main() { }); group('computeV2Signature', () { test('computeV2Signature should return valid signature', () { + PubNub.version = '1.0.0'; + Core.version = '1.0.0'; + Time.mock(DateTime.fromMillisecondsSinceEpoch(1234567890000)); var keyset = Keyset( subscribeKey: 'test', publishKey: 'test', @@ -34,7 +38,7 @@ void main() { var queryParams = {'b': 'second', 'c': 'third', 'a': 'first'}; var path = ['test', 'test']; var body = 'test'; - var expectedSign = 'v2.6UBAX_8m4xezj6eTDrrxUkXMXOtXkolfIbzx1yCwpUY'; + var expectedSign = 'v2.GtlYbLJgz5DjClB2Z2o47BbJngI7uQ3E07HUnL1NN3Q'; var response = computeV2Signature(keyset, requestType, path, queryParams, body); diff --git a/pubnub/test/unit/net/fake_net.dart b/pubnub/test/unit/net/fake_net.dart index 424303a7..7422e95a 100644 --- a/pubnub/test/unit/net/fake_net.dart +++ b/pubnub/test/unit/net/fake_net.dart @@ -1,6 +1,6 @@ import 'dart:async'; import 'dart:convert'; - +import 'package:pool/pool.dart'; import 'package:pubnub/core.dart'; class MockException extends PubNubException { @@ -10,8 +10,9 @@ class MockException extends PubNubException { class FakeRequestHandler extends IRequestHandler { final FakeNetworkingModule module; final Mock mock; + final PoolResource resource; - FakeRequestHandler(this.module, this.mock); + FakeRequestHandler(this.module, this.mock, this.resource); @override Future response(Request request) { @@ -46,9 +47,12 @@ class FakeRequestHandler extends IRequestHandler { var doesUriMatch = expectedUri.toString() == actualUri.toString(); return Future.microtask(() { + resource.release(); + if (doesMethodMatch && doesBodyMatch && doesUriMatch) { if (![200, 204].contains(mock.response.statusCode)) { - throw RequestFailureException(mock.response); + throw RequestFailureException(mock.response, + statusCode: mock.response.statusCode); } else { return mock.response; } @@ -152,17 +156,22 @@ MockBuilder when({ } class FakeNetworkingModule implements INetworkingModule { + final Pool _pool = Pool(2); + FakeNetworkingModule() { _queue.clear(); } @override Future handler() async { + var resource = await _pool.request(); + if (_queue.isEmpty) { + resource.release(); throw MockException('set up the mock first'); } - return FakeRequestHandler(this, _queue.removeAt(0)); + return FakeRequestHandler(this, _queue.removeAt(0), resource); } @override