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_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/session/session.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,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -75,9 +80,19 @@ abstract class EmailDataSource {
|
||||
{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,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -106,8 +121,14 @@ abstract class EmailDataSource {
|
||||
{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(
|
||||
Session session,
|
||||
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:get/get.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/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||
@@ -75,7 +77,10 @@ class EmailDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> markAsRead(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> markAsRead(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -112,14 +117,24 @@ class EmailDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@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 await emailAPI.moveToMailbox(session, accountId, moveRequest);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> markAsStar(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> markAsStar(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -211,9 +226,20 @@ class EmailDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@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 await emailAPI.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
||||
return await emailAPI.deleteMultipleEmailsPermanently(
|
||||
session,
|
||||
accountId,
|
||||
emailIds,
|
||||
);
|
||||
}).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_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/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||
@@ -82,7 +84,14 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@@ -120,7 +129,10 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> markAsRead(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> markAsRead(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -130,12 +142,27 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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/core/capability/capability_identifier.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/patch_object.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/download/download_task_id.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/read_actions.dart';
|
||||
import 'package:model/extensions/email_extension.dart';
|
||||
import 'package:model/extensions/email_id_extensions.dart';
|
||||
import 'package:model/extensions/keyword_identifier_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/session_extension.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,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
ReadActions readActions,
|
||||
) async {
|
||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
||||
final totalEmails = emails.length;
|
||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||
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) {
|
||||
int end = (start + maxBatches < totalEmails)
|
||||
@@ -254,20 +260,16 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
: totalEmails;
|
||||
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)
|
||||
..addUpdates(currentListEmails.listEmailIds.generateMapUpdateObjectMarkAsRead(readActions));
|
||||
|
||||
final getEmailMethod = GetEmailMethod(accountId)
|
||||
..addIds(emails.listEmailIds.toIds().toSet())
|
||||
..addProperties(Properties({EmailProperty.keywords}));
|
||||
..addUpdates(
|
||||
currentListEmailIds.generateMapUpdateObjectMarkAsRead(readActions)
|
||||
);
|
||||
|
||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||
|
||||
requestBuilder.invocation(setEmailMethod);
|
||||
|
||||
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
|
||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||
|
||||
final capabilities = setEmailMethod.requiredCapabilities
|
||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
@@ -277,18 +279,19 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
.build()
|
||||
.execute();
|
||||
|
||||
final getEmailResponse = response.parse<GetEmailResponse>(
|
||||
getEmailInvocation.methodCallId,
|
||||
GetEmailResponse.deserialize,
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
setEmailInvocation.methodCallId,
|
||||
SetEmailResponse.deserialize,
|
||||
);
|
||||
|
||||
final listEmails = getEmailResponse?.list ?? [];
|
||||
if (listEmails.isNotEmpty) {
|
||||
updatedEmails.addAll(listEmails);
|
||||
}
|
||||
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||
|
||||
updatedEmailIds.addAll(listEmailIds);
|
||||
mapErrors.addAll(mapErrors);
|
||||
}
|
||||
|
||||
return updatedEmails;
|
||||
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||
}
|
||||
|
||||
Future<List<DownloadTaskId>> downloadAttachments(
|
||||
@@ -397,47 +400,55 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
return bytesDownloaded;
|
||||
}
|
||||
|
||||
Future<List<EmailId>> moveToMailbox(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> moveToMailbox(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
MoveToMailboxRequest moveRequest
|
||||
) async {
|
||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
||||
|
||||
final List<EmailId> listEmailIdResult = List.empty(growable: true);
|
||||
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||
|
||||
final listMailboxIds = moveRequest.currentMailboxes.keys.toList();
|
||||
for (int i = 0; i < listMailboxIds.length; i++) {
|
||||
final currentMailboxId = listMailboxIds[i];
|
||||
final listEmailIds = moveRequest.currentMailboxes[currentMailboxId]!;
|
||||
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,
|
||||
accountId: accountId,
|
||||
listEmailIds: listEmailIds,
|
||||
emailIds: listEmailIds,
|
||||
currentMailboxId: currentMailboxId,
|
||||
maxBatches: maxBatches,
|
||||
destinationMailboxId: moveRequest.destinationMailboxId,
|
||||
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 AccountId accountId,
|
||||
required List<EmailId> listEmailIds,
|
||||
required List<EmailId> emailIds,
|
||||
required MailboxId currentMailboxId,
|
||||
required MailboxId destinationMailboxId,
|
||||
required int maxBatches,
|
||||
bool isMovingToSpam = false,
|
||||
}) async {
|
||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
||||
final totalEmails = listEmailIds.length;
|
||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||
final totalEmails = emailIds.length;
|
||||
final maxBatches = min(totalEmails, maxObjects);
|
||||
|
||||
final List<EmailId> updatedEmailIds = List.empty(growable: true);
|
||||
final Map<Id, SetError> mapErrors = <Id, SetError>{};
|
||||
|
||||
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||
int end = (start + maxBatches < totalEmails)
|
||||
@@ -445,7 +456,7 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
: totalEmails;
|
||||
log('EmailAPI::_moveEmailsBetweenMailboxes:emails from ${start + 1} to $end');
|
||||
|
||||
final currentEmailIds = listEmailIds.sublist(start, end);
|
||||
final currentEmailIds = emailIds.sublist(start, end);
|
||||
|
||||
final moveProperties = isMovingToSpam
|
||||
? currentEmailIds.generateMapUpdateObjectMoveToSpam(
|
||||
@@ -477,13 +488,14 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
SetEmailResponse.deserialize,
|
||||
);
|
||||
|
||||
final listIdsUpdated = setEmailResponse?.updated?.keys ?? [];
|
||||
if (listIdsUpdated.isNotEmpty == true) {
|
||||
final listEmailIdsUpdated = listIdsUpdated.map((e) => EmailId(e)).toList();
|
||||
updatedEmailIds.addAll(listEmailIdsUpdated);
|
||||
}
|
||||
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||
|
||||
updatedEmailIds.addAll(listEmailIds);
|
||||
mapErrors.addAll(mapErrors);
|
||||
}
|
||||
return updatedEmailIds;
|
||||
|
||||
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||
}
|
||||
|
||||
int _getMaxObjectsInSetMethod(Session session, AccountId accountId) {
|
||||
@@ -502,16 +514,21 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
return minOfMaxObjectsInSetMethod;
|
||||
}
|
||||
|
||||
Future<List<EmailId>> markAsStar(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> markAsStar(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
MarkStarAction markStarAction
|
||||
) async {
|
||||
final maxBatches = _getMaxObjectsInSetMethod(session, accountId);
|
||||
final totalEmails = emails.length;
|
||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||
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) {
|
||||
int end = (start + maxBatches < totalEmails)
|
||||
@@ -519,20 +536,16 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
: totalEmails;
|
||||
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)
|
||||
..addUpdates(currentListEmails.listEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction));
|
||||
|
||||
final getEmailMethod = GetEmailMethod(accountId)
|
||||
..addIds(emails.listEmailIds.toIds().toSet())
|
||||
..addProperties(Properties({EmailProperty.keywords}));
|
||||
..addUpdates(
|
||||
currentListEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction),
|
||||
);
|
||||
|
||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||
|
||||
requestBuilder.invocation(setEmailMethod);
|
||||
|
||||
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
|
||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||
|
||||
final capabilities = setEmailMethod.requiredCapabilities
|
||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
@@ -542,18 +555,19 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
.build()
|
||||
.execute();
|
||||
|
||||
final getEmailResponse = response.parse<GetEmailResponse>(
|
||||
getEmailInvocation.methodCallId,
|
||||
GetEmailResponse.deserialize,
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
setEmailInvocation.methodCallId,
|
||||
SetEmailResponse.deserialize,
|
||||
);
|
||||
|
||||
final listEmails = getEmailResponse?.list ?? [];
|
||||
if (listEmails.isNotEmpty) {
|
||||
updatedEmails.addAll(listEmails);
|
||||
}
|
||||
final listEmailIds = setEmailResponse?.updated?.keys.toEmailIds() ?? [];
|
||||
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||
|
||||
updatedEmailIds.addAll(listEmailIds);
|
||||
mapErrors.addAll(mapErrors);
|
||||
}
|
||||
|
||||
return updatedEmails;
|
||||
return (emailIdsSuccess: updatedEmailIds, mapErrors: mapErrors);
|
||||
}
|
||||
|
||||
Future<Email> saveEmailAsDrafts(
|
||||
@@ -656,36 +670,56 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
return emailCreated;
|
||||
}
|
||||
|
||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> deleteMultipleEmailsPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds
|
||||
) async {
|
||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||
final setEmailMethod = SetEmailMethod(accountId)
|
||||
..addDestroy(emailIds.map((emailId) => emailId.id).toSet());
|
||||
final maxObjects = _getMaxObjectsInSetMethod(session, accountId);
|
||||
final totalEmails = emailIds.length;
|
||||
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
|
||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
for (int start = 0; start < totalEmails; start += maxBatches) {
|
||||
int end = (start + maxBatches < totalEmails)
|
||||
? start + maxBatches
|
||||
: totalEmails;
|
||||
log('EmailAPI::deleteMultipleEmailsPermanently:emails from ${start + 1} to $end');
|
||||
|
||||
final response = await (requestBuilder
|
||||
..usings(capabilities))
|
||||
.build()
|
||||
.execute();
|
||||
final currentListEmailIds = emailIds.sublist(start, end);
|
||||
|
||||
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,
|
||||
SetEmailResponse.deserialize);
|
||||
SetEmailResponse.deserialize,
|
||||
);
|
||||
|
||||
final listIdResult = setEmailResponse?.destroyed;
|
||||
final listEmailIds = setEmailResponse?.destroyed?.toEmailIds() ?? [];
|
||||
final mapErrors = handleSetResponse([setEmailResponse]);
|
||||
|
||||
if (listIdResult != null) {
|
||||
return listIdResult.map((id) => EmailId(id)).toList();
|
||||
destroyedEmailIds.addAll(listEmailIds);
|
||||
mapErrors.addAll(mapErrors);
|
||||
}
|
||||
|
||||
return List.empty();
|
||||
return (emailIdsSuccess: destroyedEmailIds, mapErrors: mapErrors);
|
||||
}
|
||||
|
||||
Future<bool> deleteEmailPermanently(
|
||||
@@ -698,19 +732,20 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
final setEmailMethod = SetEmailMethod(accountId)
|
||||
..addDestroy({emailId.id});
|
||||
|
||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||
|
||||
final capabilities = setEmailMethod.requiredCapabilities
|
||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
final capabilities = setEmailMethod.requiredCapabilities
|
||||
.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
|
||||
final response = await (requestBuilder
|
||||
..usings(capabilities))
|
||||
.build()
|
||||
.execute(cancelToken: cancelToken);
|
||||
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
setEmailInvocation.methodCallId,
|
||||
SetEmailResponse.deserialize);
|
||||
SetEmailResponse.deserialize,
|
||||
);
|
||||
|
||||
return setEmailResponse?.destroyed?.contains(emailId.id) == true;
|
||||
}
|
||||
@@ -757,10 +792,10 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
|
||||
final capabilities = setEmailMethod.requiredCapabilities.toCapabilitiesSupportTeamMailboxes(session, accountId);
|
||||
|
||||
final response = await (requestBuilder
|
||||
..usings(capabilities))
|
||||
.build()
|
||||
.execute();
|
||||
final response = await (requestBuilder
|
||||
..usings(capabilities))
|
||||
.build()
|
||||
.execute();
|
||||
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
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_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/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||
@@ -83,7 +85,10 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> markAsRead(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> markAsRead(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -124,12 +129,26 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest) {
|
||||
return emailDataSource[DataSourceType.network]!.moveToMailbox(session, accountId, moveRequest);
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> moveToMailbox(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
MoveToMailboxRequest moveRequest,
|
||||
) {
|
||||
return emailDataSource[DataSourceType.network]!.moveToMailbox(
|
||||
session,
|
||||
accountId,
|
||||
moveRequest,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> markAsStar(
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> markAsStar(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -228,8 +247,19 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
|
||||
return emailDataSource[DataSourceType.network]!.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
})> deleteMultipleEmailsPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
) {
|
||||
return emailDataSource[DataSourceType.network]!.deleteMultipleEmailsPermanently(
|
||||
session,
|
||||
accountId,
|
||||
emailIds,
|
||||
);
|
||||
}
|
||||
|
||||
@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_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/session/session.dart';
|
||||
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,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -77,9 +82,19 @@ abstract class EmailRepository {
|
||||
{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,
|
||||
AccountId accountId,
|
||||
List<EmailId> emailIds,
|
||||
@@ -114,7 +129,14 @@ abstract class EmailRepository {
|
||||
{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(
|
||||
Session session,
|
||||
|
||||
+4
-4
@@ -16,10 +16,10 @@ class DeleteMultipleEmailsPermanentlyInteractor {
|
||||
try {
|
||||
yield Right<Failure, Success>(LoadingDeleteMultipleEmailsPermanentlyAll());
|
||||
final listResult = await _emailRepository.deleteMultipleEmailsPermanently(session, accountId, emailIds);
|
||||
if (listResult.length == emailIds.length) {
|
||||
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyAllSuccess(listResult));
|
||||
} else if (listResult.isNotEmpty) {
|
||||
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyHasSomeEmailFailure(listResult));
|
||||
if (listResult.emailIdsSuccess.length == emailIds.length) {
|
||||
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyAllSuccess(listResult.emailIdsSuccess));
|
||||
} else if (listResult.emailIdsSuccess.isNotEmpty) {
|
||||
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyHasSomeEmailFailure(listResult.emailIdsSuccess));
|
||||
} else {
|
||||
yield Left<Failure, Success>(DeleteMultipleEmailsPermanentlyAllFailure());
|
||||
}
|
||||
|
||||
@@ -29,11 +29,15 @@ class MarkAsEmailReadInteractor {
|
||||
readAction,
|
||||
);
|
||||
|
||||
yield Right(MarkAsEmailReadSuccess(
|
||||
result.first,
|
||||
readAction,
|
||||
markReadAction,
|
||||
));
|
||||
if (result.emailIdsSuccess.isEmpty) {
|
||||
yield Left(MarkAsEmailReadFailure(readAction));
|
||||
} else {
|
||||
yield Right(MarkAsEmailReadSuccess(
|
||||
result.emailIdsSuccess.first,
|
||||
readAction,
|
||||
markReadAction,
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
yield Left(MarkAsEmailReadFailure(readAction, exception: e));
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ class MoveToMailboxInteractor {
|
||||
try {
|
||||
yield Right(LoadingMoveToMailbox());
|
||||
final result = await _emailRepository.moveToMailbox(session, accountId, moveRequest);
|
||||
if (result.isNotEmpty) {
|
||||
if (result.emailIdsSuccess.isNotEmpty) {
|
||||
yield Right(MoveToMailboxSuccess(
|
||||
result.first,
|
||||
result.emailIdsSuccess.first,
|
||||
moveRequest.currentMailboxes.keys.first,
|
||||
moveRequest.destinationMailboxId,
|
||||
moveRequest.moveAction,
|
||||
|
||||
@@ -138,8 +138,8 @@ class MailboxIsolateWorker {
|
||||
listEmailUnread.listEmailIds,
|
||||
ReadActions.markAsRead);
|
||||
|
||||
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): MARK_READ: ${result.length}');
|
||||
emailIdsCompleted.addAll(result);
|
||||
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): MARK_READ: ${result.emailIdsSuccess.length}');
|
||||
emailIdsCompleted.addAll(result.emailIdsSuccess);
|
||||
sendPort.send(emailIdsCompleted);
|
||||
}
|
||||
}
|
||||
@@ -206,8 +206,8 @@ class MailboxIsolateWorker {
|
||||
listEmailUnread.listEmailIds,
|
||||
ReadActions.markAsRead,
|
||||
);
|
||||
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): MARK_READ: ${result.length}');
|
||||
emailIdsCompleted.addAll(result);
|
||||
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): MARK_READ: ${result.emailIdsSuccess.length}');
|
||||
emailIdsCompleted.addAll(result.emailIdsSuccess);
|
||||
|
||||
onProgressController.add(Right(UpdatingMarkAsMailboxReadState(
|
||||
mailboxId: mailboxId,
|
||||
|
||||
@@ -100,7 +100,7 @@ class ThreadIsolateWorker {
|
||||
..setIsAscending(false)),
|
||||
filter: EmailFilterCondition(inMailbox: args.mailboxId, before: lastEmail?.receivedAt),
|
||||
properties: Properties({
|
||||
EmailProperty.id,
|
||||
EmailProperty.id,
|
||||
EmailProperty.receivedAt
|
||||
}),
|
||||
);
|
||||
@@ -119,7 +119,7 @@ class ThreadIsolateWorker {
|
||||
args.session,
|
||||
args.accountId,
|
||||
newEmailList.listEmailIds);
|
||||
emailListCompleted.addAll(listEmailIdDeleted);
|
||||
emailListCompleted.addAll(listEmailIdDeleted.emailIdsSuccess);
|
||||
sendPort.send(emailListCompleted);
|
||||
} else {
|
||||
hasEmails = false;
|
||||
@@ -154,7 +154,7 @@ class ThreadIsolateWorker {
|
||||
..setIsAscending(false)),
|
||||
filter: EmailFilterCondition(inMailbox: mailboxId, before: lastEmail?.receivedAt),
|
||||
properties: Properties({
|
||||
EmailProperty.id,
|
||||
EmailProperty.id,
|
||||
EmailProperty.receivedAt
|
||||
}),
|
||||
);
|
||||
@@ -173,7 +173,7 @@ class ThreadIsolateWorker {
|
||||
session,
|
||||
accountId,
|
||||
newEmailList.listEmailIds);
|
||||
emailListCompleted.addAll(listEmailIdDeleted);
|
||||
emailListCompleted.addAll(listEmailIdDeleted.emailIdsSuccess);
|
||||
|
||||
onProgressController.add(Right<Failure, Success>(EmptyingFolderState(
|
||||
mailboxId, emailListCompleted.length, totalEmails
|
||||
|
||||
@@ -29,16 +29,16 @@ class MarkAsMultipleEmailReadInteractor {
|
||||
readAction,
|
||||
);
|
||||
|
||||
if (emailIds.length == result.length) {
|
||||
if (emailIds.length == result.emailIdsSuccess.length) {
|
||||
yield Right(MarkAsMultipleEmailReadAllSuccess(
|
||||
result.length,
|
||||
result.emailIdsSuccess.length,
|
||||
readAction,
|
||||
));
|
||||
} else if (result.isEmpty) {
|
||||
} else if (result.emailIdsSuccess.isEmpty) {
|
||||
yield Left(MarkAsMultipleEmailReadAllFailure(readAction));
|
||||
} else {
|
||||
yield Right(MarkAsMultipleEmailReadHasSomeEmailFailure(
|
||||
result.length,
|
||||
result.emailIdsSuccess.length,
|
||||
readAction,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -24,16 +24,16 @@ class MarkAsStarMultipleEmailInteractor {
|
||||
|
||||
final result = await _emailRepository.markAsStar(session, accountId, emailIds, markStarAction);
|
||||
|
||||
if (emailIds.length == result.length) {
|
||||
if (emailIds.length == result.emailIdsSuccess.length) {
|
||||
yield Right(MarkAsStarMultipleEmailAllSuccess(
|
||||
emailIds.length,
|
||||
markStarAction,
|
||||
));
|
||||
} else if (result.isEmpty) {
|
||||
} else if (result.emailIdsSuccess.isEmpty) {
|
||||
yield Left(MarkAsStarMultipleEmailAllFailure(markStarAction));
|
||||
} else {
|
||||
yield Right(MarkAsStarMultipleEmailHasSomeEmailFailure(
|
||||
result.length,
|
||||
result.emailIdsSuccess.length,
|
||||
markStarAction,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -22,20 +22,20 @@ class MoveMultipleEmailToMailboxInteractor {
|
||||
try {
|
||||
yield Right(LoadingMoveMultipleEmailToMailboxAll());
|
||||
final result = await _emailRepository.moveToMailbox(session, accountId, moveRequest);
|
||||
if (moveRequest.totalEmails == result.length) {
|
||||
if (moveRequest.totalEmails == result.emailIdsSuccess.length) {
|
||||
yield Right(MoveMultipleEmailToMailboxAllSuccess(
|
||||
result,
|
||||
result.emailIdsSuccess,
|
||||
moveRequest.currentMailboxes.keys.first,
|
||||
moveRequest.destinationMailboxId,
|
||||
moveRequest.moveAction,
|
||||
moveRequest.emailActionType,
|
||||
destinationPath: moveRequest.destinationPath,
|
||||
));
|
||||
} else if (result.isEmpty) {
|
||||
} else if (result.emailIdsSuccess.isEmpty) {
|
||||
yield Left(MoveMultipleEmailToMailboxAllFailure(moveRequest.moveAction, moveRequest.emailActionType));
|
||||
} else {
|
||||
yield Right(MoveMultipleEmailToMailboxHasSomeEmailFailure(
|
||||
result,
|
||||
result.emailIdsSuccess,
|
||||
moveRequest.currentMailboxes.keys.first,
|
||||
moveRequest.destinationMailboxId,
|
||||
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/utc_date_extension.dart';
|
||||
export 'extensions/contact_support_capability_extension.dart';
|
||||
export 'extensions/list_id_extension.dart';
|
||||
// Identity
|
||||
export 'identity/identity_request_dto.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/download/download_manager.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@@ -60,7 +59,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 50;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -102,16 +101,16 @@ void main() {
|
||||
]
|
||||
});
|
||||
|
||||
final emails = List.generate(
|
||||
final emailIds = List.generate(
|
||||
totalEmails,
|
||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
||||
(index) => EmailId(Id('email_$index')),
|
||||
);
|
||||
|
||||
// Act
|
||||
final result = await emailApi.markAsRead(
|
||||
aliceSession,
|
||||
AccountFixtures.aliceAccountId,
|
||||
emails,
|
||||
emailIds,
|
||||
ReadActions.markAsRead,
|
||||
);
|
||||
|
||||
@@ -121,7 +120,8 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).called(countIterations);
|
||||
expect(result.length, totalEmails);
|
||||
expect(result.emailIdsSuccess.length, totalEmails);
|
||||
expect(result.mapErrors.isEmpty, isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -133,7 +133,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 200;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -175,16 +175,16 @@ void main() {
|
||||
]
|
||||
});
|
||||
|
||||
final emails = List.generate(
|
||||
final emailIds = List.generate(
|
||||
totalEmails,
|
||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
||||
(index) => EmailId(Id('email_$index')),
|
||||
);
|
||||
|
||||
// Act
|
||||
final result = await emailApi.markAsRead(
|
||||
aliceSession,
|
||||
AccountFixtures.aliceAccountId,
|
||||
emails,
|
||||
emailIds,
|
||||
ReadActions.markAsRead,
|
||||
);
|
||||
|
||||
@@ -194,7 +194,8 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).called(countIterations);
|
||||
expect(result.length, totalEmails);
|
||||
expect(result.emailIdsSuccess.length, totalEmails);
|
||||
expect(result.mapErrors.isEmpty, isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -206,7 +207,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 20;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -248,16 +249,16 @@ void main() {
|
||||
]
|
||||
});
|
||||
|
||||
final emails = List.generate(
|
||||
final emailIds = List.generate(
|
||||
totalEmails,
|
||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
||||
(index) => EmailId(Id('email_$index')),
|
||||
);
|
||||
|
||||
// Act
|
||||
final result = await emailApi.markAsRead(
|
||||
aliceSession,
|
||||
AccountFixtures.aliceAccountId,
|
||||
emails,
|
||||
emailIds,
|
||||
ReadActions.markAsRead,
|
||||
);
|
||||
|
||||
@@ -267,7 +268,83 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).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 maxObjectsInSet = 50;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -323,16 +400,16 @@ void main() {
|
||||
]
|
||||
});
|
||||
|
||||
final emails = List.generate(
|
||||
final emailIds = List.generate(
|
||||
totalEmails,
|
||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
||||
(index) => EmailId(Id('email_$index')),
|
||||
);
|
||||
|
||||
// Act
|
||||
final result = await emailApi.markAsStar(
|
||||
aliceSession,
|
||||
AccountFixtures.aliceAccountId,
|
||||
emails,
|
||||
emailIds,
|
||||
MarkStarAction.markStar,
|
||||
);
|
||||
|
||||
@@ -342,7 +419,8 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).called(countIterations);
|
||||
expect(result.length, totalEmails);
|
||||
expect(result.emailIdsSuccess.length, totalEmails);
|
||||
expect(result.mapErrors.isEmpty, isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -354,7 +432,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 200;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -396,16 +474,16 @@ void main() {
|
||||
]
|
||||
});
|
||||
|
||||
final emails = List.generate(
|
||||
final emailIds = List.generate(
|
||||
totalEmails,
|
||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
||||
(index) => EmailId(Id('email_$index')),
|
||||
);
|
||||
|
||||
// Act
|
||||
final result = await emailApi.markAsStar(
|
||||
aliceSession,
|
||||
AccountFixtures.aliceAccountId,
|
||||
emails,
|
||||
emailIds,
|
||||
MarkStarAction.markStar,
|
||||
);
|
||||
|
||||
@@ -415,7 +493,8 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).called(countIterations);
|
||||
expect(result.length, totalEmails);
|
||||
expect(result.emailIdsSuccess.length, totalEmails);
|
||||
expect(result.mapErrors.isEmpty, isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -427,7 +506,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 20;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -469,16 +548,16 @@ void main() {
|
||||
]
|
||||
});
|
||||
|
||||
final emails = List.generate(
|
||||
final emailIds = List.generate(
|
||||
totalEmails,
|
||||
(index) => Email(id: EmailId(Id('email_$index'))),
|
||||
(index) => EmailId(Id('email_$index')),
|
||||
);
|
||||
|
||||
// Act
|
||||
final result = await emailApi.markAsStar(
|
||||
aliceSession,
|
||||
AccountFixtures.aliceAccountId,
|
||||
emails,
|
||||
emailIds,
|
||||
MarkStarAction.markStar,
|
||||
);
|
||||
|
||||
@@ -488,7 +567,306 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).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 maxObjectsInSet = 50;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -554,7 +932,8 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).called(countIterations);
|
||||
expect(result.length, totalEmails);
|
||||
expect(result.emailIdsSuccess.length, totalEmails);
|
||||
expect(result.mapErrors.isEmpty, isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -566,7 +945,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 200;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -618,7 +997,8 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).called(countIterations);
|
||||
expect(result.length, totalEmails);
|
||||
expect(result.emailIdsSuccess.length, totalEmails);
|
||||
expect(result.mapErrors.isEmpty, isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -630,7 +1010,7 @@ void main() {
|
||||
const defaultMaxObjectsInSet = 50;
|
||||
const maxObjectsInSet = 20;
|
||||
const totalEmails = 100;
|
||||
final maxBatches = min(maxObjectsInSet, defaultMaxObjectsInSet);
|
||||
final maxBatches = [maxObjectsInSet, defaultMaxObjectsInSet, totalEmails].min;
|
||||
final countIterations = (totalEmails / maxBatches).ceil();
|
||||
final aliceSession = SessionFixtures.getAliceSessionWithMaxObjectsInSet(maxObjectsInSet);
|
||||
|
||||
@@ -682,7 +1062,74 @@ void main() {
|
||||
data: anyNamed('data'),
|
||||
cancelToken: anyNamed('cancelToken'),
|
||||
)).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