Skip to content

Commit

Permalink
TF-2143 Write unit test for composer controller
Browse files Browse the repository at this point in the history
  • Loading branch information
dab246 committed May 29, 2024
1 parent 6f4adc3 commit 19c9dd6
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 60 deletions.
15 changes: 7 additions & 8 deletions lib/features/composer/presentation/composer_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ class ComposerController extends BaseController with DragDropFileMixin {

final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
final networkConnectionController = Get.find<NetworkConnectionController>();
final _dynamicUrlInterceptors = Get.find<DynamicUrlInterceptors>();

final composerArguments = Rxn<ComposerArguments>();
final isEnableEmailSendButton = false.obs;
Expand Down Expand Up @@ -186,7 +185,7 @@ class ComposerController extends BaseController with DragDropFileMixin {
ButtonState _closeComposerButtonState = ButtonState.enabled;
ButtonState _saveToDraftButtonState = ButtonState.enabled;
ButtonState _sendButtonState = ButtonState.enabled;
ButtonState _openNewTabButtonState = ButtonState.enabled;
ButtonState openNewTabButtonState = ButtonState.enabled;

late Worker uploadInlineImageWorker;
late Worker dashboardViewStateWorker;
Expand Down Expand Up @@ -333,7 +332,7 @@ class ComposerController extends BaseController with DragDropFileMixin {
} else if (failure is GetAlwaysReadReceiptSettingFailure) {
hasRequestReadReceipt.value = false;
} else if (failure is StoreComposedEmailToLocalStorageBrowserFailure) {
_openNewTabButtonState = ButtonState.enabled;
openNewTabButtonState = ButtonState.enabled;
}
}

Expand Down Expand Up @@ -1109,7 +1108,7 @@ class ComposerController extends BaseController with DragDropFileMixin {
final session = mailboxDashBoardController.sessionCurrent;
final accountId = mailboxDashBoardController.accountId.value;
if (session != null && accountId != null) {
final uploadUri = session.getUploadUri(accountId, jmapUrl: _dynamicUrlInterceptors.jmapUrl);
final uploadUri = session.getUploadUri(accountId, jmapUrl: dynamicUrlInterceptors.jmapUrl);
uploadController.justUploadAttachmentsAction(
uploadFiles: pickedFiles,
uploadUri: uploadUri,
Expand Down Expand Up @@ -1659,7 +1658,7 @@ class ComposerController extends BaseController with DragDropFileMixin {
void _handleUploadInlineSuccess(SuccessAttachmentUploadState uploadState) {
uploadController.clearUploadInlineViewState();

final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(jmapUrl: _dynamicUrlInterceptors.jmapUrl);
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl);
final accountId = mailboxDashBoardController.accountId.value;

if (baseDownloadUrl != null && accountId != null) {
Expand Down Expand Up @@ -2202,11 +2201,11 @@ class ComposerController extends BaseController with DragDropFileMixin {
}

Future<void> onOpenNewTabAction() async {
if (_openNewTabButtonState == ButtonState.disabled) {
if (openNewTabButtonState == ButtonState.disabled) {
log('ComposerController::onOpenNewTabAction: OPENING NEW TAB COMPOSER');
return;
}
_openNewTabButtonState = ButtonState.disabled;
openNewTabButtonState = ButtonState.disabled;

final arguments = composerArguments.value;
final session = mailboxDashBoardController.sessionCurrent;
Expand Down Expand Up @@ -2248,7 +2247,7 @@ class ComposerController extends BaseController with DragDropFileMixin {
}

Future<void> _handleStoreComposedEmailToLocalStorageBrowserSuccess() async {
_openNewTabButtonState = ButtonState.enabled;
openNewTabButtonState = ButtonState.enabled;

await AppUtils.launchLink(
RouteUtils.createUrlWebLocationBar(AppRoutes.dashboard).toString()
Expand Down
206 changes: 206 additions & 0 deletions test/features/composer/presentation/composer_controller_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import 'package:core/data/network/config/dynamic_url_interceptors.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/application_manager.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:tmail_ui_user/features/base/state/button_state.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_save_email_to_drafts_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_send_email_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/download_image_as_base64_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/transform_html_email_content_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_composed_email_to_local_storage_browser_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/features/network_connection/presentation/network_connection_controller.dart';
import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_always_read_receipt_setting_interactor.dart';
import 'package:tmail_ui_user/features/upload/domain/usecases/local_file_picker_interactor.dart';
import 'package:tmail_ui_user/features/upload/domain/usecases/local_image_picker_interactor.dart';
import 'package:tmail_ui_user/features/upload/presentation/controller/upload_controller.dart';
import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart';
import 'package:uuid/uuid.dart';

import '../../../fixtures/account_fixtures.dart';
import '../../../fixtures/session_fixtures.dart';
import 'composer_controller_test.mocks.dart';

mockControllerCallback() => InternalFinalCallback<void>(callback: () {});
const fallbackGenerators = {
#onStart: mockControllerCallback,
#onDelete: mockControllerCallback,
};

@GenerateNiceMocks([
MockSpec<LocalFilePickerInteractor>(),
MockSpec<LocalImagePickerInteractor>(),
MockSpec<GetEmailContentInteractor>(),
MockSpec<GetAllIdentitiesInteractor>(),
MockSpec<UploadController>(),
MockSpec<RemoveComposerCacheOnWebInteractor>(),
MockSpec<SaveComposerCacheOnWebInteractor>(),
MockSpec<DownloadImageAsBase64Interactor>(),
MockSpec<TransformHtmlEmailContentInteractor>(),
MockSpec<GetAlwaysReadReceiptSettingInteractor>(),
MockSpec<CreateNewAndSendEmailInteractor>(),
MockSpec<CreateNewAndSaveEmailToDraftsInteractor>(),
MockSpec<StoreComposedEmailToLocalStorageBrowserInteractor>(),
MockSpec<MailboxDashBoardController>(fallbackGenerators: fallbackGenerators),
MockSpec<NetworkConnectionController>(fallbackGenerators: fallbackGenerators),
MockSpec<CachingManager>(),
MockSpec<LanguageCacheManager>(),
MockSpec<AuthorizationInterceptors>(),
MockSpec<DynamicUrlInterceptors>(),
MockSpec<DeleteCredentialInteractor>(),
MockSpec<LogoutOidcInteractor>(),
MockSpec<DeleteAuthorityOidcInteractor>(),
MockSpec<AppToast>(),
MockSpec<ImagePaths>(),
MockSpec<ResponsiveUtils>(),
MockSpec<Uuid>(),
MockSpec<ApplicationManager>(),
])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();

late ComposerController composerController;
late MockLocalFilePickerInteractor mockLocalFilePickerInteractor;
late MockLocalImagePickerInteractor mockLocalImagePickerInteractor;
late MockGetEmailContentInteractor mockGetEmailContentInteractor;
late MockGetAllIdentitiesInteractor mockGetAllIdentitiesInteractor;
late MockUploadController mockUploadController;
late MockRemoveComposerCacheOnWebInteractor mockRemoveComposerCacheOnWebInteractor;
late MockSaveComposerCacheOnWebInteractor mockSaveComposerCacheOnWebInteractor;
late MockDownloadImageAsBase64Interactor mockDownloadImageAsBase64Interactor;
late MockTransformHtmlEmailContentInteractor mockTransformHtmlEmailContentInteractor;
late MockGetAlwaysReadReceiptSettingInteractor mockGetAlwaysReadReceiptSettingInteractor;
late MockCreateNewAndSendEmailInteractor mockCreateNewAndSendEmailInteractor;
late MockCreateNewAndSaveEmailToDraftsInteractor mockCreateNewAndSaveEmailToDraftsInteractor;
late MockStoreComposedEmailToLocalStorageBrowserInteractor mockStoreComposedEmailToLocalStorageBrowserInteractor;

late MockNetworkConnectionController mockNetworkConnectionController;
late MockMailboxDashBoardController mockMailboxDashBoardController;

late MockCachingManager mockCachingManager;
late MockLanguageCacheManager mockLanguageCacheManager;
late MockAuthorizationInterceptors mockAuthorizationInterceptors;
late MockDynamicUrlInterceptors mockDynamicUrlInterceptors;
late MockDeleteCredentialInteractor mockDeleteCredentialInteractor;
late MockLogoutOidcInteractor mockLogoutOidcInteractor;
late MockDeleteAuthorityOidcInteractor mockDeleteAuthorityOidcInteractor;
late MockAppToast mockAppToast;
late MockImagePaths mockImagePaths;
late MockResponsiveUtils mockResponsiveUtils;
late MockUuid mockUuid;
late MockApplicationManager mockApplicationManager;

setUpAll(() {
mockLocalFilePickerInteractor = MockLocalFilePickerInteractor();
mockLocalImagePickerInteractor = MockLocalImagePickerInteractor();
mockGetEmailContentInteractor = MockGetEmailContentInteractor();
mockGetAllIdentitiesInteractor = MockGetAllIdentitiesInteractor();
mockUploadController = MockUploadController();
mockRemoveComposerCacheOnWebInteractor = MockRemoveComposerCacheOnWebInteractor();
mockSaveComposerCacheOnWebInteractor = MockSaveComposerCacheOnWebInteractor();
mockDownloadImageAsBase64Interactor = MockDownloadImageAsBase64Interactor();
mockTransformHtmlEmailContentInteractor = MockTransformHtmlEmailContentInteractor();
mockGetAlwaysReadReceiptSettingInteractor = MockGetAlwaysReadReceiptSettingInteractor();
mockCreateNewAndSendEmailInteractor = MockCreateNewAndSendEmailInteractor();
mockCreateNewAndSaveEmailToDraftsInteractor = MockCreateNewAndSaveEmailToDraftsInteractor();
mockStoreComposedEmailToLocalStorageBrowserInteractor = MockStoreComposedEmailToLocalStorageBrowserInteractor();

mockNetworkConnectionController = MockNetworkConnectionController();
mockMailboxDashBoardController = MockMailboxDashBoardController();

// mock base controller
mockCachingManager = MockCachingManager();
mockLanguageCacheManager = MockLanguageCacheManager();
mockAuthorizationInterceptors = MockAuthorizationInterceptors();
mockDynamicUrlInterceptors = MockDynamicUrlInterceptors();
mockDeleteCredentialInteractor = MockDeleteCredentialInteractor();
mockLogoutOidcInteractor = MockLogoutOidcInteractor();
mockDeleteAuthorityOidcInteractor = MockDeleteAuthorityOidcInteractor();
mockAppToast = MockAppToast();
mockImagePaths = MockImagePaths();
mockResponsiveUtils = MockResponsiveUtils();
mockUuid = MockUuid();
mockApplicationManager = MockApplicationManager();

Get.put<NetworkConnectionController>(mockNetworkConnectionController);
Get.put<MailboxDashBoardController>(mockMailboxDashBoardController);

Get.put<CachingManager>(mockCachingManager);
Get.put<LanguageCacheManager>(mockLanguageCacheManager);
Get.put<AuthorizationInterceptors>(mockAuthorizationInterceptors);
Get.put<AuthorizationInterceptors>(
mockAuthorizationInterceptors,
tag: BindingTag.isolateTag,
);
Get.put<DynamicUrlInterceptors>(mockDynamicUrlInterceptors);
Get.put<DeleteCredentialInteractor>(mockDeleteCredentialInteractor);
Get.put<LogoutOidcInteractor>(mockLogoutOidcInteractor);
Get.put<DeleteAuthorityOidcInteractor>(mockDeleteAuthorityOidcInteractor);
Get.put<AppToast>(mockAppToast);
Get.put<ImagePaths>(mockImagePaths);
Get.put<ResponsiveUtils>(mockResponsiveUtils);
Get.put<Uuid>(mockUuid);
Get.put<ApplicationManager>(mockApplicationManager);

Get.testMode = true;

composerController = ComposerController(
mockLocalFilePickerInteractor,
mockLocalImagePickerInteractor,
mockGetEmailContentInteractor,
mockGetAllIdentitiesInteractor,
mockUploadController,
mockRemoveComposerCacheOnWebInteractor,
mockSaveComposerCacheOnWebInteractor,
mockDownloadImageAsBase64Interactor,
mockTransformHtmlEmailContentInteractor,
mockGetAlwaysReadReceiptSettingInteractor,
mockCreateNewAndSendEmailInteractor,
mockCreateNewAndSaveEmailToDraftsInteractor,
mockStoreComposedEmailToLocalStorageBrowserInteractor,
);
});

group("ComposerController::onOpenNewTabAction test", () {
test(
'WHEN onOpenNewTabAction invoked\n'
'THEN _storeComposedEmailToLocalStorageBrowserInteractor should be executed',
() async {
// Arrange
when(mockMailboxDashBoardController.accountId).thenReturn(Rxn(AccountFixtures.aliceAccountId));
when(mockMailboxDashBoardController.sessionCurrent).thenReturn(SessionFixtures.aliceSession);

composerController.composerArguments.value = ComposerArguments();
composerController.openNewTabButtonState = ButtonState.enabled;

// Act
composerController.onOpenNewTabAction();

await untilCalled(mockStoreComposedEmailToLocalStorageBrowserInteractor.execute(any));

// Assert
verify(mockStoreComposedEmailToLocalStorageBrowserInteractor.execute(any)).called(1);
});
});

tearDown(() {
Get.deleteAll();
});
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:date_format/date_format.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:date_format/date_format.dart' as date_format;
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/calendar_event.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart';

void main() {
group('calendar event extension test', () {
group('CalendarEventExtension::formatDateTime test', () {
final dateTime = DateTime(2021, 10, 10, 10, 30, 00, 00, 00);

const locale = date_format.EnglishDateLocale();
Expand All @@ -27,4 +29,48 @@ void main() {
expect(formattedTime, expectedFormattedTime);
});
});

group('CalendarEventExtension::getDateTimeEvent test', () {
test('dateTimeEventAsString should return string with format start date - end date (timezone offset) and date formatted as DD, MM dd, YYYY for all-day event for many days', () {
const expectedFormattedDateString = 'Sunday, October 10, 2021 - Sunday, October 24, 2021 (GMT+0)';

final startDate = DateTime(2021, 10, 10, 00, 00, 00, 00, 00);
final endDate = DateTime(2021, 10, 25, 00, 00, 00, 00, 00);

final calendarEvent = CalendarEvent(
startDate: startDate,
endDate: endDate,
startUtcDate: UTCDate(startDate),
endUtcDate: UTCDate(endDate),
);

final formattedDateString = calendarEvent.getDateTimeEvent(
timeZone: 'GMT+0',
dateLocale: const EnglishDateLocale()
);

expect(formattedDateString, expectedFormattedDateString);
});

test('dateTimeEventAsString should return string with format date (timezone offset) and date formatted as DD, MM dd, YYYY for all-day event for one day', () {
const expectedFormattedDateString = 'Sunday, October 10, 2021 (GMT+0)';

final startDate = DateTime(2021, 10, 10, 00, 00, 00, 00, 00);
final endDate = DateTime(2021, 10, 11, 00, 00, 00, 00, 00);

final calendarEvent = CalendarEvent(
startDate: startDate,
endDate: endDate,
startUtcDate: UTCDate(startDate),
endUtcDate: UTCDate(endDate),
);

final formattedDateString = calendarEvent.getDateTimeEvent(
timeZone: 'GMT+0',
dateLocale: const EnglishDateLocale()
);

expect(formattedDateString, expectedFormattedDateString);
});
});
}

This file was deleted.

0 comments on commit 19c9dd6

Please sign in to comment.