TF-2536 Write unit test for getAllMailbox method repository

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2024-02-06 14:41:03 +07:00
committed by Dat PHAM HOANG
parent 16f362a61a
commit eb3e22b467
14 changed files with 291 additions and 127 deletions
@@ -188,9 +188,9 @@ abstract class HiveCacheClient<T> {
Future<void> clearAllDataContainKey(String nestedKey) {
return Future.sync(() async {
final boxItem = encryption ? await openBoxEncryption() : await openBox();
final mapItemNotContainNestedKey = boxItem.toMap().where((key, value) => !_matchedNestedKey(key, nestedKey));
log('HiveCacheClient::clearAllDataContainKey:mapItemNotContainNestedKey: ${mapItemNotContainNestedKey.length}');
return boxItem.putAll(mapItemNotContainNestedKey);
final listKeys = boxItem.toMap().where((key, value) => _matchedNestedKey(key, nestedKey)).keys;
log('HiveCacheClient::clearAllDataContainKey:listKeys: ${listKeys.length}');
return boxItem.deleteAll(listKeys);
}).catchError((error) {
throw error;
});
@@ -11,18 +11,18 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/get/get_mailbox_response.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart';
abstract class MailboxDataSource {
Future<GetMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties});
Future<JmapMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties});
Future<List<Mailbox>> getAllMailboxCache(AccountId accountId, UserName userName);
@@ -12,13 +12,13 @@ import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/get/get_mailbox_response.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
@@ -33,7 +33,7 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
MailboxCacheDataSourceImpl(this._mailboxCacheManager, this._exceptionThrower);
@override
Future<GetMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties}) {
Future<JmapMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties}) {
throw UnimplementedError();
}
@@ -12,7 +12,6 @@ import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/get/get_mailbox_response.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
@@ -20,6 +19,7 @@ import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
@@ -35,7 +35,7 @@ class MailboxDataSourceImpl extends MailboxDataSource {
MailboxDataSourceImpl(this.mailboxAPI, this._mailboxIsolateWorker, this._exceptionThrower);
@override
Future<GetMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties}) {
Future<JmapMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties}) {
return Future.sync(() async {
return await mailboxAPI.getAllMailbox(session, accountId, properties: properties);
}).catchError(_exceptionThrower.throwException);
@@ -30,12 +30,12 @@ import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/mixin/handle_error_mixin.dart';
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exception.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_change_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/mailbox_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/exceptions/set_mailbox_method_exception.dart';
import 'package:tmail_ui_user/features/mailbox/domain/extensions/list_mailbox_id_extension.dart';
import 'package:tmail_ui_user/features/mailbox/domain/extensions/role_extension.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
@@ -51,7 +51,7 @@ class MailboxAPI with HandleSetErrorMixin {
MailboxAPI(this.httpClient, this._uuid);
Future<GetMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties}) async {
Future<JmapMailboxResponse> getAllMailbox(Session session, AccountId accountId, {Properties? properties}) async {
final processingInvocation = ProcessingInvocation();
final jmapRequestBuilder = JmapRequestBuilder(httpClient, processingInvocation);
@@ -74,10 +74,12 @@ class MailboxAPI with HandleSetErrorMixin {
queryInvocation.methodCallId,
GetMailboxResponse.deserialize);
if (getMailboxResponse == null) {
throw NotFoundGetMailboxResponseException();
if (getMailboxResponse != null && getMailboxResponse.list.isNotEmpty) {
return JmapMailboxResponse(
mailboxes: getMailboxResponse.list,
state: getMailboxResponse.state);
} else {
return getMailboxResponse;
throw NotFoundMailboxException();
}
}
@@ -23,11 +23,10 @@ import 'package:tmail_ui_user/features/mailbox/data/extensions/state_extension.d
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/cache_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/full_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/jmap_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/partial_mailbox_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_multiple_mailbox_request.dart';
@@ -50,33 +49,18 @@ class MailboxRepositoryImpl extends MailboxRepository {
yield cacheMailboxResponse;
}
final newMailboxResponse = await _getAllMailboxFromJMAP(accountId, session);
if (newMailboxResponse == null) {
final jmapMailboxResponse = await _getAllMailboxFromJMAP(accountId, session);
if (jmapMailboxResponse == null) {
return;
}
if (newMailboxResponse is FullMailboxResponse) {
await _syncNewInCache(
accountId,
session.username,
newMailboxResponse.mailboxes,
newMailboxResponse.state!);
await _syncNewInCache(
accountId,
session.username,
jmapMailboxResponse.mailboxes,
jmapMailboxResponse.state!);
yield newMailboxResponse;
} else if (newMailboxResponse is PartialMailboxResponse) {
await _syncUpdateInCache(
accountId,
session.username,
newMailboxResponse.mailboxes,
newMailboxResponse.state!);
cacheMailboxResponse = await _getAllMailboxFromCache(accountId, session.username);
if (cacheMailboxResponse != null) {
yield cacheMailboxResponse;
} else {
yield newMailboxResponse;
}
}
yield jmapMailboxResponse;
}
Future<CacheMailboxResponse?> _getAllMailboxFromCache(AccountId accountId, UserName userName) async {
@@ -93,27 +77,18 @@ class MailboxRepositoryImpl extends MailboxRepository {
}
}
Future<MailboxResponse?> _getAllMailboxFromJMAP(
Future<JmapMailboxResponse?> _getAllMailboxFromJMAP(
AccountId accountId,
Session session,
{Properties? properties}
) async {
try {
final getMailboxResponse = await mapDataSource[DataSourceType.network]!.getAllMailbox(
final jmapMailboxResponse = await mapDataSource[DataSourceType.network]!.getAllMailbox(
session,
accountId,
properties: properties);
log('MailboxRepositoryImpl::_getAllMailboxFromJMAP: MAILBOX_NETWORK = ${getMailboxResponse.list.length} | STATE_NETWORK = ${getMailboxResponse.state.value}');
if (getMailboxResponse.notFound?.isNotEmpty == true) {
return PartialMailboxResponse(
mailboxNotFound: getMailboxResponse.notFound!,
mailboxes: getMailboxResponse.list,
state: getMailboxResponse.state);
} else {
return FullMailboxResponse(
mailboxes: getMailboxResponse.list,
state: getMailboxResponse.state);
}
log('MailboxRepositoryImpl::_getAllMailboxFromJMAP: MAILBOX_NETWORK = ${jmapMailboxResponse.mailboxes.length} | STATE_NETWORK = ${jmapMailboxResponse.state}');
return jmapMailboxResponse;
} catch (e) {
logError('MailboxRepositoryImpl::_getAllMailboxFromJMAP: Exception: $e');
return null;
@@ -126,10 +101,12 @@ class MailboxRepositoryImpl extends MailboxRepository {
List<Mailbox> newMailboxes,
State newState,
) async {
await Future.wait([
_syncNewMailboxesInCache(accountId, userName, newMailboxes),
_syncNewMailboxStateInCache(accountId, userName, newState)
]);
try {
await _syncNewMailboxesInCache(accountId, userName, newMailboxes);
await _syncNewMailboxStateInCache(accountId, userName, newState);
} catch (e) {
logError('MailboxRepositoryImpl::_syncNewInCache: Exception = $e');
}
}
Future<void> _syncNewMailboxesInCache(
@@ -137,17 +114,13 @@ class MailboxRepositoryImpl extends MailboxRepository {
UserName userName,
List<Mailbox> newMailboxes
) async {
try {
await mapDataSource[DataSourceType.local]!.clearAllMailboxCache(
accountId,
userName);
await mapDataSource[DataSourceType.local]!.update(
accountId,
userName,
created: newMailboxes);
} catch (e) {
logError('MailboxRepositoryImpl::_syncNewMailboxesInCache: Exception = $e');
}
await mapDataSource[DataSourceType.local]!.clearAllMailboxCache(
accountId,
userName);
await mapDataSource[DataSourceType.local]!.update(
accountId,
userName,
created: newMailboxes);
}
Future<void> _syncNewMailboxStateInCache(
@@ -155,41 +128,10 @@ class MailboxRepositoryImpl extends MailboxRepository {
UserName userName,
State newState
) async {
try {
await stateDataSource.saveState(
accountId,
userName,
newState.toStateCache(StateType.mailbox));
} catch (e) {
logError('MailboxRepositoryImpl::_syncNewMailboxStateInCache: Exception = $e');
}
}
Future<void> _syncUpdateInCache(
AccountId accountId,
UserName userName,
List<Mailbox> newMailboxes,
State newState,
) async {
await Future.wait([
_syncUpdateMailboxesInCache(accountId, userName, newMailboxes),
_syncNewMailboxStateInCache(accountId, userName, newState)
]);
}
Future<void> _syncUpdateMailboxesInCache(
AccountId accountId,
UserName userName,
List<Mailbox> newMailboxes
) async {
try {
await mapDataSource[DataSourceType.local]!.update(
accountId,
userName,
updated: newMailboxes);
} catch (e) {
logError('MailboxRepositoryImpl::_syncUpdateMailboxesInCache: Exception = $e');
}
await stateDataSource.saveState(
accountId,
userName,
newState.toStateCache(StateType.mailbox));
}
Future<List<Mailbox>?> _combineMailboxCache({
@@ -1 +0,0 @@
class NotFoundGetMailboxResponseException implements Exception {}
@@ -1,6 +0,0 @@
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart';
class FullMailboxResponse extends MailboxResponse {
FullMailboxResponse({required super.mailboxes, super.state});
}
@@ -0,0 +1,6 @@
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart';
class JmapMailboxResponse extends MailboxResponse {
JmapMailboxResponse({required super.mailboxes, super.state});
}
@@ -1,16 +0,0 @@
import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.dart';
class PartialMailboxResponse extends MailboxResponse {
final List<Id> mailboxNotFound;
PartialMailboxResponse({
required this.mailboxNotFound,
required super.mailboxes,
super.state,
});
@override
List<Object?> get props => [mailboxNotFound, ...super.props];
}
@@ -131,8 +131,7 @@ class FCMRepositoryImpl extends FCMRepository {
return mailboxesCacheNotPutNotifications;
} else {
final mailboxResponse = await _mapMailboxDataSource[DataSourceType.network]!.getAllMailbox(session, accountId);
final mailboxes = mailboxResponse.list;
final mailboxesNotPutNotifications = mailboxes
final mailboxesNotPutNotifications = mailboxResponse.mailboxes
.map((mailbox) => mailbox.toPresentationMailbox())
.where((presentationMailbox) => presentationMailbox.pushNotificationDeactivated)
.toList();