From 14d70cc1ab32c989d2ade2a1c26316d338cda237 Mon Sep 17 00:00:00 2001 From: ManhNTX Date: Tue, 16 Aug 2022 10:56:06 +0700 Subject: [PATCH] TF-836: Create module forward --- forward/.gitignore | 33 +++++++ forward/.metadata | 10 ++ forward/README.md | 39 ++++++++ forward/analysis_options.yaml | 4 + forward/lib/forward/capability_forward.dart | 3 + .../converter/rule_filter_id_coverter.dart | 13 +++ forward/lib/forward/forward.dart | 6 ++ forward/lib/forward/forward_id.dart | 29 ++++++ .../lib/forward/get/get_forward_method.dart | 39 ++++++++ .../lib/forward/get/get_forward_response.dart | 30 ++++++ forward/lib/forward/tmail_forward.dart | 32 +++++++ forward/pubspec.yaml | 71 ++++++++++++++ .../test/forward/get_forward_method_test.dart | 95 +++++++++++++++++++ 13 files changed, 404 insertions(+) create mode 100644 forward/.gitignore create mode 100644 forward/.metadata create mode 100644 forward/README.md create mode 100644 forward/analysis_options.yaml create mode 100644 forward/lib/forward/capability_forward.dart create mode 100644 forward/lib/forward/converter/rule_filter_id_coverter.dart create mode 100644 forward/lib/forward/forward.dart create mode 100644 forward/lib/forward/forward_id.dart create mode 100644 forward/lib/forward/get/get_forward_method.dart create mode 100644 forward/lib/forward/get/get_forward_response.dart create mode 100644 forward/lib/forward/tmail_forward.dart create mode 100644 forward/pubspec.yaml create mode 100644 forward/test/forward/get_forward_method_test.dart diff --git a/forward/.gitignore b/forward/.gitignore new file mode 100644 index 000000000..4dbb0d67c --- /dev/null +++ b/forward/.gitignore @@ -0,0 +1,33 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ + +#generated file +*.g.dart +*.mocks.dart diff --git a/forward/.metadata b/forward/.metadata new file mode 100644 index 000000000..e7011f64f --- /dev/null +++ b/forward/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + channel: stable + +project_type: package diff --git a/forward/README.md b/forward/README.md new file mode 100644 index 000000000..8b55e735b --- /dev/null +++ b/forward/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/forward/analysis_options.yaml b/forward/analysis_options.yaml new file mode 100644 index 000000000..a5744c1cf --- /dev/null +++ b/forward/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/forward/lib/forward/capability_forward.dart b/forward/lib/forward/capability_forward.dart new file mode 100644 index 000000000..c61e3b772 --- /dev/null +++ b/forward/lib/forward/capability_forward.dart @@ -0,0 +1,3 @@ +import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; + +final capabilityForward = CapabilityIdentifier(Uri.parse('com:linagora:params:jmap:forward')); \ No newline at end of file diff --git a/forward/lib/forward/converter/rule_filter_id_coverter.dart b/forward/lib/forward/converter/rule_filter_id_coverter.dart new file mode 100644 index 000000000..a0c8b4a68 --- /dev/null +++ b/forward/lib/forward/converter/rule_filter_id_coverter.dart @@ -0,0 +1,13 @@ +import 'package:forward/forward/forward_id.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class ForwardIdConverter implements JsonConverter { + const ForwardIdConverter(); + + @override + ForwardId fromJson(String json) => ForwardId(id: Id(json)); + + @override + String toJson(ForwardId object) => object.id.value; +} diff --git a/forward/lib/forward/forward.dart b/forward/lib/forward/forward.dart new file mode 100644 index 000000000..5fc575f0b --- /dev/null +++ b/forward/lib/forward/forward.dart @@ -0,0 +1,6 @@ +import 'package:equatable/equatable.dart'; + +abstract class Forward with EquatableMixin { + @override + List get props => []; +} \ No newline at end of file diff --git a/forward/lib/forward/forward_id.dart b/forward/lib/forward/forward_id.dart new file mode 100644 index 000000000..a4ac343c7 --- /dev/null +++ b/forward/lib/forward/forward_id.dart @@ -0,0 +1,29 @@ +import 'package:equatable/equatable.dart'; +import 'package:forward/forward/converter/rule_filter_id_coverter.dart'; +import 'package:jmap_dart_client/http/converter/id_converter.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; + +enum ForwardIdType { + singleton('singleton'); + + const ForwardIdType(this.value); + + final String value; +} + +@ForwardIdConverter() +@IdConverter() +class ForwardId with EquatableMixin { + final Id id; + + ForwardId({ + required this.id, + }); + + @override + List get props => [id]; +} + +extension ForwardIdSingleton on ForwardId { + static ForwardId get forwardIdSingleton => ForwardId(id: Id(ForwardIdType.singleton.value)); +} diff --git a/forward/lib/forward/get/get_forward_method.dart b/forward/lib/forward/get/get_forward_method.dart new file mode 100644 index 000000000..5fce71200 --- /dev/null +++ b/forward/lib/forward/get/get_forward_method.dart @@ -0,0 +1,39 @@ +import 'package:forward/forward/capability_forward.dart'; +import 'package:forward/forward/converter/rule_filter_id_coverter.dart'; +import 'package:jmap_dart_client/http/converter/account_id_converter.dart'; +import 'package:jmap_dart_client/http/converter/id_converter.dart'; +import 'package:jmap_dart_client/http/converter/properties_converter.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; +import 'package:jmap_dart_client/jmap/core/method/request/get_method.dart'; +import 'package:jmap_dart_client/jmap/core/request/request_invocation.dart'; +import 'package:jmap_dart_client/jmap/core/request/result_reference.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'get_forward_method.g.dart'; + +@IdConverter() +@ForwardIdConverter() +@AccountIdConverter() +@PropertiesConverter() +@JsonSerializable(explicitToJson: true) +class GetForwardMethod extends GetMethod { + GetForwardMethod(AccountId accountId) : super(accountId); + + @override + MethodName get methodName => MethodName('Forward/get'); + + @override + Set get requiredCapabilities => { + CapabilityIdentifier.jmapCore, + capabilityForward, + }; + + @override + List get props => [methodName, accountId, ids, requiredCapabilities]; + + factory GetForwardMethod.fromJson(Map json) => _$GetForwardMethodFromJson(json); + + @override + Map toJson() => _$GetForwardMethodToJson(this); +} \ No newline at end of file diff --git a/forward/lib/forward/get/get_forward_response.dart b/forward/lib/forward/get/get_forward_response.dart new file mode 100644 index 000000000..09b2ccf83 --- /dev/null +++ b/forward/lib/forward/get/get_forward_response.dart @@ -0,0 +1,30 @@ +import 'package:forward/forward/tmail_forward.dart'; +import 'package:jmap_dart_client/http/converter/account_id_converter.dart'; +import 'package:jmap_dart_client/http/converter/id_converter.dart'; +import 'package:jmap_dart_client/http/converter/state_converter.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:jmap_dart_client/jmap/core/method/response/get_response.dart'; +import 'package:jmap_dart_client/jmap/core/state.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'get_forward_response.g.dart'; + +@StateConverter() +@AccountIdConverter() +@IdConverter() +@JsonSerializable() +class GetForwardResponse extends GetResponse { + GetForwardResponse(AccountId accountId, State state, List list, List? notFound) : super(accountId, state, list, notFound); + + factory GetForwardResponse.fromJson(Map json) => _$GetForwardResponseFromJson(json); + + static GetForwardResponse deserialize(Map json) { + return GetForwardResponse.fromJson(json); + } + + Map toJson() => _$GetForwardResponseToJson(this); + + @override + List get props => [accountId, state, list, notFound]; +} \ No newline at end of file diff --git a/forward/lib/forward/tmail_forward.dart b/forward/lib/forward/tmail_forward.dart new file mode 100644 index 000000000..cd188662c --- /dev/null +++ b/forward/lib/forward/tmail_forward.dart @@ -0,0 +1,32 @@ +import 'package:forward/forward/converter/rule_filter_id_coverter.dart'; +import 'package:forward/forward/forward.dart'; +import 'package:forward/forward/forward_id.dart'; +import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'tmail_forward.g.dart'; + +@ForwardIdConverter() +@JsonSerializable() +class TmailForward extends Forward { + final ForwardId id; + final bool localCopy; + final Set forwards; + TmailForward({ + required this.id, + required this.localCopy, + required this.forwards, + }); + + factory TmailForward.fromJson(Map json) => + _$TmailForwardFromJson(json); + + Map toJson() => _$TmailForwardToJson(this); + + @override + List get props => [ + id, + localCopy, + forwards, + ]; +} diff --git a/forward/pubspec.yaml b/forward/pubspec.yaml new file mode 100644 index 000000000..05107c8e3 --- /dev/null +++ b/forward/pubspec.yaml @@ -0,0 +1,71 @@ +name: forward +description: TMail forward extension +publish_to: 'none' + +version: 1.0.0+1 + +environment: + sdk: ">=2.17.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + equatable: 2.0.3 + + json_annotation: 4.5.0 + + jmap_dart_client: + git: + url: https://github.com/linagora/jmap-dart-client.git + ref: master + + http_mock_adapter: 0.3.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^1.0.0 + + build_runner: 2.1.11 + + json_serializable: 6.2.0 + + mockito: 5.2.0 +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + uses-material-design: true + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/forward/test/forward/get_forward_method_test.dart b/forward/test/forward/get_forward_method_test.dart new file mode 100644 index 000000000..cc3db3820 --- /dev/null +++ b/forward/test/forward/get_forward_method_test.dart @@ -0,0 +1,95 @@ +import 'package:dio/dio.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:forward/forward/forward_id.dart'; +import 'package:forward/forward/get/get_forward_method.dart'; +import 'package:forward/forward/get/get_forward_response.dart'; +import 'package:forward/forward/tmail_forward.dart'; +import 'package:http_mock_adapter/http_mock_adapter.dart'; +import 'package:jmap_dart_client/http/http_client.dart'; +import 'package:jmap_dart_client/jmap/account_id.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:jmap_dart_client/jmap/jmap_request.dart'; + +void main() { + group('test to json get forward method', () { + final expectRuleFilter1 = TmailForward( + id: ForwardIdSingleton.forwardIdSingleton, + localCopy: true, + forwards: {"bob@domain.org", "alice@domain.org"}, + ); + + test('get forward method and response parsing', () async { + final baseOption = BaseOptions(method: 'POST'); + final dio = Dio(baseOption)..options.baseUrl = 'http://domain.com'; + final dioAdapter = DioAdapter(dio: dio); + dioAdapter.onPost( + '/jmap', + (server) => server.reply(200, { + "sessionState": "abcdefghij", + "methodResponses": [ + [ + "Forward/get", + { + "accountId": "123", + "notFound": [], + "state": "1", + "list": [ + { + "id": "singleton", + "localCopy": true, + "forwards": ["bob@domain.org", "alice@domain.org"] + } + ] + }, + "c0" + ] + ] + }), + data: { + "using": [ + "urn:ietf:params:jmap:core", + "com:linagora:params:jmap:forward" + ], + "methodCalls": [ + [ + "Forward/get", + { + "accountId": + "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + "ids": ["singleton"] + }, + "c0" + ] + ] + }, + headers: { + "accept": "application/json;jmapVersion=rfc-8621", + "content-type": "application/json; charset=utf-8", + "content-length": 212 + }); + + final httpClient = HttpClient(dio); + final processingInvocation = ProcessingInvocation(); + final requestBuilder = + JmapRequestBuilder(httpClient, processingInvocation); + final accountId = AccountId(Id( + '29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6')); + + final getForwardMethod = GetForwardMethod(accountId) + ..addIds({ForwardIdSingleton.forwardIdSingleton.id}); + final getRuleFilterInvocation = + requestBuilder.invocation(getForwardMethod); + final response = await (requestBuilder + ..usings(getForwardMethod.requiredCapabilities)) + .build() + .execute(); + + final resultList = response.parse( + getRuleFilterInvocation.methodCallId, + GetForwardResponse.deserialize); + + expect(resultList?.list.length, equals(1)); + expect(resultList?.list, containsAll({expectRuleFilter1})); + }); + }); +}