TF-3697 Open specific thread detail email
This commit is contained in:
@@ -2,7 +2,14 @@ import 'package:core/presentation/state/failure.dart';
|
|||||||
import 'package:core/presentation/state/success.dart';
|
import 'package:core/presentation/state/success.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
import 'package:model/email/presentation_email.dart';
|
||||||
|
|
||||||
class GettingEmailsByIds extends LoadingState {}
|
class GettingEmailsByIds extends LoadingState {
|
||||||
|
GettingEmailsByIds({this.loadingIndex});
|
||||||
|
|
||||||
|
final int? loadingIndex;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [loadingIndex];
|
||||||
|
}
|
||||||
|
|
||||||
class GetEmailsByIdsSuccess extends UIState {
|
class GetEmailsByIdsSuccess extends UIState {
|
||||||
GetEmailsByIdsSuccess(this.presentationEmails);
|
GetEmailsByIdsSuccess(this.presentationEmails);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class GetEmailsByIdsInteractor {
|
|||||||
AccountId accountId,
|
AccountId accountId,
|
||||||
List<EmailId> emailIds, {
|
List<EmailId> emailIds, {
|
||||||
Properties? properties,
|
Properties? properties,
|
||||||
|
int? loadMoreIndex,
|
||||||
}) async* {
|
}) async* {
|
||||||
try {
|
try {
|
||||||
if (emailIds.length > 1 && (
|
if (emailIds.length > 1 && (
|
||||||
@@ -31,7 +32,7 @@ class GetEmailsByIdsInteractor {
|
|||||||
throw ThreadDetailOverloadException();
|
throw ThreadDetailOverloadException();
|
||||||
}
|
}
|
||||||
|
|
||||||
yield Right(GettingEmailsByIds());
|
yield Right(GettingEmailsByIds(loadingIndex: loadMoreIndex));
|
||||||
final result = await _threadDetailRepository.getEmailsByIds(
|
final result = await _threadDetailRepository.getEmailsByIds(
|
||||||
session,
|
session,
|
||||||
accountId,
|
accountId,
|
||||||
|
|||||||
+14
-19
@@ -1,4 +1,3 @@
|
|||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:model/email/email_action_type.dart';
|
import 'package:model/email/email_action_type.dart';
|
||||||
import 'package:model/extensions/presentation_email_extension.dart';
|
import 'package:model/extensions/presentation_email_extension.dart';
|
||||||
@@ -8,6 +7,8 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions
|
|||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/load_more_thread_detail_emails.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/load_more_thread_detail_emails.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_on_email_action_click.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_on_email_action_click.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_open_email_address_detail_action.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_open_email_address_detail_action.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_emails_by_ids_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_load_more_segments.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/toggle_thread_detail_collape_expand.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/toggle_thread_detail_collape_expand.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/widgets/thread_detail_collapsed_email.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/widgets/thread_detail_collapsed_email.dart';
|
||||||
@@ -16,35 +17,29 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
|||||||
|
|
||||||
extension GetThreadDetailEmailViews on ThreadDetailController {
|
extension GetThreadDetailEmailViews on ThreadDetailController {
|
||||||
List<Widget> getThreadDetailEmailViews() {
|
List<Widget> getThreadDetailEmailViews() {
|
||||||
int? firstEmailNotLoadedIndex;
|
final loadMoreSegments = Map<LoadMoreIndex, LoadMoreCount>.from(this.loadMoreSegments);
|
||||||
if (emailsToLoadMoreCount > 0) {
|
|
||||||
final firstNotLoadedEmailId = emailIdsPresentation.entries.firstWhereOrNull(
|
|
||||||
(entry) => entry.value == null
|
|
||||||
)?.key;
|
|
||||||
if (firstNotLoadedEmailId == null) {
|
|
||||||
firstEmailNotLoadedIndex = -1;
|
|
||||||
} else {
|
|
||||||
firstEmailNotLoadedIndex = emailIdsPresentation
|
|
||||||
.keys
|
|
||||||
.toList()
|
|
||||||
.indexOf(firstNotLoadedEmailId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return emailIdsPresentation.entries.map((entry) {
|
return emailIdsPresentation.entries.map((entry) {
|
||||||
final emailId = entry.key;
|
final emailId = entry.key;
|
||||||
final presentationEmail = entry.value;
|
final presentationEmail = entry.value;
|
||||||
final indexOfEmailId = emailIdsPresentation.keys.toList().indexOf(emailId);
|
final indexOfEmailId = emailIdsPresentation.keys.toList().indexOf(emailId);
|
||||||
if (presentationEmail == null) {
|
if (presentationEmail == null) {
|
||||||
if (indexOfEmailId != firstEmailNotLoadedIndex) {
|
if (loadMoreSegments[indexOfEmailId] == null) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ThreadDetailLoadMoreCircle(
|
return ThreadDetailLoadMoreCircle(
|
||||||
count: emailsToLoadMoreCount,
|
count: loadMoreSegments[indexOfEmailId]!,
|
||||||
onTap: loadMoreThreadDetailEmails,
|
onTap: () => loadMoreThreadDetailEmails(
|
||||||
|
loadMoreIndex: indexOfEmailId,
|
||||||
|
loadMoreCount: loadMoreSegments[indexOfEmailId]!,
|
||||||
|
),
|
||||||
imagePaths: imagePaths,
|
imagePaths: imagePaths,
|
||||||
isLoading: loadingThreadDetail,
|
isLoading: viewState.value.fold(
|
||||||
|
(failure) => false,
|
||||||
|
(success) => success is GettingEmailsByIds &&
|
||||||
|
success.loadingIndex == indexOfEmailId,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -13,6 +13,7 @@ extension HandleGetEmailsByIdsSuccess on ThreadDetailController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final selectedEmailId = mailboxDashBoardController.selectedEmail.value?.id;
|
||||||
final isLoadMore = emailIdsPresentation.values.whereNotNull().isNotEmpty;
|
final isLoadMore = emailIdsPresentation.values.whereNotNull().isNotEmpty;
|
||||||
final currentScrollPosition = scrollController?.position.pixels;
|
final currentScrollPosition = scrollController?.position.pixels;
|
||||||
final maxScrollExtent = scrollController?.position.maxScrollExtent;
|
final maxScrollExtent = scrollController?.position.maxScrollExtent;
|
||||||
@@ -23,12 +24,12 @@ extension HandleGetEmailsByIdsSuccess on ThreadDetailController {
|
|||||||
|
|
||||||
for (var presentationEmail in success.presentationEmails) {
|
for (var presentationEmail in success.presentationEmails) {
|
||||||
if (presentationEmail.id == null) continue;
|
if (presentationEmail.id == null) continue;
|
||||||
if (presentationEmail.id == emailIdsPresentation.keys.last) {
|
if (presentationEmail.id == selectedEmailId) {
|
||||||
EmailBindings(currentEmailId: presentationEmail.id).dependencies();
|
EmailBindings(currentEmailId: presentationEmail.id).dependencies();
|
||||||
currentExpandedEmailId.value = presentationEmail.id;
|
currentExpandedEmailId.value = presentationEmail.id;
|
||||||
}
|
}
|
||||||
emailIdsPresentation[presentationEmail.id!] = presentationEmail.copyWith(
|
emailIdsPresentation[presentationEmail.id!] = presentationEmail.copyWith(
|
||||||
emailInThreadStatus: presentationEmail.id == emailIdsPresentation.keys.last
|
emailInThreadStatus: presentationEmail.id == selectedEmailId
|
||||||
? EmailInThreadStatus.expanded
|
? EmailInThreadStatus.expanded
|
||||||
: EmailInThreadStatus.collapsed,
|
: EmailInThreadStatus.collapsed,
|
||||||
);
|
);
|
||||||
|
|||||||
+4
-4
@@ -7,9 +7,9 @@ import 'package:tmail_ui_user/features/thread_detail/presentation/utils/thread_d
|
|||||||
|
|
||||||
extension InitializeThreadDetailEmails on ThreadDetailController {
|
extension InitializeThreadDetailEmails on ThreadDetailController {
|
||||||
void initializeThreadDetailEmails() {
|
void initializeThreadDetailEmails() {
|
||||||
final emailIdToLoadContent = emailIdsPresentation.keys.last;
|
final emailIdsToLoadMetaData = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
final emailIdsToLoadMetaData = ThreadDetailPresentationUtils.getEmailIdsToLoad(
|
emailIdsPresentation.keys.toList(),
|
||||||
Map.from(emailIdsPresentation)..remove(emailIdToLoadContent),
|
selectedEmailId: mailboxDashBoardController.selectedEmail.value?.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (accountId == null || session == null) {
|
if (accountId == null || session == null) {
|
||||||
@@ -21,7 +21,7 @@ extension InitializeThreadDetailEmails on ThreadDetailController {
|
|||||||
consumeState(getEmailsByIdsInteractor.execute(
|
consumeState(getEmailsByIdsInteractor.execute(
|
||||||
session!,
|
session!,
|
||||||
accountId!,
|
accountId!,
|
||||||
[...emailIdsToLoadMetaData, emailIdToLoadContent],
|
emailIdsToLoadMetaData,
|
||||||
properties: EmailUtils.getPropertiesForEmailGetMethod(
|
properties: EmailUtils.getPropertiesForEmailGetMethod(
|
||||||
session!,
|
session!,
|
||||||
accountId!,
|
accountId!,
|
||||||
|
|||||||
+22
-3
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||||
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
|
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
|
||||||
@@ -6,7 +8,10 @@ import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_
|
|||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/utils/thread_detail_presentation_utils.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/utils/thread_detail_presentation_utils.dart';
|
||||||
|
|
||||||
extension LoadMoreThreadDetailEmails on ThreadDetailController {
|
extension LoadMoreThreadDetailEmails on ThreadDetailController {
|
||||||
void loadMoreThreadDetailEmails() {
|
void loadMoreThreadDetailEmails({
|
||||||
|
required int loadMoreIndex,
|
||||||
|
required int loadMoreCount,
|
||||||
|
}) {
|
||||||
if (accountId == null || session == null) {
|
if (accountId == null || session == null) {
|
||||||
consumeState(Stream.value(Left(GetEmailsByIdsFailure(
|
consumeState(Stream.value(Left(GetEmailsByIdsFailure(
|
||||||
exception: NotFoundSessionException(),
|
exception: NotFoundSessionException(),
|
||||||
@@ -14,8 +19,21 @@ extension LoadMoreThreadDetailEmails on ThreadDetailController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final emailIdsToLoadMetaData = ThreadDetailPresentationUtils
|
final currentExpandedEmailIndex = currentExpandedEmailId.value == null
|
||||||
.getEmailIdsToLoad(emailIdsPresentation);
|
? -1
|
||||||
|
: emailIdsPresentation.keys.toList().indexOf(currentExpandedEmailId.value!);
|
||||||
|
final loadMoreEmailIds = emailIdsPresentation.keys.toList().sublist(
|
||||||
|
loadMoreIndex,
|
||||||
|
min(
|
||||||
|
loadMoreIndex + loadMoreCount,
|
||||||
|
emailIdsPresentation.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final emailIdsToLoadMetaData = ThreadDetailPresentationUtils.getLoadMoreEmailIds(
|
||||||
|
loadMoreEmailIds,
|
||||||
|
loadEmailsAfterSelectedEmail: loadMoreIndex > currentExpandedEmailIndex,
|
||||||
|
);
|
||||||
if (emailIdsToLoadMetaData.isEmpty) {
|
if (emailIdsToLoadMetaData.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -27,6 +45,7 @@ extension LoadMoreThreadDetailEmails on ThreadDetailController {
|
|||||||
session!,
|
session!,
|
||||||
accountId!,
|
accountId!,
|
||||||
).union(additionalProperties),
|
).union(additionalProperties),
|
||||||
|
loadMoreIndex: loadMoreIndex,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
||||||
|
|
||||||
|
typedef LoadMoreIndex = int;
|
||||||
|
typedef LoadMoreCount = int;
|
||||||
|
typedef LoadMoreSegments = Map<LoadMoreIndex, LoadMoreCount>;
|
||||||
|
|
||||||
|
extension ThreadDetailLoadMoreSegments on ThreadDetailController {
|
||||||
|
LoadMoreSegments get loadMoreSegments {
|
||||||
|
final loadMoreInfo = <LoadMoreIndex, LoadMoreCount>{};
|
||||||
|
int currentIndex = 0;
|
||||||
|
final emailIds = emailIdsPresentation.values.toList();
|
||||||
|
|
||||||
|
while (currentIndex < emailIdsPresentation.length) {
|
||||||
|
if (emailIds[currentIndex] == null) {
|
||||||
|
// Found start of a null segment
|
||||||
|
int segmentIndex = currentIndex;
|
||||||
|
int segmentCount = 0;
|
||||||
|
|
||||||
|
// Count consecutive nulls
|
||||||
|
while (currentIndex < emailIdsPresentation.length &&
|
||||||
|
emailIds[currentIndex] == null) {
|
||||||
|
segmentCount++;
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMoreInfo[segmentIndex] = segmentCount;
|
||||||
|
} else {
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loadMoreInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,15 +90,6 @@ class ThreadDetailController extends BaseController {
|
|||||||
PresentationMailbox.roleSent,
|
PresentationMailbox.roleSent,
|
||||||
);
|
);
|
||||||
String? get ownEmailAddress => session?.getOwnEmailAddress();
|
String? get ownEmailAddress => session?.getOwnEmailAddress();
|
||||||
int get emailsToLoadMoreCount => emailIdsPresentation
|
|
||||||
.values
|
|
||||||
.where((email) => email == null)
|
|
||||||
.length;
|
|
||||||
bool get loadingThreadDetail => viewState.value.fold(
|
|
||||||
(failure) => false,
|
|
||||||
(success) => success is GettingThreadById
|
|
||||||
|| success is GettingEmailsByIds,
|
|
||||||
);
|
|
||||||
bool get isSearchRunning {
|
bool get isSearchRunning {
|
||||||
final isWebSearchRunning = mailboxDashBoardController
|
final isWebSearchRunning = mailboxDashBoardController
|
||||||
.searchController
|
.searchController
|
||||||
|
|||||||
+38
-20
@@ -2,7 +2,6 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
|
||||||
|
|
||||||
class ThreadDetailPresentationUtils {
|
class ThreadDetailPresentationUtils {
|
||||||
const ThreadDetailPresentationUtils._();
|
const ThreadDetailPresentationUtils._();
|
||||||
@@ -11,29 +10,48 @@ class ThreadDetailPresentationUtils {
|
|||||||
static const _defaultLoadSize = 20;
|
static const _defaultLoadSize = 20;
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
static get initialLoadSize => _initialLoadSize;
|
static int get defaultLoadSize => _defaultLoadSize;
|
||||||
@visibleForTesting
|
|
||||||
static get defaultLoadSize => _defaultLoadSize;
|
|
||||||
|
|
||||||
static List<EmailId> getEmailIdsToLoad(
|
static List<EmailId> getFirstLoadEmailIds(
|
||||||
Map<EmailId, PresentationEmail?> emailIdsPresentation,
|
List<EmailId> emailIds, {
|
||||||
) {
|
EmailId? selectedEmailId,
|
||||||
final validEmailIdsToLoad = emailIdsPresentation.entries
|
}) {
|
||||||
.where((entry) => entry.value == null)
|
// Default first, second and last email
|
||||||
.map((entry) => entry.key)
|
if (emailIds.length <= 3) return emailIds;
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (validEmailIdsToLoad.length == emailIdsPresentation.length) {
|
if (selectedEmailId == null ||
|
||||||
// No email loaded yet
|
!emailIds.contains(selectedEmailId) ||
|
||||||
return validEmailIdsToLoad.sublist(
|
selectedEmailId == emailIds.first ||
|
||||||
0,
|
selectedEmailId == emailIds.last ||
|
||||||
min(validEmailIdsToLoad.length, _initialLoadSize),
|
selectedEmailId == emailIds.elementAt(1)) {
|
||||||
);
|
|
||||||
|
return [
|
||||||
|
...emailIds.sublist(
|
||||||
|
0,
|
||||||
|
min(emailIds.length, _initialLoadSize),
|
||||||
|
),
|
||||||
|
emailIds.last,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return validEmailIdsToLoad.sublist(
|
return [
|
||||||
validEmailIdsToLoad.length - min(validEmailIdsToLoad.length, _defaultLoadSize),
|
emailIds.first,
|
||||||
validEmailIdsToLoad.length,
|
selectedEmailId,
|
||||||
|
emailIds.last,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getLoadMoreEmailIds(
|
||||||
|
List<EmailId> emailIds, {
|
||||||
|
bool loadEmailsAfterSelectedEmail = false,
|
||||||
|
}) {
|
||||||
|
if (loadEmailsAfterSelectedEmail) {
|
||||||
|
return emailIds.sublist(0, min(emailIds.length, _defaultLoadSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
return emailIds.sublist(
|
||||||
|
emailIds.length - min(_defaultLoadSize, emailIds.length),
|
||||||
|
emailIds.length,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -6,6 +6,7 @@ import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
|||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:mockito/annotations.dart';
|
import 'package:mockito/annotations.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_emails_by_ids_interactor.dart';
|
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_emails_by_ids_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/initialize_thread_detail_emails.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/initialize_thread_detail_emails.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
||||||
@@ -16,15 +17,18 @@ import 'initialize_thread_detail_emails_test.mocks.dart';
|
|||||||
@GenerateNiceMocks([
|
@GenerateNiceMocks([
|
||||||
MockSpec<GetEmailsByIdsInteractor>(),
|
MockSpec<GetEmailsByIdsInteractor>(),
|
||||||
MockSpec<ThreadDetailController>(),
|
MockSpec<ThreadDetailController>(),
|
||||||
|
MockSpec<MailboxDashBoardController>(),
|
||||||
])
|
])
|
||||||
void main() {
|
void main() {
|
||||||
group('InitializeThreadDetailEmails', () {
|
group('InitializeThreadDetailEmails', () {
|
||||||
late MockGetEmailsByIdsInteractor getEmailsByIdsInteractor;
|
late MockGetEmailsByIdsInteractor getEmailsByIdsInteractor;
|
||||||
late MockThreadDetailController threadDetailController;
|
late MockThreadDetailController threadDetailController;
|
||||||
|
late MockMailboxDashBoardController mailboxDashboardController;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
getEmailsByIdsInteractor = MockGetEmailsByIdsInteractor();
|
getEmailsByIdsInteractor = MockGetEmailsByIdsInteractor();
|
||||||
threadDetailController = MockThreadDetailController();
|
threadDetailController = MockThreadDetailController();
|
||||||
|
mailboxDashboardController = MockMailboxDashBoardController();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initializeThreadDetailEmails should call getEmailsByIdsInteractor with 3 elements', () async {
|
test('initializeThreadDetailEmails should call getEmailsByIdsInteractor with 3 elements', () async {
|
||||||
@@ -52,6 +56,8 @@ void main() {
|
|||||||
final session = SessionFixtures.aliceSession;
|
final session = SessionFixtures.aliceSession;
|
||||||
when(threadDetailController.accountId).thenReturn(accountId);
|
when(threadDetailController.accountId).thenReturn(accountId);
|
||||||
when(threadDetailController.session).thenReturn(session);
|
when(threadDetailController.session).thenReturn(session);
|
||||||
|
when(threadDetailController.mailboxDashBoardController).thenReturn(mailboxDashboardController);
|
||||||
|
when(mailboxDashboardController.selectedEmail).thenReturn(Rxn());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
threadDetailController.initializeThreadDetailEmails();
|
threadDetailController.initializeThreadDetailEmails();
|
||||||
|
|||||||
+121
-14
@@ -7,9 +7,11 @@ import 'package:mockito/annotations.dart';
|
|||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
import 'package:model/email/presentation_email.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_emails_by_ids_interactor.dart';
|
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_emails_by_ids_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/load_more_thread_detail_emails.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/load_more_thread_detail_emails.dart';
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread_detail/presentation/utils/thread_detail_presentation_utils.dart';
|
||||||
|
|
||||||
import '../../../../fixtures/account_fixtures.dart';
|
import '../../../../fixtures/account_fixtures.dart';
|
||||||
import '../../../../fixtures/session_fixtures.dart';
|
import '../../../../fixtures/session_fixtures.dart';
|
||||||
@@ -18,55 +20,66 @@ import 'load_more_thread_detail_emails_test.mocks.dart';
|
|||||||
@GenerateNiceMocks([
|
@GenerateNiceMocks([
|
||||||
MockSpec<ThreadDetailController>(),
|
MockSpec<ThreadDetailController>(),
|
||||||
MockSpec<GetEmailsByIdsInteractor>(),
|
MockSpec<GetEmailsByIdsInteractor>(),
|
||||||
|
MockSpec<MailboxDashBoardController>(),
|
||||||
])
|
])
|
||||||
void main() {
|
void main() {
|
||||||
late MockThreadDetailController controller;
|
late MockThreadDetailController controller;
|
||||||
late MockGetEmailsByIdsInteractor getEmailsByIdsInteractor;
|
late MockGetEmailsByIdsInteractor getEmailsByIdsInteractor;
|
||||||
|
late MockMailboxDashBoardController mailboxDashBoardController;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
controller = MockThreadDetailController();
|
controller = MockThreadDetailController();
|
||||||
getEmailsByIdsInteractor = MockGetEmailsByIdsInteractor();
|
getEmailsByIdsInteractor = MockGetEmailsByIdsInteractor();
|
||||||
|
mailboxDashBoardController = MockMailboxDashBoardController();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Only call getEmailsByIdsInteractor.execute on emails where presentation email is null, max 20 emails', () async {
|
test('Only call getEmailsByIdsInteractor.execute on emails where presentation email is null, max 20 emails', () async {
|
||||||
// Arrange
|
// Arrange
|
||||||
when(controller.emailIdsPresentation).thenReturn({
|
when(controller.emailIdsPresentation).thenReturn({
|
||||||
for (int i = 0; i < 40; i++)
|
for (int i = 0; i < 40; i++) EmailId(Id('$i')): null,
|
||||||
EmailId(Id('$i')): null,
|
|
||||||
EmailId(Id('40')): PresentationEmail(),
|
|
||||||
}.obs);
|
}.obs);
|
||||||
|
when(controller.currentExpandedEmailId).thenReturn(Rxn());
|
||||||
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
||||||
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
||||||
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
||||||
when(controller.additionalProperties).thenReturn(Properties.empty());
|
when(controller.additionalProperties).thenReturn(Properties.empty());
|
||||||
|
when(controller.mailboxDashBoardController).thenReturn(mailboxDashBoardController);
|
||||||
|
when(mailboxDashBoardController.selectedEmail).thenReturn(Rxn());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
controller.loadMoreThreadDetailEmails();
|
controller.loadMoreThreadDetailEmails(
|
||||||
|
loadMoreIndex: 0,
|
||||||
|
loadMoreCount: controller.emailIdsPresentation.length,
|
||||||
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
verify(getEmailsByIdsInteractor.execute(
|
verify(getEmailsByIdsInteractor.execute(
|
||||||
SessionFixtures.aliceSession,
|
SessionFixtures.aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
List.generate(20, (i) => EmailId(Id('${i + 20}'))),
|
List.generate(20, (i) => EmailId(Id('$i'))),
|
||||||
properties: EmailUtils.getPropertiesForEmailGetMethod(
|
properties: EmailUtils.getPropertiesForEmailGetMethod(
|
||||||
SessionFixtures.aliceSession,
|
SessionFixtures.aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
),
|
),
|
||||||
|
loadMoreIndex: 0,
|
||||||
)).called(1);
|
)).called(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('No getEmailsByIdsInteractor.execute call if emailIdsToLoadMetaData is empty', () async {
|
test('No getEmailsByIdsInteractor.execute call if emailIdsToLoadMetaData is empty', () async {
|
||||||
// Arrange
|
// Arrange
|
||||||
when(controller.emailIdsPresentation).thenReturn({
|
when(controller.emailIdsPresentation).thenReturn(<EmailId, PresentationEmail?>{}.obs);
|
||||||
EmailId(Id('1')): PresentationEmail(),
|
when(controller.currentExpandedEmailId).thenReturn(Rxn());
|
||||||
EmailId(Id('2')): PresentationEmail(),
|
|
||||||
}.obs);
|
|
||||||
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
||||||
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
||||||
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
||||||
|
when(controller.mailboxDashBoardController).thenReturn(mailboxDashBoardController);
|
||||||
|
when(mailboxDashBoardController.selectedEmail).thenReturn(Rxn());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
controller.loadMoreThreadDetailEmails();
|
controller.loadMoreThreadDetailEmails(
|
||||||
|
loadMoreIndex: 0,
|
||||||
|
loadMoreCount: controller.emailIdsPresentation.length,
|
||||||
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
verifyNever(getEmailsByIdsInteractor.execute(
|
verifyNever(getEmailsByIdsInteractor.execute(
|
||||||
@@ -81,17 +94,21 @@ void main() {
|
|||||||
// Arrange
|
// Arrange
|
||||||
const limit = 15;
|
const limit = 15;
|
||||||
when(controller.emailIdsPresentation).thenReturn({
|
when(controller.emailIdsPresentation).thenReturn({
|
||||||
for (int i = 0; i < limit; i++)
|
for (int i = 0; i < limit; i++) EmailId(Id('$i')): null,
|
||||||
EmailId(Id('$i')): null,
|
|
||||||
EmailId(Id('$limit')): PresentationEmail(),
|
|
||||||
}.obs);
|
}.obs);
|
||||||
|
when(controller.currentExpandedEmailId).thenReturn(Rxn());
|
||||||
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
||||||
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
||||||
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
||||||
when(controller.additionalProperties).thenReturn(Properties.empty());
|
when(controller.additionalProperties).thenReturn(Properties.empty());
|
||||||
|
when(controller.mailboxDashBoardController).thenReturn(mailboxDashBoardController);
|
||||||
|
when(mailboxDashBoardController.selectedEmail).thenReturn(Rxn());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
controller.loadMoreThreadDetailEmails();
|
controller.loadMoreThreadDetailEmails(
|
||||||
|
loadMoreIndex: 0,
|
||||||
|
loadMoreCount: controller.emailIdsPresentation.length,
|
||||||
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
verify(getEmailsByIdsInteractor.execute(
|
verify(getEmailsByIdsInteractor.execute(
|
||||||
@@ -102,6 +119,96 @@ void main() {
|
|||||||
SessionFixtures.aliceSession,
|
SessionFixtures.aliceSession,
|
||||||
AccountFixtures.aliceAccountId,
|
AccountFixtures.aliceAccountId,
|
||||||
),
|
),
|
||||||
|
loadMoreIndex: 0,
|
||||||
|
)).called(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should call getEmailsByIdsInteractor.execute '
|
||||||
|
'with ThreadDetailPresentationUtils.defaultLoadSize (20) top to bottom '
|
||||||
|
'when loadMoreIndex is larger than index of currentExpandedEmailId',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final loadMoreEmails = {
|
||||||
|
for (int i = 31; i < 60; i++) EmailId(Id('$i')): null
|
||||||
|
};
|
||||||
|
const loadMoreIndex = 32;
|
||||||
|
when(controller.emailIdsPresentation).thenReturn({
|
||||||
|
for (int i = 0; i < 30; i++) EmailId(Id('$i')): null,
|
||||||
|
EmailId(Id('30')): PresentationEmail(),
|
||||||
|
...loadMoreEmails,
|
||||||
|
}.obs);
|
||||||
|
when(controller.currentExpandedEmailId).thenReturn(Rxn(EmailId(Id('30'))));
|
||||||
|
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
||||||
|
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
||||||
|
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
||||||
|
when(controller.mailboxDashBoardController).thenReturn(mailboxDashBoardController);
|
||||||
|
when(mailboxDashBoardController.selectedEmail).thenReturn(Rxn());
|
||||||
|
|
||||||
|
// act
|
||||||
|
controller.loadMoreThreadDetailEmails(
|
||||||
|
loadMoreIndex: loadMoreIndex,
|
||||||
|
loadMoreCount: loadMoreEmails.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
verify(getEmailsByIdsInteractor.execute(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
List.generate(
|
||||||
|
ThreadDetailPresentationUtils.defaultLoadSize,
|
||||||
|
(i) => EmailId(Id('${i + loadMoreIndex}')),
|
||||||
|
),
|
||||||
|
properties: EmailUtils.getPropertiesForEmailGetMethod(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
),
|
||||||
|
loadMoreIndex: loadMoreIndex,
|
||||||
|
)).called(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should call getEmailsByIdsInteractor.execute '
|
||||||
|
'with ThreadDetailPresentationUtils.defaultLoadSize (20) bottom to top '
|
||||||
|
'when loadMoreIndex is larger than index of currentExpandedEmailId',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final loadMoreEmails = {
|
||||||
|
for (int i = 0; i < 30; i++) EmailId(Id('$i')): null
|
||||||
|
};
|
||||||
|
const loadMoreIndex = 0;
|
||||||
|
when(controller.emailIdsPresentation).thenReturn({
|
||||||
|
...loadMoreEmails,
|
||||||
|
EmailId(Id('30')): PresentationEmail(),
|
||||||
|
for (int i = 31; i < 60; i++) EmailId(Id('$i')): null,
|
||||||
|
}.obs);
|
||||||
|
when(controller.currentExpandedEmailId).thenReturn(Rxn(EmailId(Id('30'))));
|
||||||
|
when(controller.session).thenReturn(SessionFixtures.aliceSession);
|
||||||
|
when(controller.accountId).thenReturn(AccountFixtures.aliceAccountId);
|
||||||
|
when(controller.getEmailsByIdsInteractor).thenReturn(getEmailsByIdsInteractor);
|
||||||
|
when(controller.mailboxDashBoardController).thenReturn(mailboxDashBoardController);
|
||||||
|
when(mailboxDashBoardController.selectedEmail).thenReturn(Rxn());
|
||||||
|
|
||||||
|
// act
|
||||||
|
controller.loadMoreThreadDetailEmails(
|
||||||
|
loadMoreIndex: loadMoreIndex,
|
||||||
|
loadMoreCount: loadMoreEmails.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
verify(getEmailsByIdsInteractor.execute(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
List.generate(
|
||||||
|
ThreadDetailPresentationUtils.defaultLoadSize,
|
||||||
|
(i) => EmailId(Id('${loadMoreEmails.length - i - 1}')),
|
||||||
|
).reversed.toList(),
|
||||||
|
properties: EmailUtils.getPropertiesForEmailGetMethod(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
),
|
||||||
|
loadMoreIndex: loadMoreIndex,
|
||||||
)).called(1);
|
)).called(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:mockito/annotations.dart';
|
||||||
|
import 'package:mockito/mockito.dart';
|
||||||
|
import 'package:model/email/presentation_email.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_load_more_segments.dart';
|
||||||
|
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
|
||||||
|
|
||||||
|
import 'thread_detail_load_more_segments_test.mocks.dart';
|
||||||
|
|
||||||
|
@GenerateNiceMocks([MockSpec<ThreadDetailController>()])
|
||||||
|
void main() {
|
||||||
|
late MockThreadDetailController controller;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
controller = MockThreadDetailController();
|
||||||
|
});
|
||||||
|
|
||||||
|
group('ThreadDetailLoadMoreSegments', () {
|
||||||
|
test(
|
||||||
|
'should return empty map when emailIdsPresentation is empty',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
when(controller.emailIdsPresentation).thenReturn(<EmailId, PresentationEmail?>{}.obs);
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = controller.loadMoreSegments;
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return correct load more segments when there are null values in emailIdsPresentation',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
when(controller.emailIdsPresentation).thenReturn({
|
||||||
|
EmailId(Id('1')): PresentationEmail(),
|
||||||
|
EmailId(Id('2')): null,
|
||||||
|
EmailId(Id('3')): null,
|
||||||
|
EmailId(Id('4')): PresentationEmail(),
|
||||||
|
EmailId(Id('5')): null,
|
||||||
|
}.obs);
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = controller.loadMoreSegments;
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result, {
|
||||||
|
1: 2,
|
||||||
|
4: 1,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return correct load more segments when there are no null values in emailIdsPresentation',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
when(controller.emailIdsPresentation).thenReturn({
|
||||||
|
EmailId(Id('1')): PresentationEmail(),
|
||||||
|
EmailId(Id('2')): PresentationEmail(),
|
||||||
|
EmailId(Id('3')): PresentationEmail(),
|
||||||
|
EmailId(Id('4')): PresentationEmail(),
|
||||||
|
EmailId(Id('5')): PresentationEmail(),
|
||||||
|
}.obs);
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = controller.loadMoreSegments;
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result, {});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
+307
-49
@@ -1,68 +1,326 @@
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
|
||||||
import 'package:tmail_ui_user/features/thread_detail/presentation/utils/thread_detail_presentation_utils.dart';
|
import 'package:tmail_ui_user/features/thread_detail/presentation/utils/thread_detail_presentation_utils.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('ThreadDetailPresentationUtils', () {
|
group('ThreadDetailPresentationUtils', () {
|
||||||
group('getEmailIdsToLoad', () {
|
group('getEmailIdsToLoad', () {
|
||||||
test('loads first time with length equal or more than initial load size', () {
|
test(
|
||||||
final emailIdsPresentation = {
|
'should return empty list '
|
||||||
EmailId(Id('1')): null,
|
'when emailIds is empty',
|
||||||
EmailId(Id('2')): null,
|
() {
|
||||||
EmailId(Id('3')): null,
|
// arrange
|
||||||
EmailId(Id('4')): null,
|
final emailIds = <EmailId>[];
|
||||||
EmailId(Id('5')): null,
|
|
||||||
};
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
final result = ThreadDetailPresentationUtils.getEmailIdsToLoad(emailIdsPresentation);
|
emailIds,
|
||||||
|
);
|
||||||
expect(result.length, equals(ThreadDetailPresentationUtils.initialLoadSize));
|
|
||||||
expect(result, equals([EmailId(Id('1')), EmailId(Id('2'))]));
|
// assert
|
||||||
|
expect(result, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('loads first time with length smaller than initial load size', () {
|
test(
|
||||||
final emailIdsPresentation = {
|
'should return all email ids in emailIds '
|
||||||
EmailId(Id('1')): null,
|
'when isFirstLoad is true '
|
||||||
EmailId(Id('2')): null,
|
'and emailIds contains equal to or less than 3 email ids',
|
||||||
};
|
() {
|
||||||
|
// arrange
|
||||||
final result = ThreadDetailPresentationUtils.getEmailIdsToLoad(emailIdsPresentation);
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
expect(result.length, equals(emailIdsPresentation.length));
|
EmailId(Id('2')),
|
||||||
expect(result, equals([EmailId(Id('1')), EmailId(Id('2'))]));
|
EmailId(Id('3')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(result, equals(emailIds));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('loads with length equal or more than default load size', () {
|
test(
|
||||||
final emailIdsPresentation = {
|
'should return first two emails and last email '
|
||||||
EmailId(Id('1')): PresentationEmail(),
|
'when isFirstLoad is true '
|
||||||
EmailId(Id('2')): null,
|
'and emailIds contains more than 3 email ids '
|
||||||
EmailId(Id('3')): null,
|
'and selectedEmailId is not null ',
|
||||||
EmailId(Id('4')): null,
|
() {
|
||||||
EmailId(Id('5')): null,
|
// arrange
|
||||||
EmailId(Id('6')): null,
|
final emailIds = [
|
||||||
EmailId(Id('7')): null,
|
EmailId(Id('1')),
|
||||||
};
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
final result = ThreadDetailPresentationUtils.getEmailIdsToLoad(emailIdsPresentation);
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
expect(result.length, equals(6));
|
];
|
||||||
expect(result, equals([EmailId(Id('2')), EmailId(Id('3')), EmailId(Id('4')), EmailId(Id('5')), EmailId(Id('6')), EmailId(Id('7'))]));
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals([EmailId(Id('1')), EmailId(Id('2')), EmailId(Id('5'))]),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('loads with length smaller than default load size', () {
|
test(
|
||||||
final emailIdsPresentation = {
|
'should return first two emails and last email '
|
||||||
EmailId(Id('1')): PresentationEmail(),
|
'when isFirstLoad is true '
|
||||||
EmailId(Id('2')): null,
|
'and emailIds contains more than 3 email ids '
|
||||||
EmailId(Id('3')): null,
|
'and selectedEmailId is not inside emailIds',
|
||||||
};
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
selectedEmailId: EmailId(Id('6')),
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals([EmailId(Id('1')), EmailId(Id('2')), EmailId(Id('5'))]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
final result = ThreadDetailPresentationUtils.getEmailIdsToLoad(emailIdsPresentation);
|
test(
|
||||||
|
'should return first two emails and last email '
|
||||||
|
'when isFirstLoad is true '
|
||||||
|
'and emailIds contains more than 3 email ids '
|
||||||
|
'and selectedEmailId is first element of emailIds',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
selectedEmailId: emailIds.first,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals([EmailId(Id('1')), EmailId(Id('2')), EmailId(Id('5'))]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
expect(result.length, equals(emailIdsPresentation.length - 1));
|
test(
|
||||||
expect(result, equals([EmailId(Id('2')), EmailId(Id('3'))]));
|
'should return first two emails and last email '
|
||||||
|
'when isFirstLoad is true '
|
||||||
|
'and emailIds contains more than 3 email ids '
|
||||||
|
'and selectedEmailId is last element of emailIds',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
selectedEmailId: emailIds.last,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals([EmailId(Id('1')), EmailId(Id('2')), EmailId(Id('5'))]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return first two emails and last email '
|
||||||
|
'when isFirstLoad is true '
|
||||||
|
'and emailIds contains more than 3 email ids '
|
||||||
|
'and selectedEmailId is second element of emailIds',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
selectedEmailId: emailIds.elementAt(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals([EmailId(Id('1')), EmailId(Id('2')), EmailId(Id('5'))]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return first, last and selected email '
|
||||||
|
'when emailIds contains more than 3 email ids '
|
||||||
|
'and isFirstLoad is true '
|
||||||
|
'and selectedEmailId is inside emailIds '
|
||||||
|
'and selectedEmailId is not first, last or second element of emailIds',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
final selectedEmail = EmailId(Id('3'));
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getFirstLoadEmailIds(
|
||||||
|
emailIds,
|
||||||
|
selectedEmailId: selectedEmail,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals([emailIds.first, selectedEmail, emailIds.last]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return all emails '
|
||||||
|
'when emailIds contains more than 3 email ids '
|
||||||
|
'and isFirstLoad is false '
|
||||||
|
'and loadEmailsAfterSelectedEmail is true '
|
||||||
|
'and emailsIds.length is less than defaultLoadSize',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getLoadMoreEmailIds(
|
||||||
|
emailIds,
|
||||||
|
loadEmailsAfterSelectedEmail: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals(emailIds),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return first defaultLoadSize (20) emails '
|
||||||
|
'when emailIds contains more than 3 email ids '
|
||||||
|
'and isFirstLoad is false '
|
||||||
|
'and loadEmailsAfterSelectedEmail is true '
|
||||||
|
'and emailsIds.length is more than defaultLoadSize',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = List.generate(30, (i) => EmailId(Id('$i')));
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getLoadMoreEmailIds(
|
||||||
|
emailIds,
|
||||||
|
loadEmailsAfterSelectedEmail: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals(emailIds.sublist(
|
||||||
|
0,
|
||||||
|
ThreadDetailPresentationUtils.defaultLoadSize,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return all emails '
|
||||||
|
'when emailIds contains more than 3 email ids '
|
||||||
|
'and isFirstLoad is false '
|
||||||
|
'and loadEmailsAfterSelectedEmail is false '
|
||||||
|
'and emailsIds.length is less than defaultLoadSize',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = [
|
||||||
|
EmailId(Id('1')),
|
||||||
|
EmailId(Id('2')),
|
||||||
|
EmailId(Id('3')),
|
||||||
|
EmailId(Id('4')),
|
||||||
|
EmailId(Id('5')),
|
||||||
|
];
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getLoadMoreEmailIds(
|
||||||
|
emailIds,
|
||||||
|
loadEmailsAfterSelectedEmail: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals(emailIds),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should return last defaultLoadSize (20) emails '
|
||||||
|
'when emailIds contains more than 3 email ids '
|
||||||
|
'and isFirstLoad is false '
|
||||||
|
'and loadEmailsAfterSelectedEmail is false '
|
||||||
|
'and emailsIds.length is more than defaultLoadSize',
|
||||||
|
() {
|
||||||
|
// arrange
|
||||||
|
final emailIds = List.generate(30, (i) => EmailId(Id('$i')));
|
||||||
|
|
||||||
|
// act
|
||||||
|
final result = ThreadDetailPresentationUtils.getLoadMoreEmailIds(
|
||||||
|
emailIds,
|
||||||
|
loadEmailsAfterSelectedEmail: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(
|
||||||
|
result,
|
||||||
|
equals(emailIds.sublist(
|
||||||
|
emailIds.length - ThreadDetailPresentationUtils.defaultLoadSize,
|
||||||
|
emailIds.length,
|
||||||
|
)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user