TF-4236 Implement remove a label from an email when unselect in context menu Label as
This commit is contained in:
@@ -5,6 +5,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_i
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/remove_a_label_from_an_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/bindings/email_interactor_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
|
||||
@@ -25,6 +26,7 @@ class EmailBindings extends Bindings {
|
||||
Get.find<GetAllIdentitiesInteractor>(),
|
||||
Get.find<StoreOpenedEmailInteractor>(),
|
||||
Get.find<AddALabelToAnEmailInteractor>(),
|
||||
Get.find<RemoveALabelFromAnEmailInteractor>(),
|
||||
Get.find<PrintEmailInteractor>(),
|
||||
currentEmailId: currentEmailId,
|
||||
), tag: tag);
|
||||
|
||||
@@ -24,6 +24,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/remove_a_label_from_an_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
|
||||
@@ -121,6 +122,9 @@ class EmailInteractorBindings extends InteractorsBindings {
|
||||
Get.lazyPut<AddALabelToAnEmailInteractor>(
|
||||
() => AddALabelToAnEmailInteractor(Get.find<EmailRepository>()),
|
||||
);
|
||||
Get.lazyPut<RemoveALabelFromAnEmailInteractor>(
|
||||
() => RemoveALabelFromAnEmailInteractor(Get.find<EmailRepository>()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -47,6 +47,7 @@ import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_sta
|
||||
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/parse_calendar_event_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/print_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/remove_a_label_from_an_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/send_receipt_to_sender_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/add_a_label_to_an_email_interactor.dart';
|
||||
@@ -60,6 +61,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/maybe_calendar_event_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/parse_calendar_event_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/remove_a_label_from_an_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/send_receipt_to_sender_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
|
||||
@@ -119,6 +121,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
final StoreOpenedEmailInteractor _storeOpenedEmailInteractor;
|
||||
final PrintEmailInteractor _printEmailInteractor;
|
||||
final AddALabelToAnEmailInteractor addALabelToAnEmailInteractor;
|
||||
final RemoveALabelFromAnEmailInteractor removeALabelFromAnEmailInteractor;
|
||||
final EmailId? _currentEmailId;
|
||||
|
||||
CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor;
|
||||
@@ -189,6 +192,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
this._getAllIdentitiesInteractor,
|
||||
this._storeOpenedEmailInteractor,
|
||||
this.addALabelToAnEmailInteractor,
|
||||
this.removeALabelFromAnEmailInteractor,
|
||||
this._printEmailInteractor, {
|
||||
EmailId? currentEmailId,
|
||||
}) : _currentEmailId = currentEmailId;
|
||||
@@ -247,6 +251,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
calendarEventSuccess(success);
|
||||
} else if (success is AddALabelToAnEmailSuccess) {
|
||||
handleAddLabelToEmailSuccess(success);
|
||||
} else if (success is RemoveALabelFromAnEmailSuccess) {
|
||||
handleRemoveLabelFromEmailSuccess(success);
|
||||
} else {
|
||||
super.handleSuccessViewState(success);
|
||||
}
|
||||
@@ -266,6 +272,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
_calendarEventFailure(failure);
|
||||
} else if (failure is AddALabelToAnEmailFailure) {
|
||||
handleAddLabelToEmailFailure(failure);
|
||||
} else if (failure is RemoveALabelFromAnEmailFailure) {
|
||||
handleRemoveLabelFromEmailFailure(failure);
|
||||
} else {
|
||||
super.handleFailureViewState(failure);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:dartz/dartz.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/mail/email/email.dart';
|
||||
@@ -8,6 +7,7 @@ import 'package:labels/extensions/label_extension.dart';
|
||||
import 'package:labels/model/label.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/add_a_label_to_an_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/remove_a_label_from_an_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/extensions/email_loaded_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/extensions/presentation_email_extension.dart';
|
||||
@@ -27,16 +27,23 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
}
|
||||
|
||||
void toggleLabelToEmail(EmailId emailId, Label label, bool isSelected) {
|
||||
if (isSelected) {
|
||||
final accountId = mailboxDashBoardController.accountId.value;
|
||||
final session = mailboxDashBoardController.sessionCurrent;
|
||||
final accountId = mailboxDashBoardController.accountId.value;
|
||||
final session = mailboxDashBoardController.sessionCurrent;
|
||||
|
||||
if (isSelected) {
|
||||
_addALabelToAnEmail(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
emailId: emailId,
|
||||
label: label,
|
||||
);
|
||||
} else {
|
||||
_removeALabelFromAnEmail(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
emailId: emailId,
|
||||
label: label,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,24 +56,22 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
final labelDisplay = label.safeDisplayName;
|
||||
|
||||
if (session == null) {
|
||||
consumeState(
|
||||
Stream.value(
|
||||
Left(AddALabelToAnEmailFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
labelDisplay: labelDisplay,
|
||||
)),
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: AddALabelToAnEmailFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
consumeState(
|
||||
Stream.value(
|
||||
Left(AddALabelToAnEmailFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
labelDisplay: labelDisplay,
|
||||
)),
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: AddALabelToAnEmailFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
);
|
||||
return;
|
||||
@@ -74,13 +79,12 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
|
||||
final labelKeyword = label.keyword;
|
||||
if (labelKeyword == null) {
|
||||
consumeState(
|
||||
Stream.value(Left(
|
||||
AddALabelToAnEmailFailure(
|
||||
exception: LabelKeywordIsNull(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
)),
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: AddALabelToAnEmailFailure(
|
||||
exception: LabelKeywordIsNull(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -100,6 +104,7 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
_autoSyncLabelToSelectedEmailOnMemory(
|
||||
emailId: success.emailId,
|
||||
labelKeyword: success.labelKeyword,
|
||||
remove: false,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -110,11 +115,13 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
void _autoSyncLabelToSelectedEmailOnMemory({
|
||||
required EmailId emailId,
|
||||
required KeyWordIdentifier labelKeyword,
|
||||
required bool remove,
|
||||
}) {
|
||||
_updateLabelInEmailOnMemory(
|
||||
emailId: emailId,
|
||||
labelKeyword: labelKeyword,
|
||||
isMobileThreadDisabled: PlatformInfo.isMobile && !isThreadDetailEnabled,
|
||||
remove: remove,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -122,27 +129,32 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
required EmailId emailId,
|
||||
required KeyWordIdentifier labelKeyword,
|
||||
required bool isMobileThreadDisabled,
|
||||
required bool remove,
|
||||
}) {
|
||||
_updateLabelOnSelectedEmailIfNeeded(
|
||||
emailId: emailId,
|
||||
labelKeyword: labelKeyword,
|
||||
isMobileThreadDisabled: isMobileThreadDisabled,
|
||||
remove: remove,
|
||||
);
|
||||
|
||||
_updateLabelOnThreadIfNeeded(
|
||||
emailId: emailId,
|
||||
labelKeyword: labelKeyword,
|
||||
isMobileThreadDisabled: isMobileThreadDisabled,
|
||||
remove: remove,
|
||||
);
|
||||
|
||||
_updateLabelOnCurrentEmailLoaded(
|
||||
emailId: emailId,
|
||||
labelKeyword: labelKeyword,
|
||||
remove: remove,
|
||||
);
|
||||
|
||||
_notifyLabelUpdated(
|
||||
emailId: emailId,
|
||||
labelKeyword: labelKeyword,
|
||||
remove: remove,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -150,19 +162,21 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
required EmailId emailId,
|
||||
required KeyWordIdentifier labelKeyword,
|
||||
required bool isMobileThreadDisabled,
|
||||
required bool remove,
|
||||
}) {
|
||||
if (!isMobileThreadDisabled) return;
|
||||
|
||||
final selectedEmail = mailboxDashBoardController.selectedEmail.value;
|
||||
if (selectedEmail?.id != emailId) return;
|
||||
|
||||
selectedEmail?.keywords?.addKeyword(labelKeyword);
|
||||
selectedEmail?.keywords?.toggleKeyword(labelKeyword, remove);
|
||||
}
|
||||
|
||||
void _updateLabelOnThreadIfNeeded({
|
||||
required EmailId emailId,
|
||||
required KeyWordIdentifier labelKeyword,
|
||||
required bool isMobileThreadDisabled,
|
||||
required bool remove,
|
||||
}) {
|
||||
if (isMobileThreadDisabled) return;
|
||||
|
||||
@@ -173,20 +187,21 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
controller.emailIdsPresentation.toggleEmailKeywordById(
|
||||
emailId: emailId,
|
||||
keyword: labelKeyword,
|
||||
remove: false,
|
||||
remove: remove,
|
||||
);
|
||||
|
||||
controller.emailsInThreadDetailInfo.value =
|
||||
controller.emailsInThreadDetailInfo.toggleEmailKeywordById(
|
||||
emailId: emailId,
|
||||
keyword: labelKeyword,
|
||||
remove: false,
|
||||
remove: remove,
|
||||
);
|
||||
}
|
||||
|
||||
void _updateLabelOnCurrentEmailLoaded({
|
||||
required EmailId emailId,
|
||||
required KeyWordIdentifier labelKeyword,
|
||||
required bool remove,
|
||||
}) {
|
||||
final emailLoaded = currentEmailLoaded.value;
|
||||
if (emailLoaded == null) return;
|
||||
@@ -195,17 +210,18 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
currentEmailLoaded.value = emailLoaded.toggleEmailKeyword(
|
||||
emailId: emailId,
|
||||
keyword: labelKeyword,
|
||||
remove: false,
|
||||
remove: remove,
|
||||
);
|
||||
}
|
||||
|
||||
void _notifyLabelUpdated({
|
||||
required EmailId emailId,
|
||||
required KeyWordIdentifier labelKeyword,
|
||||
required bool remove,
|
||||
}) {
|
||||
mailboxDashBoardController.updateEmailFlagByEmailIds(
|
||||
[emailId],
|
||||
isLabelAdded: true,
|
||||
isLabelAdded: !remove,
|
||||
labelKeyword: labelKeyword,
|
||||
);
|
||||
|
||||
@@ -235,4 +251,73 @@ extension HandleLabelForEmailExtension on SingleEmailController {
|
||||
dialogLabel: 'add-label-to-email-modal',
|
||||
);
|
||||
}
|
||||
|
||||
void _removeALabelFromAnEmail({
|
||||
required Session? session,
|
||||
required AccountId? accountId,
|
||||
required Label label,
|
||||
required EmailId emailId,
|
||||
}) {
|
||||
final labelDisplay = label.safeDisplayName;
|
||||
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: RemoveALabelFromAnEmailFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: RemoveALabelFromAnEmailFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final labelKeyword = label.keyword;
|
||||
if (labelKeyword == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: RemoveALabelFromAnEmailFailure(
|
||||
exception: LabelKeywordIsNull(),
|
||||
labelDisplay: labelDisplay,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
consumeState(removeALabelFromAnEmailInteractor.execute(
|
||||
session,
|
||||
accountId,
|
||||
emailId,
|
||||
labelKeyword,
|
||||
label.safeDisplayName,
|
||||
));
|
||||
}
|
||||
|
||||
void handleRemoveLabelFromEmailSuccess(
|
||||
RemoveALabelFromAnEmailSuccess success,
|
||||
) {
|
||||
toastManager.showMessageSuccess(success);
|
||||
|
||||
_autoSyncLabelToSelectedEmailOnMemory(
|
||||
emailId: success.emailId,
|
||||
labelKeyword: success.labelKeyword,
|
||||
remove: true,
|
||||
);
|
||||
}
|
||||
|
||||
void handleRemoveLabelFromEmailFailure(
|
||||
RemoveALabelFromAnEmailFailure failure,
|
||||
) {
|
||||
toastManager.showMessageFailure(failure);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,4 +27,16 @@ extension MapKeywordsExtension on Map<KeyWordIdentifier, bool>? {
|
||||
void addKeyword(KeyWordIdentifier keyword) {
|
||||
this?[keyword] = true;
|
||||
}
|
||||
|
||||
void removeKeyword(KeyWordIdentifier keyword) {
|
||||
this?.remove(keyword);
|
||||
}
|
||||
|
||||
void toggleKeyword(KeyWordIdentifier keyword, bool remove) {
|
||||
if (remove) {
|
||||
this?.remove(keyword);
|
||||
} else {
|
||||
this?[keyword] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5381,5 +5381,25 @@
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
},
|
||||
"removeLabelFromEmailSuccessfullyMessage": "Email removed from the \"{labelName}\" label",
|
||||
"@removeLabelFromEmailSuccessfullyMessage": {
|
||||
"type": "text",
|
||||
"placeholders_order": [
|
||||
"labelName"
|
||||
],
|
||||
"placeholders": {
|
||||
"labelName": {}
|
||||
}
|
||||
},
|
||||
"removeLabelFromEmailFailureMessage": "Cannot remove email from the \"{labelName}\" label",
|
||||
"@removeLabelFromEmailFailureMessage": {
|
||||
"type": "text",
|
||||
"placeholders_order": [
|
||||
"labelName"
|
||||
],
|
||||
"placeholders": {
|
||||
"labelName": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5709,4 +5709,19 @@ class AppLocalizations {
|
||||
name: 'editLabelFailure',
|
||||
);
|
||||
}
|
||||
String removeLabelFromEmailSuccessfullyMessage(String labelName) {
|
||||
return Intl.message(
|
||||
'Email removed from the "$labelName" label',
|
||||
name: 'removeLabelFromEmailSuccessfullyMessage',
|
||||
args: [labelName],
|
||||
);
|
||||
}
|
||||
|
||||
String removeLabelFromEmailFailureMessage(String labelName) {
|
||||
return Intl.message(
|
||||
'Cannot remove email from the "$labelName" label',
|
||||
name: 'removeLabelFromEmailFailureMessage',
|
||||
args: [labelName],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import 'package:tmail_ui_user/features/email/domain/state/calendar_event_reply_s
|
||||
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/parse_email_by_blob_id_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/preview_email_from_eml_file_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/remove_a_label_from_an_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/home/domain/state/get_session_state.dart';
|
||||
import 'package:tmail_ui_user/features/labels/domain/state/create_new_label_state.dart';
|
||||
@@ -212,6 +213,11 @@ class ToastManager {
|
||||
appLocalizations.addLabelToThreadFailureMessage(failure.labelDisplay);
|
||||
} else if (failure is EditLabelFailure) {
|
||||
message = message ?? appLocalizations.editLabelFailure;
|
||||
} else if (failure is RemoveALabelFromAnEmailFailure) {
|
||||
message = message ??
|
||||
appLocalizations.removeLabelFromEmailFailureMessage(
|
||||
failure.labelDisplay,
|
||||
);
|
||||
}
|
||||
log('ToastManager::showMessageFailure: Message: $message');
|
||||
if (message?.trim().isNotEmpty == true) {
|
||||
@@ -291,6 +297,10 @@ class ToastManager {
|
||||
message = appLocalizations.addLabelToThreadSuccessfullyMessage(
|
||||
success.labelDisplay,
|
||||
);
|
||||
} else if (success is RemoveALabelFromAnEmailSuccess) {
|
||||
message = appLocalizations.removeLabelFromEmailSuccessfullyMessage(
|
||||
success.labelDisplay,
|
||||
);
|
||||
}
|
||||
log('ToastManager::showMessageSuccess: Message: $message');
|
||||
if (message?.trim().isNotEmpty == true) {
|
||||
|
||||
@@ -28,5 +28,6 @@ extension KeyWordIdentifierExtension on KeyWordIdentifier {
|
||||
|
||||
PatchObject generateUnsubscribeActionPath() => _boolPatch(true);
|
||||
|
||||
PatchObject generateLabelActionPath() => _boolPatch(true);
|
||||
PatchObject generateLabelActionPath({bool remove = false}) =>
|
||||
_boolPatch(remove ? null : true);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/maybe_calendar_event_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/parse_calendar_event_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/remove_a_label_from_an_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/store_opened_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
|
||||
@@ -75,6 +76,7 @@ const fallbackGenerators = {
|
||||
MockSpec<GetAllIdentitiesInteractor>(),
|
||||
MockSpec<StoreOpenedEmailInteractor>(),
|
||||
MockSpec<AddALabelToAnEmailInteractor>(),
|
||||
MockSpec<RemoveALabelFromAnEmailInteractor>(),
|
||||
MockSpec<MailboxDashBoardController>(fallbackGenerators: fallbackGenerators),
|
||||
MockSpec<DownloadController>(fallbackGenerators: fallbackGenerators),
|
||||
MockSpec<DownloadManager>(fallbackGenerators: fallbackGenerators),
|
||||
@@ -109,6 +111,7 @@ void main() {
|
||||
final getAllIdentitiesInteractor = MockGetAllIdentitiesInteractor();
|
||||
final storeOpenedEmailInteractor = MockStoreOpenedEmailInteractor();
|
||||
final addALabelToAnEmailInteractor = MockAddALabelToAnEmailInteractor();
|
||||
final removeALabelFromAnEmailInteractor = MockRemoveALabelFromAnEmailInteractor();
|
||||
final mailboxDashboardController = MockMailboxDashBoardController();
|
||||
final downloadController = MockDownloadController();
|
||||
final downloadManager = MockDownloadManager();
|
||||
@@ -175,6 +178,7 @@ void main() {
|
||||
getAllIdentitiesInteractor,
|
||||
storeOpenedEmailInteractor,
|
||||
addALabelToAnEmailInteractor,
|
||||
removeALabelFromAnEmailInteractor,
|
||||
printEmailInteractor,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -171,4 +171,190 @@ void main() {
|
||||
expect(map[keyword], true);
|
||||
});
|
||||
});
|
||||
|
||||
group('MapKeywordsExtension - removeKeyword()', () {
|
||||
test('removes existing keyword from map', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
keyword: true,
|
||||
KeyWordIdentifier('\$flagged'): true,
|
||||
};
|
||||
|
||||
map.removeKeyword(keyword);
|
||||
|
||||
expect(map.length, 1);
|
||||
expect(map.containsKey(keyword), false);
|
||||
});
|
||||
|
||||
test('removes keyword even if its value is false', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
keyword: false,
|
||||
};
|
||||
|
||||
map.removeKeyword(keyword);
|
||||
|
||||
expect(map.isEmpty, true);
|
||||
});
|
||||
|
||||
test('does nothing when keyword does not exist', () {
|
||||
final map = {
|
||||
KeyWordIdentifier('\$flagged'): true,
|
||||
};
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
map.removeKeyword(keyword);
|
||||
|
||||
expect(map.length, 1);
|
||||
expect(map.values.first, true);
|
||||
});
|
||||
|
||||
test('does not throw when map is empty', () {
|
||||
final map = <KeyWordIdentifier, bool>{};
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
expect(() => map.removeKeyword(keyword), returnsNormally);
|
||||
expect(map.isEmpty, true);
|
||||
});
|
||||
|
||||
test('does not throw when map is null', () {
|
||||
Map<KeyWordIdentifier, bool>? map;
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
expect(() => map.removeKeyword(keyword), returnsNormally);
|
||||
});
|
||||
|
||||
test('calling removeKeyword on null map has no side effects', () {
|
||||
Map<KeyWordIdentifier, bool>? map;
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
map.removeKeyword(keyword);
|
||||
|
||||
expect(map, isNull);
|
||||
});
|
||||
|
||||
test('mutates the same map instance', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
keyword: true,
|
||||
};
|
||||
|
||||
final originalIdentity = identityHashCode(map);
|
||||
|
||||
map.removeKeyword(keyword);
|
||||
|
||||
expect(identityHashCode(map), originalIdentity);
|
||||
expect(map.isEmpty, true);
|
||||
});
|
||||
});
|
||||
|
||||
group('MapKeywordsExtension - toggleKeyword()', () {
|
||||
test('adds keyword when remove is false on empty map', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = <KeyWordIdentifier, bool>{};
|
||||
|
||||
map.toggleKeyword(keyword, false);
|
||||
|
||||
expect(map.length, 1);
|
||||
expect(map[keyword], true);
|
||||
});
|
||||
|
||||
test('adds keyword when remove is false on non-empty map', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
KeyWordIdentifier('\$flagged'): true,
|
||||
};
|
||||
|
||||
map.toggleKeyword(keyword, false);
|
||||
|
||||
expect(map.length, 2);
|
||||
expect(map[keyword], true);
|
||||
});
|
||||
|
||||
test('overwrites existing keyword value to true when remove is false', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
keyword: false,
|
||||
};
|
||||
|
||||
map.toggleKeyword(keyword, false);
|
||||
|
||||
expect(map.length, 1);
|
||||
expect(map[keyword], true);
|
||||
});
|
||||
|
||||
test('removes keyword when remove is true', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
keyword: true,
|
||||
KeyWordIdentifier('\$flagged'): true,
|
||||
};
|
||||
|
||||
map.toggleKeyword(keyword, true);
|
||||
|
||||
expect(map.length, 1);
|
||||
expect(map.containsKey(keyword), false);
|
||||
});
|
||||
|
||||
test('does nothing when remove is true and keyword does not exist', () {
|
||||
final map = {
|
||||
KeyWordIdentifier('\$flagged'): true,
|
||||
};
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
map.toggleKeyword(keyword, true);
|
||||
|
||||
expect(map.length, 1);
|
||||
expect(map.values.first, true);
|
||||
});
|
||||
|
||||
test('does not throw when map is empty and remove is true', () {
|
||||
final map = <KeyWordIdentifier, bool>{};
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
expect(() => map.toggleKeyword(keyword, true), returnsNormally);
|
||||
expect(map.isEmpty, true);
|
||||
});
|
||||
|
||||
test('adds keyword when map is empty and remove is false', () {
|
||||
final map = <KeyWordIdentifier, bool>{};
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
expect(() => map.toggleKeyword(keyword, false), returnsNormally);
|
||||
expect(map.length, 1);
|
||||
expect(map[keyword], true);
|
||||
});
|
||||
|
||||
test('does not throw when map is null', () {
|
||||
Map<KeyWordIdentifier, bool>? map;
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
expect(() => map.toggleKeyword(keyword, true), returnsNormally);
|
||||
expect(() => map.toggleKeyword(keyword, false), returnsNormally);
|
||||
});
|
||||
|
||||
test('calling toggleKeyword on null map has no side effects', () {
|
||||
Map<KeyWordIdentifier, bool>? map;
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
|
||||
map.toggleKeyword(keyword, false);
|
||||
map.toggleKeyword(keyword, true);
|
||||
|
||||
expect(map, isNull);
|
||||
});
|
||||
|
||||
test('mutates the same map instance', () {
|
||||
final keyword = KeyWordIdentifier('\$seen');
|
||||
final map = {
|
||||
keyword: true,
|
||||
};
|
||||
|
||||
final originalIdentity = identityHashCode(map);
|
||||
|
||||
map.toggleKeyword(keyword, true);
|
||||
|
||||
expect(identityHashCode(map), originalIdentity);
|
||||
expect(map.isEmpty, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user