From 3fc44a33c509e186a3bc5d2434169f44dcfe4169 Mon Sep 17 00:00:00 2001 From: dab246 Date: Mon, 4 Dec 2023 10:57:31 +0700 Subject: [PATCH] TF-2298 Write unit test to check token expired time Signed-off-by: dab246 --- .../domain/extensions/datetime_extension.dart | 13 ++- .../controller/fcm_token_controller.dart | 23 ++-- .../presentation/utils/fcm_utils.dart | 37 ++++++ test/features/fcm/fcm_utils_test.dart | 110 +++++++++++++----- 4 files changed, 142 insertions(+), 41 deletions(-) diff --git a/core/lib/domain/extensions/datetime_extension.dart b/core/lib/domain/extensions/datetime_extension.dart index 8f2d6831f9..da3316d4b4 100644 --- a/core/lib/domain/extensions/datetime_extension.dart +++ b/core/lib/domain/extensions/datetime_extension.dart @@ -17,9 +17,16 @@ extension DateTimeExtension on DateTime { } int daysBetween(DateTime from) { - from = DateTime(from.year, from.month, from.day); - final to = DateTime(year, month, day); - return (to.difference(from).inHours / 24).round().abs(); + from = DateTime(from.year, from.month, from.day, from.hour); + final to = DateTime(year, month, day, hour); + return (to.difference(from).inHours / Duration.hoursPerDay).round().abs(); + } + + + int minutesBetween(DateTime from) { + from = DateTime(from.year, from.month, from.day, from.hour, from.minute); + final to = DateTime(year, month, day, hour, minute); + return to.difference(from).inMinutes.abs(); } } diff --git a/lib/features/push_notification/presentation/controller/fcm_token_controller.dart b/lib/features/push_notification/presentation/controller/fcm_token_controller.dart index 63a485ca71..9666aed335 100644 --- a/lib/features/push_notification/presentation/controller/fcm_token_controller.dart +++ b/lib/features/push_notification/presentation/controller/fcm_token_controller.dart @@ -1,12 +1,12 @@ -import 'package:core/domain/extensions/datetime_extension.dart'; import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; +import 'package:core/utils/build_utils.dart'; import 'package:fcm/model/device_client_id.dart'; -import 'package:fcm/model/firebase_registration_expired_time.dart'; -import 'package:fcm/model/firebase_registration.dart'; import 'package:fcm/model/fcm_token.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; @@ -92,15 +92,20 @@ class FcmTokenController extends FcmBaseController { } } - bool _validateFirebaseRegistrationTokenExpired(FirebaseRegistration firebaseRegistration) { - log('FcmTokenController::_validateFirebaseRegistrationTokenExpired():firebaseRegistration: $firebaseRegistration'); + bool _isFirebaseRegistrationTokenExpired(FirebaseRegistration firebaseRegistration) { + log('FcmTokenController::_isFirebaseRegistrationTokenExpired():firebaseRegistration: $firebaseRegistration'); if (firebaseRegistration.expires != null) { final expireTimeLocal = firebaseRegistration.expires!.value.value.toLocal(); final currentTime = DateTime.now(); log('FcmTokenController::_validateFirebaseRegistrationTokenExpired():expireTimeLocal: $expireTimeLocal | currentTime: $currentTime'); - final offsetTime = expireTimeLocal.minutesBetween(currentTime); - log('FcmTokenController::_validateFirebaseRegistrationTokenExpired():offsetTime: $offsetTime'); - return currentTime.isBefore(expireTimeLocal) && offsetTime <= limitedTimeToExpire; + return FcmUtils.instance.checkExpirationTimeWithinGivenPeriod( + expiredTime: expireTimeLocal, + currentTime: currentTime, + limitOffsetTime: limitedTimeToExpire, + offsetTimeUnit: BuildUtils.isDebugMode + ? OffsetTimeUnit.minute + : OffsetTimeUnit.day + ); } else { return true; } @@ -161,7 +166,7 @@ class FcmTokenController extends FcmBaseController { void handleSuccessViewState(Success success) { log('FcmTokenController::_handleSuccessViewState(): $success'); if (success is GetFirebaseRegistrationByDeviceIdSuccess && - _validateFirebaseRegistrationTokenExpired(success.firebaseRegistration)) { + _isFirebaseRegistrationTokenExpired(success.firebaseRegistration)) { _updateNewExpiredTimeForFirebaseRegistration(success.firebaseRegistration); } else if (success is GetStoredFirebaseRegistrationSuccess) { _getFirebaseRegistrationFromServer(deviceClientId: success.firebaseRegistration.deviceClientId!); diff --git a/lib/features/push_notification/presentation/utils/fcm_utils.dart b/lib/features/push_notification/presentation/utils/fcm_utils.dart index d4114e223c..92956b7d10 100644 --- a/lib/features/push_notification/presentation/utils/fcm_utils.dart +++ b/lib/features/push_notification/presentation/utils/fcm_utils.dart @@ -1,6 +1,7 @@ import 'dart:io'; +import 'package:core/domain/extensions/datetime_extension.dart'; import 'package:core/utils/app_logger.dart'; import 'package:core/utils/platform_info.dart'; import 'package:dartz/dartz.dart'; @@ -10,6 +11,15 @@ import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/push/state_change.dart'; import 'package:jmap_dart_client/jmap/push/type_state.dart'; +enum OffsetTimeUnit { + year, + month, + day, + hour, + minute, + second +} + class FcmUtils { FcmUtils._internal(); @@ -115,4 +125,31 @@ class FcmUtils { } bool get isMobileAndroid => PlatformInfo.isMobile && Platform.isAndroid; + + bool checkExpirationTimeWithinGivenPeriod({ + required DateTime expiredTime, + required DateTime currentTime, + required int limitOffsetTime, + required OffsetTimeUnit offsetTimeUnit + }) { + if (currentTime.isBefore(expiredTime)) { + log('FcmUtils::checkExpiredTimeWithOffsetTime: currentTime BEFORE expiredTime'); + int offsetTime = 0; + switch(offsetTimeUnit) { + case OffsetTimeUnit.minute: + offsetTime = expiredTime.minutesBetween(currentTime); + break; + case OffsetTimeUnit.day: + offsetTime = expiredTime.daysBetween(currentTime); + break; + default: + break; + } + log('FcmUtils::checkExpiredTimeWithOffsetTime:offsetTime: $offsetTime'); + return offsetTime <= limitOffsetTime; + } else { + log('FcmUtils::checkExpiredTimeWithOffsetTime: currentTime AFTER expiredTime'); + return true; + } + } } \ No newline at end of file diff --git a/test/features/fcm/fcm_utils_test.dart b/test/features/fcm/fcm_utils_test.dart index 9021619427..4690105435 100644 --- a/test/features/fcm/fcm_utils_test.dart +++ b/test/features/fcm/fcm_utils_test.dart @@ -1,4 +1,5 @@ +import 'package:flutter_date_range_picker/flutter_date_range_picker.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; @@ -7,37 +8,36 @@ import 'package:jmap_dart_client/jmap/push/type_state.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/utils/fcm_utils.dart'; void main() { + group('decodeFirebaseDataMessageToStateChange test', () { + final expectStateChange1 = StateChange( + 'StateChange', + { + AccountId(Id('a3123')): TypeState({ + 'Email': 'd35ecb040aab', + 'EmailDelivery': '428d565f2440', + 'CalendarEvent': '87accfac587a' + }), + AccountId(Id('a43461d')): TypeState({ + 'Mailbox': '0af7a512ce70', + 'CalendarEvent': '7a4297cecd76' + }) + } + ); - final expectStateChange1 = StateChange( - 'StateChange', - { - AccountId(Id('a3123')): TypeState({ - 'Email': 'd35ecb040aab', - 'EmailDelivery': '428d565f2440', - 'CalendarEvent': '87accfac587a' - }), - AccountId(Id('a43461d')): TypeState({ - 'Mailbox': '0af7a512ce70', - 'CalendarEvent': '7a4297cecd76' - }) - } - ); - - final expectStateChange2 = StateChange( - 'StateChange', - { - AccountId(Id('a3123')): TypeState({ - 'EmailDelivery': '428d565f2440', - 'CalendarEvent': '87accfac587a' - }), - AccountId(Id('a43461d')): TypeState({ - 'Mailbox': '0af7a512ce70', - 'CalendarEvent': '7a4297cecd76' - }) - } - ); + final expectStateChange2 = StateChange( + 'StateChange', + { + AccountId(Id('a3123')): TypeState({ + 'EmailDelivery': '428d565f2440', + 'CalendarEvent': '87accfac587a' + }), + AccountId(Id('a43461d')): TypeState({ + 'Mailbox': '0af7a512ce70', + 'CalendarEvent': '7a4297cecd76' + }) + } + ); - group('decodeFirebaseDataMessageToStateChange test', () { test('should return StateChange when parse from firebase data message with key/value is not empty', () { final dataMessage = { @@ -92,4 +92,56 @@ void main() { expect(stateChange, equals(expectStateChange2)); }); }); + + group('checkExpirationTimeWithinGivenPeriod test', () { + final DateFormat dateFormat = DateFormat('dd/MM/yyyy HH:mm:ss'); + + test('should return true when currentTime is before expiredTime and within offsetTime = 5m & limitOffsetTime = 10m', () { + final currentTime = dateFormat.parse("19/12/2023 10:00:00"); + final expiredTime = dateFormat.parse("19/12/2023 10:05:00"); + final result = FcmUtils.instance.checkExpirationTimeWithinGivenPeriod( + expiredTime: expiredTime, + currentTime: currentTime, + limitOffsetTime: 10, + offsetTimeUnit: OffsetTimeUnit.minute, + ); + expect(result, isTrue); + }); + + test('should return true when currentTime is before expiredTime and within offsetTime = 10m & limitOffsetTime = 10m', () { + final currentTime = dateFormat.parse("19/12/2023 10:00:00"); + final expiredTime = dateFormat.parse("19/12/2023 10:10:00"); + final result = FcmUtils.instance.checkExpirationTimeWithinGivenPeriod( + expiredTime: expiredTime, + currentTime: currentTime, + limitOffsetTime: 10, + offsetTimeUnit: OffsetTimeUnit.minute, + ); + expect(result, isTrue); + }); + + test('should return false when currentTime is before expiredTime and within offsetTime = 15m & limitOffsetTime = 10m', () { + final currentTime = dateFormat.parse("19/12/2023 10:00:00"); + final expiredTime = dateFormat.parse("19/12/2023 10:15:00"); + final result = FcmUtils.instance.checkExpirationTimeWithinGivenPeriod( + expiredTime: expiredTime, + currentTime: currentTime, + limitOffsetTime: 10, + offsetTimeUnit: OffsetTimeUnit.minute, + ); + expect(result, isFalse); + }); + + test('should return true when currentTime is after expiredTime', () { + final currentTime = dateFormat.parse("19/12/2023 10:10:00"); + final expiredTime = dateFormat.parse("19/12/2023 10:00:00"); + final result = FcmUtils.instance.checkExpirationTimeWithinGivenPeriod( + expiredTime: expiredTime, + currentTime: currentTime, + limitOffsetTime: 10, + offsetTimeUnit: OffsetTimeUnit.minute, + ); + expect(result, isTrue); + }); + }); } \ No newline at end of file