From b9a9d6814c5bec660b4e7a8b6875fee07e4e804c Mon Sep 17 00:00:00 2001 From: Client Date: Wed, 10 Jun 2020 15:41:31 +0000 Subject: [PATCH] PubNub SDK v1.2.0 release. --- .gitignore | 3 + .pubnub.yml | 48 +- CHANGELOG.md | 10 +- lib/pubnub.dart | 4 +- lib/src/core/core.dart | 2 +- lib/src/default.dart | 76 +- lib/src/dx/_endpoints/message_action.dart | 26 +- .../_endpoints/objects/channel_metadata.dart | 202 ++++ lib/src/dx/_endpoints/objects/membership.dart | 330 ------ .../objects/membership_metadata.dart | 293 ++++++ .../dx/_endpoints/objects/objects_types.dart | 34 +- lib/src/dx/_endpoints/objects/space.dart | 287 ------ lib/src/dx/_endpoints/objects/user.dart | 277 ----- .../dx/_endpoints/objects/uuid_metadata.dart | 199 ++++ lib/src/dx/_endpoints/push.dart | 4 +- lib/src/dx/_utils/default_result.dart | 29 +- lib/src/dx/objects/channel_metadata.dart | 143 +++ lib/src/dx/objects/membership.dart | 481 --------- lib/src/dx/objects/objects.dart | 961 +++++++++++++++++- lib/src/dx/objects/objects_types.dart | 8 + lib/src/dx/objects/schema.dart | 54 +- lib/src/dx/objects/space.dart | 245 ----- lib/src/dx/objects/user.dart | 204 ---- lib/src/dx/objects/uuid_metadata.dart | 104 ++ pubspec.yaml | 2 +- test/dx/objects/channel_metadata_test.dart | 65 ++ .../dx/objects/fixtures/channel_metadata.dart | 63 ++ test/dx/objects/fixtures/membership.dart | 34 - .../objects/fixtures/membership_metadata.dart | 98 ++ test/dx/objects/fixtures/space.dart | 53 - test/dx/objects/fixtures/user.dart | 52 - test/dx/objects/fixtures/uuid_metadata.dart | 67 ++ test/dx/objects/membership_metadata_test.dart | 129 +++ test/dx/objects/membership_test.dart | 248 ----- test/dx/objects/objects.dart | 7 - test/dx/objects/space_test.dart | 237 ----- test/dx/objects/user_test.dart | 240 ----- test/dx/objects/uuid_metadata_test.dart | 85 ++ test/dx/push_test.dart | 9 +- 39 files changed, 2569 insertions(+), 2844 deletions(-) create mode 100644 lib/src/dx/_endpoints/objects/channel_metadata.dart delete mode 100644 lib/src/dx/_endpoints/objects/membership.dart create mode 100644 lib/src/dx/_endpoints/objects/membership_metadata.dart delete mode 100644 lib/src/dx/_endpoints/objects/space.dart delete mode 100644 lib/src/dx/_endpoints/objects/user.dart create mode 100644 lib/src/dx/_endpoints/objects/uuid_metadata.dart create mode 100644 lib/src/dx/objects/channel_metadata.dart delete mode 100644 lib/src/dx/objects/membership.dart create mode 100644 lib/src/dx/objects/objects_types.dart delete mode 100644 lib/src/dx/objects/space.dart delete mode 100644 lib/src/dx/objects/user.dart create mode 100644 lib/src/dx/objects/uuid_metadata.dart create mode 100644 test/dx/objects/channel_metadata_test.dart create mode 100644 test/dx/objects/fixtures/channel_metadata.dart delete mode 100644 test/dx/objects/fixtures/membership.dart create mode 100644 test/dx/objects/fixtures/membership_metadata.dart delete mode 100644 test/dx/objects/fixtures/space.dart delete mode 100644 test/dx/objects/fixtures/user.dart create mode 100644 test/dx/objects/fixtures/uuid_metadata.dart create mode 100644 test/dx/objects/membership_metadata_test.dart delete mode 100644 test/dx/objects/membership_test.dart delete mode 100644 test/dx/objects/objects.dart delete mode 100644 test/dx/objects/space_test.dart delete mode 100644 test/dx/objects/user_test.dart create mode 100644 test/dx/objects/uuid_metadata_test.dart diff --git a/.gitignore b/.gitignore index 71029c79..54ddf335 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,6 @@ coverage_badge.svg deployment_keys deployment_keys-private deployment_keys.tar + +.travis/github-labels-policy.json +.travis/github-labels.json diff --git a/.pubnub.yml b/.pubnub.yml index 2f5f2d01..a1d8e508 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,5 +1,15 @@ --- changelog: + - + changes: + - + text: "Add simplified Objects API support with UUID and Channel metadata / membership management." + type: feature + - + text: "Fixes missing PushGateway type support of fcm for Push Notification." + type: bug + date: Jun 10, 20 + version: v1.2.0 - changes: - @@ -171,24 +181,24 @@ features: signal: - SIGNAL-SEND objects: - - OBJECTS-GET-USER - - OBJECTS-GET-USERS - - OBJECTS-CREATE-USER - - OBJECTS-UPDATE-USER - - OBJECTS-DELETE-USER - - OBJECTS-GET-SPACE - - OBJECTS-GET-SPACES - - OBJECTS-CREATE-SPACE - - OBJECTS-UPDATE-SPACE - - OBJECTS-DELETE-SPACE - - OBJECTS-GET-MEMBERSHIPS - - OBJECTS-JOIN-SPACES - - OBJECTS-UPDATE-MEMBERSHIPS - - OBJECTS-LEAVE-SPACES - - OBJECTS-GET-MEMBERS - - OBJECTS-ADD-MEMBERS - - OBJECTS-UPDATE-MEMBERS - - OBJECTS-REMOVE-MEMBERS + - OBJECTS-GET-ALL-UUID-METADATA + - OBJECTS-GET-UUID-METADATA + - OBJECTS-SET-UUID-METADATA + - OBJECTS-REMOVE-UUID-METADATA + - OBJECTS-GET-ALL-CHANNEL-METADATA + - OBJECTS-GET-CHANNEL-METADATA + - OBJECTS-SET-CHANNEL-METADATA + - OBJECTS-REMOVE-CHANNEL-METADATA + - OBJECTS-GET-MEMBERSHIPS-V2 + - OBJECTS-SET-MEMBERSHIPS-V2 + - OBJECTS-REMOVE-MEMBERSHIPS-V2 + - OBJECTS-GET-CHANNEL-MEMBERS-V2 + - OBJECTS-SET-CHANNEL-MEMBERS-V2 + - OBJECTS-REMOVE-CHANNEL-MEMBERS-V2 + - OBJECTS-MANAGE-MEMBERSHIPS-V2 + - OBJECTS-MANAGE-CHANNEL-MEMBERS-V2 + - OBJECTS-FILTERING + - OBJECTS-SORTING message-actions: - MESSAGE-ACTIONS-GET - MESSAGE-ACTIONS-ADD @@ -205,4 +215,4 @@ supported-platforms: platforms: - "Dart SDK >=2.6.0 <3.0.0" version: "PubNub Dart SDK" -version: "1.1.3" +version: "1.2.0" diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a13fcda..8dfee961 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,14 @@ +## [v1.2.0](https://github.com/pubnub/dart/releases/tag/v1.2.0) +June 10 2020 + +[Full Changelog](https://github.com/pubnub/dart/compare/v1.1.3...v1.2.0) + +- 🌟️ Add simplified Objects API support with UUID and Channel metadata / membership management. +- 🐛 Fixes missing PushGateway type support of fcm for Push Notification. + ## [v1.1.3](https://github.com/pubnub/dart/releases/tag/v1.1.3) May 11 2020 -[Full Changelog](https://github.com/pubnub/dart/compare/v1.1.2...v1.1.3) - - 🐛 Fixes unsubscribeAll so its no longer modifying subscription list during iteration. Fixed the following issues reported by [@pushpendraKh](https://github.com/pushpendraKh): [#6](https://github.com/pubnub/dart/issues/6). - 🐛 Fixes exports to include presence and channel group results. diff --git a/lib/pubnub.dart b/lib/pubnub.dart index a4112741..15adaea9 100644 --- a/lib/pubnub.dart +++ b/lib/pubnub.dart @@ -7,7 +7,7 @@ export './src/dx/_utils/ensure.dart' show InvariantException; export './src/dx/channel/channel.dart' show Channel; export './src/dx/channel/channel_group.dart' show ChannelGroup; - +export './src/dx/push/push.dart' show Device; export './src/dx/_endpoints/publish.dart' show PublishResult; export './src/dx/_endpoints/presence.dart' show HeartbeatResult, LeaveResult, HereNowResult, StateInfo; @@ -45,6 +45,8 @@ export './src/dx/_endpoints/objects/objects_types.dart'; export './src/dx/pam/pam.dart' show Resource, ResourceType, ResourceTypeExtension, TokenRequest, Token; +export './src/dx/objects/objects_types.dart'; + export './src/logging/logging.dart' show StreamLogger, LogRecord; export './src/default.dart'; diff --git a/lib/src/core/core.dart b/lib/src/core/core.dart index 48bcbb7b..db78d55f 100644 --- a/lib/src/core/core.dart +++ b/lib/src/core/core.dart @@ -20,7 +20,7 @@ class Core { NetworkModule networking; ParserModule parser; - static String version = '1.1.3'; + static String version = '1.2.0'; Core( {Keyset defaultKeyset, diff --git a/lib/src/default.dart b/lib/src/default.dart index cc007c17..2e89b708 100644 --- a/lib/src/default.dart +++ b/lib/src/default.dart @@ -15,11 +15,9 @@ import 'dx/channel/channel_group.dart'; import 'dx/message_action/message_action.dart'; import 'dx/pam/pam.dart'; import 'dx/push/push.dart'; -import 'dx/objects/schema.dart'; -import 'dx/objects/membership.dart'; -import 'dx/objects/space.dart'; -import 'dx/objects/user.dart'; import 'dx/presence/presence.dart'; +import 'dx/objects/objects_types.dart'; +import 'dx/objects/objects.dart'; /// PubNub library. /// @@ -55,15 +53,9 @@ class PubNub extends Core /// [ChannelGroupDx] contains methods that allow manipulating channel groups. ChannelGroupDx channelGroups; - /// [UserDx] contains methods that provide functionality to manage users. - UserDx users; - - /// [SpaceDx] contains methods that allow manipulating spaces. - SpaceDx spaces; - - /// [MembershipDx] contains methods that allow managing members of spaces and - /// their users' memberships. - MembershipDx memberships; + /// [ObjectsDx] contains methods to manage channel, uuid metadata and + /// UUID's membership and Channel's members + ObjectsDx objects; /// Current version of this library. static String version = Core.version; @@ -75,9 +67,7 @@ class PubNub extends Core parser: PubNubParserModule()) { batch = BatchDx(this); channelGroups = ChannelGroupDx(this); - users = UserDx(this); - spaces = SpaceDx(this); - memberships = MembershipDx(this); + objects = ObjectsDx(this); } /// Returns a representation of a channel. @@ -98,47 +88,55 @@ class PubNub extends Core return ChannelGroup(this, keyset, name); } - /// Creates and returns a new instance of [User] (from Objects API). - Future user(String userId, String name, - {String email, - dynamic custom, + /// Creates [UUIDMetadata], sets metadata for given `uuid` to the database + /// * If `uuid` argument is null then it picks `uuid` of `keyset` + /// Returned [UUIDMetadata] instance is further useful to manage it's membership metadata + Future uuidMetadata( + {String uuid, + String name, + String email, + Map custom, String externalId, String profileUrl, Keyset keyset, String using}) async { keyset ??= keysets.get(using, defaultIfNameIsNull: true); - - User usr; - var result = await users.create( - UserDetails(userId, name, + UUIDMetadata uuidMetadata; + var result = await objects.setUUIDMetadata( + UuidMetadataInput( + name: name, email: email, externalId: externalId, profileUrl: profileUrl, custom: custom), + uuid: uuid, keyset: keyset); - - var userObject = result.data; - if (result.status == 200) { - usr = User(this, keyset, userObject.id); + if (result.metadata != null) { + uuidMetadata = UUIDMetadata(this, keyset, result.metadata.id); } - return usr; + return uuidMetadata; } - /// Creates and returns a new instance of [Space] (from Objects API). - Future space(String spaceId, String name, - {String description, dynamic custom, Keyset keyset, String using}) async { + /// Creates and returns a new instance of [ChannelMetadata] (from Objects API). + Future channelMetadata(String channelId, + {String name, + String description, + Map custom, + Keyset keyset, + String using}) async { keyset ??= keysets.get(using, defaultIfNameIsNull: true); - Space space; - var result = await spaces.create( - SpaceDetails(spaceId, name, description: description, custom: custom), + ChannelMetadata channelMetadata; + var result = await objects.setChannelMetadata( + channelId, + ChannelMetadataInput( + name: name, description: description, custom: custom), keyset: keyset); - var spaceObject = result.data; - if (result.status == 200) { - space = Space(this, keyset, spaceObject.id); + if (result.metadata != null) { + channelMetadata = ChannelMetadata(this, keyset, result.metadata.id); } - return space; + return channelMetadata; } /// Returns a new instance of [Device] (from Push Notification API). diff --git a/lib/src/dx/_endpoints/message_action.dart b/lib/src/dx/_endpoints/message_action.dart index 0ab1c9e4..d2880a22 100644 --- a/lib/src/dx/_endpoints/message_action.dart +++ b/lib/src/dx/_endpoints/message_action.dart @@ -1,5 +1,4 @@ import 'package:pubnub/src/core/core.dart'; -import 'package:pubnub/src/dx/_utils/utils.dart'; class FetchMessageActionsParams extends Parameters { Keyset keyset; @@ -52,15 +51,13 @@ class FetchMessageActionsResult extends Result { FetchMessageActionsResult(); factory FetchMessageActionsResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); return FetchMessageActionsResult() - .._status = result.status as int - .._actions = (result.data as List) + .._status = object['status'] as int + .._actions = (object['data'] as List) ?.map((e) => e == null ? null : MessageAction.fromJson(e)) ?.toList() - .._moreActions = result.otherKeys['more'] != null - ? MoreAction.fromJson(result.otherKeys['more']) - : null + .._moreActions = + object['more'] != null ? MoreAction.fromJson(object['more']) : null .._error = object['error']; } } @@ -145,11 +142,11 @@ class AddMessageActionResult extends Result { AddMessageActionResult(); factory AddMessageActionResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); return AddMessageActionResult() - .._status = result.status - .._data = result.data != null ? MessageAction.fromJson(result.data) : null - .._error = result.error; + .._status = object['status'] + .._data = + object['data'] != null ? MessageAction.fromJson(object['data']) : null + .._error = object['error']; } } @@ -199,10 +196,9 @@ class DeleteMessageActionResult extends Result { DeleteMessageActionResult(); factory DeleteMessageActionResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); return DeleteMessageActionResult() - .._status = result.status as int - .._data = result.data - .._error = result.error; + .._status = object['status'] as int + .._data = object['data'] + .._error = object['error']; } } diff --git a/lib/src/dx/_endpoints/objects/channel_metadata.dart b/lib/src/dx/_endpoints/objects/channel_metadata.dart new file mode 100644 index 00000000..cf0d5316 --- /dev/null +++ b/lib/src/dx/_endpoints/objects/channel_metadata.dart @@ -0,0 +1,202 @@ +import 'package:pubnub/src/core/core.dart'; + +class GetAllChannelMetadataParams extends Parameters { + Keyset keyset; + Set include; + int limit; + String start; + String end; + bool includeCount; + String filter; + Set sort; + + GetAllChannelMetadataParams(this.keyset, + {this.limit, + this.include, + this.start, + this.end, + this.includeCount, + this.filter, + this.sort}); + + @override + Request toRequest() { + var pathSegments = ['v2', 'objects', keyset.subscribeKey, 'channels']; + + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (limit != null) 'limit': '$limit', + if (start != null) 'start': start, + if (end != null) 'end': end, + if (includeCount != null) 'count': '$includeCount', + if (filter != null && filter.isNotEmpty) 'filter': filter, + if (sort != null && sort.isNotEmpty) 'sort': sort.join(','), + if (keyset.authKey != null) 'auth': '${keyset.authKey}' + }; + return Request(RequestType.get, pathSegments, + queryParameters: queryParameters); + } +} + +class ChannelMetadataDetails { + String _id; + String _name; + String _description; + Map _custom; + String _updated; + String _eTag; + + String get id => _id; + String get name => _name; + String get description => _description; + Map get custom => _custom; + String get updated => _updated; + String get eTag => _eTag; + + ChannelMetadataDetails._(); + + factory ChannelMetadataDetails.fromJson(dynamic object) => + ChannelMetadataDetails._() + .._id = object['id'] as String + .._name = object['name'] as String + .._description = object['description'] as String + .._custom = object['custom'] as Map + .._updated = object['updated'] as String + .._eTag = object['eTag'] as String; +} + +class GetAllChannelMetadataResult extends Result { + List _metadataList; + int _totalCount; + String _next; + String _prev; + + List get metadataList => _metadataList; + int get totalCount => _totalCount; + String get next => _next; + String get prev => _prev; + + GetAllChannelMetadataResult(); + + factory GetAllChannelMetadataResult.fromJson(dynamic object) => + GetAllChannelMetadataResult() + .._metadataList = (object['data'] as List) + ?.map((e) => e == null ? null : ChannelMetadataDetails.fromJson(e)) + ?.toList() + .._totalCount = object['totalCount'] as int + .._next = object['next'] as String + .._prev = object['prev'] as String; +} + +class GetChannelMetadataParams extends Parameters { + Keyset keyset; + String channelId; + + Set include; + + GetChannelMetadataParams(this.keyset, this.channelId, {this.include}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'channels', + channelId, + ]; + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (keyset.authKey != null) 'auth': keyset.authKey + }; + + return Request(RequestType.get, pathSegments, + queryParameters: queryParameters); + } +} + +class GetChannelMetadataResult extends Result { + ChannelMetadataDetails _metadata; + ChannelMetadataDetails get metadata => _metadata; + + GetChannelMetadataResult._(); + + factory GetChannelMetadataResult.fromJson(dynamic object) => + GetChannelMetadataResult._() + .._metadata = ChannelMetadataDetails.fromJson(object['data']); +} + +class SetChannelMetadataParams extends Parameters { + Keyset keyset; + String channelId; + + Set include; + + String channelMetadata; + + SetChannelMetadataParams(this.keyset, this.channelId, this.channelMetadata, + {this.include}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'channels', + channelId + ]; + + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (keyset.authKey != null) 'auth': keyset.authKey, + }; + + return Request(RequestType.patch, pathSegments, + queryParameters: queryParameters.isNotEmpty ? queryParameters : null, + body: channelMetadata); + } +} + +class SetChannelMetadataResult extends Result { + ChannelMetadataDetails _metadata; + SetChannelMetadataResult._(); + + ChannelMetadataDetails get metadata => _metadata; + + factory SetChannelMetadataResult.fromJson(dynamic object) => + SetChannelMetadataResult._() + .._metadata = ChannelMetadataDetails.fromJson(object['data']); +} + +class RemoveChannelMetadataParams extends Parameters { + Keyset keyset; + String channelID; + + RemoveChannelMetadataParams(this.keyset, this.channelID); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'channels', + channelID + ]; + + var queryParameters = { + if (keyset.authKey != null) 'auth': keyset.authKey, + }; + + return Request(RequestType.delete, pathSegments, + queryParameters: queryParameters); + } +} + +class RemoveChannelMetadataResult extends Result { + RemoveChannelMetadataResult._(); + + factory RemoveChannelMetadataResult.fromJson(dynamic object) => + RemoveChannelMetadataResult._(); +} diff --git a/lib/src/dx/_endpoints/objects/membership.dart b/lib/src/dx/_endpoints/objects/membership.dart deleted file mode 100644 index 8f79c43c..00000000 --- a/lib/src/dx/_endpoints/objects/membership.dart +++ /dev/null @@ -1,330 +0,0 @@ -import 'package:pubnub/src/core/core.dart'; -import 'package:pubnub/src/dx/_utils/utils.dart'; -import 'space.dart'; -import 'user.dart'; - -class GetMembershipsParams extends Parameters { - Keyset keyset; - String userId; - - Set include; - int limit; - String start; - String end; - bool count; - String filter; - Set sort; - - GetMembershipsParams(this.keyset, this.userId, - {this.include, - this.limit, - this.start, - this.end, - this.count, - this.filter, - this.sort}); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'users', - userId, - 'spaces' - ]; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (limit != null) 'limit': limit.toString(), - if (start != null) 'start': start, - if (end != null) 'end': end, - if (keyset.authKey != null) 'auth': keyset.authKey, - if (count != null) 'count': count.toString(), - if (filter != null && filter != '') 'filter': filter, - if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') - }; - - return Request(RequestType.get, pathSegments, - queryParameters: queryParameters); - } -} - -class MembershipsResult extends Result { - int _status; - List _data; - int _totalCount; - String _next; - String _prev; - Map _error; - - int get status => _status; - List get data => _data ?? []; - int get totalCount => _totalCount; - String get next => _next; - String get prev => _prev; - Map get error => _error; - - MembershipsResult(); - - factory MembershipsResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return MembershipsResult() - .._status = result.status as int - .._data = (result.data as List) - ?.map((e) => e == null ? null : MembershipInfo.fromJson(e)) - ?.toList() - .._error = result.error - .._totalCount = result.otherKeys['totalCount'] as int - .._next = result.otherKeys['next'] as String - .._prev = result.otherKeys['prev'] as String; - } -} - -class MembershipInfo { - String _id; - dynamic _custom; - SpaceInfo _space; - String _created; - String _updated; - String _eTag; - - String get id => _id; - SpaceInfo get space => _space; - dynamic get custom => _custom; - String get created => _created; - String get updated => _updated; - String get eTag => _eTag; - - MembershipInfo(); - - factory MembershipInfo.fromJson(dynamic object) { - return MembershipInfo() - .._id = object['id'] as String - .._custom = object['custom'] - .._space = - object['space'] == null ? null : SpaceInfo.fromJson(object['space']) - .._created = object['created'] as String - .._updated = object['updated'] as String - .._eTag = object['eTag'] as String; - } -} - -class ManageMembershipsParams extends Parameters { - Keyset keyset; - String userId; - - Set include; - int limit; - String start; - String end; - bool count; - String filter; - Set sort; - - String membershipChanges; // Json String - - ManageMembershipsParams(this.keyset, this.userId, this.membershipChanges, - {this.include, - this.limit, - this.start, - this.end, - this.count, - this.filter, - this.sort}); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'users', - userId, - 'spaces' - ]; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (limit != null) 'limit': limit.toString(), - if (start != null) 'start': start, - if (end != null) 'end': end, - if (keyset.authKey != null) 'auth': keyset.authKey, - if (count != null) 'count': count.toString(), - if (filter != null && filter != '') 'filter': filter, - if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') - }; - - return Request( - RequestType.patch, - pathSegments, - queryParameters: queryParameters.isNotEmpty ? queryParameters : null, - body: membershipChanges, - ); - } -} - -class GetSpaceMembersParams extends Parameters { - Keyset keyset; - String spaceId; - - Set include; - int limit; - String start; - String end; - bool count; - String filter; - Set sort; - - GetSpaceMembersParams(this.keyset, this.spaceId, - {this.include, - this.limit, - this.start, - this.end, - this.count, - this.filter, - this.sort}); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'spaces', - spaceId, - 'users', - ]; - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (limit != null) 'limit': limit.toString(), - if (start != null) 'start': start, - if (end != null) 'end': end, - if (keyset.authKey != null) 'auth': keyset.authKey, - if (count != null) 'count': count.toString(), - if (filter != null && filter != '') 'filter': filter, - if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') - }; - - return Request( - RequestType.get, - pathSegments, - queryParameters: queryParameters, - ); - } -} - -class SpaceMembersResult extends Result { - int _status; - List _data; - int _totalCount; - String _next; - String _prev; - Map _error; - - int get status => _status; - List get data => _data ?? []; - int get totalCount => _totalCount; - String get next => _next; - String get prev => _prev; - Map get error => _error; - - SpaceMembersResult(); - - factory SpaceMembersResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return SpaceMembersResult() - .._status = result.status as int - .._data = (result.data as List) - ?.map((e) => e == null ? null : SpaceMemberInfo.fromJson(e)) - ?.toList() - .._error = result.error - .._totalCount = result.otherKeys['totalCount'] as int - .._next = result.otherKeys['next'] as String - .._prev = result.otherKeys['prev'] as String; - } -} - -class SpaceMemberInfo { - String _id; - dynamic _custom; - UserInfo _user; - String _created; - String _updated; - String _eTag; - - String get id => _id; - dynamic get custom => _custom; - UserInfo get user => _user; - String get created => _created; - String get updated => _updated; - String get eTag => _eTag; - - SpaceMemberInfo(); - - factory SpaceMemberInfo.fromJson(dynamic object) { - return SpaceMemberInfo() - .._id = object['id'] as String - .._custom = object['custom'] - .._user = - object['user'] == null ? null : UserInfo.fromJson(object['user']) - .._created = object['created'] as String - .._updated = object['updated'] as String - .._eTag = object['eTag'] as String; - } -} - -class ManageSpaceMembersParams extends Parameters { - Keyset keyset; - String spaceId; - - Set include; - int limit; - String start; - String end; - bool count; - String filter; - Set sort; - - String spaceMembersChanges; // Json String - - ManageSpaceMembersParams(this.keyset, this.spaceId, this.spaceMembersChanges, - {this.include, - this.limit, - this.start, - this.end, - this.count, - this.filter, - this.sort}); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'spaces', - spaceId, - 'users' - ]; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (limit != null) 'limit': limit.toString(), - if (start != null) 'start': start, - if (end != null) 'end': end, - if (keyset.authKey != null) 'auth': keyset.authKey, - if (count != null) 'count': count.toString(), - if (filter != null && filter != '') 'filter': filter, - if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') - }; - - return Request( - RequestType.patch, - pathSegments, - queryParameters: queryParameters.isNotEmpty ? queryParameters : null, - body: spaceMembersChanges, - ); - } -} diff --git a/lib/src/dx/_endpoints/objects/membership_metadata.dart b/lib/src/dx/_endpoints/objects/membership_metadata.dart new file mode 100644 index 00000000..475ee396 --- /dev/null +++ b/lib/src/dx/_endpoints/objects/membership_metadata.dart @@ -0,0 +1,293 @@ +import 'package:pubnub/src/core/core.dart'; + +import 'package:pubnub/src/dx/_endpoints/objects/channel_metadata.dart' + show ChannelMetadataDetails; +import 'package:pubnub/src/dx/_endpoints/objects/uuid_metadata.dart' + show UuidMetadataDetails; + +class GetMembershipsMetadataParams extends Parameters { + Keyset keyset; + String uuid; + int limit; + String start; + String end; + Set include; + bool includeCount; + String filter; + Set sort; + + GetMembershipsMetadataParams(this.keyset, + {this.uuid, + this.limit, + this.start, + this.end, + this.include, + this.includeCount, + this.filter, + this.sort}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'uuids', + uuid ?? '${keyset.uuid}', + 'channels' + ]; + + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (limit != null) 'limit': '$limit', + if (start != null) 'start': start, + if (end != null) 'end': end, + if (keyset.authKey != null) 'auth': keyset.authKey, + if (includeCount != null) 'count': '$includeCount', + if (filter != null && filter.isNotEmpty) 'filter': filter, + if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') + }; + + return Request(RequestType.get, pathSegments, + queryParameters: queryParameters); + } +} + +class MembershipMetadata { + ChannelMetadataDetails _channel; + dynamic _custom; + String _updated; + String _eTag; + + ChannelMetadataDetails get channel => _channel; + dynamic get custom => _custom; + String get updated => _updated; + String get eTag => _eTag; + + MembershipMetadata._(); + + factory MembershipMetadata.fromJson(dynamic object) => MembershipMetadata._() + .._channel = ChannelMetadataDetails.fromJson(object['channel']) + .._custom = object['custom'] + .._updated = object['updated'] as String + .._eTag = object['eTag'] as String; +} + +class MembershipsResult extends Result { + List _metadataList; + int _totalCount; + String _next; + String _prev; + + List get metadataList => _metadataList; + int get totalCount => _totalCount; + String get next => _next; + String get prev => _prev; + + MembershipsResult._(); + + factory MembershipsResult.fromJson(dynamic object) => MembershipsResult._() + .._metadataList = (object['data'] as List) + ?.map((e) => e == null ? null : MembershipMetadata.fromJson(e)) + ?.toList() + .._totalCount = object['totalCount'] as int + .._next = object['next'] as String + .._prev = object['prev'] as String; +} + +class ManageMembershipsParams extends Parameters { + Keyset keyset; + String uuid; + int limit; + String start; + String end; + Set include; + bool includeCount; + String filter; + Set sort; + + String membershipMetadata; + + ManageMembershipsParams(this.keyset, this.membershipMetadata, + {this.uuid, + this.limit, + this.start, + this.end, + this.include, + this.includeCount, + this.filter, + this.sort}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'uuids', + uuid ?? '${keyset.uuid}', + 'channels' + ]; + + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (limit != null) 'limit': '$limit', + if (start != null) 'start': start, + if (end != null) 'end': end, + if (keyset.authKey != null) 'auth': keyset.authKey, + if (includeCount != null) 'count': '$includeCount', + if (filter != null && filter.isNotEmpty) 'filter': filter, + if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') + }; + + return Request(RequestType.patch, pathSegments, + queryParameters: queryParameters, body: membershipMetadata); + } +} + +class GetChannelMembersParams extends Parameters { + Keyset keyset; + String channelId; + + int limit; + String start; + String end; + Set include; + bool includeCount; + String filter; + Set sort; + + GetChannelMembersParams(this.keyset, this.channelId, + {this.limit, + this.start, + this.end, + this.include, + this.includeCount, + this.filter, + this.sort}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'channels', + channelId, + 'uuids', + ]; + + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (limit != null) 'limit': '$limit', + if (start != null) 'start': start, + if (end != null) 'end': end, + if (keyset.authKey != null) 'auth': keyset.authKey, + if (includeCount != null) 'count': '$includeCount', + if (filter != null && filter != '') 'filter': filter, + if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') + }; + + return Request( + RequestType.get, + pathSegments, + queryParameters: queryParameters, + ); + } +} + +class ChannelMemberMetadata { + UuidMetadataDetails _uuid; + dynamic _custom; + String _updated; + String _eTag; + + UuidMetadataDetails get uuid => _uuid; + dynamic get custom => _custom; + String get updated => _updated; + String get eTag => _eTag; + + ChannelMemberMetadata._(); + + factory ChannelMemberMetadata.fromJson(dynamic object) => + ChannelMemberMetadata._() + .._uuid = UuidMetadataDetails.fromJson(object['uuid']) + .._custom = object['custom'] + .._updated = object['updated'] as String + .._eTag = object['eTag'] as String; +} + +class ChannelMembersResult extends Result { + List _metadataList; + int _totalCount; + String _next; + String _prev; + + List get metadataList => _metadataList; + int get totalCount => _totalCount; + String get next => _next; + String get prev => _prev; + + ChannelMembersResult._(); + + factory ChannelMembersResult.fromJson(dynamic object) => + ChannelMembersResult._() + .._metadataList = (object['data'] as List) + ?.map((e) => e == null ? null : ChannelMemberMetadata.fromJson(e)) + ?.toList() + .._totalCount = object['totalCount'] as int + .._next = object['next'] as String + .._prev = object['prev'] as String; +} + +class ManageChannelMembersParams extends Parameters { + Keyset keyset; + String channelId; + + int limit; + String start; + String end; + Set include; + bool includeCount; + String filter; + Set sort; + + String membersMetadata; + + ManageChannelMembersParams(this.keyset, this.channelId, this.membersMetadata, + {this.limit, + this.start, + this.end, + this.include, + this.includeCount, + this.filter, + this.sort}); + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'channels', + channelId, + 'uuids' + ]; + + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (limit != null) 'limit': '$limit', + if (start != null) 'start': start, + if (end != null) 'end': end, + if (keyset.authKey != null) 'auth': '${keyset.authKey}', + if (includeCount != null) 'count': '$includeCount', + if (filter != null && filter.isNotEmpty) 'filter': filter, + if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') + }; + return Request( + RequestType.patch, + pathSegments, + queryParameters: queryParameters, + body: membersMetadata, + ); + } +} diff --git a/lib/src/dx/_endpoints/objects/objects_types.dart b/lib/src/dx/_endpoints/objects/objects_types.dart index 621a31b8..c783a3ab 100644 --- a/lib/src/dx/_endpoints/objects/objects_types.dart +++ b/lib/src/dx/_endpoints/objects/objects_types.dart @@ -1,20 +1,22 @@ -export './membership.dart' - show SpaceMemberInfo, MembershipInfo, MembershipsResult, SpaceMembersResult; +export './uuid_metadata.dart' + show + UuidMetadataDetails, + GetAllUuidMetadataResult, + GetUuidMetadataResult, + SetUuidMetadataResult, + RemoveUuidMetadataResult; -export './space.dart' +export './channel_metadata.dart' show - SpaceInfo, - GetSpaceResult, - GetAllSpacesResult, - CreateSpaceResult, - UpdateSpaceResult, - DeleteSpaceResult; + ChannelMetadataDetails, + GetAllChannelMetadataResult, + GetChannelMetadataResult, + SetChannelMetadataResult, + RemoveChannelMetadataResult; -export './user.dart' +export './membership_metadata.dart' show - UserInfo, - GetAllUsersResult, - CreateUserResult, - UpdateUserResult, - GetUserResult, - DeleteUserResult; + MembershipMetadata, + ChannelMemberMetadata, + MembershipsResult, + ChannelMembersResult; diff --git a/lib/src/dx/_endpoints/objects/space.dart b/lib/src/dx/_endpoints/objects/space.dart deleted file mode 100644 index 6957b2a1..00000000 --- a/lib/src/dx/_endpoints/objects/space.dart +++ /dev/null @@ -1,287 +0,0 @@ -import 'package:pubnub/src/core/core.dart'; -import 'package:pubnub/src/dx/_utils/utils.dart'; - -class CreateSpaceParams extends Parameters { - Keyset keyset; - List include; - String space; - - CreateSpaceParams(this.space, this.keyset, {this.include}); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'spaces']; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (keyset.authKey != null) 'auth': keyset.authKey, - }; - - return Request(RequestType.post, pathSegments, - queryParameters: queryParameters.isNotEmpty ? queryParameters : null, - body: space); - } -} - -class UpdateSpaceParams extends Parameters { - Keyset keyset; - List include; - String space; - String spaceId; - - UpdateSpaceParams(this.keyset, this.space, this.spaceId, {this.include}); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'spaces', - spaceId - ]; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (keyset.authKey != null) 'auth': keyset.authKey, - }; - - return Request(RequestType.patch, pathSegments, - queryParameters: queryParameters.isNotEmpty ? queryParameters : null, - body: space); - } -} - -class DeleteSpaceParams extends Parameters { - Keyset keyset; - String spaceId; - - DeleteSpaceParams(this.keyset, this.spaceId); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'spaces', - spaceId - ]; - - var queryParameters = { - if (keyset.authKey != null) 'auth': keyset.authKey, - }; - - return Request(RequestType.delete, pathSegments, - queryParameters: queryParameters); - } -} - -class GetSpaceParams extends Parameters { - Keyset keyset; - String spaceId; - - List include; - - GetSpaceParams(this.keyset, this.spaceId, {this.include}); - - @override - Request toRequest() { - var pathSegments = [ - 'v1', - 'objects', - keyset.subscribeKey, - 'spaces', - spaceId, - ]; - var queryParameters = { - if (keyset.authKey != null) 'auth': keyset.authKey, - if (include != null && include.isNotEmpty) 'include': include.join(','), - }; - - return Request(RequestType.get, pathSegments, - queryParameters: queryParameters); - } -} - -class GetAllSpacesParams extends Parameters { - Keyset keyset; - List include; - int limit; - String start; - String end; - bool count; - String filter; - List sort; - - GetAllSpacesParams(this.keyset, - {this.include, - this.limit, - this.start, - this.end, - this.count, - this.filter, - this.sort}); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'spaces']; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (limit != null) 'limit': limit.toString(), - if (start != null) 'start': start, - if (end != null) 'end': end, - if (keyset.authKey != null) 'auth': keyset.authKey, - if (count != null) 'count': count.toString(), - if (filter != null && filter != '') 'filter': filter, - if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') - }; - - return Request(RequestType.get, pathSegments, - queryParameters: queryParameters); - } -} - -class SpaceInfo { - String _id; - String _name; - String _description; - dynamic _custom; - String _created; - String _updated; - String _eTag; - - String get id => _id; - String get name => _name; - String get description => _description; - dynamic get custom => _custom; - String get created => _created; - String get updated => _updated; - String get eTag => _eTag; - - SpaceInfo(); - - factory SpaceInfo.fromJson(dynamic object) { - return SpaceInfo() - .._id = object['id'] as String - .._name = object['name'] as String - .._description = object['description'] as String - .._custom = object['custom'] - .._created = object['created'] as String - .._updated = object['updated'] as String - .._eTag = object['eTag'] as String; - } -} - -class GetSpaceResult extends Result { - int _status; - SpaceInfo _data; - Map _error; - - int get status => _status; - SpaceInfo get data => _data ?? SpaceInfo(); - Map get error => _error; - - GetSpaceResult(); - - factory GetSpaceResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return GetSpaceResult() - .._status = result.status as int - .._error = result.error - .._data = result.error.isEmpty ? SpaceInfo.fromJson(result.data) : {}; - } -} - -class GetAllSpacesResult extends Result { - int _status; - List _data; - int _totalCount; - String _next; - String _prev; - Map _error; - - int get status => _status; - List get data => _data ?? []; - int get totalCount => _totalCount; - String get next => _next; - String get prev => _prev; - Map get error => _error; - - GetAllSpacesResult(); - - factory GetAllSpacesResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - - return GetAllSpacesResult() - .._status = result.status as int - .._error = result.error - .._data = (result.data as List) - ?.map((e) => e == null ? null : SpaceInfo.fromJson(e)) - ?.toList() - .._totalCount = result.otherKeys['totalCount'] as int - .._next = result.otherKeys['next'] as String - .._prev = result.otherKeys['prev'] as String; - } -} - -class UpdateSpaceResult extends Result { - int _status; - SpaceInfo _data; - Map _error; - - UpdateSpaceResult(); - - int get status => _status; - SpaceInfo get data => _data ?? SpaceInfo(); - Map get error => _error; - - factory UpdateSpaceResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return UpdateSpaceResult() - .._status = result.status as int - .._error = result.error - .._data = result.data != null ? SpaceInfo.fromJson(result.data) : null; - } -} - -class DeleteSpaceResult extends Result { - String _status; - dynamic _data; - Map _error; - - String get status => _status; - dynamic get data => _data; - Map get error => _error; - - DeleteSpaceResult(); - - factory DeleteSpaceResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return DeleteSpaceResult() - .._status = result.status as String - .._error = result.error - .._data = result.error.isEmpty ? result.data : {}; - } -} - -class CreateSpaceResult extends Result { - int _status; - SpaceInfo _data; - Map _error; - - int get status => _status; - SpaceInfo get data => _data ?? SpaceInfo(); - Map get error => _error; - - CreateSpaceResult(); - - factory CreateSpaceResult.fromJson(Map object) { - var result = DefaultObjectResult.fromJson(object); - return CreateSpaceResult() - .._status = result.status as int - .._error = result.error - .._data = result.error.isEmpty ? SpaceInfo.fromJson(result.data) : null; - } -} diff --git a/lib/src/dx/_endpoints/objects/user.dart b/lib/src/dx/_endpoints/objects/user.dart deleted file mode 100644 index 63be9aae..00000000 --- a/lib/src/dx/_endpoints/objects/user.dart +++ /dev/null @@ -1,277 +0,0 @@ -import 'package:pubnub/src/core/core.dart'; -import 'package:pubnub/src/dx/_utils/utils.dart'; - -class CreateUserParams extends Parameters { - Keyset keyset; - - List include; - - String user; - - CreateUserParams(this.user, this.keyset, {this.include}); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'users']; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (keyset.authKey != null) 'auth': keyset.authKey, - }; - - return Request(RequestType.post, pathSegments, - queryParameters: queryParameters.isNotEmpty ? queryParameters : null, - headers: {'Content-Type': 'application/json'}, - body: user); - } -} - -class UpdateUserParams extends Parameters { - Keyset keyset; - String user; - String userId; - - List include; - - UpdateUserParams(this.keyset, this.user, this.userId, {this.include}); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'users', userId]; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (keyset.authKey != null) 'auth': keyset.authKey, - }; - - return Request(RequestType.patch, pathSegments, - queryParameters: queryParameters.isNotEmpty ? queryParameters : null, - headers: {'Content-Type': 'application/json'}, - body: user); - } -} - -class DeleteUserParams extends Parameters { - Keyset keyset; - String userId; - - DeleteUserParams(this.keyset, this.userId); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'users', userId]; - - var queryParameters = { - if (keyset.authKey != null) 'auth': keyset.authKey, - }; - - return Request(RequestType.delete, pathSegments, - queryParameters: queryParameters, - headers: {'Content-Type': 'application/json'}); - } -} - -class GetUserParams extends Parameters { - Keyset keyset; - String userid; - - List include; - - GetUserParams(this.keyset, this.userid, {this.include}); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'users', userid]; - var queryParameters = { - if (keyset.authKey != null) 'auth': keyset.authKey, - if (include != null && include.isNotEmpty) 'include': include.join(','), - }; - - return Request(RequestType.get, pathSegments, - queryParameters: queryParameters); - } -} - -class GetAllUsersParams extends Parameters { - Keyset keyset; - - List include; - int limit; - String start; - String end; - bool count; - String filter; - List sort; - - GetAllUsersParams(this.keyset, - {this.include, - this.limit, - this.start, - this.end, - this.count, - this.filter, - this.sort}); - - @override - Request toRequest() { - var pathSegments = ['v1', 'objects', keyset.subscribeKey, 'users']; - - var queryParameters = { - if (include != null && include.isNotEmpty) 'include': include.join(','), - if (limit != null) 'limit': limit.toString(), - if (start != null) 'start': start, - if (end != null) 'end': end, - if (keyset.authKey != null) 'auth': keyset.authKey, - if (count != null) 'count': count.toString(), - if (filter != null && filter != '') 'filter': filter, - if (sort != null && sort.isNotEmpty) 'sort': sort.join(',') - }; - - return Request(RequestType.get, pathSegments, - queryParameters: queryParameters, - headers: {'Content-Type': 'application/json'}); - } -} - -class UserInfo { - String _id; - String _name; - String _externalId; - String _profileUrl; - String _email; - dynamic _custom; - String _created; - String _updated; - String _eTag; - - String get id => _id; - String get name => _name; - String get externalId => _externalId; - String get profileUrl => _profileUrl; - String get email => _email; - dynamic get custom => _custom; - String get created => _created; - String get updated => _updated; - String get eTag => _eTag; - - UserInfo(); - - factory UserInfo.fromJson(dynamic json) { - return UserInfo() - .._id = json['id'] as String - .._name = json['name'] as String - .._externalId = json['externalId'] as String - .._profileUrl = json['profileUrl'] as String - .._email = json['email'] as String - .._custom = json['custom'] - .._created = json['created'] as String - .._updated = json['upadted'] as String - .._eTag = json['eTag'] as String; - } -} - -class UpdateUserResult extends Result { - int _status; - UserInfo _data; - Map _error; - - UpdateUserResult(); - - int get status => _status; - UserInfo get data => _data ?? UserInfo(); - Map get error => _error; - - factory UpdateUserResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return UpdateUserResult() - .._status = result.status as int - .._error = result.error - .._data = result.data == null ? null : UserInfo.fromJson(result.data); - } -} - -class GetAllUsersResult extends Result { - int _status; - List _data; - int _totalCount; - Map _error; - - int get status => _status; - List get data => _data ?? []; - int get totalCount => _totalCount; - Map get error => _error; - - GetAllUsersResult(); - - factory GetAllUsersResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - - return GetAllUsersResult() - .._status = result.status as int - .._error = result.error - .._data = (result.data as List) - ?.map((e) => e == null ? null : UserInfo.fromJson(e)) - ?.toList() - .._totalCount = result.otherKeys['totalCount'] as int; - } -} - -class GetUserResult extends Result { - int _status; - UserInfo _data; - Map _error; - - int get status => _status; - UserInfo get data => _data ?? UserInfo(); - Map get error => _error; - - GetUserResult(); - - factory GetUserResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return GetUserResult() - .._status = result.status as int - .._error = result.error - .._data = result.data == null ? null : UserInfo.fromJson(result.data); - } -} - -class DeleteUserResult extends Result { - dynamic _status; - dynamic _data; - Map _error; - - dynamic get status => _status; - dynamic get data => _data; - Map get error => _error; - - DeleteUserResult(); - - factory DeleteUserResult.fromJson(dynamic object) { - var result = DefaultObjectResult.fromJson(object); - return DeleteUserResult() - .._status = result.status - .._error = result.error - .._data = result.data; - } -} - -class CreateUserResult extends Result { - int _status; - UserInfo _data; - Map _error; - - int get status => _status; - UserInfo get data => _data ?? UserInfo(); - Map get error => _error; - - CreateUserResult(); - - factory CreateUserResult.fromJson(Map object) { - var result = DefaultObjectResult.fromJson(object); - return CreateUserResult() - .._status = result.status as int - .._error = result.error - .._data = result.error.isEmpty ? UserInfo.fromJson(result.data) : null; - } -} diff --git a/lib/src/dx/_endpoints/objects/uuid_metadata.dart b/lib/src/dx/_endpoints/objects/uuid_metadata.dart new file mode 100644 index 00000000..37a06e98 --- /dev/null +++ b/lib/src/dx/_endpoints/objects/uuid_metadata.dart @@ -0,0 +1,199 @@ +import 'package:pubnub/src/core/core.dart'; + +class GetAllUuidMetadataParams extends Parameters { + Keyset keyset; + Set include; + int limit; + String start; + String end; + bool includeCount; + String filter; + Set sort; + + GetAllUuidMetadataParams(this.keyset, + {this.limit, + this.include, + this.start, + this.end, + this.includeCount, + this.filter, + this.sort}); + + @override + Request toRequest() { + var pathSegments = ['v2', 'objects', keyset.subscribeKey, 'uuids']; + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (limit != null) 'limit': '$limit', + if (start != null) 'start': start, + if (end != null) 'end': end, + if (includeCount != null) 'count': '$includeCount', + if (filter != null && filter.isNotEmpty) 'filter': filter, + if (sort != null && sort.isNotEmpty) 'sort': sort.join(','), + if (keyset.authKey != null) 'auth': '${keyset.authKey}' + }; + return Request(RequestType.get, pathSegments, + queryParameters: queryParameters); + } +} + +class UuidMetadataDetails { + String _id; + String _name; + String _externalId; + String _profileUrl; + String _email; + Map _custom; + String _updated; + String _eTag; + + String get id => _id; + String get name => _name; + String get externalId => _externalId; + String get profileUrl => _profileUrl; + String get email => _email; + dynamic get custom => _custom; + String get updated => _updated; + String get eTag => _eTag; + + UuidMetadataDetails._(); + + factory UuidMetadataDetails.fromJson(dynamic json) => UuidMetadataDetails._() + .._id = json['id'] as String + .._name = json['name'] as String + .._externalId = json['externalId'] as String + .._profileUrl = json['profileUrl'] as String + .._email = json['email'] as String + .._custom = json['custom'] as Map + .._updated = json['upadted'] as String + .._eTag = json['eTag'] as String; +} + +class GetAllUuidMetadataResult extends Result { + List _metadataList; + int _totalCount; + String _next; + String _prev; + + List get metadataList => _metadataList; + int get totalCount => _totalCount; + String get next => _next; + String get prev => _prev; + + GetAllUuidMetadataResult._(); + + factory GetAllUuidMetadataResult.fromJson(dynamic object) => + GetAllUuidMetadataResult._() + .._metadataList = (object['data'] as List) + ?.map((e) => e == null ? null : UuidMetadataDetails.fromJson(e)) + ?.toList() + .._totalCount = object['totalCount'] as int + .._next = object['next'] as String + .._prev = object['prev'] as String; +} + +class GetUuidMetadataParams extends Parameters { + Keyset keyset; + String uuid; + + Set include; + + GetUuidMetadataParams(this.keyset, {this.include, this.uuid}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'uuids', + uuid ?? '${keyset.uuid}' + ]; + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (keyset.authKey != null) 'auth': '${keyset.authKey}' + }; + return Request(RequestType.get, pathSegments, + queryParameters: queryParameters); + } +} + +class GetUuidMetadataResult extends Result { + UuidMetadataDetails _metadata; + + UuidMetadataDetails get metadata => _metadata; + + GetUuidMetadataResult(); + + factory GetUuidMetadataResult.fromJson(dynamic object) => + GetUuidMetadataResult() + .._metadata = UuidMetadataDetails.fromJson(object['data']); +} + +class SetUuidMetadataParams extends Parameters { + Keyset keyset; + String uuid; + + Set include; + + String uuidMetadata; + + SetUuidMetadataParams(this.keyset, this.uuidMetadata, + {this.include, this.uuid}); + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'uuids', + uuid ?? '${keyset.uuid}' + ]; + var queryParameters = { + if (include != null && include.isNotEmpty) 'include': include.join(','), + if (keyset.authKey != null) 'auth': keyset.authKey + }; + return Request(RequestType.patch, pathSegments, + queryParameters: queryParameters, body: uuidMetadata); + } +} + +class SetUuidMetadataResult extends Result { + UuidMetadataDetails _metadata; + + SetUuidMetadataResult._(); + + UuidMetadataDetails get metadata => _metadata; + + factory SetUuidMetadataResult.fromJson(dynamic object) => + SetUuidMetadataResult._() + .._metadata = UuidMetadataDetails.fromJson(object['data']); +} + +class RemoveUuidMetadataParams extends Parameters { + Keyset keyset; + String uuid; + + RemoveUuidMetadataParams(this.keyset, {this.uuid}); + + @override + Request toRequest() { + var pathSegments = [ + 'v2', + 'objects', + keyset.subscribeKey, + 'uuids', + uuid ?? '${keyset.uuid}' + ]; + var queryParameters = {if (keyset.authKey != null) 'auth': keyset.authKey}; + return Request(RequestType.delete, pathSegments, + queryParameters: queryParameters); + } +} + +class RemoveUuidMetadataResult extends Result { + RemoveUuidMetadataResult._(); + + factory RemoveUuidMetadataResult.fromJson(dynamic object) => + RemoveUuidMetadataResult._(); +} diff --git a/lib/src/dx/_endpoints/push.dart b/lib/src/dx/_endpoints/push.dart index 8d09aa22..738d9239 100644 --- a/lib/src/dx/_endpoints/push.dart +++ b/lib/src/dx/_endpoints/push.dart @@ -1,7 +1,7 @@ import 'package:pubnub/src/core/core.dart'; import 'package:pubnub/src/dx/_utils/utils.dart'; -enum PushGateway { apns, gcm, mpns, apns2 } +enum PushGateway { apns, fcm, gcm, mpns, apns2 } enum Environment { development, production } @@ -21,6 +21,8 @@ extension EnvironmentExtension on Environment { extension PushGatewayExtension on PushGateway { String value() { switch (this) { + case PushGateway.fcm: + return 'fcm'; case PushGateway.gcm: return 'gcm'; case PushGateway.apns: diff --git a/lib/src/dx/_utils/default_result.dart b/lib/src/dx/_utils/default_result.dart index c0651ec4..47164e76 100644 --- a/lib/src/dx/_utils/default_result.dart +++ b/lib/src/dx/_utils/default_result.dart @@ -34,6 +34,10 @@ class DefaultResult extends Result { hasError = true; errorDetails = object['error']; errorMessage = errorDetails['message']; + if (errorDetails['details'] != null) { + (errorDetails['details'] as List).forEach((e) => errorMessage += + '\n Error Details: ${e['message']} for ${e['location']} in ${e['locationType']}'); + } } else if (object['error'] is bool) { hasError = object['error'] as bool; errorMessage = object['error_message']; @@ -53,28 +57,3 @@ class DefaultResult extends Result { object, ['status', 'error', 'message', 'error_message', 'service']); } } - -class DefaultObjectResult extends Result { - dynamic status; - Map error; - dynamic data; - Map otherKeys = {}; - - DefaultObjectResult._(); - - static Map collectOtherKeys( - dynamic object, List knownKeys) { - var clone = Map.from(object); - for (var key in knownKeys) { - clone.remove(key); - } - return clone; - } - - factory DefaultObjectResult.fromJson(dynamic object) => - DefaultObjectResult._() - ..status = object['status'] - ..data = object['data'] - ..error = object['error'] as Map ?? {} - ..otherKeys = collectOtherKeys(object, ['status', 'error', 'data']); -} diff --git a/lib/src/dx/objects/channel_metadata.dart b/lib/src/dx/objects/channel_metadata.dart new file mode 100644 index 00000000..9cdcbd04 --- /dev/null +++ b/lib/src/dx/objects/channel_metadata.dart @@ -0,0 +1,143 @@ +import 'package:pubnub/pubnub.dart'; +import 'package:pubnub/src/core/core.dart'; + +/// Represents a Channel Metadata object +/// Useful to deal with a specific channel's Metadata +class ChannelMetadata { + final PubNub _core; + final Keyset _keyset; + final String _id; + + ChannelMetadata(this._core, this._keyset, this._id); + + /// You can use this method to add a uuidMetadata(membersMetadata) into given channel + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future setChannelMembersMetadata( + List channelMembersMetadata, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount, + String filter, + Set sort}) => + _core.objects.setChannelMembers(_id, channelMembersMetadata, + limit: limit, + start: start, + end: end, + includeCustomFields: includeCustomFields, + includeUUIDFields: includeUUIDFields, + includeUUIDCustomFields: includeUUIDCustomFields, + includeCount: includeCount, + filter: filter, + sort: sort); + + /// You can use this method to remove an existing users(members) from given space + /// Provide valid `uuids` to remove it from given channel + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future removeChannelMembersMetadata(Set uuids, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount, + String filter, + Set sort}) => + _core.objects.removeChannelMembers(_id, uuids, + keyset: _keyset, + limit: limit, + start: start, + end: end, + includeCustomFields: includeCustomFields, + includeUUIDFields: includeUUIDFields, + includeUUIDCustomFields: includeUUIDCustomFields, + includeCount: includeCount, + filter: filter, + sort: sort); + + /// It returns paginated list of channels members Metadata + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future getChannelMembersMetadata( + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount, + String filter, + Set sort, + Keyset keyset, + String using}) => + _core.objects.getChannelMembers(_id, + limit: limit, + start: start, + end: end, + includeCustomFields: includeCustomFields, + includeUUIDFields: includeUUIDFields, + includeUUIDCustomFields: includeUUIDCustomFields, + includeCount: includeCount, + filter: filter, + sort: sort); +} diff --git a/lib/src/dx/objects/membership.dart b/lib/src/dx/objects/membership.dart deleted file mode 100644 index 235af173..00000000 --- a/lib/src/dx/objects/membership.dart +++ /dev/null @@ -1,481 +0,0 @@ -import 'package:pubnub/src/core/core.dart'; - -import 'package:pubnub/src/dx/_utils/utils.dart'; -import 'package:pubnub/src/dx/_endpoints/objects/membership.dart'; -import 'schema.dart'; - -final _logger = injectLogger('dx.objects.membership'); - -class MembershipDx { - final Core _core; - MembershipDx(this._core); - - /// Returns the specified user's space memberships, - /// optionally including the custom data objects for: the user's perspective on their membership set ("custom"), - /// the user's perspective on the space ("space"), and the space's custom data ("space.custom"). - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - Future getUserMemberships(String userId, - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(userId).isNotEmpty('userId'); - - var params = GetMembershipsParams(keyset, userId, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => MembershipsResult.fromJson(object)); - } - - /// Updates the specified user's space memberships. - /// Use the add, update, and remove properties in the request body - /// to perform those operations on one or more memberships. - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - /// - /// Returns the user's space memberships, optionally including: - /// * The user's custom data object - /// * the custom data objects for the user's membership in each space - /// each space's custom data object Notes: - /// * You can change all of the membership object's properties, except its ID. - /// * Invalid property names are silently ignored and will not cause a request to fail. - /// * If you update the "custom" property, you must completely replace it; partial updates are not supported. - /// * The custom object can only contain scalar values - Future manageUserMemberships(String userId, - {Set add, - List update, - Set remove, - Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(userId).isNotEmpty('userId'); - - var updates = {}; - if (add != null && add.isNotEmpty) { - var addIds = []; - add.forEach((id) => addIds.add(IdInfo(id))); - updates['add'] = addIds; - } - if (update != null && update.isNotEmpty) { - updates['update'] = update; - } - if (remove != null && remove.isNotEmpty) { - var removeIds = []; - remove.forEach((id) => removeIds.add(IdInfo(id))); - updates['remove'] = removeIds; - } - var membershipChanges = await _core.parser.encode(updates); - var params = ManageMembershipsParams(keyset, userId, membershipChanges, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => MembershipsResult.fromJson(object)); - } - - /// Use this method to add user's space memberships. - /// [spaceIds] are List of space Ids to which you want to add the user [userId] - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - /// - /// Returns the user's space memberships, optionally including: - /// * The user's custom data object - /// * the custom data objects for the user's membership in each space - /// each space's custom data object Notes: - /// * Invalid property names are silently ignored and will not cause a request to fail. - Future addUserMemberships( - String userId, List spaceIds, - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(userId).isNotEmpty('userId'); - - var updates = {}; - if (spaceIds.isNotEmpty) { - var addIds = []; - spaceIds.forEach((id) => addIds.add(IdInfo(id))); - updates['add'] = addIds; - } - var membershipChanges = await _core.parser.encode(updates); - var params = ManageMembershipsParams(keyset, userId, membershipChanges, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => MembershipsResult.fromJson(object)); - } - - /// Use this method to remove user's space memberships. - /// It will remove user [userId] from all spaces specificed by [spaceIds] - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - /// - /// Returns the user's space memberships, optionally including: - /// * The user's custom data object - /// * the custom data objects for the user's membership in each space - /// each space's custom data object Notes: - /// * You can change all of the membership object's properties, except its ID. - /// * Invalid property names are silently ignored and will not cause a request to fail. - /// * If you update the "custom" property, you must completely replace it; partial updates are not supported. - /// * The custom object can only contain scalar values - Future removeUserMemberships( - String userId, List spaceIds, - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(userId).isNotEmpty('userId'); - - var updates = {}; - if (spaceIds.isNotEmpty) { - var removeIds = []; - spaceIds.forEach((id) => removeIds.add(IdInfo(id))); - updates['remove'] = removeIds; - } - var membershipChanges = await _core.parser.encode(updates); - var params = ManageMembershipsParams(keyset, userId, membershipChanges, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => MembershipsResult.fromJson(object)); - } - - /// Use this method to update membership information of user with [userId] - /// Provide list of [UpdateInfo] object which contains id and custom data which you want to update - /// for that specific user's membership - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - /// - /// Returns the user's space memberships, optionally including: - /// * The user's custom data object - /// * the custom data objects for the user's membership in each space - /// each space's custom data object Notes: - /// * You can change all of the membership object's properties, except its ID. - /// * Invalid property names are silently ignored and will not cause a request to fail. - /// * If you update the "custom" property, you must completely replace it; partial updates are not supported. - /// * The custom object can only contain scalar values - Future updateUserMemberships( - String userId, List update, - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(userId).isNotEmpty('userId'); - - var updates = {}; - if (update.isNotEmpty) { - updates['update'] = update; - } - var membershipChanges = await _core.parser.encode(updates); - var params = ManageMembershipsParams(keyset, userId, membershipChanges, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => MembershipsResult.fromJson(object)); - } - - /// Returns the users in a space, optionally including: - /// * Each user's custom data object - /// * The custom data objects for each user's membership in the space - /// * The space's custom data object - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - Future getSpaceMembers(String spaceId, - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(spaceId).isNotEmpty('spaceId'); - var params = GetSpaceMembersParams(keyset, spaceId, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => SpaceMembersResult.fromJson(object)); - } - - /// Updates the specified space's user list. - /// Use the add, update, and remove properties in the request body to perform those operations on one or more memberships. - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - /// - /// Returns the space's user memberships, optionally including: - /// * The space's custom data object - /// * The custom data objects for each user's membership in the space - /// * Each user's custom data object Notes: - /// * You can change all of the membership object's properties, except its ID. - /// * Invalid property names are silently ignored and will not cause a request to fail. - /// * If you update the "custom" property, you must completely replace it; partial updates are not supported. - /// * The custom object can only contain scalar values. - Future manageSpaceMembers(String spaceId, - {Set add, - List update, - Set remove, - Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - Ensure(spaceId).isNotEmpty('spaceId'); - - var updates = {}; - if (add != null && add.isNotEmpty) { - var addIds = []; - add.forEach((id) => addIds.add(IdInfo(id))); - updates['add'] = addIds; - } - if (update != null && update.isNotEmpty) { - updates['update'] = update; - } - if (remove != null && remove.isNotEmpty) { - var removeIds = []; - remove.forEach((id) => removeIds.add(IdInfo(id))); - updates['remove'] = removeIds; - } - - var spaceMembersChanges = await _core.parser.encode(updates); - var params = ManageSpaceMembersParams(keyset, spaceId, spaceMembersChanges, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => SpaceMembersResult.fromJson(object)); - } -} diff --git a/lib/src/dx/objects/objects.dart b/lib/src/dx/objects/objects.dart index 6468e7bf..1dcb1fb3 100644 --- a/lib/src/dx/objects/objects.dart +++ b/lib/src/dx/objects/objects.dart @@ -1,3 +1,958 @@ -export 'membership.dart' show MembershipDx; -export 'space.dart' show SpaceDx, Space; -export 'user.dart' show UserDx, User; +import 'package:pubnub/src/core/core.dart'; +import 'package:pubnub/src/dx/_endpoints/objects/uuid_metadata.dart'; +import 'package:pubnub/src/dx/_endpoints/objects/channel_metadata.dart'; +import 'package:pubnub/src/dx/_endpoints/objects/membership_metadata.dart'; +import '../_utils/utils.dart'; +import 'schema.dart'; + +final _logger = injectLogger('dx.objects'); + +class ObjectsDx { + final Core _core; + + ObjectsDx(this._core); + + /// Returns a paginated list of all uuidMetadata associated with the given subscription key, + /// optionally including each uuidMetadata record's custom data object. + /// + /// To include `custom` property fields in response, set [includeCustomFields] to `true` + /// Omit this parameter if you don't want to retrieve additional metadata. + /// + /// You can limit number of returned user object using [limit] parameter + /// Default is 100, which is also the maximum value. + /// + /// You can specify [start] and [end] to specify previously-returned cursor bookmark + /// for fetching the next/previous page + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// [filter] is Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// For sorting, use [sort] which is List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future getAllUUIDMetadata( + {bool includeCustomFields, + int limit, + String start, + String end, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + + var params = GetAllUuidMetadataParams(keyset, + include: include, + limit: limit, + start: start, + end: end, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => GetAllUuidMetadataResult.fromJson(object)); + } + + /// Returns the specified uuidMetadata, optionally including uuidMetadata's custom data object. + /// + /// To include `custom` property fields in response, set [includeCustomFields] to `true` + /// Omit this parameter if you don't want to retrieve additional metadata. + /// + /// `uuid` is Unique identifier of an end-user. It may contain up to 92 UTF-8 byte sequences. + /// Prohibited characters are ,, /, \, *, :, channel, non-printable ASCII control characters, and Unicode zero. + /// * If `uuid` not provided then it picks `uuid` from `keyset` or PubNub instance's `uuid` + /// * If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid`not provided in argument then it throws InvariantException + Future getUUIDMetadata( + {String uuid, + Keyset keyset, + String using, + bool includeCustomFields}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + if (keyset.uuid == null) { + Ensure(uuid).isNotNull('uuid'); + } + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + + var params = GetUuidMetadataParams(keyset, uuid: uuid, include: include); + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => GetUuidMetadataResult.fromJson(object)); + } + + /// Sets metadata for the specified uuid in the database. + /// Returns the updated uuid object, optionally including custom properties. + /// + /// * You can change all of the uuid object's properties, except its identifier. + /// * Invalid property names are silently ignored and will not cause a request to fail. + /// * If you set the "custom" property, you must completely replace it; partial updates are not supported. + /// * The custom object can only contain scalar values. + /// + /// To include `custom` property fields in response, set [includeCustomFields] to `true` + /// Omit this parameter if you don't want to retrieve additional metadata. + /// + /// `uuid` is Unique identifier of an end-user. It may contain up to 92 UTF-8 byte sequences. + /// Prohibited characters are ,, /, \, *, :, channel, non-printable ASCII control characters, and Unicode zero. + /// * If `uuid` parameter is provied then it sets metadata for given uuid. + /// * In case of null `uuid` it sets metadata for PubNub instance's `uuid` + /// * If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid` not provided in method argument then it throws InvariantException + Future setUUIDMetadata( + UuidMetadataInput uuidMetadataInput, + {String uuid, + bool includeCustomFields, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + Ensure(uuidMetadataInput).isNotNull('uuid metadata input'); + + if (keyset.uuid == null) { + Ensure(uuid).isNotNull('uuid'); + } + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + + var payload = await _core.parser.encode(uuidMetadataInput); + var params = + SetUuidMetadataParams(keyset, payload, uuid: uuid, include: include); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => SetUuidMetadataResult.fromJson(object)); + } + + /// Deletes the specified uuid's metadata form the database. + /// If `uuid` is provied then it deletes metadata for given uuid. + /// In case of null `uuid` it deletes metadata for PubNub instance's `uuid` + /// If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid` not provided in argument then it throws InvariantException + Future removeUUIDMetadata( + {String uuid, Keyset keyset, String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + if (keyset.uuid == null) { + Ensure(uuid).isNotNull('uuid'); + } + + var params = RemoveUuidMetadataParams(keyset, uuid: uuid); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => RemoveUuidMetadataResult.fromJson(object)); + } + + // Channel Metadata + + /// Returns a paginated list of all channelMetadata associated with the given subscription key, + /// optionally including each channelMetadata record's custom data object. + /// + /// To include `custom` property fields in response, set [includeCustomFields] to `true` + /// Omit this parameter if you don't want to retrieve additional metadata. + /// + /// You can limit number of returned user object using [limit] parameter + /// Default is 100, which is also the maximum value. + /// + /// You can specify [start] and [end] to specify previously-returned cursor bookmark + /// for fetching the next/previous page + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// [filter] is Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// For sorting, use [sort] which is List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future getAllChannelMetadata( + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + + var params = GetAllChannelMetadataParams(keyset, + include: include, + limit: limit, + start: start, + end: end, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => + GetAllChannelMetadataResult.fromJson(object)); + } + + /// Returns the specified channelMetadata, optionally including channelMetadata's custom data object. + /// + /// To include `custom` property fields in response, set [includeCustomFields] to `true` + /// Omit this parameter if you don't want to retrieve additional metadata. + /// + /// `channelId` is Channel identifier. Must not be empty, and may contain up to 92 UTF-8 byte sequences. + /// Prohibited characters are ,, /, \, *, :, channel, non-printable ASCII control characters, and Unicode zero. + Future getChannelMetadata(String channelId, + {Keyset keyset, String using, bool includeCustomFields}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + Ensure(channelId).isNotEmpty('channelIds'); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + + var params = GetChannelMetadataParams(keyset, channelId, include: include); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => GetChannelMetadataResult.fromJson(object)); + } + + /// Sets metadata for the specified `channelId` in the database. + /// Returns the updated uuid object, optionally including custom properties. + /// `channelId` is Channel identifier. Must not be empty, and may contain up to 92 UTF-8 byte sequences. + /// Prohibited characters are ,, /, \, *, :, channel, non-printable ASCII control characters, and Unicode zero. + /// + /// * You can change all of the channel's metadata, except its identifier. + /// * Invalid property names are silently ignored and will not cause a request to fail. + /// * If you set the "custom" property, you must completely replace it; partial updates are not supported. + /// * The custom object can only contain scalar values. + /// + /// To include `custom` property fields in response, set [includeCustomFields] to `true` + /// Omit this parameter if you don't want to retrieve additional metadata. + Future setChannelMetadata( + String channelId, ChannelMetadataInput channelMetadataInput, + {bool includeCustomFields, Keyset keyset, String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + + Ensure(keyset).isNotNull('keyset'); + Ensure(channelId).isNotNull('channelId'); + Ensure(channelMetadataInput).isNotNull('channelMetadataInput'); + + var payload = await _core.parser.encode(channelMetadataInput); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + + var params = + SetChannelMetadataParams(keyset, channelId, payload, include: include); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => SetChannelMetadataResult.fromJson(object)); + } + + /// Deletes metadata for the specified channel `channelId` from the database. + /// `channelId` is Channel identifier. Must not be empty, and may contain up to 92 UTF-8 byte sequences. + /// Prohibited characters are ,, /, \, *, :, channel, non-printable ASCII control characters, and Unicode zero. + Future removeChannelMetadata(String channelId, + {Keyset keyset, String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + Ensure(channelId).isNotEmpty('channelId'); + var params = RemoveChannelMetadataParams(keyset, channelId); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => + RemoveChannelMetadataResult.fromJson(object)); + } + + //UUID-Membership and Channel-Members metadata + + /// Returns the specified `uuid` channel memberships, + /// optionally including the custom data objects for: the uuid's perspective on their membership set ("custom"), + /// the uuid's perspective on the channel ("channel"), and the channel's custom data ("channel.custom"). + /// + /// * If `uuid` not provided then it picks `uuid` from given `keyset` or PubNub instance's `uuid` + /// * If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid`not provided in argument then it throws InvariantException + /// + /// To include `custom` property fields of membership in response, set [includeCustomFields] to `true` + /// To include `channel` metadata fields of uuid's membership in response, set [includeChannelFields] to `true` + /// To include `custom` fields of membership's channel metadata, set [includeChannelCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future getMemberships( + {String uuid, + int limit, + String start, + String end, + bool includeCustomFields, + bool includeChannelFields, + bool includeChannelCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + if (keyset.uuid == null) Ensure(uuid).isNotNull('uuid'); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeChannelFields != null && includeChannelFields) { + include.add('channel'); + } + if (includeChannelCustomFields != null && includeChannelCustomFields) { + include.add('channel.custom'); + } + + var params = GetMembershipsMetadataParams(keyset, + uuid: uuid, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => MembershipsResult.fromJson(object)); + } + + /// Sets channel membership metadata and/or deletes memberships metadata for the specified uuid. + /// `setMetadata` is memberships metadata input to provide metadata details + /// It deletes uuid's membership from given `removeChannelIds` channels + /// + /// Returns the updated uuid's channel membership metadata, optionally including + /// the custom data objects for: the uuid's perspective on their membership set ("custom"), + /// the uuid's perspective on the channel ("channel"), and the channel's custom data ("channel.custom"). + /// + /// * If `uuid` not provided then it picks `uuid` from given `keyset` or PubNub instance's `uuid` + /// * If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid`not provided in argument then it throws InvariantException + /// + /// * You can change all of the membership object's properties, except its identifier. + /// * Invalid property names are silently ignored and will not cause a request to fail. + /// * If you set the "custom" property, you must completely replace it; partial updates are not supported. + /// * The custom object can only contain scalar values. + /// + /// To include `custom` property fields of membership in response, set [includeCustomFields] to `true` + /// To include `channel` metadata fields of uuid's membership in response, set [includeChannelFields] to `true` + /// To include `custom` fields of membership's channelmetadata, set [includeChannelCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future manageMemberships( + List setMetadata, Set removeChannelIds, + {String uuid, + int limit, + String start, + String end, + bool includeCustomFields, + bool includeChannelFields, + bool includeChannelCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + if (keyset.uuid == null) { + Ensure(uuid).isNotNull('uuid'); + } + + var manageMembershipMetadata = {}; + manageMembershipMetadata['set'] = setMetadata; + var deleteInputs = []; + removeChannelIds.forEach((id) => deleteInputs.add(ChannelIdInfo(id))); + manageMembershipMetadata['delete'] = deleteInputs; + + var payload = await _core.parser.encode(manageMembershipMetadata); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeChannelFields != null && includeChannelFields) { + include.add('channel'); + } + if (includeChannelCustomFields != null && includeChannelCustomFields) { + include.add('channel.custom'); + } + + var params = ManageMembershipsParams(keyset, payload, + uuid: uuid, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => MembershipsResult.fromJson(object)); + } + + /// Sets channel membership metadata for the specified uuid. + /// `setMetadata` is memberships metadata input to provide metadata details + /// + /// Returns the updated uuid's channel membership metadata, optionally including + /// the custom data objects for: the uuid's perspective on their membership set ("custom"), + /// the uuid's perspective on the channel ("channel"), and the channel's custom data ("channel.custom"). + /// + /// * If `uuid` not provided then it picks `uuid` from given `keyset` or PubNub instance's `uuid` + /// * If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid`not provided in argument then it throws InvariantException + /// + /// * You can change all of the membership object's properties, except its identifier. + /// * Invalid property names are silently ignored and will not cause a request to fail. + /// * If you set the "custom" property, you must completely replace it; partial updates are not supported. + /// * The custom object can only contain scalar values. + /// + /// To include `custom` property fields of membership in response, set [includeCustomFields] to `true` + /// To include `channel` metadata fields of uuid's membership in response, set [includeChannelFields] to `true` + /// To include `custom` fields of membership's channel metadata, set [includeChannelCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future setMemberships( + List setMetadata, + {String uuid, + int limit, + String start, + String end, + bool includeCustomFields, + bool includeChannelFields, + bool includeChannelCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + if (keyset.uuid == null) { + Ensure(uuid).isNotNull('uuid'); + } + + var manageMembershipMetadata = {}; + manageMembershipMetadata['set'] = setMetadata; + + var payload = await _core.parser.encode(manageMembershipMetadata); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeChannelFields != null && includeChannelFields) { + include.add('channel'); + } + if (includeChannelCustomFields != null && includeChannelCustomFields) { + include.add('channel.custom'); + } + + var params = ManageMembershipsParams(keyset, payload, + uuid: uuid, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => MembershipsResult.fromJson(object)); + } + + /// Deletes memberships metadata for the specified uuid. + /// `channelIds` is set of channelIds from which specified uuid's membership metadata removed + /// + /// Returns the updated uuid's channel membership metadata, optionally including + /// the custom data objects for: the uuid's perspective on their membership set ("custom"), + /// the uuid's perspective on the channel ("channel"), and the channel's custom data ("channel.custom"). + /// + /// To include `custom` property fields of membership in response, set [includeCustomFields] to `true` + /// To include `channel` metadata fields of uuid's membership in response, set [includeChannelFields] to `true` + /// To include `custom` fields of membership's channel metadata, set [includeChannelCustomFields] to `true` + /// + /// * If `uuid` not provided then it picks `uuid` from given `keyset` or PubNub instance's `uuid` + /// * If no `uuid` is set in PubNub instance default keyset, `keyset` does not hold uuid + /// and `uuid`not provided in argument then it throws InvariantException + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future removeMemberships(Set channelIds, + {String uuid, + int limit, + String start, + String end, + bool includeCustomFields, + bool includeChannelFields, + bool includeChannelCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + if (keyset.uuid == null) { + Ensure(uuid).isNotNull('uuid'); + } + + var manageMembershipMetadata = {}; + + var deleteInputs = []; + channelIds.forEach((id) => deleteInputs.add(ChannelIdInfo(id))); + manageMembershipMetadata['delete'] = deleteInputs; + + var payload = await _core.parser.encode(manageMembershipMetadata); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeChannelFields != null && includeChannelFields) { + include.add('channel'); + } + if (includeChannelCustomFields != null && includeChannelCustomFields) { + include.add('channel.custom'); + } + + var params = ManageMembershipsParams(keyset, payload, + uuid: uuid, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => MembershipsResult.fromJson(object)); + } + + /// Returns the members' metadata in the specified channel `channelId`, + /// optionally including the custom data objects for: the channel's perspective on their members set ("custom"), + /// the channel's perspective of the member ("uuid"), and the uuid's custom data ("uuid.custom"). + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future getChannelMembers(String channelId, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + Ensure(channelId).isNotEmpty('channelId'); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeUUIDFields != null && includeUUIDFields) { + include.add('uuid'); + } + if (includeUUIDCustomFields != null && includeUUIDCustomFields) { + include.add('uuid.custom'); + } + + var params = GetChannelMembersParams(keyset, channelId, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => ChannelMembersResult.fromJson(object)); + } + + /// Sets the members's metadata in the specified channel `channelId` and/or deletes members `uuids` metadata + /// it returns members paginated list optionally including + /// the custom data objects for: the channel's perspective on their members set ("custom"), + /// the channel's perspective of the member ("uuid"), and the uuid's custom data ("uuid.custom"). + /// + /// Provide `removeMemberUuids` list of member uuids for which member metadata need to be deleted + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future manageChannelMembers( + String channelId, + List setMetadata, + Set removeMemberUuids, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + Ensure(channelId).isNotEmpty('channelId'); + + var manageInput = {}; + manageInput['set'] = setMetadata; + var deleteInput = []; + removeMemberUuids.forEach((id) => deleteInput.add(UuIdInfo(id))); + manageInput['delete'] = deleteInput; + + var membersMetadata = await _core.parser.encode(manageInput); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeUUIDFields != null && includeUUIDFields) { + include.add('uuid'); + } + if (includeUUIDCustomFields != null && includeUUIDCustomFields) { + include.add('uuid.custom'); + } + + var params = ManageChannelMembersParams(keyset, channelId, membersMetadata, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => ChannelMembersResult.fromJson(object)); + } + + /// Sets the members's metadata in the specified channel and returns members paginated list + /// optionally including the custom data objects for: the channel's perspective on their members set ("custom"), + /// the channel's perspective of the member ("uuid"), and the uuid's custom data ("uuid.custom"). + /// + /// Provide `uuids` list of members for which member metadata need to be deleted + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future setChannelMembers( + String channelId, List setMetadata, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + Ensure(channelId).isNotEmpty('channelId'); + + var manageInput = {}; + manageInput['set'] = setMetadata; + + var membersMetadata = await _core.parser.encode(manageInput); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeUUIDFields != null && includeUUIDFields) { + include.add('uuid'); + } + if (includeUUIDCustomFields != null && includeUUIDCustomFields) { + include.add('uuid.custom'); + } + + var params = ManageChannelMembersParams(keyset, channelId, membersMetadata, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => ChannelMembersResult.fromJson(object)); + } + + /// Removes channel members [uuids] from the specified channel [channelId] and returns remaining members paginated list + /// optionally including the custom data objects for: the channel's perspective on their members set ("custom"), + /// the channel's perspective of the member ("uuid"), and the uuid's custom data ("uuid.custom"). + /// + /// Provide `uuids` list of members for which member metadata need to be deleted + /// + /// To include `custom` property fields of member in response, set [includeCustomFields] to `true` + /// To include `uuid` metadata fields of channel's memebrs in response, set [includeUUIDFields] to `true` + /// To include `custom` fields of channel member's uuidMetadata, set [includeUUIDCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future removeChannelMembers( + String channelId, Set uuids, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeUUIDFields, + bool includeUUIDCustomFields, + bool includeCount = true, + String filter, + Set sort, + Keyset keyset, + String using}) async { + keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); + Ensure(keyset).isNotNull('keyset'); + + Ensure(channelId).isNotEmpty('channelId'); + + var manageInput = {}; + var deleteInput = []; + uuids.forEach((id) => deleteInput.add(UuIdInfo(id))); + manageInput['delete'] = deleteInput; + + var membersMetadata = await _core.parser.encode(manageInput); + + var include = {}; + if (includeCustomFields != null && includeCustomFields) { + include.add('custom'); + } + if (includeUUIDFields != null && includeUUIDFields) { + include.add('uuid'); + } + if (includeUUIDCustomFields != null && includeUUIDCustomFields) { + include.add('uuid.custom'); + } + + var params = ManageChannelMembersParams(keyset, channelId, membersMetadata, + limit: limit, + start: start, + end: end, + include: include, + includeCount: includeCount, + filter: filter, + sort: sort); + + return defaultFlow( + logger: _logger, + core: _core, + params: params, + serialize: (object, [_]) => ChannelMembersResult.fromJson(object)); + } +} diff --git a/lib/src/dx/objects/objects_types.dart b/lib/src/dx/objects/objects_types.dart new file mode 100644 index 00000000..500e37c0 --- /dev/null +++ b/lib/src/dx/objects/objects_types.dart @@ -0,0 +1,8 @@ +export 'uuid_metadata.dart' show UUIDMetadata; +export 'channel_metadata.dart' show ChannelMetadata; +export 'schema.dart' + show + UuidMetadataInput, + ChannelMetadataInput, + ChannelMemberMetadataInput, + MembershipMetadataInput; diff --git a/lib/src/dx/objects/schema.dart b/lib/src/dx/objects/schema.dart index ef43423f..f2b3f40c 100644 --- a/lib/src/dx/objects/schema.dart +++ b/lib/src/dx/objects/schema.dart @@ -1,16 +1,14 @@ -class UserDetails { - String id; +class UuidMetadataInput { String name; String email; dynamic custom; String externalId; String profileUrl; - UserDetails(this.id, this.name, - {this.email, this.externalId, this.profileUrl, this.custom}); + UuidMetadataInput( + {this.name, this.email, this.externalId, this.profileUrl, this.custom}); Map toJson() => { - 'id': id, 'name': name, 'email': email, 'custom': custom, @@ -19,40 +17,60 @@ class UserDetails { }; } -class SpaceDetails { - String id; +class ChannelMetadataInput { String name; String description; dynamic custom; - SpaceDetails(this.id, this.name, {this.description, this.custom}); + ChannelMetadataInput({this.name, this.description, this.custom}); Map toJson() => { - 'id': id, 'name': name, 'description': description, 'custom': custom, }; } -class UpdateInfo { - String id; - dynamic custom; +class ChannelMemberMetadataInput { + String uuid; + Map custom; + + ChannelMemberMetadataInput(this.uuid, {this.custom}); + + Map toJson() => { + 'uuid': {'id': uuid}, + 'custom': custom, + }; +} - UpdateInfo(this.id, this.custom); +class MembershipMetadataInput { + String channelId; + Map custom; + + MembershipMetadataInput(this.channelId, {this.custom}); Map toJson() => { - 'id': id, + 'channel': {'id': channelId}, 'custom': custom, }; } -class IdInfo { - String id; +class UuIdInfo { + String uuid; + + UuIdInfo(this.uuid); + + Map toJson() => { + 'uuid': {'id': uuid}, + }; +} + +class ChannelIdInfo { + String channelId; - IdInfo(this.id); + ChannelIdInfo(this.channelId); Map toJson() => { - 'id': id, + 'channel': {'id': channelId}, }; } diff --git a/lib/src/dx/objects/space.dart b/lib/src/dx/objects/space.dart deleted file mode 100644 index ff177c6d..00000000 --- a/lib/src/dx/objects/space.dart +++ /dev/null @@ -1,245 +0,0 @@ -import 'package:pubnub/src/core/core.dart'; -import 'package:pubnub/src/default.dart'; - -import 'package:pubnub/src/dx/_utils/utils.dart'; -import 'package:pubnub/src/dx/_endpoints/objects/membership.dart'; -import 'package:pubnub/src/dx/_endpoints/objects/space.dart'; -import 'schema.dart'; - -final _logger = injectLogger('dx.objects.space'); - -class SpaceDx { - final Core _core; - SpaceDx(this._core); - - /// Creates a space with the specified attributes. - /// Returns the created space object, optionally including its custom data object. - /// - /// Space ID and name are required. - /// The custom object can only contain scalar values. - /// - /// If [keyset] is not provided, then it tries to obtain a keyset [using] name. - /// If that fails, then it uses the default keyset. - /// If that fails as well, then it will throw [EnsureException]. - /// - /// Returns 409 if a space already exists with the specified ID - Future create(SpaceDetails space, - {List include, Keyset keyset, String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(space).isNotNull('space details'); - var payload = await _core.parser.encode(space); - var params = CreateSpaceParams(payload, keyset, include: include); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => CreateSpaceResult.fromJson(object)); - } - - /// Returns the spaces associated with the given subscriber key, - /// optionally including each space's custom data object. - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - /// - /// If [keyset] is not provided, then it tries to obtain a keyset [using] name. - /// If that fails, then it uses the default keyset. - /// If that fails as well, then it will throw [EnsureException]. - Future getAllSpaces( - {List include, - int limit, - String start, - String end, - bool count, - String filter, - List sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - var params = GetAllSpacesParams(keyset, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => GetAllSpacesResult.fromJson(object)); - } - - /// Returns the specified space, optionally including its custom data object. - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Required field [spaceId] is the unique space identifier. - /// - /// If [keyset] is not provided, then it tries to obtain a keyset [using] name. - /// If that fails, then it uses the default keyset. - /// If that fails as well, then it will throw [EnsureException]. - Future getSpace(String spaceId, - {Keyset keyset, String using, List include}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(spaceId).isNotEmpty('spaceId'); - - var params = GetSpaceParams(keyset, spaceId, include: include); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => GetSpaceResult.fromJson(object)); - } - - /// Updates the specified space. Returns the space object, - /// optionally including its custom data object. - /// - /// You can change all of the space object's properties, except its ID. - /// Invalid property names are silently ignored and will not cause a request to fail. - /// - /// If you update the "custom" property in [space], you must completely replace it; - /// partial updates are not supported. - /// The custom object can only contain scalar values. - /// - /// If [keyset] is not provided, then it tries to obtain a keyset [using] name. - /// If that fails, then it uses the default keyset. - /// If that fails as well, then it will throw [EnsureException]. - Future updateSpace(SpaceDetails space, String spaceId, - {Keyset keyset, String using, List include}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(space).isNotNull('space details'); - Ensure(spaceId).isNotEmpty('spaceId'); - - var payload = await _core.parser.encode(space); - - var params = UpdateSpaceParams(keyset, payload, spaceId, include: include); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => UpdateSpaceResult.fromJson(object)); - } - - /// Deletes the specified space. - /// - /// [spaceId] should be a valid identifier of the space - /// - /// If [keyset] is not provided, then it tries to obtain a keyset [using] name. - /// If that fails, then it uses the default keyset. - /// If that fails as well, then it will throw [EnsureException]. - Future deleteSpace(String spaceId, - {Keyset keyset, String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(spaceId).isNotEmpty('spaceId'); - var params = DeleteSpaceParams(keyset, spaceId); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => DeleteSpaceResult.fromJson(object)); - } -} - -/// Represents a Space object -class Space { - final PubNub _core; - final Keyset _keyset; - final String _id; - - Space(this._core, this._keyset, this._id); - - /// You can use this method to add a users(members) into given space - /// Provide valid [userId] to add it to space - /// - /// Returns true if user is added to space successfully - Future addMembers(Set memberIds) async { - var success = false; - var result = await _core.memberships - .manageSpaceMembers(_id, add: memberIds, keyset: _keyset); - success = result.status == 200; - return success; - } - - /// You can use this method to remove an existing users(members) from given space - /// Provide valid [userId] to remove it from given space - /// - /// Returns true if user(member) is remove from given space successfully - Future removeMembers(Set memberIds) async { - var success = false; - var result = await _core.memberships - .manageSpaceMembers(_id, remove: memberIds, keyset: _keyset); - success = result.status == 200; - return success; - } - - /// It returns space's list of members - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - Future getMembers( - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - return await _core.memberships.getSpaceMembers(_id, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort, - keyset: keyset, - using: using); - } -} diff --git a/lib/src/dx/objects/user.dart b/lib/src/dx/objects/user.dart deleted file mode 100644 index 4f01dd54..00000000 --- a/lib/src/dx/objects/user.dart +++ /dev/null @@ -1,204 +0,0 @@ -import 'package:pubnub/src/core/core.dart'; -import 'package:pubnub/src/default.dart'; - -import 'package:pubnub/src/dx/_utils/utils.dart'; -import 'package:pubnub/src/dx/_endpoints/objects/membership.dart'; -import 'package:pubnub/src/dx/_endpoints/objects/user.dart'; -import 'schema.dart'; - -final _logger = injectLogger('dx.objects.user'); - -class UserDx { - final Core _core; - UserDx(this._core); - - /// Creates a user with specified deatils [UserDetails] - /// Returns created object optionally including the user's custom data object - /// - /// The custom object can only contain scalar values. - /// Id and name are required in [user] object. - /// Returns 400 if required properties are missing, or if any properties are of the wrong type. - /// Returns 409 if a user already exists with the specified ID. - Future create(UserDetails user, - {List include, Keyset keyset, String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(user).isNotNull('user details'); - var payload = await _core.parser.encode(user); - var params = CreateUserParams(payload, keyset, include: include); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => CreateUserResult.fromJson(object)); - } - - /// Returns a paginated list of users associated with the given subscription key, - /// optionally including each user record's custom data object. - /// - /// Provide [include] for List of additional/complex user properties to include in response. - /// Omit this parameter if you don't want to retrieve additional properties. - /// - /// You can limit number of returned user object using [limit] parameter - /// Default is 100, which is also the maximum value. - /// - /// You can specify [start] and [end] to specify previously-returned cursor bookmark - /// for fetching the next/previous page - /// - /// [filter] is Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// For sorting, use [sort] which is List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - Future getAllUsers( - {List include, - int limit, - String start, - String end, - bool count, - String filter, - List sort, - Keyset keyset, - String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - - var params = GetAllUsersParams(keyset, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => GetAllUsersResult.fromJson(object)); - } - - /// Returns the specified user object, optionally including the user's custom data object. - /// [userId] is unique user identifier to fetch the user object - Future getUser(String userId, - {Keyset keyset, String using, List include}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(userId).isNotEmpty('userId'); - var params = GetUserParams(keyset, userId, include: include); - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => GetUserResult.fromJson(object)); - } - - /// Updates the specified [userId] user object with any new information you provide. - /// Returns the updated user object, optionally including the user's custom data object. - /// - /// Notes: - /// You can change all of the user object's properties, except its ID. - /// Invalid property names are silently ignored and will not cause a request to fail. - /// If you update the "custom" property, you must completely replace it; partial updates are not supported. - /// The custom object can only contain scalar values. - Future updateUser(UserDetails user, String userId, - {Keyset keyset, String using, List include}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(user).isNotNull('user update details'); - Ensure(userId).isNotEmpty('userId'); - - var payload = await _core.parser.encode(user); - - var params = UpdateUserParams(keyset, payload, userId, include: include); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => UpdateUserResult.fromJson(object)); - } - - /// Deletes the specified [userId] user. - Future deleteUser(String userId, - {Keyset keyset, String using}) async { - keyset ??= _core.keysets.get(using, defaultIfNameIsNull: true); - Ensure(keyset).isNotNull('keyset'); - Ensure(userId).isNotEmpty('userId'); - - var params = DeleteUserParams(keyset, userId); - - return defaultFlow( - logger: _logger, - core: _core, - params: params, - serialize: (object, [_]) => DeleteUserResult.fromJson(object)); - } -} - -/// Representation of a user object -class User { - final PubNub _core; - final Keyset _keyset; - final String _id; - - User(this._core, this._keyset, this._id); - - /// Adds user to space - /// It registers the user to the spaces [spaceIds] - /// Provide valid [spaceIds] of spaces to which user needs to be added - /// - /// Returns true if user is added to space successfully - Future addToSpaces(Set spaceIds) async { - var success = false; - var result = await _core.memberships - .manageUserMemberships(_id, add: spaceIds, keyset: _keyset); - success = result.status == 200; - return success; - } - - /// It returns user's membership list - /// - /// Provide [include] List of additional/complex attributes to include in response. - /// Omit this parameter if you don't want to retrieve additional attributes. - /// - /// Use [limit] to specify Number of objects to return in response. - /// Default is 100, which is also the maximum value. - /// - /// [filter] is a Expression used to filter the results. - /// Only objects whose properties satisfy the given expression are returned. - /// - /// Provide [start] and [end] for Previously-returned cursor bookmark for - /// fetching the next/previous page. - /// - /// You can specify [count] to Request totalCount to be included in paginated response. - /// By default, totalCount is omitted. - /// - /// You can provide [sort] List of attributes to sort by. - /// Append :asc or :desc to an attribute to specify sort direction. - /// The default sort direction is ascending. - Future getMemberships( - {Set include, - int limit, - String start, - String end, - bool count, - String filter, - Set sort, - Keyset keyset, - String using}) async { - return await _core.memberships.getUserMemberships(_id, - include: include, - limit: limit, - start: start, - end: end, - count: count, - filter: filter, - sort: sort, - keyset: keyset, - using: using); - } -} diff --git a/lib/src/dx/objects/uuid_metadata.dart b/lib/src/dx/objects/uuid_metadata.dart new file mode 100644 index 00000000..b3ae4b2e --- /dev/null +++ b/lib/src/dx/objects/uuid_metadata.dart @@ -0,0 +1,104 @@ +import 'package:pubnub/pubnub.dart'; +import 'package:pubnub/src/core/core.dart'; +import 'package:pubnub/src/dx/_endpoints/objects/objects_types.dart'; + +import 'schema.dart'; + +/// Representation of UuidMetadata object +/// Useful while dealing with one specific `uuid` details +class UUIDMetadata { + final PubNub _core; + final Keyset _keyset; + final String _uuid; + + UUIDMetadata(this._core, this._keyset, this._uuid); + + /// It adds membership metadata for given `uuid` and returns paginated list of memberships metadata + /// + /// To include `custom` property fields of membership in response, set [includeCustomFields] to `true` + /// To include `channel` metadata fields of uuid's membership in response, set [includeChannelFields] to `true` + /// To include `custom` fields of membership's channel metadata, set [includeChannelCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future setMemberships( + List membershipMetadata, + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeChannelFields, + bool includeChannelCustomFields, + bool includeCount, + String filter, + Set sort}) => + _core.objects.setMemberships(membershipMetadata, + uuid: _uuid, + keyset: _keyset, + limit: limit, + start: start, + end: end, + includeCustomFields: includeCustomFields, + includeChannelFields: includeChannelFields, + includeChannelCustomFields: includeChannelCustomFields, + includeCount: includeCount, + filter: filter, + sort: sort); + + /// It returns membership metadata paginated list if `uuid` + /// + /// To include `custom` property fields of membership in response, set [includeCustomFields] to `true` + /// To include `channel` metadata fields of uuid's membership in response, set [includeChannelFields] to `true` + /// To include `custom` fields of membership's channel metadata, set [includeChannelCustomFields] to `true` + /// + /// Use [limit] to specify Number of objects to return in response. + /// Default is 100, which is also the maximum value. + /// + /// [filter] is a Expression used to filter the results. + /// Only objects whose properties satisfy the given expression are returned. + /// + /// Provide [start] and [end] for Previously-returned cursor bookmark for + /// fetching the next/previous page. + /// + /// To omit `totalCount` field from paginated list, set [includeCount] to `false` + /// Default is `true`. + /// + /// You can provide [sort] List of attributes to sort by. + /// Append :asc or :desc to an attribute to specify sort direction. + /// The default sort direction is ascending. + Future getMemberships( + {int limit, + String start, + String end, + bool includeCustomFields, + bool includeChannelFields, + bool includeChannelCustomFields, + bool includeCount, + String filter, + Set sort}) => + _core.objects.getMemberships( + uuid: _uuid, + limit: limit, + start: start, + end: end, + includeCustomFields: includeCustomFields, + includeChannelFields: includeChannelFields, + includeChannelCustomFields: includeChannelCustomFields, + includeCount: includeCount, + filter: filter, + sort: sort, + keyset: _keyset); +} diff --git a/pubspec.yaml b/pubspec.yaml index 4fa8998a..46c521b0 100644 --- a/pubspec.yaml +++ b/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: 1.1.3 +version: 1.2.0 homepage: https://www.pubnub.com/docs environment: diff --git a/test/dx/objects/channel_metadata_test.dart b/test/dx/objects/channel_metadata_test.dart new file mode 100644 index 00000000..cb2e8384 --- /dev/null +++ b/test/dx/objects/channel_metadata_test.dart @@ -0,0 +1,65 @@ +import 'package:test/test.dart'; +import 'package:pubnub/pubnub.dart'; +import '../../net/fake_net.dart'; + +part 'fixtures/channel_metadata.dart'; + +void main() { + PubNub pubnub; + group('DX [objectMetadata] [channel]', () { + setUp(() { + pubnub = PubNub(networking: FakeNetworkingModule()) + ..keysets.add( + Keyset( + subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('uuid-1')), + name: 'default', + useAsDefault: true); + }); + + test('#getAllChannelMetadata()', () async { + when( + path: + 'v2/objects/demo/channels?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}', + 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}', + 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}', + 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}', + method: 'DELETE', + ).then(status: 200, body: _removeMetadataSuccessResponse); + var response = await pubnub.objects.removeChannelMetadata('my-channel'); + expect(response, isA()); + }); + }); +} diff --git a/test/dx/objects/fixtures/channel_metadata.dart b/test/dx/objects/fixtures/channel_metadata.dart new file mode 100644 index 00000000..9abdbd18 --- /dev/null +++ b/test/dx/objects/fixtures/channel_metadata.dart @@ -0,0 +1,63 @@ +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/test/dx/objects/fixtures/membership.dart b/test/dx/objects/fixtures/membership.dart deleted file mode 100644 index 806319be..00000000 --- a/test/dx/objects/fixtures/membership.dart +++ /dev/null @@ -1,34 +0,0 @@ -part of '../membership_test.dart'; - -final _getUserMembershipsSuccessResponse = - '{"status":200,"data":[{"id":"my-channel","custom":{"starred":false},"space":{"id":"my-channel","name":"My space","description":"A space that is mine","created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" },"created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RUNDMDUwNjktNUYwRC00RTI0LUI1M0QtNUUzNkE2NkU0MEVFCg=="},{"id":"main","custom":{"starred":true},"space":{"id":"main","name":"Main space","description":"The main space","custom":{"public":true,"motd":"Always check your spelling!" },"created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg=="},"created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RUNDMDUwNjktNUYwRC00RTI0LUI1M0QtNUUzNkE2NkU0MEVFCg=="}],"totalCount":7,"next":"RDIwQUIwM0MtNUM2Ni00ODQ5LUFGRjMtNDk1MzNDQzE3MUVCCg==","prev":"MzY5RjkzQUQtNTM0NS00QjM0LUI0M0MtNjNBQUFGODQ5MTk2Cg=="}'; - -final _manageUserMembershipsBody = - '{"add":[{"id":"space-1"}],"update":[{"id":"space-X","custom":{"expression":"null"}}],"remove":[{"id":"space-2"}]}'; - -final _addUserMembershipsBody = '{"add":[{"id":"space-1"}]}'; - -final _removeUserMembershipsBody = '{"remove":[{"id":"space-2"}]}'; - -final _updateUserMembershipsBody = - '{"update":[{"id":"space-X","custom":{"expression":"null"}}]}'; - -final _manageUserMembershipsSuccessResponse = - '{"status":200,"data":[{"id":"space-1","custom":{"starred":false},"space":{"id":"my-channel","name":"My space","description":"A space that is mine","created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" },"created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RUNDMDUwNjktNUYwRC00RTI0LUI1M0QtNUUzNkE2NkU0MEVFCg=="},{"id":"main","custom":{"starred":true},"space":{"id":"main","name":"Main space","description":"The main space","custom":{"public":true,"motd":"Always check your spelling!" },"created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg=="},"created":"2019-02-20T23:11:20.893755","updated":"2019-02-20T23:11:20.893755","eTag":"RUNDMDUwNjktNUYwRC00RTI0LUI1M0QtNUUzNkE2NkU0MEVFCg=="}],"totalCount":7,"next":"RDIwQUIwM0MtNUM2Ni00ODQ5LUFGRjMtNDk1MzNDQzE3MUVCCg==","prev":"MzY5RjkzQUQtNTM0NS00QjM0LUI0M0MtNjNBQUFGODQ5MTk2Cg=="}'; - -final _getSpaceMembersSuccessResponse = - '{ "status": 200, "data": [ { "id": "user-1", "custom": { "role": "admin" }, "user": { "id": "user-1", "name": "John Doe", "externalId": null, "profileUrl": null, "email": "jack@twitter.com", "custom": null, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg==" }, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" }, { "id": "user-2", "custom": { "role": "moderator" }, "user": { "id": "user-2", "name": "Bob Cat", "externalId": null, "profileUrl": null, "email": "bobc@example.com", "custom": { "phone": "999-999-9999" }, "created": "2019-02-19T13:10:20.893755", "updated": "2019-02-21T03:29:00.173452", "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" }, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" } ], "totalCount": 37, "next": "RDIwQUIwM0MtNUM2Ni00ODQ5LUFGRjMtNDk1MzNDQzE3MUVCCg==", "prev": "MzY5RjkzQUQtNTM0NS00QjM0LUI0M0MtNjNBQUFGODQ5MTk2Cg==" }'; - -final _manageSpaceMembersBody = - '{"add":[{"id":"user-1"}],"update":[{"id":"user-1","custom":{"address":"null"}}],"remove":[{"id":"user-2"}]}'; - -final _manageSpaceMembersSuccessResponse = - '{ "status": 200, "data": [ { "id": "user-1", "custom": { "role": "admin" }, "user": { "id": "user-1", "name": "John Doe", "externalId": null, "profileUrl": null, "email": "jack@twitter.com", "custom": null, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg==" }, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" }, { "id": "user-2", "custom": { "role": "moderator" }, "user": { "id": "user-2", "name": "Bob Cat", "externalId": null, "profileUrl": null, "email": "bobc@example.com", "custom": { "phone": "999-999-9999" }, "created": "2019-02-19T13:10:20.893755", "updated": "2019-02-21T03:29:00.173452", "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" }, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "QkRENDA5MjItMUZCNC00REI5LUE4QTktRjJGNUMxNTc2MzE3Cg==" } ], "totalCount": 37, "next": "RDIwQUIwM0MtNUM2Ni00ODQ5LUFGRjMtNDk1MzNDQzE3MUVCCg==", "prev": "MzY5RjkzQUQtNTM0NS00QjM0LUI0M0MtNjNBQUFGODQ5MTk2Cg==" }'; - -final _commonObjectError = '''{ - "status": 500, - "error": { - "message": "An unexpected error ocurred while processing the request.", - "source": "objects" - } -}'''; diff --git a/test/dx/objects/fixtures/membership_metadata.dart b/test/dx/objects/fixtures/membership_metadata.dart new file mode 100644 index 00000000..614a6ad6 --- /dev/null +++ b/test/dx/objects/fixtures/membership_metadata.dart @@ -0,0 +1,98 @@ +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/test/dx/objects/fixtures/space.dart b/test/dx/objects/fixtures/space.dart deleted file mode 100644 index 92036ff1..00000000 --- a/test/dx/objects/fixtures/space.dart +++ /dev/null @@ -1,53 +0,0 @@ -part of '../space_test.dart'; - -class FakePubNub implements PubNub { - List invocations = []; - - FakePubNub(); - - @override - void noSuchMethod(Invocation invocation) { - invocations.add(invocation); - } -} - -final _createSpaceBody = - '{"id":"my-channel","name":"My space","description":"A space that is mine","custom":null}'; - -final _createSpaceSuccessResponse = - '{"status": 200,"data": {"id": "my-channel","name": "My space","description": "A space that is mine","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg=="}}'; - -final _getAllSpacesSuccessResponse = - '{ "status": 200, "data": [ { "id": "my-channel", "name": "My space", "description": "A space that is mine", "custom": null, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" }, { "id": "main", "name": "Main space", "description": "The main space", "custom": { "public": true, "motd": "Always check your spelling!" }, "created": "2019-02-20T23:11:20.893755", "updated": "2019-02-20T23:11:20.893755", "eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg==" } ], "totalCount": 9, "next": "MUIwQTAwMUItQkRBRC00NDkyLTgyMEMtODg2OUU1N0REMTNBCg==", "prev": "M0FFODRENzMtNjY2Qy00RUExLTk4QzktNkY1Q0I2MUJFNDRCCg==" }'; - -final _getSpaceSuccessResponse = - '{"status": 200,"data": {"id": "space-1","name": "My space","description": "A space that is mine","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg=="}}'; - -final _updateSpaceSuccessResponse = - '{"status": 200,"data": {"id": "space-1","name": "My space","description": "A space that is mine","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "RTc1NUQwNUItREMyNy00Q0YxLUJCNDItMEZDMTZDMzVCN0VGCg=="}}'; - -final _updateSpaceBody = - '{"id":"space-1","name":"My space","description":"A space that is mine","custom":null}'; - -final _httpError400 = '''{ - "status": 400, - "error": { - "message": "Request payload contained invalid input.", - "source": "objects", - "details": [ - { - "message": "User email must be a valid email address.", - "location": "user.email", - "locationType": "body" - } - ] - } -}'''; - -final _commonObjectError = '''{ - "status": 500, - "error": { - "message": "An unexpected error ocurred while processing the request.", - "source": "objects" - } -}'''; diff --git a/test/dx/objects/fixtures/user.dart b/test/dx/objects/fixtures/user.dart deleted file mode 100644 index 95f15e00..00000000 --- a/test/dx/objects/fixtures/user.dart +++ /dev/null @@ -1,52 +0,0 @@ -part of '../user_test.dart'; - -class FakePubNub implements PubNub { - List invocations = []; - - FakePubNub(); - - @override - void noSuchMethod(Invocation invocation) { - invocations.add(invocation); - } -} - -final _createuserBody = - '{"id":"user-1","name":"Name 1","email":"email@email.com","custom":null,"externalId":null,"profileUrl":null}'; - -final _createUserSuccessResponse = - '{"status": 200,"data": {"id": "user-1","name": "Name 1","externalId": null,"profileUrl": null,"email": "email@email.com","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg=="}}'; - -final _getAllUserSuccessResponse = - '{"status": 200,"data":[{"id": "user-1","name": "Name 1","externalId": null,"profileUrl": null,"email": "email@email.com","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg=="}]}'; - -final _getUserSuccessResponse = - '{"status": 200,"data":{"id": "user-1","name": "Name 1","externalId": null,"profileUrl": null,"email": "email@email.com","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg=="}}'; - -final _updateUserBody = - '{"id":"user-1","name":"Name 1","email":"email@email.com","custom":null,"externalId":null,"profileUrl":null}'; - -final _updateUserSuccessResponse = - '{"status": 200,"data":{"id": "user-1","name": "Name 1","externalId": null,"profileUrl": null,"email": "email@email.com","created": "2019-02-20T23:11:20.893755","updated": "2019-02-20T23:11:20.893755","eTag": "MDcyQ0REOTUtNEVBOC00QkY2LTgwOUUtNDkwQzI4MjgzMTcwCg=="}}'; -final _httpError400 = '''{ - "status": 400, - "error": { - "message": "Request payload contained invalid input.", - "source": "objects", - "details": [ - { - "message": "User email must be a valid email address.", - "location": "user.email", - "locationType": "body" - } - ] - } -}'''; - -final _commonObjectError = '''{ - "status": 500, - "error": { - "message": "An unexpected error ocurred while processing the request.", - "source": "objects" - } -}'''; diff --git a/test/dx/objects/fixtures/uuid_metadata.dart b/test/dx/objects/fixtures/uuid_metadata.dart new file mode 100644 index 00000000..918db508 --- /dev/null +++ b/test/dx/objects/fixtures/uuid_metadata.dart @@ -0,0 +1,67 @@ +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/test/dx/objects/membership_metadata_test.dart b/test/dx/objects/membership_metadata_test.dart new file mode 100644 index 00000000..5c14c50c --- /dev/null +++ b/test/dx/objects/membership_metadata_test.dart @@ -0,0 +1,129 @@ +import 'package:test/test.dart'; +import 'package:pubnub/pubnub.dart'; +import '../../net/fake_net.dart'; + +part 'fixtures/membership_metadata.dart'; + +void main() { + PubNub pubnub; + group('DX [objects] [membership]', () { + setUp(() { + pubnub = PubNub(networking: FakeNetworkingModule()) + ..keysets.add( + Keyset( + subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('uuid-1')), + name: 'default', + useAsDefault: true); + }); + + test('#getMemberships()', () async { + when( + path: + 'v2/objects/demo/uuids/uuid-2/channels?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}', + 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}', + 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}', + 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}', + 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}', + 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}', + 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}', + 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}', + 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/test/dx/objects/membership_test.dart b/test/dx/objects/membership_test.dart deleted file mode 100644 index c6106909..00000000 --- a/test/dx/objects/membership_test.dart +++ /dev/null @@ -1,248 +0,0 @@ -import 'objects.dart'; - -import 'package:pubnub/src/dx/_endpoints/objects/membership.dart'; -part 'fixtures/membership.dart'; - -void main() { - PubNub pubnub; - group('DX [objects] [memberships]', () { - setUp(() { - pubnub = PubNub(networking: FakeNetworkingModule()) - ..keysets.add(Keyset(subscribeKey: 'demo', publishKey: 'demo'), - name: 'default', useAsDefault: true); - }); - test('getUserMemberships throws when userId is empty', () { - var userId = ''; - expect(pubnub.memberships.getUserMemberships(userId), - throwsA(TypeMatcher())); - }); - test('getUserMemberships throws if there is no available keyset', () { - pubnub.keysets.remove('default'); - var userId = 'user-1'; - expect(pubnub.memberships.getUserMemberships(userId), - throwsA(TypeMatcher())); - }); - - test('getUserMemberships returnes valid response', () async { - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _getUserMembershipsSuccessResponse); - var response = await pubnub.memberships.getUserMemberships(userId); - - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - test('getUserMemberships returnes error', () async { - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.memberships.getUserMemberships(userId); - expect(response, isA()); - expect(response.status, 500); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('manageUserMemberships throws when userId is empty', () async { - var userId = ''; - expect(pubnub.memberships.manageUserMemberships(userId), - throwsA(TypeMatcher())); - }); - test('manageUserMemberships throws if there is no available keyset', - () async { - pubnub.keysets.remove('default'); - var userId = 'user-1'; - expect(pubnub.memberships.manageUserMemberships(userId), - throwsA(TypeMatcher())); - }); - - test('manageUserMemberships returnes valid response', () async { - var userId = 'user-1'; - var add = 'space-1'; - var update = UpdateInfo('space-X', {'expression': 'null'}); - var remove = 'space-2'; - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _manageUserMembershipsBody, - ).then(status: 200, body: _manageUserMembershipsSuccessResponse); - var response = await pubnub.memberships.manageUserMemberships(userId, - add: {add}, update: [update], remove: {remove}); - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - test('addUserMemberships returnes valid response', () async { - var userId = 'user-1'; - var add = 'space-1'; - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _addUserMembershipsBody, - ).then(status: 200, body: _manageUserMembershipsSuccessResponse); - var response = await pubnub.memberships.addUserMemberships(userId, [add]); - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - - test('removeUserMemberships returnes valid response', () async { - var userId = 'user-1'; - var remove = 'space-2'; - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _removeUserMembershipsBody, - ).then(status: 200, body: _manageUserMembershipsSuccessResponse); - var response = - await pubnub.memberships.removeUserMemberships(userId, [remove]); - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - - test('updateUserMemberships returnes valid response', () async { - var userId = 'user-1'; - var update = UpdateInfo('space-X', {'expression': 'null'}); - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _updateUserMembershipsBody, - ).then(status: 200, body: _manageUserMembershipsSuccessResponse); - var response = - await pubnub.memberships.updateUserMemberships(userId, [update]); - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - test('manageUserMemberships error response', () async { - var userId = 'user-1'; - var add = 'space-1'; - var update = UpdateInfo('space-X', {'expression': 'null'}); - var remove = 'space-2'; - when( - path: - 'v1/objects/demo/users/user-1/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _manageUserMembershipsBody, - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.memberships.manageUserMemberships(userId, - add: {add}, update: [update], remove: {remove}); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('getSpaceMembers throws when spaceId is empty', () async { - var spaceId = ''; - expect(pubnub.memberships.getSpaceMembers(spaceId), - throwsA(TypeMatcher())); - }); - test('getSpaceMembers throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - var spaceId = 'space-1'; - expect(pubnub.memberships.getSpaceMembers(spaceId), - throwsA(TypeMatcher())); - }); - - test('getSpaceMembers returnes valid response', () async { - var spaceId = 'space-1'; - when( - path: - 'v1/objects/demo/spaces/space-1/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _getSpaceMembersSuccessResponse); - var response = await pubnub.memberships.getSpaceMembers(spaceId); - - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - - test('getSpaceMembers returnes error response', () async { - var spaceId = 'space-1'; - when( - path: - 'v1/objects/demo/spaces/space-1/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.memberships.getSpaceMembers(spaceId); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('manageSpaceMembers throws when spaceId is empty', () async { - var spaceId = ''; - var add = 'user-1'; - var update = UpdateInfo('user-1', {'address': 'null'}); - var remove = 'user-2'; - expect( - pubnub.memberships.manageSpaceMembers(spaceId, - add: {add}, update: [update], remove: {remove}), - throwsA(TypeMatcher())); - }); - test('manageSpaceMembers throws if there is no available keyset', - () async { - pubnub.keysets.remove('default'); - var spaceId = 'space-1'; - var add = 'user-1'; - var update = UpdateInfo('user-1', {'address': 'null'}); - var remove = 'user-2'; - expect( - pubnub.memberships.manageSpaceMembers(spaceId, - add: {add}, update: [update], remove: {remove}), - throwsA(TypeMatcher())); - }); - - test('manageSpaceMembers returnes valid response', () async { - var spaceId = 'space-1'; - var add = 'user-1'; - var update = UpdateInfo('user-1', {'address': 'null'}); - var remove = 'user-2'; - when( - path: - 'v1/objects/demo/spaces/space-1/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _manageSpaceMembersBody, - ).then(status: 200, body: _manageSpaceMembersSuccessResponse); - var response = await pubnub.memberships.manageSpaceMembers(spaceId, - add: {add}, update: [update], remove: {remove}); - - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data[0], isA()); - }); - test('manageSpaceMembers returnes error response', () async { - var spaceId = 'space-1'; - var add = 'user-1'; - var update = UpdateInfo('user-1', {'address': 'null'}); - var remove = 'user-2'; - when( - path: - 'v1/objects/demo/spaces/space-1/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _manageSpaceMembersBody, - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.memberships.manageSpaceMembers(spaceId, - add: {add}, update: [update], remove: {remove}); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - }); -} diff --git a/test/dx/objects/objects.dart b/test/dx/objects/objects.dart deleted file mode 100644 index b24159e6..00000000 --- a/test/dx/objects/objects.dart +++ /dev/null @@ -1,7 +0,0 @@ -export 'package:test/test.dart'; -export 'package:pubnub/pubnub.dart'; - -export 'package:pubnub/src/core/core.dart'; -export 'package:pubnub/src/dx/objects/schema.dart'; - -export '../../net/fake_net.dart'; diff --git a/test/dx/objects/space_test.dart b/test/dx/objects/space_test.dart deleted file mode 100644 index 4c11abb0..00000000 --- a/test/dx/objects/space_test.dart +++ /dev/null @@ -1,237 +0,0 @@ -import 'objects.dart'; - -import 'package:pubnub/src/dx/_endpoints/objects/space.dart'; - -part 'fixtures/space.dart'; - -void main() { - PubNub pubnub; - group('DX [objects] [spaces]', () { - setUp(() { - pubnub = PubNub(networking: FakeNetworkingModule()) - ..keysets.add(Keyset(subscribeKey: 'demo', publishKey: 'demo'), - name: 'default', useAsDefault: true); - }); - - test('create throws when space object is null', () async { - expect(pubnub.spaces.create(null), - throwsA(TypeMatcher())); - }); - - test('create space successfully creates space', () async { - var space = SpaceDetails('my-channel', 'My space', - description: 'A space that is mine'); - when( - path: 'v1/objects/demo/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'POST', - body: _createSpaceBody, - ).then(status: 200, body: _createSpaceSuccessResponse); - var response = await pubnub.spaces.create(space); - - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data.id, equals(space.id)); - }); - test('create space response with http 400', () async { - var space = SpaceDetails('my-channel', 'My space', - description: 'A space that is mine'); - when( - path: 'v1/objects/demo/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'POST', - body: _createSpaceBody, - ).then(status: 200, body: _httpError400); - var response = await pubnub.spaces.create(space); - - expect(response, isA()); - expect(response.status, equals(400)); - }); - - test('create space error response', () async { - var space = SpaceDetails('my-channel', 'My space', - description: 'A space that is mine'); - when( - path: 'v1/objects/demo/spaces?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'POST', - body: _createSpaceBody, - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.spaces.create(space); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - test('create space throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - var space = SpaceDetails('my-channel', 'My space', - description: 'A space that is mine'); - expect( - pubnub.spaces.create(space), throwsA(TypeMatcher())); - }); - - test('getAllSpaces should return valid response', () async { - var id = 'my-channel'; - when( - path: - 'v1/objects/demo/spaces?limit=10&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _getAllSpacesSuccessResponse); - var response = await pubnub.spaces.getAllSpaces(limit: 10); - expect(response.status, 200); - expect(response, isA()); - expect(response.data[0], isA()); - expect(response.data[0].id, id); - }); - test('getAllSpaces sends error response', () async { - when( - path: - 'v1/objects/demo/spaces?limit=10&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.spaces.getAllSpaces(limit: 10); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - test('getAllSpaces throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - expect(pubnub.spaces.getAllSpaces(limit: 10), - throwsA(TypeMatcher())); - }); - test('getSpace should return valid response', () async { - var spaceId = 'space-1'; - when( - path: - 'v1/objects/demo/spaces/space-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _getSpaceSuccessResponse); - var response = await pubnub.spaces.getSpace(spaceId); - expect(response, isA()); - expect(response.data.id, spaceId); - }); - - test('getSpace throws when spaceId is empty', () async { - var spaceId = ''; - expect(pubnub.spaces.getSpace(spaceId), - throwsA(TypeMatcher())); - }); - - test('getSpace throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - var spaceId = 'space-1'; - expect(pubnub.spaces.getSpace(spaceId), - throwsA(TypeMatcher())); - }); - - test('updateSpace throws when spaceId is empty', () async { - var space = SpaceDetails('my-channel', 'My space', - description: 'A space that is mine'); - expect(pubnub.spaces.updateSpace(space, ''), - throwsA(TypeMatcher())); - }); - - test('updateSpace throws when space object is null', () async { - expect(pubnub.spaces.updateSpace(null, 'space-1'), - throwsA(TypeMatcher())); - }); - - test('updateSpace throws if there is no available keyset', () async { - var space = SpaceDetails('space-1', 'My space', - description: 'A space that is mine'); - pubnub.keysets.remove('default'); - var spaceId = 'space-1'; - expect(pubnub.spaces.updateSpace(space, spaceId), - throwsA(TypeMatcher())); - }); - - test('updateSpace returns valid response', () async { - var space = SpaceDetails('space-1', 'My space', - description: 'A space that is mine'); - var spaceId = 'space-1'; - when( - path: - 'v1/objects/demo/spaces/space-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _updateSpaceBody, - ).then(status: 200, body: _updateSpaceSuccessResponse); - var response = await pubnub.spaces.updateSpace(space, spaceId); - expect(response, isA()); - expect(response.status, 200); - expect(response.data.id, spaceId); - }); - - test('updateSpace error response', () async { - var space = SpaceDetails('space-1', 'My space', - description: 'A space that is mine'); - var spaceId = 'space-1'; - when( - path: - 'v1/objects/demo/spaces/space-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _updateSpaceBody, - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.spaces.updateSpace(space, spaceId); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - test('deleteSpace throws when spaceId is empty', () async { - expect(pubnub.spaces.deleteSpace(''), - throwsA(TypeMatcher())); - }); - - test('updateSpace throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - var spaceId = 'space-1'; - expect(pubnub.spaces.deleteSpace(spaceId), - throwsA(TypeMatcher())); - }); - - test('deleteSpace returns valid response', () async { - var spaceId = 'space-1'; - var expectedThen = '{"status": "0","data": {}}'; - when( - path: - 'v1/objects/demo/spaces/space-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'DELETE', - ).then(status: 200, body: expectedThen); - var response = await pubnub.spaces.deleteSpace(spaceId); - expect(response, isA()); - expect(response.status, '0'); - expect(response.data, {}); - }); - - test('deleteSpace returns valid response', () async { - var spaceId = 'space-1'; - var expectedThen = '{"status": "0","data": {}}'; - when( - path: - 'v1/objects/demo/spaces/space-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'DELETE', - ).then(status: 200, body: expectedThen); - var response = await pubnub.spaces.deleteSpace(spaceId); - expect(response, isA()); - expect(response.status, '0'); - expect(response.data, {}); - }); - test('space() should delegate to spaces.create()', () async { - var fakePubnub = FakePubNub(); - var keyset = Keyset(subscribeKey: 'test', publishKey: 'test'); - await fakePubnub.space('space-1', 'space-name', keyset: keyset); - - var invocation = fakePubnub.invocations[0]; - - expect(invocation.isMethod, equals(true)); - expect(invocation.memberName, equals(#space)); - expect(invocation.positionalArguments, equals(['space-1', 'space-name'])); - expect( - invocation.namedArguments, - equals({ - #description: null, - #custom: null, - #keyset: keyset, - #using: null - })); - }); - }); -} diff --git a/test/dx/objects/user_test.dart b/test/dx/objects/user_test.dart deleted file mode 100644 index 55a249a1..00000000 --- a/test/dx/objects/user_test.dart +++ /dev/null @@ -1,240 +0,0 @@ -import 'objects.dart'; - -import 'package:pubnub/src/dx/_endpoints/objects/user.dart'; - -part 'fixtures/user.dart'; - -void main() { - PubNub pubnub; - - group('DX [objects] [users]', () { - setUp(() { - pubnub = PubNub(networking: FakeNetworkingModule()) - ..keysets.add(Keyset(subscribeKey: 'demo', publishKey: 'demo'), - name: 'default', useAsDefault: true); - }); - test('create throws when user object is null', () async { - expect(pubnub.users.create(null), - throwsA(TypeMatcher())); - }); - test('create throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - expect(pubnub.users.create(usr), throwsA(TypeMatcher())); - }); - - test('create successfully creates user', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - when( - path: 'v1/objects/demo/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'POST', - body: _createuserBody, - ).then(status: 200, body: _createUserSuccessResponse); - var response = await pubnub.users.create(usr); - - expect(response, isA()); - expect(response.status, equals(200)); - expect(response.data.id, equals(usr.id)); - }); - - test('create user response 400', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - when( - path: 'v1/objects/demo/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'POST', - body: _createuserBody, - ).then(status: 200, body: _httpError400); - var response = await pubnub.users.create(usr); - - expect(response, isA()); - expect(response.status, equals(400)); - }); - - test('create user error response', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - when( - path: 'v1/objects/demo/users?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'POST', - body: _createuserBody, - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.users.create(usr); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('getAllUsers should return valid response', () async { - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users?limit=10&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _getAllUserSuccessResponse); - var response = await pubnub.users.getAllUsers(limit: 10); - expect(response, isA()); - expect(response.data[0], isA()); - expect(response.data[0].id, userId); - }); - test('getAllUsers sends error response', () async { - when( - path: - 'v1/objects/demo/users?limit=10&pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.users.getAllUsers(limit: 10); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('getAllUsers throws if there is no available keyset', () async { - pubnub.keysets.remove('default'); - expect(pubnub.users.getAllUsers(limit: 10), - throwsA(TypeMatcher())); - }); - - test('getUser should return valid response', () async { - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _getUserSuccessResponse); - var response = await pubnub.users.getUser(userId); - expect(response, isA()); - expect(response.data.id, userId); - }); - - test('getUser should return valid response', () async { - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'GET', - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.users.getUser(userId); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('get user throws when userId is empty', () async { - expect( - pubnub.users.getUser(''), throwsA(TypeMatcher())); - }); - test('getUser throws if there is no available keyset', () async { - var userId = 'user-1'; - pubnub.keysets.remove('default'); - expect(pubnub.users.getUser(userId), - throwsA(TypeMatcher())); - }); - test('update user throws when userId is empty', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - expect(pubnub.users.updateUser(usr, ''), - throwsA(TypeMatcher())); - }); - test('updateUser throws if there is no available keyset', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - var userId = 'user-1'; - pubnub.keysets.remove('default'); - expect(pubnub.users.updateUser(usr, userId), - throwsA(TypeMatcher())); - }); - test('update user throws when user object is null', () async { - expect(pubnub.users.updateUser(null, 'user-1'), - throwsA(TypeMatcher())); - }); - - test('update user returns valid response', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _updateUserBody, - ).then(status: 200, body: _updateUserSuccessResponse); - var response = await pubnub.users.updateUser(usr, userId); - expect(response, isA()); - expect(response.status, 200); - expect(response.data.id, userId); - }); - - test('update user returns error', () async { - var usr = UserDetails('user-1', 'Name 1', email: 'email@email.com'); - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'PATCH', - body: _updateUserBody, - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.users.updateUser(usr, userId); - expect(response, isA()); - expect(response.status, 500); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - - test('delete user throws when userId is empty', () async { - expect(pubnub.users.deleteUser(''), - throwsA(TypeMatcher())); - }); - test('deleteUser throws if there is no available keyset', () async { - var userId = 'user-1'; - pubnub.keysets.remove('default'); - expect(pubnub.users.deleteUser(userId), - throwsA(TypeMatcher())); - }); - - test('delete user returns valid response', () async { - var userId = 'user-1'; - var expectedThen = '{"status": "0","data": {}}'; - when( - path: - 'v1/objects/demo/users/user-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'DELETE', - ).then(status: 200, body: expectedThen); - var response = await pubnub.users.deleteUser(userId); - expect(response, isA()); - expect(response.status, '0'); - expect(response.data, {}); - }); - test('delete user returns error', () async { - var userId = 'user-1'; - when( - path: - 'v1/objects/demo/users/user-1?pnsdk=PubNub-Dart%2F${PubNub.version}', - method: 'DELETE', - ).then(status: 200, body: _commonObjectError); - var response = await pubnub.users.deleteUser(userId); - expect(response, isA()); - expect(response.status, equals(500)); - expect(response.error['message'], - equals('An unexpected error ocurred while processing the request.')); - }); - test('user() should delegate to users.create()', () async { - var fakePubnub = FakePubNub(); - var keyset = Keyset(subscribeKey: 'test', publishKey: 'test'); - await fakePubnub.user('user-1', 'name', keyset: keyset); - - var invocation = fakePubnub.invocations[0]; - - expect(invocation.isMethod, equals(true)); - expect(invocation.memberName, equals(#user)); - expect(invocation.positionalArguments, equals(['user-1', 'name'])); - expect( - invocation.namedArguments, - equals({ - #email: null, - #custom: null, - #externalId: null, - #profileUrl: null, - #keyset: keyset, - #using: null - })); - }); - }); -} diff --git a/test/dx/objects/uuid_metadata_test.dart b/test/dx/objects/uuid_metadata_test.dart new file mode 100644 index 00000000..6e17d51c --- /dev/null +++ b/test/dx/objects/uuid_metadata_test.dart @@ -0,0 +1,85 @@ +import 'package:test/test.dart'; +import 'package:pubnub/pubnub.dart'; +import '../../net/fake_net.dart'; + +part 'fixtures/uuid_metadata.dart'; + +void main() { + PubNub pubnub; + group('DX [objects] [uuid]', () { + setUp(() { + pubnub = PubNub(networking: FakeNetworkingModule()) + ..keysets.add( + Keyset( + subscribeKey: 'demo', publishKey: 'demo', uuid: UUID('uuid-1')), + name: 'default', + useAsDefault: true); + }); + test('#getAllUUIDMetadata()', () async { + when( + path: + 'v2/objects/demo/uuids?limit=10&count=true&pnsdk=PubNub-Dart%2F${PubNub.version}', + 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}', + 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}', + 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}', + 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}', + 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}', + method: 'DELETE', + ).then(status: 200, body: _removeMetadataSuccessResponse); + var response = await pubnub.objects.removeUUIDMetadata(); + expect(response, isA()); + }); + }); +} diff --git a/test/dx/push_test.dart b/test/dx/push_test.dart index 34b10588..dacc17b2 100644 --- a/test/dx/push_test.dart +++ b/test/dx/push_test.dart @@ -1,12 +1,5 @@ -@Timeout(Duration(seconds: 55)) import 'package:test/test.dart'; - -import 'objects/objects.dart'; - -import 'package:pubnub/src/default.dart'; -import 'package:pubnub/src/dx/_endpoints/push.dart'; -import 'package:pubnub/src/dx/push/push.dart'; - +import 'package:pubnub/pubnub.dart'; import '../net/fake_net.dart'; part './fixtures/push.dart';