[bugfix] TF-2316 Can not delete folder when its children are hidden (#2519)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:collection';
|
||||||
import 'package:core/presentation/state/failure.dart';
|
import 'package:core/presentation/state/failure.dart';
|
||||||
import 'package:core/presentation/state/success.dart';
|
import 'package:core/presentation/state/success.dart';
|
||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
@@ -5,6 +6,8 @@ import 'package:dartz/dartz.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/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
|
import 'package:model/extensions/mailbox_extension.dart';
|
||||||
|
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
|
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart';
|
import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart';
|
||||||
|
|
||||||
@@ -14,24 +17,40 @@ class DeleteMultipleMailboxInteractor {
|
|||||||
DeleteMultipleMailboxInteractor(this._mailboxRepository);
|
DeleteMultipleMailboxInteractor(this._mailboxRepository);
|
||||||
|
|
||||||
Stream<Either<Failure, Success>> execute(
|
Stream<Either<Failure, Success>> execute(
|
||||||
Session session,
|
Session session,
|
||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
Map<MailboxId, List<MailboxId>> mapMailboxIdToDelete,
|
List<MailboxId> selectedMailboxIds,
|
||||||
List<MailboxId> listMailboxIdToDelete
|
|
||||||
) async* {
|
) async* {
|
||||||
try {
|
try {
|
||||||
yield Right<Failure, Success>(LoadingDeleteMultipleMailboxAll());
|
yield Right<Failure, Success>(LoadingDeleteMultipleMailboxAll());
|
||||||
|
|
||||||
final currentMailboxState = await _mailboxRepository.getMailboxState(session, accountId);
|
final currentMailboxState = await _mailboxRepository.getMailboxState(session, accountId);
|
||||||
|
|
||||||
|
final mailboxResponses = await _mailboxRepository.getAllMailbox(session, accountId).toList();
|
||||||
|
|
||||||
|
final Set<MailboxId> seenIds = {};
|
||||||
|
final List<PresentationMailbox> allMailboxes = [];
|
||||||
|
for (final response in mailboxResponses) {
|
||||||
|
for (final mailbox in response.mailboxes) {
|
||||||
|
final presentation = mailbox.toPresentationMailbox();
|
||||||
|
if (seenIds.add(presentation.id)) {
|
||||||
|
allMailboxes.add(presentation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final deleteMap = _buildDeleteMap(selectedMailboxIds, allMailboxes);
|
||||||
|
final mapMailboxIdToDelete = deleteMap.value1;
|
||||||
|
final listMailboxIdToDelete = deleteMap.value2;
|
||||||
|
|
||||||
final listResult = await Future.wait(
|
final listResult = await Future.wait(
|
||||||
mapMailboxIdToDelete.keys.map((mailboxId) {
|
mapMailboxIdToDelete.keys.map((mailboxId) {
|
||||||
final mailboxIdsToDelete = mapMailboxIdToDelete[mailboxId]!;
|
return _mailboxRepository.deleteMultipleMailbox(
|
||||||
return _mailboxRepository.deleteMultipleMailbox(
|
session,
|
||||||
session,
|
accountId,
|
||||||
accountId,
|
mapMailboxIdToDelete[mailboxId]!,
|
||||||
mailboxIdsToDelete);
|
);
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
final allSuccess = listResult.every((result) => result.isEmpty);
|
final allSuccess = listResult.every((result) => result.isEmpty);
|
||||||
@@ -39,18 +58,85 @@ class DeleteMultipleMailboxInteractor {
|
|||||||
|
|
||||||
if (allSuccess) {
|
if (allSuccess) {
|
||||||
yield Right<Failure, Success>(DeleteMultipleMailboxAllSuccess(
|
yield Right<Failure, Success>(DeleteMultipleMailboxAllSuccess(
|
||||||
listMailboxIdToDelete,
|
listMailboxIdToDelete,
|
||||||
currentMailboxState: currentMailboxState));
|
currentMailboxState: currentMailboxState,
|
||||||
|
));
|
||||||
} else if (allFailed) {
|
} else if (allFailed) {
|
||||||
yield Left<Failure, Success>(DeleteMultipleMailboxAllFailure());
|
yield Left<Failure, Success>(DeleteMultipleMailboxAllFailure());
|
||||||
} else {
|
} else {
|
||||||
yield Right<Failure, Success>(DeleteMultipleMailboxHasSomeSuccess(
|
yield Right<Failure, Success>(DeleteMultipleMailboxHasSomeSuccess(
|
||||||
listMailboxIdToDelete,
|
listMailboxIdToDelete,
|
||||||
currentMailboxState: currentMailboxState));
|
currentMailboxState: currentMailboxState,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logWarning('DeleteMultipleMailboxInteractor::execute(): exception: $e');
|
logWarning('DeleteMultipleMailboxInteractor::execute(): exception: $e');
|
||||||
yield Left<Failure, Success>(DeleteMultipleMailboxFailure(e));
|
yield Left<Failure, Success>(DeleteMultipleMailboxFailure(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Builds the map of [MailboxId] → ordered delete list for each selected root,
|
||||||
|
/// plus a flat list of all IDs to delete.
|
||||||
|
///
|
||||||
|
/// Uses [allMailboxes] (subscribed and unsubscribed) so hidden subfolders are
|
||||||
|
/// automatically included — no separate unsubscribed-tree pass is needed.
|
||||||
|
Tuple2<Map<MailboxId, List<MailboxId>>, List<MailboxId>> _buildDeleteMap(
|
||||||
|
List<MailboxId> selectedMailboxIds,
|
||||||
|
List<PresentationMailbox> allMailboxes,
|
||||||
|
) {
|
||||||
|
final parentToChildren = _buildParentToChildrenMap(allMailboxes);
|
||||||
|
final Map<MailboxId, List<MailboxId>> mapDescendantIds = {};
|
||||||
|
final Set<MailboxId> processedIds = {};
|
||||||
|
|
||||||
|
for (final mailboxId in selectedMailboxIds) {
|
||||||
|
if (processedIds.contains(mailboxId)) continue;
|
||||||
|
|
||||||
|
// Collect all descendants (pre-order DFS), then reverse so deepest children
|
||||||
|
// come first — the server requires children to be deleted before parents.
|
||||||
|
final descendants = _collectDescendantsPreOrder(mailboxId, parentToChildren);
|
||||||
|
final deleteOrder = descendants.reversed.toList();
|
||||||
|
|
||||||
|
mapDescendantIds[mailboxId] = deleteOrder;
|
||||||
|
processedIds.addAll(deleteOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
final allMailboxIds = mapDescendantIds.values.expand((ids) => ids).toList();
|
||||||
|
return Tuple2(mapDescendantIds, allMailboxIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<MailboxId, List<MailboxId>> _buildParentToChildrenMap(
|
||||||
|
List<PresentationMailbox> mailboxes,
|
||||||
|
) {
|
||||||
|
final Map<MailboxId, List<MailboxId>> parentToChildren = HashMap();
|
||||||
|
for (final mailbox in mailboxes) {
|
||||||
|
final parentId = mailbox.parentId;
|
||||||
|
if (parentId != null) {
|
||||||
|
parentToChildren.putIfAbsent(parentId, () => []).add(mailbox.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parentToChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pre-order DFS: root first, then children. Caller should reverse the result
|
||||||
|
/// to get deepest-first deletion order.
|
||||||
|
List<MailboxId> _collectDescendantsPreOrder(
|
||||||
|
MailboxId rootId,
|
||||||
|
Map<MailboxId, List<MailboxId>> parentToChildren,
|
||||||
|
) {
|
||||||
|
final result = <MailboxId>[];
|
||||||
|
final stack = ListQueue<MailboxId>()..addLast(rootId);
|
||||||
|
|
||||||
|
while (stack.isNotEmpty) {
|
||||||
|
final current = stack.removeLast();
|
||||||
|
result.add(current);
|
||||||
|
final children = parentToChildren[current];
|
||||||
|
if (children != null) {
|
||||||
|
// Push in reverse so the first child is processed first (stack is LIFO).
|
||||||
|
for (final child in children.reversed) {
|
||||||
|
stack.addLast(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,6 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.d
|
|||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_action_reactor.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_action_reactor.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
|
||||||
@@ -1039,18 +1038,10 @@ class MailboxController extends BaseMailboxController
|
|||||||
|
|
||||||
void _deleteMailboxAction(PresentationMailbox presentationMailbox) {
|
void _deleteMailboxAction(PresentationMailbox presentationMailbox) {
|
||||||
if (session != null && accountId != null) {
|
if (session != null && accountId != null) {
|
||||||
final tupleMap = MailboxUtils.generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
[presentationMailbox],
|
|
||||||
defaultMailboxTree.value,
|
|
||||||
personalMailboxTree.value);
|
|
||||||
final mapDescendantIds = tupleMap.value1;
|
|
||||||
final listMailboxId = tupleMap.value2;
|
|
||||||
|
|
||||||
consumeState(_deleteMultipleMailboxInteractor.execute(
|
consumeState(_deleteMultipleMailboxInteractor.execute(
|
||||||
session!,
|
session!,
|
||||||
accountId!,
|
accountId!,
|
||||||
mapDescendantIds,
|
[presentationMailbox.id],
|
||||||
listMailboxId,
|
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
_deleteMailboxFailure(DeleteMultipleMailboxFailure(null));
|
_deleteMailboxFailure(DeleteMultipleMailboxFailure(null));
|
||||||
|
|||||||
@@ -1,60 +1,9 @@
|
|||||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
|
||||||
import 'package:core/utils/app_logger.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:email_recovery/email_recovery/capability_deleted_messages_vault.dart';
|
import 'package:email_recovery/email_recovery/capability_deleted_messages_vault.dart';
|
||||||
import 'package:flutter/material.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/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
|
||||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
|
||||||
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||||
|
|
||||||
class MailboxUtils {
|
class MailboxUtils {
|
||||||
|
|
||||||
static Tuple2<Map<MailboxId, List<MailboxId>>, List<MailboxId>> generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
List<PresentationMailbox> selectedMailboxList,
|
|
||||||
MailboxTree defaultMailboxTree,
|
|
||||||
MailboxTree folderMailboxTree,
|
|
||||||
) {
|
|
||||||
Map<MailboxId, List<MailboxId>> mapDescendantIds = {};
|
|
||||||
List<MailboxId> allMailboxIds = [];
|
|
||||||
|
|
||||||
for (var mailbox in selectedMailboxList) {
|
|
||||||
final currentMailboxId = mailbox.id;
|
|
||||||
|
|
||||||
if (allMailboxIds.contains(currentMailboxId)) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
final matchedNode = defaultMailboxTree.findNode((node) => node.item.id == currentMailboxId)
|
|
||||||
?? folderMailboxTree.findNode((node) => node.item.id == currentMailboxId);
|
|
||||||
|
|
||||||
if (matchedNode != null) {
|
|
||||||
final descendantIds = matchedNode.descendantsAsList().mailboxIds;
|
|
||||||
final descendantIdsReversed = descendantIds.reversed.toList();
|
|
||||||
|
|
||||||
mapDescendantIds[currentMailboxId] = descendantIdsReversed;
|
|
||||||
allMailboxIds.addAll(descendantIdsReversed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log('MailboxUtils::generateMapDescendantIdsAndMailboxIdList(): mapDescendantIds: $mapDescendantIds');
|
|
||||||
return Tuple2(mapDescendantIds, allMailboxIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
static EdgeInsets getPaddingListViewMailboxSearched(BuildContext context, ResponsiveUtils responsiveUtils) {
|
|
||||||
if (responsiveUtils.isWebDesktop(context)) {
|
|
||||||
return const EdgeInsets.only(left: 16, right: 16, bottom: 16);
|
|
||||||
} else {
|
|
||||||
if (responsiveUtils.isScreenWithShortestSide(context)) {
|
|
||||||
return const EdgeInsets.all(16);
|
|
||||||
} else {
|
|
||||||
return const EdgeInsets.symmetric(horizontal: 32, vertical: 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isDeletedMessageVaultSupported(Session? session, AccountId? accountId) {
|
static bool isDeletedMessageVaultSupported(Session? session, AccountId? accountId) {
|
||||||
if (session == null || accountId == null) {
|
if (session == null || accountId == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentat
|
|||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_action_reactor.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_action_reactor.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
|
||||||
@@ -584,19 +583,10 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
|
|||||||
|
|
||||||
void _deleteMailboxAction(PresentationMailbox presentationMailbox) {
|
void _deleteMailboxAction(PresentationMailbox presentationMailbox) {
|
||||||
if (session != null && accountId != null) {
|
if (session != null && accountId != null) {
|
||||||
final tupleMap = MailboxUtils.generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
[presentationMailbox],
|
|
||||||
defaultMailboxTree.value,
|
|
||||||
personalMailboxTree.value
|
|
||||||
);
|
|
||||||
final mapDescendantIds = tupleMap.value1;
|
|
||||||
final listMailboxId = tupleMap.value2;
|
|
||||||
|
|
||||||
consumeState(_deleteMultipleMailboxInteractor.execute(
|
consumeState(_deleteMultipleMailboxInteractor.execute(
|
||||||
session!,
|
session!,
|
||||||
accountId!,
|
accountId!,
|
||||||
mapDescendantIds,
|
[presentationMailbox.id],
|
||||||
listMailboxId
|
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
_deleteMailboxFailure(DeleteMultipleMailboxFailure(null));
|
_deleteMailboxFailure(DeleteMultipleMailboxFailure(null));
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/error/error_type.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/mail/mailbox/mailbox.dart';
|
||||||
|
import 'package:mockito/annotations.dart';
|
||||||
|
import 'package:mockito/mockito.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart';
|
||||||
|
import '../../../../fixtures/account_fixtures.dart';
|
||||||
|
import '../../../../fixtures/mailbox_fixtures.dart';
|
||||||
|
import '../../../../fixtures/session_fixtures.dart';
|
||||||
|
import 'delete_multiple_mailbox_interactor_test.mocks.dart';
|
||||||
|
|
||||||
|
@GenerateMocks([MailboxRepository])
|
||||||
|
|
||||||
|
void _stubGetMailboxState(MailboxRepository repo, jmap.State state) {
|
||||||
|
when(
|
||||||
|
repo.getMailboxState(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenAnswer((_) => Future.value(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stubGetAllMailboxWithHiddenMailboxes(MailboxRepository repo, jmap.State state) {
|
||||||
|
when(
|
||||||
|
repo.getAllMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenAnswer((_) => Stream.fromIterable({
|
||||||
|
JmapMailboxResponse(
|
||||||
|
mailboxes: [
|
||||||
|
MailboxFixtures.inboxMailbox,
|
||||||
|
MailboxFixtures.sentMailbox,
|
||||||
|
MailboxFixtures.selectedFolderToDelete,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_1,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_2,
|
||||||
|
],
|
||||||
|
state: state,
|
||||||
|
),
|
||||||
|
JmapMailboxResponse(
|
||||||
|
mailboxes: [
|
||||||
|
MailboxFixtures.inboxMailbox,
|
||||||
|
MailboxFixtures.sentMailbox,
|
||||||
|
MailboxFixtures.selectedFolderToDelete,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_1,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_2,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_3,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_4,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_5,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_6,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_7,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_8,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_9,
|
||||||
|
MailboxFixtures.selectedFolderToDelete_10,
|
||||||
|
],
|
||||||
|
state: state,
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stubGetAllMailboxWithSubscribedFolders(MailboxRepository repo, jmap.State state) {
|
||||||
|
when(
|
||||||
|
repo.getAllMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenAnswer((_) => Stream.value(JmapMailboxResponse(
|
||||||
|
mailboxes: [MailboxFixtures.subscribedFolder, MailboxFixtures.subscribedChild],
|
||||||
|
state: state,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stubDeleteMailboxSuccess(MailboxRepository repo, List<MailboxId> ids) {
|
||||||
|
when(
|
||||||
|
repo.deleteMultipleMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId, ids),
|
||||||
|
).thenAnswer((_) => Future.value({}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stubDeleteMailboxFailure(
|
||||||
|
MailboxRepository repo,
|
||||||
|
List<MailboxId> ids,
|
||||||
|
Map<Id, SetError> errors,
|
||||||
|
) {
|
||||||
|
when(
|
||||||
|
repo.deleteMultipleMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId, ids),
|
||||||
|
).thenAnswer((_) => Future.value(errors));
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<dynamic> _executeDelete(
|
||||||
|
DeleteMultipleMailboxInteractor interactor,
|
||||||
|
List<MailboxId> ids,
|
||||||
|
) => interactor.execute(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId, ids);
|
||||||
|
|
||||||
|
Matcher _emitsLoadingThen(dynamic result) => emitsInOrder([
|
||||||
|
Right(LoadingDeleteMultipleMailboxAll()),
|
||||||
|
result,
|
||||||
|
]);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
late MailboxRepository mailboxRepository;
|
||||||
|
late DeleteMultipleMailboxInteractor deleteMultipleMailboxInteractor;
|
||||||
|
|
||||||
|
group('[DeleteMultipleMailboxInteractor]', () {
|
||||||
|
setUp(() {
|
||||||
|
mailboxRepository = MockMailboxRepository();
|
||||||
|
deleteMultipleMailboxInteractor = DeleteMultipleMailboxInteractor(mailboxRepository);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('with hidden mailbox responses', () {
|
||||||
|
final state = jmap.State('s1');
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
_stubGetMailboxState(mailboxRepository, state);
|
||||||
|
_stubGetAllMailboxWithHiddenMailboxes(mailboxRepository, state);
|
||||||
|
// second batch defaults to success; override per-test when needed
|
||||||
|
_stubDeleteMailboxSuccess(mailboxRepository, MailboxFixtures.listDescendantMailboxForSelectedFolder2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should execute to delete selected mailbox an all its children included hidden mailbox', () {
|
||||||
|
_stubDeleteMailboxSuccess(mailboxRepository, MailboxFixtures.listDescendantMailboxForSelectedFolder);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, MailboxFixtures.listMailboxIdsToDelete),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxAllSuccess(
|
||||||
|
MailboxFixtures.listMailboxIdToDelete,
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should execute and yield DeleteMultipleMailboxAllFailure when delete selected mailbox all fail', () {
|
||||||
|
_stubDeleteMailboxFailure(
|
||||||
|
mailboxRepository,
|
||||||
|
MailboxFixtures.listDescendantMailboxForSelectedFolder,
|
||||||
|
{Id('folderToDelete'): SetError(ErrorType('error'))},
|
||||||
|
);
|
||||||
|
_stubDeleteMailboxFailure(
|
||||||
|
mailboxRepository,
|
||||||
|
MailboxFixtures.listDescendantMailboxForSelectedFolder2,
|
||||||
|
{Id('folderToDelete_8'): SetError(ErrorType('error'))},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, MailboxFixtures.listMailboxIdsToDelete),
|
||||||
|
_emitsLoadingThen(Left(DeleteMultipleMailboxAllFailure())),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should execute and yield DeleteMultipleMailboxHasSomeSuccess when delete selected mailbox has some fail', () {
|
||||||
|
_stubDeleteMailboxFailure(
|
||||||
|
mailboxRepository,
|
||||||
|
MailboxFixtures.listDescendantMailboxForSelectedFolder,
|
||||||
|
{Id('folderToDelete'): SetError(ErrorType('error'))},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, MailboxFixtures.listMailboxIdsToDelete),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxHasSomeSuccess(
|
||||||
|
MailboxFixtures.listMailboxIdToDelete,
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should yield AllSuccess with empty lists when selectedMailboxIds is empty', () {
|
||||||
|
final state = jmap.State('s1');
|
||||||
|
_stubGetMailboxState(mailboxRepository, state);
|
||||||
|
when(
|
||||||
|
mailboxRepository.getAllMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenAnswer((_) => Stream.value(JmapMailboxResponse(
|
||||||
|
mailboxes: [MailboxFixtures.inboxMailbox, MailboxFixtures.sentMailbox],
|
||||||
|
state: state,
|
||||||
|
)));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, []),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxAllSuccess(
|
||||||
|
[],
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should execute and yield DeleteMultipleMailboxFailure when getAllMailbox fail', () {
|
||||||
|
final state = jmap.State('s1');
|
||||||
|
_stubGetMailboxState(mailboxRepository, state);
|
||||||
|
when(
|
||||||
|
mailboxRepository.getAllMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenThrow('error');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, MailboxFixtures.listMailboxIdsToDelete),
|
||||||
|
_emitsLoadingThen(Left(DeleteMultipleMailboxFailure('error'))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should delete selected mailbox alone when it is absent from allMailboxes (no children found)', () {
|
||||||
|
final state = jmap.State('s1');
|
||||||
|
final ghostMailboxId = MailboxId(Id('ghostMailbox'));
|
||||||
|
_stubGetMailboxState(mailboxRepository, state);
|
||||||
|
when(
|
||||||
|
mailboxRepository.getAllMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenAnswer((_) => Stream.value(JmapMailboxResponse(
|
||||||
|
mailboxes: [MailboxFixtures.inboxMailbox, MailboxFixtures.sentMailbox],
|
||||||
|
state: state,
|
||||||
|
)));
|
||||||
|
_stubDeleteMailboxSuccess(mailboxRepository, [ghostMailboxId]);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, [ghostMailboxId]),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxAllSuccess(
|
||||||
|
[ghostMailboxId],
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('with subscribed folders', () {
|
||||||
|
final state = jmap.State('s1');
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
_stubGetMailboxState(mailboxRepository, state);
|
||||||
|
_stubGetAllMailboxWithSubscribedFolders(mailboxRepository, state);
|
||||||
|
_stubDeleteMailboxSuccess(mailboxRepository, MailboxFixtures.expectedDeleteListSubscribedOnly);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should delete subscribed child before parent when no hidden subfolders exist', () {
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, MailboxFixtures.listMailboxIdsForSubscribedOnly),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxAllSuccess(
|
||||||
|
MailboxFixtures.expectedDeleteListSubscribedOnly,
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should skip already-processed descendant when it also appears in selectedMailboxIds', () {
|
||||||
|
// subscribedChild is a descendant of subscribedFolder — it must be skipped
|
||||||
|
// as a root and subsumed into the parent's batch instead.
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, [
|
||||||
|
MailboxFixtures.subscribedFolder.id!,
|
||||||
|
MailboxFixtures.subscribedChild.id!,
|
||||||
|
]),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxAllSuccess(
|
||||||
|
MailboxFixtures.expectedDeleteListSubscribedOnly,
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should delete 3-level unsubscribed nesting in deepest-first order', () {
|
||||||
|
final state = jmap.State('s1');
|
||||||
|
_stubGetMailboxState(mailboxRepository, state);
|
||||||
|
when(
|
||||||
|
mailboxRepository.getAllMailbox(SessionFixtures.aliceSession, AccountFixtures.aliceAccountId),
|
||||||
|
).thenAnswer((_) => Stream.value(JmapMailboxResponse(
|
||||||
|
mailboxes: [
|
||||||
|
MailboxFixtures.parentFolder,
|
||||||
|
MailboxFixtures.hiddenLevel1,
|
||||||
|
MailboxFixtures.hiddenLevel2,
|
||||||
|
MailboxFixtures.hiddenLevel3,
|
||||||
|
],
|
||||||
|
state: state,
|
||||||
|
)));
|
||||||
|
_stubDeleteMailboxSuccess(mailboxRepository, MailboxFixtures.expectedDeleteListThreeLevelNesting);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_executeDelete(deleteMultipleMailboxInteractor, [MailboxFixtures.parentFolder.id!]),
|
||||||
|
_emitsLoadingThen(Right(DeleteMultipleMailboxAllSuccess(
|
||||||
|
MailboxFixtures.expectedDeleteListThreeLevelNesting,
|
||||||
|
currentMailboxState: state,
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
-282
@@ -1,282 +0,0 @@
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
|
||||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
group('generate mapping delete multiple mailbox test', () {
|
|
||||||
|
|
||||||
final expectedMapOfTwoMailboxId = {
|
|
||||||
MailboxId(Id("A")): [
|
|
||||||
MailboxId(Id('A_1_1')),
|
|
||||||
MailboxId(Id('A_1')),
|
|
||||||
MailboxId(Id('A_2_1')),
|
|
||||||
MailboxId(Id('A_2')),
|
|
||||||
MailboxId(Id('A'))
|
|
||||||
],
|
|
||||||
MailboxId(Id("B_1")): [MailboxId(Id('B_1'))],
|
|
||||||
};
|
|
||||||
|
|
||||||
final expectedListMailboxId = [
|
|
||||||
MailboxId(Id('A_1_1')),
|
|
||||||
MailboxId(Id('A_1')),
|
|
||||||
MailboxId(Id('A_2_1')),
|
|
||||||
MailboxId(Id('A_2')),
|
|
||||||
MailboxId(Id('A')),
|
|
||||||
MailboxId(Id('B_1')),
|
|
||||||
];
|
|
||||||
|
|
||||||
final expectedMapOfOneMailboxId = {
|
|
||||||
MailboxId(Id("A")): [
|
|
||||||
MailboxId(Id('A_1_1')),
|
|
||||||
MailboxId(Id('A_1')),
|
|
||||||
MailboxId(Id('A_2_1')),
|
|
||||||
MailboxId(Id('A_2')),
|
|
||||||
MailboxId(Id('A'))
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
final expectedMapOfThreeMailboxId = {
|
|
||||||
MailboxId(Id("A")): [
|
|
||||||
MailboxId(Id('A_1_1')),
|
|
||||||
MailboxId(Id('A_1')),
|
|
||||||
MailboxId(Id('A_2_1')),
|
|
||||||
MailboxId(Id('A_2')),
|
|
||||||
MailboxId(Id('A'))
|
|
||||||
],
|
|
||||||
MailboxId(Id("B_1")): [MailboxId(Id('B_1'))],
|
|
||||||
MailboxId(Id("C_1")): [MailboxId(Id('C_1'))],
|
|
||||||
};
|
|
||||||
|
|
||||||
test('_generateMapDescendantIdsAndMailboxIdList should return map with 2 items when mailboxes belong to 2 different tree', () async {
|
|
||||||
final defaultMailboxTree = MailboxTree(MailboxNode(PresentationMailbox(MailboxId(Id('root')))));
|
|
||||||
|
|
||||||
final folderMailboxTree = MailboxTree(
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('root'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_2')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_2_1')), parentId: MailboxId(Id('A_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_1')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_1_1')), parentId: MailboxId(Id('A_1'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B_2')), parentId: MailboxId(Id('B'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_2_1')), parentId: MailboxId(Id('B_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_1')), parentId: MailboxId(Id('B')))),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
final selectedMailboxList = [
|
|
||||||
PresentationMailbox(MailboxId(Id("A")), parentId: null),
|
|
||||||
PresentationMailbox(MailboxId(Id('A_1')), parentId: MailboxId(Id('A'))),
|
|
||||||
PresentationMailbox(MailboxId(Id('A_2_1')), parentId: MailboxId(Id('A_2'))),
|
|
||||||
PresentationMailbox(MailboxId(Id("B_1")), parentId: MailboxId(Id('B')))
|
|
||||||
];
|
|
||||||
|
|
||||||
final tupleResult = MailboxUtils.generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
selectedMailboxList,
|
|
||||||
defaultMailboxTree,
|
|
||||||
folderMailboxTree);
|
|
||||||
|
|
||||||
expect(tupleResult.value1, equals(expectedMapOfTwoMailboxId));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('_generateMapDescendantIdsAndMailboxIdList should return list with 5 item when mailboxes belong to 2 different tree', () async {
|
|
||||||
final defaultMailboxTree = MailboxTree(MailboxNode(PresentationMailbox(MailboxId(Id('root')))));
|
|
||||||
|
|
||||||
final folderMailboxTree = MailboxTree(
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('root'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_2')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_2_1')), parentId: MailboxId(Id('A_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_1')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_1_1')), parentId: MailboxId(Id('A_1'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B_2')), parentId: MailboxId(Id('B'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_2_1')), parentId: MailboxId(Id('B_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_1')), parentId: MailboxId(Id('B')))),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
final selectedMailboxList = [
|
|
||||||
PresentationMailbox(MailboxId(Id("A")), parentId: null),
|
|
||||||
PresentationMailbox(MailboxId(Id('A_1')), parentId: MailboxId(Id('A'))),
|
|
||||||
PresentationMailbox(MailboxId(Id('A_2_1')), parentId: MailboxId(Id('A_2'))),
|
|
||||||
PresentationMailbox(MailboxId(Id("B_1")), parentId: MailboxId(Id('B')))
|
|
||||||
];
|
|
||||||
|
|
||||||
final tupleResult = MailboxUtils.generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
selectedMailboxList,
|
|
||||||
defaultMailboxTree,
|
|
||||||
folderMailboxTree);
|
|
||||||
|
|
||||||
expect(tupleResult.value2, equals(expectedListMailboxId));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('_generateMapDescendantIdsAndMailboxIdList should return map with 1 items when mailboxes belong to 2 different tree', () async {
|
|
||||||
final defaultMailboxTree = MailboxTree(MailboxNode(PresentationMailbox(MailboxId(Id('root')))));
|
|
||||||
|
|
||||||
final folderMailboxTree = MailboxTree(
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('root'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_2')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_2_1')), parentId: MailboxId(Id('A_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_1')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_1_1')), parentId: MailboxId(Id('A_1'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B_2')), parentId: MailboxId(Id('B'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_2_1')), parentId: MailboxId(Id('B_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_1')), parentId: MailboxId(Id('B')))),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
final selectedMailboxList = [
|
|
||||||
PresentationMailbox(MailboxId(Id("A")), parentId: null),
|
|
||||||
];
|
|
||||||
|
|
||||||
final tupleResult = MailboxUtils.generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
selectedMailboxList,
|
|
||||||
defaultMailboxTree,
|
|
||||||
folderMailboxTree);
|
|
||||||
|
|
||||||
expect(tupleResult.value1, equals(expectedMapOfOneMailboxId));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('_generateMapDescendantIdsAndMailboxIdList should return map with 3 items when mailboxes belong to 2 different tree', () async {
|
|
||||||
final defaultMailboxTree = MailboxTree(MailboxNode(PresentationMailbox(MailboxId(Id('root')))));
|
|
||||||
|
|
||||||
final folderMailboxTree = MailboxTree(
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('root'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_2')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_2_1')), parentId: MailboxId(Id('A_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('A_1')), parentId: MailboxId(Id('A'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('A_1_1')), parentId: MailboxId(Id('A_1'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('B_2')), parentId: MailboxId(Id('B'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_2_1')), parentId: MailboxId(Id('B_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('B_1')), parentId: MailboxId(Id('B')))),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('C')), parentId: null),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(
|
|
||||||
PresentationMailbox(MailboxId(Id('C_2')), parentId: MailboxId(Id('C'))),
|
|
||||||
childrenItems: [
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('C_2_1')), parentId: MailboxId(Id('C_2'))))
|
|
||||||
]
|
|
||||||
),
|
|
||||||
MailboxNode(PresentationMailbox(MailboxId(Id('C_1')), parentId: MailboxId(Id('C')))),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
final selectedMailboxList = [
|
|
||||||
PresentationMailbox(MailboxId(Id("A")), parentId: null),
|
|
||||||
PresentationMailbox(MailboxId(Id("B_1")), parentId: MailboxId(Id('B'))),
|
|
||||||
PresentationMailbox(MailboxId(Id("C_1")), parentId: MailboxId(Id('C')))
|
|
||||||
];
|
|
||||||
|
|
||||||
final tupleResult = MailboxUtils.generateMapDescendantIdsAndMailboxIdList(
|
|
||||||
selectedMailboxList,
|
|
||||||
defaultMailboxTree,
|
|
||||||
folderMailboxTree);
|
|
||||||
|
|
||||||
expect(tupleResult.value1, equals(expectedMapOfThreeMailboxId));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Vendored
+403
@@ -107,4 +107,407 @@ class MailboxFixtures {
|
|||||||
PresentationMailbox.actionRequiredFolder;
|
PresentationMailbox.actionRequiredFolder;
|
||||||
|
|
||||||
static final currentState = State('2c9f1b12-b35a-43e6-9af2-0106fb53a943');
|
static final currentState = State('2c9f1b12-b35a-43e6-9af2-0106fb53a943');
|
||||||
|
|
||||||
|
static final selectedFolderToDelete = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete')),
|
||||||
|
name: MailboxName('folderToDelete'),
|
||||||
|
parentId: null,
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_1 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_1')),
|
||||||
|
name: MailboxName('folderToDelete_1'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_2 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_2')),
|
||||||
|
name: MailboxName('folderToDelete_2'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_1")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_3 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_3')),
|
||||||
|
name: MailboxName('folderToDelete_3'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_4 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_4')),
|
||||||
|
name: MailboxName('folderToDelete_4'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_3")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_5 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_5')),
|
||||||
|
name: MailboxName('folderToDelete_5'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_3")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_6 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_6')),
|
||||||
|
name: MailboxName('folderToDelete_6'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_5")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_7 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_7')),
|
||||||
|
name: MailboxName('folderToDelete_7'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_6")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_8 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_8')),
|
||||||
|
name: MailboxName('folderToDelete_8'),
|
||||||
|
parentId: null,
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_9 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_9')),
|
||||||
|
name: MailboxName('folderToDelete_9'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_8")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final selectedFolderToDelete_10 = Mailbox(
|
||||||
|
id: MailboxId(Id('folderToDelete_10')),
|
||||||
|
name: MailboxName('folderToDelete_10'),
|
||||||
|
parentId: MailboxId(Id("folderToDelete_8")),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(123)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(12)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(123)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(12)),
|
||||||
|
myRights: MailboxRights(
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
isSubscribed: IsSubscribed(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
static final listMailboxIdToDelete = [
|
||||||
|
MailboxId(Id('folderToDelete_7')),
|
||||||
|
MailboxId(Id('folderToDelete_6')),
|
||||||
|
MailboxId(Id('folderToDelete_5')),
|
||||||
|
MailboxId(Id('folderToDelete_4')),
|
||||||
|
MailboxId(Id('folderToDelete_3')),
|
||||||
|
MailboxId(Id('folderToDelete_2')),
|
||||||
|
MailboxId(Id('folderToDelete_1')),
|
||||||
|
MailboxId(Id('folderToDelete')),
|
||||||
|
MailboxId(Id('folderToDelete_10')),
|
||||||
|
MailboxId(Id('folderToDelete_9')),
|
||||||
|
MailboxId(Id('folderToDelete_8'))
|
||||||
|
];
|
||||||
|
|
||||||
|
static final listDescendantMailboxForSelectedFolder = <MailboxId>[
|
||||||
|
MailboxId(Id('folderToDelete_7')),
|
||||||
|
MailboxId(Id('folderToDelete_6')),
|
||||||
|
MailboxId(Id('folderToDelete_5')),
|
||||||
|
MailboxId(Id('folderToDelete_4')),
|
||||||
|
MailboxId(Id('folderToDelete_3')),
|
||||||
|
MailboxId(Id('folderToDelete_2')),
|
||||||
|
MailboxId(Id('folderToDelete_1')),
|
||||||
|
MailboxId(Id('folderToDelete')),
|
||||||
|
];
|
||||||
|
|
||||||
|
static final listDescendantMailboxForSelectedFolder2 = <MailboxId>[
|
||||||
|
MailboxId(Id('folderToDelete_10')),
|
||||||
|
MailboxId(Id('folderToDelete_9')),
|
||||||
|
MailboxId(Id('folderToDelete_8'))
|
||||||
|
];
|
||||||
|
|
||||||
|
static final listMailboxIdsToDelete = <MailboxId>[
|
||||||
|
selectedFolderToDelete.id!,
|
||||||
|
selectedFolderToDelete_8.id!,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Fixtures for "no hidden children" scenario — all mailboxes are subscribed.
|
||||||
|
static final subscribedFolder = Mailbox(
|
||||||
|
id: MailboxId(Id('subscribedFolder')),
|
||||||
|
name: MailboxName('subscribedFolder'),
|
||||||
|
parentId: null,
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(0)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(0)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(0)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(0)),
|
||||||
|
myRights: MailboxRights(true, true, true, true, true, true, true, true, true),
|
||||||
|
isSubscribed: IsSubscribed(true),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final subscribedChild = Mailbox(
|
||||||
|
id: MailboxId(Id('subscribedChild')),
|
||||||
|
name: MailboxName('subscribedChild'),
|
||||||
|
parentId: MailboxId(Id('subscribedFolder')),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(0)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(0)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(0)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(0)),
|
||||||
|
myRights: MailboxRights(true, true, true, true, true, true, true, true, true),
|
||||||
|
isSubscribed: IsSubscribed(true),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final listMailboxIdsForSubscribedOnly = <MailboxId>[
|
||||||
|
MailboxId(Id('subscribedFolder')),
|
||||||
|
];
|
||||||
|
|
||||||
|
static final expectedDeleteListSubscribedOnly = <MailboxId>[
|
||||||
|
MailboxId(Id('subscribedChild')),
|
||||||
|
MailboxId(Id('subscribedFolder')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Fixtures for "3-level unsubscribed nesting" scenario.
|
||||||
|
// Tree: parentFolder (subscribed) → level1 (unsubscribed) → level2 (unsubscribed) → level3 (unsubscribed)
|
||||||
|
static final parentFolder = Mailbox(
|
||||||
|
id: MailboxId(Id('parentFolder')),
|
||||||
|
name: MailboxName('parentFolder'),
|
||||||
|
parentId: null,
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(0)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(0)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(0)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(0)),
|
||||||
|
myRights: MailboxRights(true, true, true, true, true, true, true, true, true),
|
||||||
|
isSubscribed: IsSubscribed(true),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final hiddenLevel1 = Mailbox(
|
||||||
|
id: MailboxId(Id('hiddenLevel1')),
|
||||||
|
name: MailboxName('hiddenLevel1'),
|
||||||
|
parentId: MailboxId(Id('parentFolder')),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(0)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(0)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(0)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(0)),
|
||||||
|
myRights: MailboxRights(true, true, true, true, true, true, true, true, true),
|
||||||
|
isSubscribed: IsSubscribed(false),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final hiddenLevel2 = Mailbox(
|
||||||
|
id: MailboxId(Id('hiddenLevel2')),
|
||||||
|
name: MailboxName('hiddenLevel2'),
|
||||||
|
parentId: MailboxId(Id('hiddenLevel1')),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(0)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(0)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(0)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(0)),
|
||||||
|
myRights: MailboxRights(true, true, true, true, true, true, true, true, true),
|
||||||
|
isSubscribed: IsSubscribed(false),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final hiddenLevel3 = Mailbox(
|
||||||
|
id: MailboxId(Id('hiddenLevel3')),
|
||||||
|
name: MailboxName('hiddenLevel3'),
|
||||||
|
parentId: MailboxId(Id('hiddenLevel2')),
|
||||||
|
role: null,
|
||||||
|
sortOrder: SortOrder(sortValue: 1000),
|
||||||
|
totalEmails: TotalEmails(UnsignedInt(0)),
|
||||||
|
unreadEmails: UnreadEmails(UnsignedInt(0)),
|
||||||
|
totalThreads: TotalThreads(UnsignedInt(0)),
|
||||||
|
unreadThreads: UnreadThreads(UnsignedInt(0)),
|
||||||
|
myRights: MailboxRights(true, true, true, true, true, true, true, true, true),
|
||||||
|
isSubscribed: IsSubscribed(false),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final expectedDeleteListThreeLevelNesting = <MailboxId>[
|
||||||
|
MailboxId(Id('hiddenLevel3')),
|
||||||
|
MailboxId(Id('hiddenLevel2')),
|
||||||
|
MailboxId(Id('hiddenLevel1')),
|
||||||
|
MailboxId(Id('parentFolder')),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user