TF-3370 Handle SetError when make email action (Mark as read/star/move/delete)
This commit is contained in:
@@ -9,6 +9,8 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
||||||
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||||
@@ -43,7 +45,10 @@ abstract class EmailDataSource {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> markAsRead(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -75,9 +80,19 @@ abstract class EmailDataSource {
|
|||||||
{CancelToken? cancelToken}
|
{CancelToken? cancelToken}
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest);
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> moveToMailbox(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
MoveToMailboxRequest moveRequest,
|
||||||
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> markAsStar(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsStar(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -106,8 +121,14 @@ abstract class EmailDataSource {
|
|||||||
{CancelToken? cancelToken}
|
{CancelToken? cancelToken}
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> deleteMultipleEmailsPermanently(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
List<EmailId> emailIds,
|
||||||
|
);
|
||||||
Future<bool> deleteEmailPermanently(
|
Future<bool> deleteEmailPermanently(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
|||||||
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||||
@@ -75,7 +77,10 @@ class EmailDataSourceImpl extends EmailDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> markAsRead(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -112,14 +117,24 @@ class EmailDataSourceImpl extends EmailDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest) {
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> moveToMailbox(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
MoveToMailboxRequest moveRequest,
|
||||||
|
) {
|
||||||
return Future.sync(() async {
|
return Future.sync(() async {
|
||||||
return await emailAPI.moveToMailbox(session, accountId, moveRequest);
|
return await emailAPI.moveToMailbox(session, accountId, moveRequest);
|
||||||
}).catchError(_exceptionThrower.throwException);
|
}).catchError(_exceptionThrower.throwException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> markAsStar(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsStar(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -211,9 +226,20 @@ class EmailDataSourceImpl extends EmailDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> deleteMultipleEmailsPermanently(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
List<EmailId> emailIds,
|
||||||
|
) {
|
||||||
return Future.sync(() async {
|
return Future.sync(() async {
|
||||||
return await emailAPI.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
return await emailAPI.deleteMultipleEmailsPermanently(
|
||||||
|
session,
|
||||||
|
accountId,
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
}).catchError(_exceptionThrower.throwException);
|
}).catchError(_exceptionThrower.throwException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
||||||
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||||
@@ -82,7 +84,14 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> deleteMultipleEmailsPermanently(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
List<EmailId> emailIds,
|
||||||
|
) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +129,10 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> markAsRead(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -130,12 +142,27 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> markAsStar(Session session, AccountId accountId, List<EmailId> emailIds, MarkStarAction markStarAction) {
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsStar(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
List<EmailId> emailIds,
|
||||||
|
MarkStarAction markStarAction,
|
||||||
|
) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest) {
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> moveToMailbox(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
MoveToMailboxRequest moveRequest,
|
||||||
|
) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import 'package:jmap_dart_client/http/http_client.dart';
|
|||||||
import 'package:jmap_dart_client/jmap/account_id.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/capability/capability_identifier.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/capability/core_capability.dart';
|
import 'package:jmap_dart_client/jmap/core/capability/core_capability.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
|
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
@@ -44,13 +45,13 @@ import 'package:model/account/account_request.dart';
|
|||||||
import 'package:model/account/authentication_type.dart';
|
import 'package:model/account/authentication_type.dart';
|
||||||
import 'package:model/download/download_task_id.dart';
|
import 'package:model/download/download_task_id.dart';
|
||||||
import 'package:model/email/attachment.dart';
|
import 'package:model/email/attachment.dart';
|
||||||
import 'package:model/email/email_property.dart';
|
|
||||||
import 'package:model/email/mark_star_action.dart';
|
import 'package:model/email/mark_star_action.dart';
|
||||||
import 'package:model/email/read_actions.dart';
|
import 'package:model/email/read_actions.dart';
|
||||||
import 'package:model/extensions/email_extension.dart';
|
import 'package:model/extensions/email_extension.dart';
|
||||||
import 'package:model/extensions/email_id_extensions.dart';
|
import 'package:model/extensions/email_id_extensions.dart';
|
||||||
import 'package:model/extensions/keyword_identifier_extension.dart';
|
import 'package:model/extensions/keyword_identifier_extension.dart';
|
||||||
import 'package:model/extensions/list_email_id_extension.dart';
|
import 'package:model/extensions/list_email_id_extension.dart';
|
||||||
|
import 'package:model/extensions/list_id_extension.dart';
|
||||||
import 'package:model/extensions/mailbox_id_extension.dart';
|
import 'package:model/extensions/mailbox_id_extension.dart';
|
||||||
import 'package:model/extensions/session_extension.dart';
|
import 'package:model/extensions/session_extension.dart';
|
||||||
import 'package:model/oidc/token_oidc.dart';
|
import 'package:model/oidc/token_oidc.dart';
|
||||||
@@ -237,16 +238,21 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<EmailId>> markAsRead(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
ReadActions readActions,
|
ReadActions readActions,
|
||||||
) async {
|
) async {
|
||||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||||
final totalEmails = emails.length;
|
final totalEmails = emailIds.length;
|
||||||
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
final List<Email> updatedEmails = List.empty(growable: true);
|
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
||||||
|
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||||
|
|
||||||
for (int start = 0; start < totalEmails; start += maxBatches) {
|
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||||
int end = (start + maxBatches < totalEmails)
|
int end = (start + maxBatches < totalEmails)
|
||||||
@@ -254,20 +260,16 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
: totalEmails;
|
: totalEmails;
|
||||||
log('EmailAPI::markAsRead:emails from ${start + 1} to $end');
|
log('EmailAPI::markAsRead:emails from ${start + 1} to $end');
|
||||||
|
|
||||||
final currentListEmails = emails.sublist(start, end);
|
final currentListEmailIds = emailIds.sublist(start, end);
|
||||||
|
|
||||||
final setEmailMethod = SetEmailMethod(accountId)
|
final setEmailMethod = SetEmailMethod(accountId)
|
||||||
..addUpdates(currentListEmails.listEmailIds.generateMapUpdateObjectMarkAsRead(readActions));
|
..addUpdates(
|
||||||
|
currentListEmailIds.generateMapUpdateObjectMarkAsRead(readActions)
|
||||||
final getEmailMethod = GetEmailMethod(accountId)
|
);
|
||||||
..addIds(emails.listEmailIds.toIds().toSet())
|
|
||||||
..addProperties(Properties({EmailProperty.keywords}));
|
|
||||||
|
|
||||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||||
|
|
||||||
requestBuilder.invocation(setEmailMethod);
|
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||||
|
|
||||||
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
|
|
||||||
|
|
||||||
final capabilities = setEmailMethod.requiredCapabilities
|
final capabilities = setEmailMethod.requiredCapabilities
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
@@ -277,18 +279,19 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
.build()
|
.build()
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
final getEmailResponse = response.parse<GetEmailResponse>(
|
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||||
getEmailInvocation.methodCallId,
|
setEmailInvocation.methodCallId,
|
||||||
GetEmailResponse.deserialize,
|
SetEmailResponse.deserialize,
|
||||||
);
|
);
|
||||||
|
|
||||||
final listEmails = getEmailResponse?.list ?? [];
|
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||||
if (listEmails.isNotEmpty) {
|
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||||
updatedEmails.addAll(listEmails);
|
|
||||||
}
|
updatedEmailIds.addAll(listEmailIds);
|
||||||
|
mapErrors.addAll(mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedEmails;
|
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<DownloadTaskId>> downloadAttachments(
|
Future<List<DownloadTaskId>> downloadAttachments(
|
||||||
@@ -397,47 +400,55 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
return bytesDownloaded;
|
return bytesDownloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<EmailId>> moveToMailbox(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> moveToMailbox(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
MoveToMailboxRequest moveRequest
|
MoveToMailboxRequest moveRequest
|
||||||
) async {
|
) async {
|
||||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
|
||||||
|
|
||||||
final List<EmailId> listEmailIdResult = List.empty(growable: true);
|
final List<EmailId> listEmailIdResult = List.empty(growable: true);
|
||||||
|
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||||
|
|
||||||
final listMailboxIds = moveRequest.currentMailboxes.keys.toList();
|
final listMailboxIds = moveRequest.currentMailboxes.keys.toList();
|
||||||
for (int i = 0; i < listMailboxIds.length; i++) {
|
for (int i = 0; i < listMailboxIds.length; i++) {
|
||||||
final currentMailboxId = listMailboxIds[i];
|
final currentMailboxId = listMailboxIds[i];
|
||||||
final listEmailIds = moveRequest.currentMailboxes[currentMailboxId]!;
|
final listEmailIds = moveRequest.currentMailboxes[currentMailboxId]!;
|
||||||
log('EmailAPI::moveToMailbox:from mailbox ${currentMailboxId.asString} with ${listEmailIds.length} emails to mailbox ${moveRequest.destinationMailboxId.asString}');
|
log('EmailAPI::moveToMailbox:from mailbox ${currentMailboxId.asString} with ${listEmailIds.length} emails to mailbox ${moveRequest.destinationMailboxId.asString}');
|
||||||
final movedEmailIds = await _moveEmailsBetweenMailboxes(
|
final resultRecords = await _moveEmailsBetweenMailboxes(
|
||||||
session: session,
|
session: session,
|
||||||
accountId: accountId,
|
accountId: accountId,
|
||||||
listEmailIds: listEmailIds,
|
emailIds: listEmailIds,
|
||||||
currentMailboxId: currentMailboxId,
|
currentMailboxId: currentMailboxId,
|
||||||
maxBatches: maxBatches,
|
|
||||||
destinationMailboxId: moveRequest.destinationMailboxId,
|
destinationMailboxId: moveRequest.destinationMailboxId,
|
||||||
isMovingToSpam: moveRequest.isMovingToSpam,
|
isMovingToSpam: moveRequest.isMovingToSpam,
|
||||||
);
|
);
|
||||||
listEmailIdResult.addAll(movedEmailIds);
|
|
||||||
|
listEmailIdResult.addAll(resultRecords.emailIdsSuccess);
|
||||||
|
mapErrors.addAll(resultRecords.mapErrors);
|
||||||
}
|
}
|
||||||
return listEmailIdResult;
|
|
||||||
|
return (emailIdsSuccess: listEmailIdResult, mapErrors: mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<EmailId>> _moveEmailsBetweenMailboxes({
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> _moveEmailsBetweenMailboxes({
|
||||||
required Session session,
|
required Session session,
|
||||||
required AccountId accountId,
|
required AccountId accountId,
|
||||||
required List<EmailId> listEmailIds,
|
required List<EmailId> emailIds,
|
||||||
required MailboxId currentMailboxId,
|
required MailboxId currentMailboxId,
|
||||||
required MailboxId destinationMailboxId,
|
required MailboxId destinationMailboxId,
|
||||||
required int maxBatches,
|
|
||||||
bool isMovingToSpam = false,
|
bool isMovingToSpam = false,
|
||||||
}) async {
|
}) async {
|
||||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||||
final totalEmails = listEmailIds.length;
|
final totalEmails = emailIds.length;
|
||||||
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
||||||
|
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||||
|
|
||||||
for (int start = 0; start < totalEmails; start += maxBatches) {
|
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||||
int end = (start + maxBatches < totalEmails)
|
int end = (start + maxBatches < totalEmails)
|
||||||
@@ -445,7 +456,7 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
: totalEmails;
|
: totalEmails;
|
||||||
log('EmailAPI::_moveEmailsBetweenMailboxes:emails from ${start + 1} to $end');
|
log('EmailAPI::_moveEmailsBetweenMailboxes:emails from ${start + 1} to $end');
|
||||||
|
|
||||||
final currentEmailIds = listEmailIds.sublist(start, end);
|
final currentEmailIds = emailIds.sublist(start, end);
|
||||||
|
|
||||||
final moveProperties = isMovingToSpam
|
final moveProperties = isMovingToSpam
|
||||||
? currentEmailIds.generateMapUpdateObjectMoveToSpam(
|
? currentEmailIds.generateMapUpdateObjectMoveToSpam(
|
||||||
@@ -477,13 +488,14 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
SetEmailResponse.deserialize,
|
SetEmailResponse.deserialize,
|
||||||
);
|
);
|
||||||
|
|
||||||
final listIdsUpdated = setEmailResponse?.updated?.keys ?? [];
|
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||||
if (listIdsUpdated.isNotEmpty == true) {
|
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||||
final listEmailIdsUpdated = listIdsUpdated.map((e) => EmailId(e)).toList();
|
|
||||||
updatedEmailIds.addAll(listEmailIdsUpdated);
|
updatedEmailIds.addAll(listEmailIds);
|
||||||
}
|
mapErrors.addAll(mapErrors);
|
||||||
}
|
}
|
||||||
return updatedEmailIds;
|
|
||||||
|
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _getMaxObjectsInSetMethod(Session session, AccountId accountId) {
|
int _getMaxObjectsInSetMethod(Session session, AccountId accountId) {
|
||||||
@@ -502,16 +514,21 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
return minOfMaxObjectsInSetMethod;
|
return minOfMaxObjectsInSetMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<EmailId>> markAsStar(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsStar(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
MarkStarAction markStarAction
|
MarkStarAction markStarAction
|
||||||
) async {
|
) async {
|
||||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||||
final totalEmails = emails.length;
|
final totalEmails = emailIds.length;
|
||||||
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
final List<Email> updatedEmails = List.empty(growable: true);
|
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
||||||
|
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||||
|
|
||||||
for (int start = 0; start < totalEmails; start += maxBatches) {
|
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||||
int end = (start + maxBatches < totalEmails)
|
int end = (start + maxBatches < totalEmails)
|
||||||
@@ -519,20 +536,16 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
: totalEmails;
|
: totalEmails;
|
||||||
log('EmailAPI::markAsStar:emails from ${start + 1} to $end');
|
log('EmailAPI::markAsStar:emails from ${start + 1} to $end');
|
||||||
|
|
||||||
final currentListEmails = emails.sublist(start, end);
|
final currentListEmailIds = emailIds.sublist(start, end);
|
||||||
|
|
||||||
final setEmailMethod = SetEmailMethod(accountId)
|
final setEmailMethod = SetEmailMethod(accountId)
|
||||||
..addUpdates(currentListEmails.listEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction));
|
..addUpdates(
|
||||||
|
currentListEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction),
|
||||||
final getEmailMethod = GetEmailMethod(accountId)
|
);
|
||||||
..addIds(emails.listEmailIds.toIds().toSet())
|
|
||||||
..addProperties(Properties({EmailProperty.keywords}));
|
|
||||||
|
|
||||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||||
|
|
||||||
requestBuilder.invocation(setEmailMethod);
|
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||||
|
|
||||||
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
|
|
||||||
|
|
||||||
final capabilities = setEmailMethod.requiredCapabilities
|
final capabilities = setEmailMethod.requiredCapabilities
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
@@ -542,18 +555,19 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
.build()
|
.build()
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
final getEmailResponse = response.parse<GetEmailResponse>(
|
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||||
getEmailInvocation.methodCallId,
|
setEmailInvocation.methodCallId,
|
||||||
GetEmailResponse.deserialize,
|
SetEmailResponse.deserialize,
|
||||||
);
|
);
|
||||||
|
|
||||||
final listEmails = getEmailResponse?.list ?? [];
|
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||||
if (listEmails.isNotEmpty) {
|
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||||
updatedEmails.addAll(listEmails);
|
|
||||||
}
|
updatedEmailIds.addAll(listEmailIds);
|
||||||
|
mapErrors.addAll(mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedEmails;
|
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Email> saveEmailAsDrafts(
|
Future<Email> saveEmailAsDrafts(
|
||||||
@@ -656,36 +670,56 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
return emailCreated;
|
return emailCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> deleteMultipleEmailsPermanently(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds
|
List<EmailId> emailIds
|
||||||
) async {
|
) async {
|
||||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||||
final setEmailMethod = SetEmailMethod(accountId)
|
final totalEmails = emailIds.length;
|
||||||
..addDestroy(emailIds.map((emailId) => emailId.id).toSet());
|
final maxBatches = min(totalEmails, maxObjects);
|
||||||
|
|
||||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
final List<EmailId> destroyedEmailIds = List.empty(growable: true);
|
||||||
|
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||||
|
|
||||||
final capabilities = setEmailMethod.requiredCapabilities
|
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
int end = (start + maxBatches < totalEmails)
|
||||||
|
? start + maxBatches
|
||||||
|
: totalEmails;
|
||||||
|
log('EmailAPI::deleteMultipleEmailsPermanently:emails from ${start + 1} to $end');
|
||||||
|
|
||||||
final response = await (requestBuilder
|
final currentListEmailIds = emailIds.sublist(start, end);
|
||||||
..usings(capabilities))
|
|
||||||
.build()
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||||
|
final setEmailMethod = SetEmailMethod(accountId)
|
||||||
|
..addDestroy(currentListEmailIds.toIds().toSet());
|
||||||
|
|
||||||
|
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||||
|
|
||||||
|
final capabilities = setEmailMethod.requiredCapabilities
|
||||||
|
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
|
|
||||||
|
final response = await (requestBuilder
|
||||||
|
..usings(capabilities))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||||
setEmailInvocation.methodCallId,
|
setEmailInvocation.methodCallId,
|
||||||
SetEmailResponse.deserialize);
|
SetEmailResponse.deserialize,
|
||||||
|
);
|
||||||
|
|
||||||
final listIdResult = setEmailResponse?.destroyed;
|
final listEmailIds = setEmailResponse?.destroyed?.toEmailIds() ?? [];
|
||||||
|
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||||
|
|
||||||
if (listIdResult != null) {
|
destroyedEmailIds.addAll(listEmailIds);
|
||||||
return listIdResult.map((id) => EmailId(id)).toList();
|
mapErrors.addAll(mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return List.empty();
|
return (emailIdsSuccess: destroyedEmailIds, mapErrors: mapErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deleteEmailPermanently(
|
Future<bool> deleteEmailPermanently(
|
||||||
@@ -698,19 +732,20 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
final setEmailMethod = SetEmailMethod(accountId)
|
final setEmailMethod = SetEmailMethod(accountId)
|
||||||
..addDestroy({emailId.id});
|
..addDestroy({emailId.id});
|
||||||
|
|
||||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||||
|
|
||||||
final capabilities = setEmailMethod.requiredCapabilities
|
final capabilities = setEmailMethod.requiredCapabilities
|
||||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
|
|
||||||
final response = await (requestBuilder
|
final response = await (requestBuilder
|
||||||
..usings(capabilities))
|
..usings(capabilities))
|
||||||
.build()
|
.build()
|
||||||
.execute(cancelToken: cancelToken);
|
.execute(cancelToken: cancelToken);
|
||||||
|
|
||||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||||
setEmailInvocation.methodCallId,
|
setEmailInvocation.methodCallId,
|
||||||
SetEmailResponse.deserialize);
|
SetEmailResponse.deserialize,
|
||||||
|
);
|
||||||
|
|
||||||
return setEmailResponse?.destroyed?.contains(emailId.id) == true;
|
return setEmailResponse?.destroyed?.contains(emailId.id) == true;
|
||||||
}
|
}
|
||||||
@@ -757,10 +792,10 @@ class EmailAPI with HandleSetErrorMixin {
|
|||||||
|
|
||||||
final capabilities = setEmailMethod.requiredCapabilities.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
final capabilities = setEmailMethod.requiredCapabilities.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||||
|
|
||||||
final response = await (requestBuilder
|
final response = await (requestBuilder
|
||||||
..usings(capabilities))
|
..usings(capabilities))
|
||||||
.build()
|
.build()
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||||
setEmailInvocation.methodCallId,
|
setEmailInvocation.methodCallId,
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
||||||
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||||
@@ -83,7 +85,10 @@ class EmailRepositoryImpl extends EmailRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> markAsRead(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -124,12 +129,26 @@ class EmailRepositoryImpl extends EmailRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest) {
|
Future<({
|
||||||
return emailDataSource[DataSourceType.network]!.moveToMailbox(session, accountId, moveRequest);
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> moveToMailbox(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
MoveToMailboxRequest moveRequest,
|
||||||
|
) {
|
||||||
|
return emailDataSource[DataSourceType.network]!.moveToMailbox(
|
||||||
|
session,
|
||||||
|
accountId,
|
||||||
|
moveRequest,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> markAsStar(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsStar(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -228,8 +247,19 @@ class EmailRepositoryImpl extends EmailRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
|
Future<({
|
||||||
return emailDataSource[DataSourceType.network]!.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> deleteMultipleEmailsPermanently(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
List<EmailId> emailIds,
|
||||||
|
) {
|
||||||
|
return emailDataSource[DataSourceType.network]!.deleteMultipleEmailsPermanently(
|
||||||
|
session,
|
||||||
|
accountId,
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action.dart';
|
||||||
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
import 'package:email_recovery/email_recovery/email_recovery_action_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||||
@@ -45,7 +47,10 @@ abstract class EmailRepository {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> markAsRead(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsRead(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -77,9 +82,19 @@ abstract class EmailRepository {
|
|||||||
{CancelToken? cancelToken}
|
{CancelToken? cancelToken}
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest);
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> moveToMailbox(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
MoveToMailboxRequest moveRequest,
|
||||||
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> markAsStar(
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> markAsStar(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds,
|
List<EmailId> emailIds,
|
||||||
@@ -114,7 +129,14 @@ abstract class EmailRepository {
|
|||||||
{CancelToken? cancelToken}
|
{CancelToken? cancelToken}
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
|
Future<({
|
||||||
|
List<EmailId> emailIdsSuccess,
|
||||||
|
Map<Id, SetError> mapErrors,
|
||||||
|
})> deleteMultipleEmailsPermanently(
|
||||||
|
Session session,
|
||||||
|
AccountId accountId,
|
||||||
|
List<EmailId> emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
Future<bool> deleteEmailPermanently(
|
Future<bool> deleteEmailPermanently(
|
||||||
Session session,
|
Session session,
|
||||||
|
|||||||
+4
-4
@@ -16,10 +16,10 @@ class DeleteMultipleEmailsPermanentlyInteractor {
|
|||||||
try {
|
try {
|
||||||
yield Right<Failure, Success>(LoadingDeleteMultipleEmailsPermanentlyAll());
|
yield Right<Failure, Success>(LoadingDeleteMultipleEmailsPermanentlyAll());
|
||||||
final listResult = await _emailRepository.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
final listResult = await _emailRepository.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
||||||
if (listResult.length == emailIds.length) {
|
if (listResult.emailIdsSuccess.length == emailIds.length) {
|
||||||
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyAllSuccess(listResult));
|
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyAllSuccess(listResult.emailIdsSuccess));
|
||||||
} else if (listResult.isNotEmpty) {
|
} else if (listResult.emailIdsSuccess.isNotEmpty) {
|
||||||
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyHasSomeEmailFailure(listResult));
|
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyHasSomeEmailFailure(listResult.emailIdsSuccess));
|
||||||
} else {
|
} else {
|
||||||
yield Left<Failure, Success>(DeleteMultipleEmailsPermanentlyAllFailure());
|
yield Left<Failure, Success>(DeleteMultipleEmailsPermanentlyAllFailure());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,15 @@ class MarkAsEmailReadInteractor {
|
|||||||
readAction,
|
readAction,
|
||||||
);
|
);
|
||||||
|
|
||||||
yield Right(MarkAsEmailReadSuccess(
|
if (result.emailIdsSuccess.isEmpty) {
|
||||||
result.first,
|
yield Left(MarkAsEmailReadFailure(readAction));
|
||||||
readAction,
|
} else {
|
||||||
markReadAction,
|
yield Right(MarkAsEmailReadSuccess(
|
||||||
));
|
result.emailIdsSuccess.first,
|
||||||
|
readAction,
|
||||||
|
markReadAction,
|
||||||
|
));
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
yield Left(MarkAsEmailReadFailure(readAction, exception: e));
|
yield Left(MarkAsEmailReadFailure(readAction, exception: e));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ class MoveToMailboxInteractor {
|
|||||||
try {
|
try {
|
||||||
yield Right(LoadingMoveToMailbox());
|
yield Right(LoadingMoveToMailbox());
|
||||||
final result = await _emailRepository.moveToMailbox(session, accountId, moveRequest);
|
final result = await _emailRepository.moveToMailbox(session, accountId, moveRequest);
|
||||||
if (result.isNotEmpty) {
|
if (result.emailIdsSuccess.isNotEmpty) {
|
||||||
yield Right(MoveToMailboxSuccess(
|
yield Right(MoveToMailboxSuccess(
|
||||||
result.first,
|
result.emailIdsSuccess.first,
|
||||||
moveRequest.currentMailboxes.keys.first,
|
moveRequest.currentMailboxes.keys.first,
|
||||||
moveRequest.destinationMailboxId,
|
moveRequest.destinationMailboxId,
|
||||||
moveRequest.moveAction,
|
moveRequest.moveAction,
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ class MailboxIsolateWorker {
|
|||||||
listEmailUnread.listEmailIds,
|
listEmailUnread.listEmailIds,
|
||||||
ReadActions.markAsRead);
|
ReadActions.markAsRead);
|
||||||
|
|
||||||
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): MARK_READ: ${result.length}');
|
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): MARK_READ: ${result.emailIdsSuccess.length}');
|
||||||
emailIdsCompleted.addAll(result);
|
emailIdsCompleted.addAll(result.emailIdsSuccess);
|
||||||
sendPort.send(emailIdsCompleted);
|
sendPort.send(emailIdsCompleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,8 +206,8 @@ class MailboxIsolateWorker {
|
|||||||
listEmailUnread.listEmailIds,
|
listEmailUnread.listEmailIds,
|
||||||
ReadActions.markAsRead,
|
ReadActions.markAsRead,
|
||||||
);
|
);
|
||||||
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): MARK_READ: ${result.length}');
|
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): MARK_READ: ${result.emailIdsSuccess.length}');
|
||||||
emailIdsCompleted.addAll(result);
|
emailIdsCompleted.addAll(result.emailIdsSuccess);
|
||||||
|
|
||||||
onProgressController.add(Right(UpdatingMarkAsMailboxReadState(
|
onProgressController.add(Right(UpdatingMarkAsMailboxReadState(
|
||||||
mailboxId: mailboxId,
|
mailboxId: mailboxId,
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class ThreadIsolateWorker {
|
|||||||
args.session,
|
args.session,
|
||||||
args.accountId,
|
args.accountId,
|
||||||
newEmailList.listEmailIds);
|
newEmailList.listEmailIds);
|
||||||
emailListCompleted.addAll(listEmailIdDeleted);
|
emailListCompleted.addAll(listEmailIdDeleted.emailIdsSuccess);
|
||||||
sendPort.send(emailListCompleted);
|
sendPort.send(emailListCompleted);
|
||||||
} else {
|
} else {
|
||||||
hasEmails = false;
|
hasEmails = false;
|
||||||
@@ -173,7 +173,7 @@ class ThreadIsolateWorker {
|
|||||||
session,
|
session,
|
||||||
accountId,
|
accountId,
|
||||||
newEmailList.listEmailIds);
|
newEmailList.listEmailIds);
|
||||||
emailListCompleted.addAll(listEmailIdDeleted);
|
emailListCompleted.addAll(listEmailIdDeleted.emailIdsSuccess);
|
||||||
|
|
||||||
onProgressController.add(Right<Failure, Success>(EmptyingFolderState(
|
onProgressController.add(Right<Failure, Success>(EmptyingFolderState(
|
||||||
mailboxId, emailListCompleted.length, totalEmails
|
mailboxId, emailListCompleted.length, totalEmails
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ class MarkAsMultipleEmailReadInteractor {
|
|||||||
readAction,
|
readAction,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (emailIds.length == result.length) {
|
if (emailIds.length == result.emailIdsSuccess.length) {
|
||||||
yield Right(MarkAsMultipleEmailReadAllSuccess(
|
yield Right(MarkAsMultipleEmailReadAllSuccess(
|
||||||
result.length,
|
result.emailIdsSuccess.length,
|
||||||
readAction,
|
readAction,
|
||||||
));
|
));
|
||||||
} else if (result.isEmpty) {
|
} else if (result.emailIdsSuccess.isEmpty) {
|
||||||
yield Left(MarkAsMultipleEmailReadAllFailure(readAction));
|
yield Left(MarkAsMultipleEmailReadAllFailure(readAction));
|
||||||
} else {
|
} else {
|
||||||
yield Right(MarkAsMultipleEmailReadHasSomeEmailFailure(
|
yield Right(MarkAsMultipleEmailReadHasSomeEmailFailure(
|
||||||
result.length,
|
result.emailIdsSuccess.length,
|
||||||
readAction,
|
readAction,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ class MarkAsStarMultipleEmailInteractor {
|
|||||||
|
|
||||||
final result = await _emailRepository.markAsStar(session, accountId, emailIds, markStarAction);
|
final result = await _emailRepository.markAsStar(session, accountId, emailIds, markStarAction);
|
||||||
|
|
||||||
if (emailIds.length == result.length) {
|
if (emailIds.length == result.emailIdsSuccess.length) {
|
||||||
yield Right(MarkAsStarMultipleEmailAllSuccess(
|
yield Right(MarkAsStarMultipleEmailAllSuccess(
|
||||||
emailIds.length,
|
emailIds.length,
|
||||||
markStarAction,
|
markStarAction,
|
||||||
));
|
));
|
||||||
} else if (result.isEmpty) {
|
} else if (result.emailIdsSuccess.isEmpty) {
|
||||||
yield Left(MarkAsStarMultipleEmailAllFailure(markStarAction));
|
yield Left(MarkAsStarMultipleEmailAllFailure(markStarAction));
|
||||||
} else {
|
} else {
|
||||||
yield Right(MarkAsStarMultipleEmailHasSomeEmailFailure(
|
yield Right(MarkAsStarMultipleEmailHasSomeEmailFailure(
|
||||||
result.length,
|
result.emailIdsSuccess.length,
|
||||||
markStarAction,
|
markStarAction,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,20 +22,20 @@ class MoveMultipleEmailToMailboxInteractor {
|
|||||||
try {
|
try {
|
||||||
yield Right(LoadingMoveMultipleEmailToMailboxAll());
|
yield Right(LoadingMoveMultipleEmailToMailboxAll());
|
||||||
final result = await _emailRepository.moveToMailbox(session, accountId, moveRequest);
|
final result = await _emailRepository.moveToMailbox(session, accountId, moveRequest);
|
||||||
if (moveRequest.totalEmails == result.length) {
|
if (moveRequest.totalEmails == result.emailIdsSuccess.length) {
|
||||||
yield Right(MoveMultipleEmailToMailboxAllSuccess(
|
yield Right(MoveMultipleEmailToMailboxAllSuccess(
|
||||||
result,
|
result.emailIdsSuccess,
|
||||||
moveRequest.currentMailboxes.keys.first,
|
moveRequest.currentMailboxes.keys.first,
|
||||||
moveRequest.destinationMailboxId,
|
moveRequest.destinationMailboxId,
|
||||||
moveRequest.moveAction,
|
moveRequest.moveAction,
|
||||||
moveRequest.emailActionType,
|
moveRequest.emailActionType,
|
||||||
destinationPath: moveRequest.destinationPath,
|
destinationPath: moveRequest.destinationPath,
|
||||||
));
|
));
|
||||||
} else if (result.isEmpty) {
|
} else if (result.emailIdsSuccess.isEmpty) {
|
||||||
yield Left(MoveMultipleEmailToMailboxAllFailure(moveRequest.moveAction, moveRequest.emailActionType));
|
yield Left(MoveMultipleEmailToMailboxAllFailure(moveRequest.moveAction, moveRequest.emailActionType));
|
||||||
} else {
|
} else {
|
||||||
yield Right(MoveMultipleEmailToMailboxHasSomeEmailFailure(
|
yield Right(MoveMultipleEmailToMailboxHasSomeEmailFailure(
|
||||||
result,
|
result.emailIdsSuccess,
|
||||||
moveRequest.currentMailboxes.keys.first,
|
moveRequest.currentMailboxes.keys.first,
|
||||||
moveRequest.destinationMailboxId,
|
moveRequest.destinationMailboxId,
|
||||||
moveRequest.moveAction,
|
moveRequest.moveAction,
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
|
||||||
|
extension ListIdExtension on Iterable<Id> {
|
||||||
|
Iterable<EmailId> toEmailIds() => map((id) => EmailId(id));
|
||||||
|
}
|
||||||
@@ -60,6 +60,7 @@ export 'extensions/session_extension.dart';
|
|||||||
export 'extensions/username_extension.dart';
|
export 'extensions/username_extension.dart';
|
||||||
export 'extensions/utc_date_extension.dart';
|
export 'extensions/utc_date_extension.dart';
|
||||||
export 'extensions/contact_support_capability_extension.dart';
|
export 'extensions/contact_support_capability_extension.dart';
|
||||||
|
export 'extensions/list_id_extension.dart';
|
||||||
// Identity
|
// Identity
|
||||||
export 'identity/identity_request_dto.dart';
|
export 'identity/identity_request_dto.dart';
|
||||||
export 'mailbox/expand_mode.dart';
|
export 'mailbox/expand_mode.dart';
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'dart:math';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
import 'package:core/data/network/dio_client.dart';
|
import 'package:core/data/network/dio_client.dart';
|
||||||
import 'package:core/data/network/download/download_manager.dart';
|
import 'package:core/data/network/download/download_manager.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
@@ -60,7 +59,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 50;
|
const maxObjectsInSet = 50;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -102,16 +101,16 @@ void main() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
final emails = List.generate(
|
final emailIds = List.generate(
|
||||||
totalEmails,
|
totalEmails,
|
||||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
(index) => EmailId(Id('email_$index')),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
final result = await emailApi.markAsRead(
|
final result = await emailApi.markAsRead(
|
||||||
aliceSession,
|
aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
emails,
|
emailIds,
|
||||||
ReadActions.markAsRead,
|
ReadActions.markAsRead,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -121,7 +120,8 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -133,7 +133,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 200;
|
const maxObjectsInSet = 200;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -175,16 +175,16 @@ void main() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
final emails = List.generate(
|
final emailIds = List.generate(
|
||||||
totalEmails,
|
totalEmails,
|
||||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
(index) => EmailId(Id('email_$index')),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
final result = await emailApi.markAsRead(
|
final result = await emailApi.markAsRead(
|
||||||
aliceSession,
|
aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
emails,
|
emailIds,
|
||||||
ReadActions.markAsRead,
|
ReadActions.markAsRead,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -194,7 +194,8 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -206,7 +207,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 20;
|
const maxObjectsInSet = 20;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -248,16 +249,16 @@ void main() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
final emails = List.generate(
|
final emailIds = List.generate(
|
||||||
totalEmails,
|
totalEmails,
|
||||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
(index) => EmailId(Id('email_$index')),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
final result = await emailApi.markAsRead(
|
final result = await emailApi.markAsRead(
|
||||||
aliceSession,
|
aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
emails,
|
emailIds,
|
||||||
ReadActions.markAsRead,
|
ReadActions.markAsRead,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -267,7 +268,83 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN totalEmails is less than defaultMaxObjectsInSet\n'
|
||||||
|
'WHEN maxObjectsInSet equal defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 50;
|
||||||
|
const totalEmails = 30;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"updated": {
|
||||||
|
for (var item in List.generate(maxBatches, (index) => {"email_$index": null}))
|
||||||
|
item.keys.first: item.values.first
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Email/get",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"state": "b965db40-c11c-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"list": List.generate(maxBatches, (index) => {
|
||||||
|
"id": "email_$index",
|
||||||
|
"keywords": {
|
||||||
|
"\$seen": true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"notFound": []
|
||||||
|
},
|
||||||
|
"c1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.markAsRead(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
emailIds,
|
||||||
|
ReadActions.markAsRead,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -281,7 +358,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 50;
|
const maxObjectsInSet = 50;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -323,16 +400,16 @@ void main() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
final emails = List.generate(
|
final emailIds = List.generate(
|
||||||
totalEmails,
|
totalEmails,
|
||||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
(index) => EmailId(Id('email_$index')),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
final result = await emailApi.markAsStar(
|
final result = await emailApi.markAsStar(
|
||||||
aliceSession,
|
aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
emails,
|
emailIds,
|
||||||
MarkStarAction.markStar,
|
MarkStarAction.markStar,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -342,7 +419,8 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -354,7 +432,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 200;
|
const maxObjectsInSet = 200;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -396,16 +474,16 @@ void main() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
final emails = List.generate(
|
final emailIds = List.generate(
|
||||||
totalEmails,
|
totalEmails,
|
||||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
(index) => EmailId(Id('email_$index')),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
final result = await emailApi.markAsStar(
|
final result = await emailApi.markAsStar(
|
||||||
aliceSession,
|
aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
emails,
|
emailIds,
|
||||||
MarkStarAction.markStar,
|
MarkStarAction.markStar,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -415,7 +493,8 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -427,7 +506,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 20;
|
const maxObjectsInSet = 20;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -469,16 +548,16 @@ void main() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
final emails = List.generate(
|
final emailIds = List.generate(
|
||||||
totalEmails,
|
totalEmails,
|
||||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
(index) => EmailId(Id('email_$index')),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
final result = await emailApi.markAsStar(
|
final result = await emailApi.markAsStar(
|
||||||
aliceSession,
|
aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
emails,
|
emailIds,
|
||||||
MarkStarAction.markStar,
|
MarkStarAction.markStar,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -488,7 +567,306 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN totalEmails is less than defaultMaxObjectsInSet\n'
|
||||||
|
'WHEN maxObjectsInSet equal defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 50;
|
||||||
|
const totalEmails = 30;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"updated": {
|
||||||
|
for (var item in List.generate(maxBatches, (index) => {"email_$index": null}))
|
||||||
|
item.keys.first: item.values.first
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Email/get",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"state": "b965db40-c11c-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"list": List.generate(maxBatches, (index) => {
|
||||||
|
"id": "email_$index",
|
||||||
|
"keywords": {
|
||||||
|
"\$flagged": true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"notFound": []
|
||||||
|
},
|
||||||
|
"c1"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.markAsStar(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
emailIds,
|
||||||
|
MarkStarAction.markStar,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('deleteMultipleEmailsPermanently::test', () {
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN maxObjectsInSet equal defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 50;
|
||||||
|
const totalEmails = 100;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"destroyed": List.generate(maxBatches, (index) => "email_$index")
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.deleteMultipleEmailsPermanently(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN maxObjectsInSet is greater than defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 200;
|
||||||
|
const totalEmails = 100;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"destroyed": List.generate(maxBatches, (index) => "email_$index")
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.deleteMultipleEmailsPermanently(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN maxObjectsInSet is less than defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 20;
|
||||||
|
const totalEmails = 100;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"destroyed": List.generate(maxBatches, (index) => "email_$index")
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.deleteMultipleEmailsPermanently(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN totalEmails is less than defaultMaxObjectsInSet\n'
|
||||||
|
'WHEN maxObjectsInSet equal defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 50;
|
||||||
|
const totalEmails = 30;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"destroyed": List.generate(maxBatches, (index) => "email_$index")
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.deleteMultipleEmailsPermanently(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -502,7 +880,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 50;
|
const maxObjectsInSet = 50;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -554,7 +932,8 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -566,7 +945,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 200;
|
const maxObjectsInSet = 200;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -618,7 +997,8 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -630,7 +1010,7 @@ void main() {
|
|||||||
const defaultMaxObjectsInSet = 50;
|
const defaultMaxObjectsInSet = 50;
|
||||||
const maxObjectsInSet = 20;
|
const maxObjectsInSet = 20;
|
||||||
const totalEmails = 100;
|
const totalEmails = 100;
|
||||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
final countIterations = (totalEmails / maxBatches).ceil();
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
@@ -682,7 +1062,74 @@ void main() {
|
|||||||
data: anyNamed('data'),
|
data: anyNamed('data'),
|
||||||
cancelToken: anyNamed('cancelToken'),
|
cancelToken: anyNamed('cancelToken'),
|
||||||
)).called(countIterations);
|
)).called(countIterations);
|
||||||
expect(result.length, totalEmails);
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'SHOULD calls execute the correct number of times\n'
|
||||||
|
'WHEN totalEmails is less than defaultMaxObjectsInSet\n'
|
||||||
|
'WHEN maxObjectsInSet equal defaultMaxObjectsInSet\n'
|
||||||
|
'AND defaultMaxObjectsInSet is 50',
|
||||||
|
() async {
|
||||||
|
// Arrange
|
||||||
|
const defaultMaxObjectsInSet = 50;
|
||||||
|
const maxObjectsInSet = 50;
|
||||||
|
const totalEmails = 30;
|
||||||
|
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||||
|
final countIterations = (totalEmails / maxBatches).ceil();
|
||||||
|
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||||
|
|
||||||
|
when(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).thenAnswer((_) async => {
|
||||||
|
"sessionState": "2c9f1b12-b35a-43e6-9af2-0106fb53a943",
|
||||||
|
"methodResponses": [
|
||||||
|
[
|
||||||
|
"Email/set",
|
||||||
|
{
|
||||||
|
"accountId": AccountFixtures.aliceAccountId.asString,
|
||||||
|
"oldState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"newState": "4cb1e760-c11b-11ef-9cfb-ef2eae0e64b1",
|
||||||
|
"updated": {
|
||||||
|
for (var item in List.generate(maxBatches, (index) => {"email_$index": null}))
|
||||||
|
item.keys.first: item.values.first
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c0"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
final emailIds = List.generate(
|
||||||
|
totalEmails,
|
||||||
|
(index) => EmailId(Id('email_$index')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
final result = await emailApi.moveToMailbox(
|
||||||
|
aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
MoveToMailboxRequest(
|
||||||
|
{
|
||||||
|
MailboxId(Id('mailboxA')): emailIds,
|
||||||
|
},
|
||||||
|
MailboxId(Id('mailboxB')),
|
||||||
|
MoveAction.moving,
|
||||||
|
EmailActionType.moveToMailbox,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(httpClient.post(
|
||||||
|
'',
|
||||||
|
data: anyNamed('data'),
|
||||||
|
cancelToken: anyNamed('cancelToken'),
|
||||||
|
)).called(countIterations);
|
||||||
|
expect(result.emailIdsSuccess.length, totalEmails);
|
||||||
|
expect(result.mapErrors.isEmpty, isTrue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user