From 11dc2f7c89a1ede3cb2063b57ba37c2b68d27a93 Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 12 Mar 2024 10:58:56 +0700 Subject: [PATCH 1/4] Add `CancelToken` to HttpClient --- lib/jmap/jmap_request.dart | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/jmap/jmap_request.dart b/lib/jmap/jmap_request.dart index 967ec52..4e0b720 100644 --- a/lib/jmap/jmap_request.dart +++ b/lib/jmap/jmap_request.dart @@ -1,4 +1,5 @@ import 'package:built_collection/built_collection.dart'; +import 'package:dio/dio.dart'; import 'package:jmap_dart_client/http/http_client.dart'; import 'package:jmap_dart_client/jmap/core/request/reference_path.dart'; import 'package:jmap_dart_client/jmap/core/request/result_reference.dart'; @@ -20,14 +21,18 @@ class JmapRequest { RequestObject? _requestObject; RequestObject? get requestObject => _requestObject; - Future execute() async { + Future execute({CancelToken? cancelToken}) async { _requestObject = (RequestObject.builder() ..usings(_capabilities.asSet()) ..methodCalls(_invocations.values.toList())) .build(); - return _httpClient.post('', data: _requestObject?.toJson()) - .then((value) => extractData(value)) + return _httpClient.post( + '', + data: _requestObject?.toJson(), + cancelToken: cancelToken + ) + .then(extractData) .catchError((error) => throw error); } From 37593bf9acc3f4fdf8c7a4a7a735a687a7bfe9ad Mon Sep 17 00:00:00 2001 From: dab246 Date: Mon, 15 Jan 2024 14:00:48 +0700 Subject: [PATCH 2/4] Add `Accept-Language` and `Content-Language` header to email body values --- lib/jmap/mail/email/email_body_value.dart | 71 ++++++++++++++++--- lib/jmap/mail/email/email_body_value.g.dart | 22 ------ .../email/individual_header_identifier.dart | 2 + test/jmap/email/email_object_test.dart | 18 ++--- .../jmap/email/set/set_email_method_test.dart | 6 +- .../set_email_submission_method_test.dart | 8 +-- 6 files changed, 81 insertions(+), 46 deletions(-) delete mode 100644 lib/jmap/mail/email/email_body_value.g.dart diff --git a/lib/jmap/mail/email/email_body_value.dart b/lib/jmap/mail/email/email_body_value.dart index 109cab1..4413d9f 100644 --- a/lib/jmap/mail/email/email_body_value.dart +++ b/lib/jmap/mail/email/email_body_value.dart @@ -1,20 +1,75 @@ import 'package:equatable/equatable.dart'; -import 'package:json_annotation/json_annotation.dart'; +import 'package:jmap_dart_client/http/converter/individual_header_identifier_converter.dart'; +import 'package:jmap_dart_client/jmap/mail/email/individual_header_identifier.dart'; -part 'email_body_value.g.dart'; - -@JsonSerializable() class EmailBodyValue with EquatableMixin { final String value; final bool isEncodingProblem; final bool isTruncated; + final Map? acceptLanguageHeader; + final Map? contentLanguageHeader; + + EmailBodyValue({ + required this.value, + required this.isEncodingProblem, + required this.isTruncated, + this.acceptLanguageHeader, + this.contentLanguageHeader + }); + + factory EmailBodyValue.fromJson(Map json) { + return EmailBodyValue( + value: json['value'] as String, + isEncodingProblem: json['isEncodingProblem'] as bool, + isTruncated: json['isTruncated'] as bool, + acceptLanguageHeader: IndividualHeaderIdentifierNullableConverter() + .parseEntry( + IndividualHeaderIdentifier.acceptLanguageHeader.value, + json[IndividualHeaderIdentifier.acceptLanguageHeader.value] as String? + ), + contentLanguageHeader: IndividualHeaderIdentifierNullableConverter() + .parseEntry( + IndividualHeaderIdentifier.contentLanguageHeader.value, + json[IndividualHeaderIdentifier.contentLanguageHeader.value] as String? + ), + ); + } - EmailBodyValue(this.value, this.isEncodingProblem, this.isTruncated); + Map toJson() { + final val = {}; - factory EmailBodyValue.fromJson(Map json) => _$EmailBodyValueFromJson(json); + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } - Map toJson() => _$EmailBodyValueToJson(this); + writeNotNull('value', value); + writeNotNull('isEncodingProblem', isEncodingProblem); + writeNotNull('isTruncated', isTruncated); + writeNotNull( + IndividualHeaderIdentifier.acceptLanguageHeader.value, + IndividualHeaderIdentifierNullableConverter().toJson( + acceptLanguageHeader, + IndividualHeaderIdentifier.acceptLanguageHeader + ) + ); + writeNotNull( + IndividualHeaderIdentifier.contentLanguageHeader.value, + IndividualHeaderIdentifierNullableConverter().toJson( + contentLanguageHeader, + IndividualHeaderIdentifier.contentLanguageHeader + ) + ); + return val; + } @override - List get props => [value, isEncodingProblem, isTruncated]; + List get props => [ + value, + isEncodingProblem, + isTruncated, + acceptLanguageHeader, + contentLanguageHeader, + ]; } \ No newline at end of file diff --git a/lib/jmap/mail/email/email_body_value.g.dart b/lib/jmap/mail/email/email_body_value.g.dart deleted file mode 100644 index 38b30ee..0000000 --- a/lib/jmap/mail/email/email_body_value.g.dart +++ /dev/null @@ -1,22 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'email_body_value.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -EmailBodyValue _$EmailBodyValueFromJson(Map json) { - return EmailBodyValue( - json['value'] as String, - json['isEncodingProblem'] as bool, - json['isTruncated'] as bool, - ); -} - -Map _$EmailBodyValueToJson(EmailBodyValue instance) => - { - 'value': instance.value, - 'isEncodingProblem': instance.isEncodingProblem, - 'isTruncated': instance.isTruncated, - }; diff --git a/lib/jmap/mail/email/individual_header_identifier.dart b/lib/jmap/mail/email/individual_header_identifier.dart index b2ed503..12b6ace 100644 --- a/lib/jmap/mail/email/individual_header_identifier.dart +++ b/lib/jmap/mail/email/individual_header_identifier.dart @@ -4,6 +4,8 @@ class IndividualHeaderIdentifier with EquatableMixin { static final headerUserAgent = IndividualHeaderIdentifier('header:User-Agent:asText'); static final headerMdn = IndividualHeaderIdentifier('header:Disposition-Notification-To:asText'); static final headerCalendarEvent = IndividualHeaderIdentifier('header:X-MEETING-UID:asText'); + static final acceptLanguageHeader = IndividualHeaderIdentifier('header:Accept-Language:asText'); + static final contentLanguageHeader = IndividualHeaderIdentifier('header:Content-Language:asText'); final String value; diff --git a/test/jmap/email/email_object_test.dart b/test/jmap/email/email_object_test.dart index da71101..0925bca 100644 --- a/test/jmap/email/email_object_test.dart +++ b/test/jmap/email/email_object_test.dart @@ -155,9 +155,9 @@ void main() { }, bodyValues: { PartId('2'): EmailBodyValue( - 'Dear, I update my last week activities. Thanks and BRs', - false, - false + value: 'Dear, I update my last week activities. Thanks and BRs', + isEncodingProblem: false, + isTruncated: false ) }, preview: 'Dear, I update my last week activities. Thanks and BRs', @@ -330,9 +330,9 @@ void main() { }, bodyValues: { PartId('2'): EmailBodyValue( - 'Dear, I update my last week activities. Thanks and BRs', - false, - false + value: 'Dear, I update my last week activities. Thanks and BRs', + isEncodingProblem: false, + isTruncated: false ) }, preview: 'Dear, I update my last week activities. Thanks and BRs', @@ -503,9 +503,9 @@ void main() { }, bodyValues: { PartId('2'): EmailBodyValue( - 'Dear, I update my last week activities. Thanks and BRs', - false, - false + value: 'Dear, I update my last week activities. Thanks and BRs', + isEncodingProblem: false, + isTruncated: false ) }, preview: 'Dear, I update my last week activities. Thanks and BRs', diff --git a/test/jmap/email/set/set_email_method_test.dart b/test/jmap/email/set/set_email_method_test.dart index 336c3ba..128ce3d 100644 --- a/test/jmap/email/set/set_email_method_test.dart +++ b/test/jmap/email/set/set_email_method_test.dart @@ -124,7 +124,7 @@ void main() { subject: 'set email 3', htmlBody: {EmailBodyPart(partId: PartId('a49d'), type: MediaType.parse('text/html'))}, bodyValues: { - PartId('a49d'): EmailBodyValue('test html html', false, false) + PartId('a49d'): EmailBodyValue(value: 'test html html', isEncodingProblem: false, isTruncated: false) }, ) ); @@ -242,7 +242,7 @@ void main() { subject: 'set email 3', htmlBody: {EmailBodyPart(partId: PartId('a49d'), type: MediaType.parse('text/html'))}, bodyValues: { - PartId('a49d'): EmailBodyValue('test html html', false, false) + PartId('a49d'): EmailBodyValue(value: 'test html html', isEncodingProblem: false, isTruncated: false) }, headerUserAgent: {IndividualHeaderIdentifier.headerUserAgent : 'Android/1.0.0 TeamMail/1.0'} ) @@ -350,7 +350,7 @@ void main() { subject: '[POSTMAN] SEND EMAIL WITH MDN MDN MDN', htmlBody: {EmailBodyPart(partId: PartId('abc123'), type: MediaType.parse('text/html'))}, bodyValues: { - PartId('abc123'): EmailBodyValue('[POSTMAN] SEND EMAIL WITH MDN', false, false) + PartId('abc123'): EmailBodyValue(value: '[POSTMAN] SEND EMAIL WITH MDN', isEncodingProblem: false, isTruncated: false) }, headerMdn: {IndividualHeaderIdentifier.headerMdn : "qkdo@linagora.com"} ) diff --git a/test/jmap/email/submission/set_email_submission_method_test.dart b/test/jmap/email/submission/set_email_submission_method_test.dart index e95efa1..30b6b2a 100644 --- a/test/jmap/email/submission/set_email_submission_method_test.dart +++ b/test/jmap/email/submission/set_email_submission_method_test.dart @@ -172,7 +172,7 @@ void main() { to: {EmailAddress("userD", 'userd@qa.open-paas.org')}, htmlBody: {EmailBodyPart(partId: PartId('mmm'), blobId: Id('aaaa'), type: MediaType.parse('text/html'))}, bodyValues: { - PartId('mmm'): EmailBodyValue('

Hello test send 2



', false, false) + PartId('mmm'): EmailBodyValue(value: '

Hello test send 2



', isEncodingProblem: false, isTruncated: false) } ) ); @@ -188,7 +188,7 @@ void main() { ..addOnSuccessUpdateEmail({ EmailSubmissionId(ReferenceId(ReferencePrefix.defaultPrefix, Id('a1234'))): PatchObject({ PatchObject.mailboxIdsProperty: { - MailboxIdConverter().toJson(MailboxId(Id('5dfb3290-0a14-11ec-b57c-2fef1ee78d9e'))): true + const MailboxIdConverter().toJson(MailboxId(Id('5dfb3290-0a14-11ec-b57c-2fef1ee78d9e'))): true } }) }); @@ -361,7 +361,7 @@ void main() { to: {EmailAddress("userD", 'userd@qa.open-paas.org')}, htmlBody: {EmailBodyPart(partId: PartId('mmm'), blobId: Id('aaaa'), type: MediaType.parse('text/html'))}, bodyValues: { - PartId('mmm'): EmailBodyValue('

Hello test send 2



', false, false) + PartId('mmm'): EmailBodyValue(value: '

Hello test send 2



', isEncodingProblem: false, isTruncated: false) }, headerUserAgent: {IndividualHeaderIdentifier.headerUserAgent : 'Android/1.0.0 TeamMail/1.0'} ) @@ -378,7 +378,7 @@ void main() { ..addOnSuccessUpdateEmail({ EmailSubmissionId(ReferenceId(ReferencePrefix.defaultPrefix, Id('a1234'))): PatchObject({ PatchObject.mailboxIdsProperty: { - MailboxIdConverter().toJson(MailboxId(Id('5dfb3290-0a14-11ec-b57c-2fef1ee78d9e'))): true + const MailboxIdConverter().toJson(MailboxId(Id('5dfb3290-0a14-11ec-b57c-2fef1ee78d9e'))): true } }) }); From 1ff66ac7bd2e4913baefc536b3f5c485da8f7bfe Mon Sep 17 00:00:00 2001 From: dab246 Date: Mon, 15 Jan 2024 14:01:53 +0700 Subject: [PATCH 3/4] Sync code format by linter --- .../identities/get/get_identity_method.dart | 1 + .../identities/set/set_identity_method.dart | 2 +- .../changes/changes_email_response.g.dart | 14 +------ lib/jmap/mail/email/set/set_email_method.dart | 2 +- .../set/set_email_submission_method.dart | 12 ++---- .../mail/mailbox/get/get_mailbox_method.dart | 1 + lib/jmap/mail/mailbox/mailbox_rights.dart | 2 + .../mail/mailbox/set/set_mailbox_method.dart | 2 +- .../vacation/get/get_vacation_method.dart | 1 + lib/jmap/mdn/send/mdn_send_response.dart | 4 +- .../get/get_push_subscription_method.dart | 1 + .../set/set_push_subscription_method.dart | 2 +- .../set/set_push_subscription_response.dart | 12 +++--- lib/jmap/push/state_change.dart | 4 +- lib/jmap/quotas/get/get_quota_method.dart | 1 + lib/util/options_extensions.dart | 6 +-- lib/util/util.dart | 4 +- test/jmap/core/session/session_test.dart | 40 +++++++++---------- test/jmap/core/utc_date_converter_test.dart | 4 +- .../query_with_operator_emails_test.dart | 4 +- .../search_by_after_use_case_test.dart | 2 +- .../search_by_form_use_case_test.dart | 2 +- ...search_by_time_and_text_use_case_test.dart | 2 +- .../search_emails_inbox_use_case_test.dart | 2 +- test/jmap/email/sort_list_email_test.dart | 2 +- 25 files changed, 60 insertions(+), 69 deletions(-) diff --git a/lib/jmap/identities/get/get_identity_method.dart b/lib/jmap/identities/get/get_identity_method.dart index 9fc408b..c40c649 100644 --- a/lib/jmap/identities/get/get_identity_method.dart +++ b/lib/jmap/identities/get/get_identity_method.dart @@ -37,5 +37,6 @@ class GetIdentityMethod extends GetMethod { factory GetIdentityMethod.fromJson(Map json) => _$GetIdentityMethodFromJson(json); + @override Map toJson() => _$GetIdentityMethodToJson(this); } \ No newline at end of file diff --git a/lib/jmap/identities/set/set_identity_method.dart b/lib/jmap/identities/set/set_identity_method.dart index 044da35..0fb0d56 100644 --- a/lib/jmap/identities/set/set_identity_method.dart +++ b/lib/jmap/identities/set/set_identity_method.dart @@ -43,7 +43,7 @@ class SetIdentityMethod extends SetMethod { writeNotNull('update', update ?.map((id, update) => SetMethodPropertiesConverter().fromMapIdToJson(id, update.toJson()))); writeNotNull('destroy', destroy - ?.map((destroyId) => IdConverter().toJson(destroyId)).toList()); + ?.map((destroyId) => const IdConverter().toJson(destroyId)).toList()); return val; } diff --git a/lib/jmap/mail/email/changes/changes_email_response.g.dart b/lib/jmap/mail/email/changes/changes_email_response.g.dart index 1b494cd..038f814 100644 --- a/lib/jmap/mail/email/changes/changes_email_response.g.dart +++ b/lib/jmap/mail/email/changes/changes_email_response.g.dart @@ -22,16 +22,4 @@ ChangesEmailResponse _$ChangesEmailResponseFromJson(Map json) { .map((e) => const IdConverter().fromJson(e as String)) .toSet(), ); -} - -Map _$ChangesEmailResponseToJson( - ChangesEmailResponse instance) => - { - 'accountId': const AccountIdConverter().toJson(instance.accountId), - 'oldState': const StateConverter().toJson(instance.oldState), - 'newState': const StateConverter().toJson(instance.newState), - 'hasMoreChanges': instance.hasMoreChanges, - 'created': instance.created.map(const IdConverter().toJson).toList(), - 'updated': instance.updated.map(const IdConverter().toJson).toList(), - 'destroyed': instance.destroyed.map(const IdConverter().toJson).toList(), - }; +} \ No newline at end of file diff --git a/lib/jmap/mail/email/set/set_email_method.dart b/lib/jmap/mail/email/set/set_email_method.dart index c190ce7..185c95b 100644 --- a/lib/jmap/mail/email/set/set_email_method.dart +++ b/lib/jmap/mail/email/set/set_email_method.dart @@ -39,7 +39,7 @@ class SetEmailMethod extends SetMethod { ?.map((id, update) => SetMethodPropertiesConverter() .fromMapIdToJson(id, update.toJson()))); writeNotNull('destroy', destroy - ?.map((destroyId) => IdConverter() + ?.map((destroyId) => const IdConverter() .toJson(destroyId)).toList()); return val; diff --git a/lib/jmap/mail/email/submission/set/set_email_submission_method.dart b/lib/jmap/mail/email/submission/set/set_email_submission_method.dart index 82820b3..7723691 100644 --- a/lib/jmap/mail/email/submission/set/set_email_submission_method.dart +++ b/lib/jmap/mail/email/submission/set/set_email_submission_method.dart @@ -45,13 +45,13 @@ class SetEmailSubmissionMethod extends SetMethod with OptionalO ?.map((id, update) => SetMethodPropertiesConverter() .fromMapIdToJson(id, update.toJson()))); writeNotNull('destroy', destroy - ?.map((destroyId) => IdConverter() + ?.map((destroyId) => const IdConverter() .toJson(destroyId)).toList()); writeNotNull('onSuccessUpdateEmail', onSuccessUpdateEmail ?.map((id, update) => SetMethodPropertiesConverter() .fromMapEmailSubmissionIdToJson(id, update))); writeNotNull('onSuccessDestroyEmail', onSuccessDestroyEmail - ?.map((destroyId) => ReferencesEmailSubmissionIdConverter() + ?.map((destroyId) => const ReferencesEmailSubmissionIdConverter() .toJson(destroyId)).toList()); return val; @@ -66,9 +66,7 @@ mixin OptionalOnSuccessUpdateEmail { Map? onSuccessUpdateEmail; void addOnSuccessUpdateEmail(Map values) { - if (onSuccessUpdateEmail == null) { - onSuccessUpdateEmail = Map(); - } + onSuccessUpdateEmail ??= {}; onSuccessUpdateEmail?.addAll(values); } } @@ -78,9 +76,7 @@ mixin OptionalOnSuccessDestroyEmail { Set? onSuccessDestroyEmail; void addOnSuccessDestroyEmail(Set values) { - if (onSuccessDestroyEmail == null) { - onSuccessDestroyEmail = Set(); - } + onSuccessDestroyEmail ??= {}; onSuccessDestroyEmail?.addAll(values); } } \ No newline at end of file diff --git a/lib/jmap/mail/mailbox/get/get_mailbox_method.dart b/lib/jmap/mail/mailbox/get/get_mailbox_method.dart index ae9fbd3..0a35847 100644 --- a/lib/jmap/mail/mailbox/get/get_mailbox_method.dart +++ b/lib/jmap/mail/mailbox/get/get_mailbox_method.dart @@ -37,5 +37,6 @@ class GetMailboxMethod extends GetMethod { factory GetMailboxMethod.fromJson(Map json) => _$GetMailboxMethodFromJson(json); + @override Map toJson() => _$GetMailboxMethodToJson(this); } \ No newline at end of file diff --git a/lib/jmap/mail/mailbox/mailbox_rights.dart b/lib/jmap/mail/mailbox/mailbox_rights.dart index 7352583..a4ee9a0 100644 --- a/lib/jmap/mail/mailbox/mailbox_rights.dart +++ b/lib/jmap/mail/mailbox/mailbox_rights.dart @@ -30,6 +30,8 @@ class MailboxRights with EquatableMixin { return _$MailboxRightsFromJson(json); } + Map toJson() => _$MailboxRightsToJson(this); + @override List get props => [mayReadItems, mayAddItems, mayRemoveItems, maySetSeen, maySetKeywords, mayCreateChild, mayRename, mayDelete, maySubmit]; diff --git a/lib/jmap/mail/mailbox/set/set_mailbox_method.dart b/lib/jmap/mail/mailbox/set/set_mailbox_method.dart index b59463e..bccbefa 100644 --- a/lib/jmap/mail/mailbox/set/set_mailbox_method.dart +++ b/lib/jmap/mail/mailbox/set/set_mailbox_method.dart @@ -38,7 +38,7 @@ class SetMailboxMethod extends SetMethod with OptionalOnDestroyRemoveEm writeNotNull('update', update ?.map((id, update) => SetMethodPropertiesConverter().fromMapIdToJson(id, update.toJson()))); writeNotNull('destroy', destroy - ?.map((destroyId) => IdConverter().toJson(destroyId)).toList()); + ?.map((destroyId) => const IdConverter().toJson(destroyId)).toList()); writeNotNull('onDestroyRemoveEmails', onDestroyRemoveEmails); return val; diff --git a/lib/jmap/mail/vacation/get/get_vacation_method.dart b/lib/jmap/mail/vacation/get/get_vacation_method.dart index d868f26..587ef45 100644 --- a/lib/jmap/mail/vacation/get/get_vacation_method.dart +++ b/lib/jmap/mail/vacation/get/get_vacation_method.dart @@ -37,5 +37,6 @@ class GetVacationMethod extends GetMethod { factory GetVacationMethod.fromJson(Map json) => _$GetVacationMethodFromJson(json); + @override Map toJson() => _$GetVacationMethodToJson(this); } \ No newline at end of file diff --git a/lib/jmap/mdn/send/mdn_send_response.dart b/lib/jmap/mdn/send/mdn_send_response.dart index 8fe8b4b..823e116 100644 --- a/lib/jmap/mdn/send/mdn_send_response.dart +++ b/lib/jmap/mdn/send/mdn_send_response.dart @@ -17,11 +17,11 @@ class MDNSendResponse extends SendResponse { const AccountIdConverter().fromJson(json['accountId'] as String), sent: (json['sent'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), MDN.fromJson(value as Map))), notSent: (json['notSent'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), SetError.fromJson(value))), ); } diff --git a/lib/jmap/push/get/get_push_subscription_method.dart b/lib/jmap/push/get/get_push_subscription_method.dart index 1b52ead..7923533 100644 --- a/lib/jmap/push/get/get_push_subscription_method.dart +++ b/lib/jmap/push/get/get_push_subscription_method.dart @@ -27,5 +27,6 @@ class GetPushSubscriptionMethod extends GetMethodNoNeedAccountId { factory GetPushSubscriptionMethod.fromJson(Map json) => _$GetPushSubscriptionMethodFromJson(json); + @override Map toJson() => _$GetPushSubscriptionMethodToJson(this); } \ No newline at end of file diff --git a/lib/jmap/push/set/set_push_subscription_method.dart b/lib/jmap/push/set/set_push_subscription_method.dart index 10610e1..9fa4f52 100644 --- a/lib/jmap/push/set/set_push_subscription_method.dart +++ b/lib/jmap/push/set/set_push_subscription_method.dart @@ -31,7 +31,7 @@ class SetPushSubscriptionMethod extends SetMethodNoNeedAccountId SetMethodPropertiesConverter().fromMapIdToJson(id, update.toJson()))); writeNotNull('destroy', destroy - ?.map((destroyId) => IdConverter().toJson(destroyId)).toList()); + ?.map((destroyId) => const IdConverter().toJson(destroyId)).toList()); return val; } diff --git a/lib/jmap/push/set/set_push_subscription_response.dart b/lib/jmap/push/set/set_push_subscription_response.dart index 9943fdc..f62f128 100644 --- a/lib/jmap/push/set/set_push_subscription_response.dart +++ b/lib/jmap/push/set/set_push_subscription_response.dart @@ -25,25 +25,25 @@ class SetPushSubscriptionResponse extends SetResponseNoAccount return SetPushSubscriptionResponse( created: (json['created'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), PushSubscription.fromJson(value as Map))), updated: (json['updated'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), value != null ? PushSubscription.fromJson(value as Map) : null)), destroyed: (json['destroyed'] as List?) - ?.map((id) => IdConverter().fromJson(id)).toSet(), + ?.map((id) => const IdConverter().fromJson(id)).toSet(), notCreated: (json['notCreated'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), SetError.fromJson(value))), notUpdated: (json['notUpdated'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), SetError.fromJson(value))), notDestroyed: (json['notDestroyed'] as Map?) ?.map((key, value) => MapEntry( - IdConverter().fromJson(key), + const IdConverter().fromJson(key), SetError.fromJson(value))), ); } diff --git a/lib/jmap/push/state_change.dart b/lib/jmap/push/state_change.dart index ebaf676..03ef325 100644 --- a/lib/jmap/push/state_change.dart +++ b/lib/jmap/push/state_change.dart @@ -12,9 +12,7 @@ class StateChange with EquatableMixin { StateChange(this.type, this.changed); factory StateChange.fromJson(Map json, {TypeStateConverter? converter}) { - if (converter == null) { - converter = TypeStateConverter.defaultConverter; - } + converter ??= TypeStateConverter.defaultConverter; return StateChange( json['@type'] as String, (json['changed'] as Map).map((key, value) => converter!.convert(key, value)), diff --git a/lib/jmap/quotas/get/get_quota_method.dart b/lib/jmap/quotas/get/get_quota_method.dart index 1840c77..e09d2da 100644 --- a/lib/jmap/quotas/get/get_quota_method.dart +++ b/lib/jmap/quotas/get/get_quota_method.dart @@ -32,5 +32,6 @@ class GetQuotaMethod extends GetMethod { factory GetQuotaMethod.fromJson(Map json) => _$GetQuotaMethodFromJson(json); + @override Map toJson() => _$GetQuotaMethodToJson(this); } \ No newline at end of file diff --git a/lib/util/options_extensions.dart b/lib/util/options_extensions.dart index f20e898..7c252cd 100644 --- a/lib/util/options_extensions.dart +++ b/lib/util/options_extensions.dart @@ -2,10 +2,10 @@ import 'package:dio/dio.dart'; extension OptionsExtension on Options { Options appendHeaders(Map additionalHeaders) { - if (this.headers != null) { - this.headers?.addAll(additionalHeaders); + if (headers != null) { + headers?.addAll(additionalHeaders); } else { - this.headers = additionalHeaders; + headers = additionalHeaders; } return this; } diff --git a/lib/util/util.dart b/lib/util/util.dart index 6a35e6c..a4b0d79 100644 --- a/lib/util/util.dart +++ b/lib/util/util.dart @@ -1,4 +1,6 @@ Iterable get positiveIntegers sync* { int i = 0; - while (true) yield i++; + while (true) { + yield i++; + } } \ No newline at end of file diff --git a/test/jmap/core/session/session_test.dart b/test/jmap/core/session/session_test.dart index e10e7d5..cdda03a 100644 --- a/test/jmap/core/session/session_test.dart +++ b/test/jmap/core/session/session_test.dart @@ -25,7 +25,7 @@ import 'test_capability.dart'; void main() { group('get session with default capabilities', () { test('get should parsing correctly session', () { - final sessionString = '''{ + const sessionString = '''{ "capabilities": { "urn:ietf:params:jmap:submission": { "maxDelayedSend": 0, @@ -170,8 +170,8 @@ void main() { supportsPush: true, url: Uri.parse('ws://domain.com/jmap/ws') ), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability(Map()), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability({}), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability({}), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability() }, @@ -206,8 +206,8 @@ void main() { emailQuerySortOptions: {"receivedAt", "sentAt", "size", "from", "to", "subject"}, mayCreateTopLevelMailbox: true ), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability(Map()), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability({}), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability({}), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability() } @@ -238,7 +238,7 @@ void main() { }); test('get should parsing correctly session with some limit capabilities', () { - final sessionString = '''{ + const sessionString = '''{ "capabilities": { "urn:ietf:params:jmap:submission": { "maxDelayedSend": 0, @@ -404,7 +404,7 @@ void main() { }); test('get should parsing correctly session with some capabilities miss property', () { - final sessionString = '''{ + const sessionString = '''{ "capabilities": { "urn:ietf:params:jmap:submission": { "maxDelayedSend": 0, @@ -550,7 +550,7 @@ void main() { group('get session with unknown capability', () { test('get should parsing correctly session with default converter', () { - final sessionString = '''{ + const sessionString = '''{ "capabilities": { "urn:tmail:custom:params:mailbox": { "param1": 1, @@ -705,8 +705,8 @@ void main() { supportsPush: true, url: Uri.parse('ws://domain.com/jmap/ws') ), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability(Map()), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability({}), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability({}), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability() }, @@ -742,8 +742,8 @@ void main() { emailQuerySortOptions: {"receivedAt", "sentAt", "size", "from", "to", "subject"}, mayCreateTopLevelMailbox: true ), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability(Map()), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability({}), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability({}), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability() } @@ -780,7 +780,7 @@ void main() { group('get session with custom capability', () { test('get should parsing correctly with relevant custom converter', () { - final sessionString = '''{ + const sessionString = '''{ "capabilities": { "urn:test:tmail:params:custom": { "testParam1": 100, @@ -943,8 +943,8 @@ void main() { supportsPush: true, url: Uri.parse('ws://domain.com/jmap/ws') ), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability(Map()), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability({}), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability({}), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability() }, @@ -980,8 +980,8 @@ void main() { emailQuerySortOptions: {"receivedAt", "sentAt", "size", "from", "to", "subject"}, mayCreateTopLevelMailbox: true ), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability(Map()), - CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:quota')): DefaultCapability({}), + CapabilityIdentifier(Uri.parse('urn:apache:james:params:jmap:mail:shares')): DefaultCapability({}), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability() } @@ -1020,7 +1020,7 @@ void main() { group('get session with empty capability', () { test('get should ignore parsing empty capability properties', () { - final sessionString = '''{ + const sessionString = '''{ "capabilities": { "urn:ietf:params:jmap:submission": { "maxDelayedSend": 0, @@ -1162,7 +1162,7 @@ void main() { group('get session for CYRUS server', () { test('get should parsing correctly session', () { - final sessionString = ''' + const sessionString = ''' { "username": "example", "apiUrl": "/jmap/", @@ -1305,7 +1305,7 @@ void main() { CapabilityIdentifier.jmapSubmission: SubmissionCapability(), CapabilityIdentifier.jmapVacationResponse: VacationCapability(), CapabilityIdentifier.jmapMdn: MdnCapability(), - CapabilityIdentifier(Uri.parse('https://cyrusimap.org/ns/jmap/sieve')): DefaultCapability(Map()), + CapabilityIdentifier(Uri.parse('https://cyrusimap.org/ns/jmap/sieve')): DefaultCapability({}), }, { AccountId(Id('example')): Account( diff --git a/test/jmap/core/utc_date_converter_test.dart b/test/jmap/core/utc_date_converter_test.dart index 364b8a2..7745d65 100644 --- a/test/jmap/core/utc_date_converter_test.dart +++ b/test/jmap/core/utc_date_converter_test.dart @@ -6,10 +6,10 @@ import 'package:jmap_dart_client/jmap/core/utc_date.dart'; void main() { - final utcDateStringTest = '2021-10-04T04:39:56.000Z'; + const utcDateStringTest = '2021-10-04T04:39:56.000Z'; final expectUTCDate = UTCDate(DateTime.parse('2021-10-04T04:39:56.000Z').toUtc()); final testUTCDate = UTCDate(DateTime.parse('2021-10-04T04:39:56.000Z').toUtc()); - final expectUTCDateString = '2021-10-04T04:39:56.000Z'; + const expectUTCDateString = '2021-10-04T04:39:56.000Z'; group('UTCDateConverter', () { test('should return UTCDate when receive a properly formatted json', () { diff --git a/test/jmap/email/query/query_with_operator_emails_test.dart b/test/jmap/email/query/query_with_operator_emails_test.dart index 07beb03..97ab8ed 100644 --- a/test/jmap/email/query/query_with_operator_emails_test.dart +++ b/test/jmap/email/query/query_with_operator_emails_test.dart @@ -244,10 +244,10 @@ void main() { }) ..addFilters(LogicFilterOperator( Operator.OR, - Set.from([ + { EmailFilterCondition(hasKeyword: "music"), EmailFilterCondition(hasKeyword: "video"), - ]))); + })); final queryEmailInvocation = jmapRequestBuilder .invocation(queryEmailMethod, methodCallId: MethodCallId('c2')); diff --git a/test/jmap/email/search/use_case_test/search_by_after_use_case_test.dart b/test/jmap/email/search/use_case_test/search_by_after_use_case_test.dart index 9b54f8b..440b6ed 100644 --- a/test/jmap/email/search/use_case_test/search_by_after_use_case_test.dart +++ b/test/jmap/email/search/use_case_test/search_by_after_use_case_test.dart @@ -179,7 +179,7 @@ void main() { ); if (resultList != null) { - resultList..sortEmails(comparator); + resultList.sortEmails(comparator); } return resultList?.list; diff --git a/test/jmap/email/search/use_case_test/search_by_form_use_case_test.dart b/test/jmap/email/search/use_case_test/search_by_form_use_case_test.dart index 0d3b3e7..55de4ec 100644 --- a/test/jmap/email/search/use_case_test/search_by_form_use_case_test.dart +++ b/test/jmap/email/search/use_case_test/search_by_form_use_case_test.dart @@ -174,7 +174,7 @@ void main() { ); if (resultList != null) { - resultList..sortEmails(comparator); + resultList.sortEmails(comparator); } return resultList?.list; diff --git a/test/jmap/email/search/use_case_test/search_by_time_and_text_use_case_test.dart b/test/jmap/email/search/use_case_test/search_by_time_and_text_use_case_test.dart index a20b0bb..45dbea4 100644 --- a/test/jmap/email/search/use_case_test/search_by_time_and_text_use_case_test.dart +++ b/test/jmap/email/search/use_case_test/search_by_time_and_text_use_case_test.dart @@ -185,7 +185,7 @@ void main() { ); if (resultList != null) { - resultList..sortEmails(comparator); + resultList.sortEmails(comparator); } return resultList?.list; diff --git a/test/jmap/email/search/use_case_test/search_emails_inbox_use_case_test.dart b/test/jmap/email/search/use_case_test/search_emails_inbox_use_case_test.dart index 3029e85..fa91863 100644 --- a/test/jmap/email/search/use_case_test/search_emails_inbox_use_case_test.dart +++ b/test/jmap/email/search/use_case_test/search_emails_inbox_use_case_test.dart @@ -247,7 +247,7 @@ void main() { ); if (resultList != null) { - resultList..sortEmails(comparator); + resultList.sortEmails(comparator); } return resultList?.list; diff --git a/test/jmap/email/sort_list_email_test.dart b/test/jmap/email/sort_list_email_test.dart index acb1185..cb61af3 100644 --- a/test/jmap/email/sort_list_email_test.dart +++ b/test/jmap/email/sort_list_email_test.dart @@ -268,7 +268,7 @@ void main() { getEmailInvocation.methodCallId, GetEmailResponse.deserialize); if (resultList != null) { - resultList..sortEmails(comparator); + resultList.sortEmails(comparator); } return resultList?.list; From 49305a382ca77211a0668fd9fe196a3c057cdc8e Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 31 Jan 2024 12:36:13 +0700 Subject: [PATCH 4/4] Fix parsing QueryEmailResponse --- lib/jmap/core/method/response/query_response.dart | 4 ++-- lib/jmap/mail/email/query/query_email_response.dart | 5 +++-- lib/jmap/mail/email/query/query_email_response.g.dart | 8 ++++---- lib/jmap/mail/mailbox/query/query_mailbox_response.dart | 5 +++-- lib/jmap/mail/mailbox/query/query_mailbox_response.g.dart | 8 ++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/jmap/core/method/response/query_response.dart b/lib/jmap/core/method/response/query_response.dart index f4fa149..06bb232 100644 --- a/lib/jmap/core/method/response/query_response.dart +++ b/lib/jmap/core/method/response/query_response.dart @@ -9,8 +9,8 @@ abstract class QueryResponse extends ResponseRequiringAccountId { final bool canCalculateChanges; final UnsignedInt position; final Set ids; - final UnsignedInt total; - final UnsignedInt limit; + final UnsignedInt? total; + final UnsignedInt? limit; QueryResponse( AccountId accountId, diff --git a/lib/jmap/mail/email/query/query_email_response.dart b/lib/jmap/mail/email/query/query_email_response.dart index 08fe06b..649815f 100644 --- a/lib/jmap/mail/email/query/query_email_response.dart +++ b/lib/jmap/mail/email/query/query_email_response.dart @@ -2,6 +2,7 @@ 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/http/converter/unsigned_int_converter.dart'; +import 'package:jmap_dart_client/http/converter/unsigned_int_nullable_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/query_response.dart'; @@ -24,8 +25,8 @@ class QueryEmailResponse extends QueryResponse { bool canCalculateChanges, UnsignedInt position, Set ids, - UnsignedInt total, - UnsignedInt limit, + UnsignedInt? total, + UnsignedInt? limit, ) : super(accountId, queryState, canCalculateChanges, position, ids, total, limit); factory QueryEmailResponse.fromJson(Map json) => _$QueryEmailResponseFromJson(json); diff --git a/lib/jmap/mail/email/query/query_email_response.g.dart b/lib/jmap/mail/email/query/query_email_response.g.dart index 4f60872..98187bf 100644 --- a/lib/jmap/mail/email/query/query_email_response.g.dart +++ b/lib/jmap/mail/email/query/query_email_response.g.dart @@ -15,8 +15,8 @@ QueryEmailResponse _$QueryEmailResponseFromJson(Map json) { (json['ids'] as List) .map((e) => const IdConverter().fromJson(e as String)) .toSet(), - const UnsignedIntConverter().fromJson(json['total'] as int), - const UnsignedIntConverter().fromJson(json['limit'] as int), + const UnsignedIntNullableConverter().fromJson(json['total'] as int?), + const UnsignedIntNullableConverter().fromJson(json['limit'] as int?), ); } @@ -27,6 +27,6 @@ Map _$QueryEmailResponseToJson(QueryEmailResponse instance) => 'canCalculateChanges': instance.canCalculateChanges, 'position': const UnsignedIntConverter().toJson(instance.position), 'ids': instance.ids.map(const IdConverter().toJson).toList(), - 'total': const UnsignedIntConverter().toJson(instance.total), - 'limit': const UnsignedIntConverter().toJson(instance.limit), + 'total': const UnsignedIntNullableConverter().toJson(instance.total), + 'limit': const UnsignedIntNullableConverter().toJson(instance.limit), }; diff --git a/lib/jmap/mail/mailbox/query/query_mailbox_response.dart b/lib/jmap/mail/mailbox/query/query_mailbox_response.dart index 3aafcbe..a9cd133 100644 --- a/lib/jmap/mail/mailbox/query/query_mailbox_response.dart +++ b/lib/jmap/mail/mailbox/query/query_mailbox_response.dart @@ -2,6 +2,7 @@ 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/http/converter/unsigned_int_converter.dart'; +import 'package:jmap_dart_client/http/converter/unsigned_int_nullable_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/query_response.dart'; @@ -24,8 +25,8 @@ class QueryMailboxResponse extends QueryResponse { bool canCalculateChanges, UnsignedInt position, Set ids, - UnsignedInt total, - UnsignedInt limit, + UnsignedInt? total, + UnsignedInt? limit, ) : super(accountId, queryState, canCalculateChanges, position, ids, total, limit); factory QueryMailboxResponse.fromJson(Map json) => _$QueryMailboxResponseFromJson(json); diff --git a/lib/jmap/mail/mailbox/query/query_mailbox_response.g.dart b/lib/jmap/mail/mailbox/query/query_mailbox_response.g.dart index c924f4a..e12f920 100644 --- a/lib/jmap/mail/mailbox/query/query_mailbox_response.g.dart +++ b/lib/jmap/mail/mailbox/query/query_mailbox_response.g.dart @@ -16,8 +16,8 @@ QueryMailboxResponse _$QueryMailboxResponseFromJson( (json['ids'] as List) .map((e) => const IdConverter().fromJson(e as String)) .toSet(), - const UnsignedIntConverter().fromJson(json['total'] as int), - const UnsignedIntConverter().fromJson(json['limit'] as int), + const UnsignedIntNullableConverter().fromJson(json['total'] as int?), + const UnsignedIntNullableConverter().fromJson(json['limit'] as int?), ); Map _$QueryMailboxResponseToJson( @@ -28,6 +28,6 @@ Map _$QueryMailboxResponseToJson( 'canCalculateChanges': instance.canCalculateChanges, 'position': const UnsignedIntConverter().toJson(instance.position), 'ids': instance.ids.map(const IdConverter().toJson).toList(), - 'total': const UnsignedIntConverter().toJson(instance.total), - 'limit': const UnsignedIntConverter().toJson(instance.limit), + 'total': const UnsignedIntNullableConverter().toJson(instance.total), + 'limit': const UnsignedIntNullableConverter().toJson(instance.limit), };