TF-2461 Write unit test for login AuthorizationInterceptors
Signed-off-by: dab246 <tdvu@linagora.com> Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -77,7 +77,7 @@ class AuthorizationInterceptors extends QueuedInterceptorsWrapper {
|
||||
case AuthenticationType.none:
|
||||
break;
|
||||
}
|
||||
log('AuthorizationInterceptors::onRequest(): URL = ${options.uri} | HEADER = ${options.headers} | DATA = ${options.data}');
|
||||
log('AuthorizationInterceptors::onRequest(): URL = ${options.uri} | HEADER = ${options.headers} | DATA = ${options.data} | METHOD = ${options.method}');
|
||||
super.onRequest(options, handler);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class AuthorizationInterceptors extends QueuedInterceptorsWrapper {
|
||||
|
||||
@override
|
||||
void onError(DioError err, ErrorInterceptorHandler handler) async {
|
||||
logError('AuthorizationInterceptors::onError(): DIO_ERROR = $err');
|
||||
logError('AuthorizationInterceptors::onError(): DIO_ERROR = $err | METHOD = ${err.requestOptions.method}');
|
||||
try {
|
||||
if (validateToRefreshToken(responseStatusCode: err.response?.statusCode)) {
|
||||
log('AuthorizationInterceptors::onError:_validateToRefreshToken');
|
||||
|
||||
+1
-1
@@ -1039,7 +1039,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
http_mock_adapter:
|
||||
dependency: transitive
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: http_mock_adapter
|
||||
sha256: "0e7eaa5d77a273af1c2b5ec5066578faaa73039b63ccda5263c200756f24441a"
|
||||
|
||||
@@ -249,6 +249,8 @@ dev_dependencies:
|
||||
|
||||
json_serializable: 6.6.1
|
||||
|
||||
http_mock_adapter: 0.4.2
|
||||
|
||||
dependency_overrides:
|
||||
|
||||
pointer_interceptor: 0.9.1
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:core/data/constants/constant.dart';
|
||||
import 'package:core/data/network/dio_client.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http_mock_adapter/http_mock_adapter.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_base.dart';
|
||||
import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/extensions/oidc_configuration_extensions.dart';
|
||||
import 'package:tmail_ui_user/main/utils/ios_sharing_manager.dart';
|
||||
|
||||
import '../../fixtures/account_fixtures.dart';
|
||||
import '../../fixtures/oidc_fixtures.dart';
|
||||
import 'authorization_interceptor_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([
|
||||
AuthenticationClientBase,
|
||||
TokenOidcCacheManager,
|
||||
AccountCacheManager,
|
||||
IOSSharingManager
|
||||
])
|
||||
void main() {
|
||||
late Dio dio;
|
||||
late DioAdapter dioAdapter;
|
||||
late AuthenticationClientBase authenticationClient;
|
||||
late TokenOidcCacheManager tokenOidcCacheManager;
|
||||
late AccountCacheManager accountCacheManager;
|
||||
late IOSSharingManager iosSharingManager;
|
||||
late AuthorizationInterceptors authorizationInterceptors;
|
||||
|
||||
const baseUrl = 'http://domain.com/jmap';
|
||||
const responseStatusCode401 = 401;
|
||||
const responseStatusCode500 = 500;
|
||||
const responseStatusCode200 = 200;
|
||||
|
||||
final dioError401 = DioError(
|
||||
error: {'message': 'Token Expired'},
|
||||
requestOptions: RequestOptions(path: baseUrl, method: 'POST'),
|
||||
response: Response(
|
||||
statusCode: responseStatusCode401,
|
||||
requestOptions: RequestOptions(path: baseUrl)
|
||||
),
|
||||
type: DioErrorType.badResponse,
|
||||
);
|
||||
|
||||
final dataRequestSuccessfully = {'message': 'Request successfully!'};
|
||||
|
||||
setUp(() {
|
||||
final headers = <String, dynamic>{
|
||||
HttpHeaders.acceptHeader: DioClient.jmapHeader,
|
||||
HttpHeaders.contentTypeHeader: Constant.contentTypeHeaderDefault
|
||||
};
|
||||
final baseOption = BaseOptions(headers: headers);
|
||||
dio = Dio(baseOption)
|
||||
..options.baseUrl = baseUrl;
|
||||
|
||||
authenticationClient = MockAuthenticationClientBase();
|
||||
tokenOidcCacheManager = MockTokenOidcCacheManager();
|
||||
accountCacheManager = MockAccountCacheManager();
|
||||
iosSharingManager = MockIOSSharingManager();
|
||||
|
||||
authorizationInterceptors = AuthorizationInterceptors(
|
||||
dio,
|
||||
authenticationClient,
|
||||
tokenOidcCacheManager,
|
||||
accountCacheManager,
|
||||
iosSharingManager);
|
||||
|
||||
dio.interceptors.add(authorizationInterceptors);
|
||||
|
||||
dioAdapter = DioAdapter(dio: dio);
|
||||
});
|
||||
|
||||
group('AuthorizationInterceptor test', () {
|
||||
|
||||
group("validateToRefreshToken method test", () {
|
||||
test('validateToRefreshToken should return true when conditions are met', () async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTime,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
final result = authorizationInterceptors.validateToRefreshToken(responseStatusCode: responseStatusCode401);
|
||||
|
||||
expect(result, true);
|
||||
});
|
||||
|
||||
test('validateToRefreshToken should return false when condition `responseStatusCode == 500`', () async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTime,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
final result = authorizationInterceptors.validateToRefreshToken(responseStatusCode: responseStatusCode500);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('validateToRefreshToken should return false when condition `OidcConfiguration is null`', () async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTime,
|
||||
newConfig: null);
|
||||
|
||||
final result = authorizationInterceptors.validateToRefreshToken(responseStatusCode: responseStatusCode401);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('validateToRefreshToken should return false when condition `token is empty`', () async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTimeAndTokenEmpty,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
final result = authorizationInterceptors.validateToRefreshToken(responseStatusCode: responseStatusCode401);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('validateToRefreshToken should return false when condition `refreshToken is empty`', () async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTimeAndRefreshTokenEmpty,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
final result = authorizationInterceptors.validateToRefreshToken(responseStatusCode: responseStatusCode401);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('validateToRefreshToken should return false when condition `Time not expired`', () async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.newTokenOidc,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
final result = authorizationInterceptors.validateToRefreshToken(responseStatusCode: responseStatusCode401);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
});
|
||||
|
||||
group('QueuedInterceptorsWrapper test', () {
|
||||
test(
|
||||
'WHEN make a request with `tokenOidcExpiredTime`\n'
|
||||
'AND returns error `dioError401`\n'
|
||||
'THEN refresh token successfully received `newTokenOidc`\n'
|
||||
'AND re-execute request with `newTokenOidc`\n'
|
||||
'THEN response data SHOULD return `dataRequestSuccessfully`\n',
|
||||
() async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTime,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
dioAdapter.onPost(
|
||||
baseUrl,
|
||||
(server) => server.throws(responseStatusCode401, dioError401),
|
||||
);
|
||||
|
||||
when(authenticationClient.refreshingTokensOIDC(
|
||||
OIDCFixtures.oidcConfiguration.clientId,
|
||||
OIDCFixtures.oidcConfiguration.redirectUrl,
|
||||
OIDCFixtures.oidcConfiguration.discoveryUrl,
|
||||
OIDCFixtures.oidcConfiguration.scopes,
|
||||
OIDCFixtures.tokenOidcExpiredTime.refreshToken
|
||||
)).thenAnswer((_) async {
|
||||
dioAdapter.onPost(
|
||||
baseUrl,
|
||||
(server) => server.reply(responseStatusCode200, dataRequestSuccessfully)
|
||||
);
|
||||
|
||||
return OIDCFixtures.newTokenOidc;
|
||||
});
|
||||
|
||||
when(accountCacheManager.getCurrentAccount()).thenAnswer((_) async => AccountFixtures.aliceAccount);
|
||||
|
||||
final response = await dio.post(baseUrl);
|
||||
|
||||
expect(response.statusCode, responseStatusCode200);
|
||||
expect(response.data, dataRequestSuccessfully);
|
||||
});
|
||||
|
||||
test(
|
||||
'WHEN make a request with `tokenOidcExpiredTime`\n'
|
||||
'AND returns error `dioError401`\n'
|
||||
'THEN refresh token successfully received `newTokenOidc`\n'
|
||||
'AND `newTokenOidc` equals `tokenOidcExpiredTime` \n'
|
||||
'AND re-execute request with `newTokenOidc`\n'
|
||||
'THEN return error SHOULD `dioError401`\n',
|
||||
() async {
|
||||
authorizationInterceptors.setTokenAndAuthorityOidc(
|
||||
newToken: OIDCFixtures.tokenOidcExpiredTime,
|
||||
newConfig: OIDCFixtures.oidcConfiguration);
|
||||
|
||||
dioAdapter.onPost(
|
||||
baseUrl,
|
||||
(server) => server.throws(responseStatusCode401, dioError401)
|
||||
);
|
||||
|
||||
when(authenticationClient.refreshingTokensOIDC(
|
||||
OIDCFixtures.oidcConfiguration.clientId,
|
||||
OIDCFixtures.oidcConfiguration.redirectUrl,
|
||||
OIDCFixtures.oidcConfiguration.discoveryUrl,
|
||||
OIDCFixtures.oidcConfiguration.scopes,
|
||||
OIDCFixtures.tokenOidcExpiredTime.refreshToken
|
||||
)).thenAnswer((_) async {
|
||||
dioAdapter.onPost(
|
||||
baseUrl,
|
||||
(server) => server.throws(responseStatusCode401, dioError401)
|
||||
);
|
||||
return OIDCFixtures.tokenOidcExpiredTime;
|
||||
});
|
||||
|
||||
when(accountCacheManager.getCurrentAccount()).thenAnswer((_) async => AccountFixtures.aliceAccount);
|
||||
|
||||
expect(
|
||||
() async => await dio.post(baseUrl),
|
||||
throwsA(predicate<DioError>((error) => error.response?.statusCode == responseStatusCode401))
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
dioAdapter.close();
|
||||
dio.close();
|
||||
});
|
||||
}
|
||||
Vendored
+11
@@ -1,6 +1,17 @@
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||
import 'package:model/account/authentication_type.dart';
|
||||
import 'package:model/account/personal_account.dart';
|
||||
|
||||
class AccountFixtures {
|
||||
static final aliceAccountId = AccountId(Id('411ce'));
|
||||
static final aliceAccount = PersonalAccount(
|
||||
'dab',
|
||||
AuthenticationType.oidc,
|
||||
isSelected: true,
|
||||
accountId: aliceAccountId,
|
||||
apiUrl: 'https://domain.com/jmap',
|
||||
userName: UserName('Alice')
|
||||
);
|
||||
}
|
||||
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
|
||||
import 'package:model/oidc/oidc_configuration.dart';
|
||||
import 'package:model/oidc/token_id.dart';
|
||||
import 'package:model/oidc/token_oidc.dart';
|
||||
|
||||
class OIDCFixtures {
|
||||
static final tokenOidcExpiredTime = TokenOIDC(
|
||||
'dab123',
|
||||
TokenId('dab123'),
|
||||
'dab456',
|
||||
expiredTime: DateTime.now().subtract(const Duration(days: 1)));
|
||||
|
||||
static final tokenOidcExpiredTimeAndRefreshTokenEmpty = TokenOIDC(
|
||||
'dab123',
|
||||
TokenId('dab123'),
|
||||
'',
|
||||
expiredTime: DateTime.now().subtract(const Duration(days: 1)));
|
||||
|
||||
static final tokenOidcExpiredTimeAndTokenEmpty = TokenOIDC(
|
||||
'',
|
||||
TokenId('dab123'),
|
||||
'dab456',
|
||||
expiredTime: DateTime.now().subtract(const Duration(days: 1)));
|
||||
|
||||
static final newTokenOidc = TokenOIDC(
|
||||
'test123',
|
||||
TokenId('test123'),
|
||||
'test456',
|
||||
expiredTime: DateTime.now().add(const Duration(days: 1)));
|
||||
|
||||
static final oidcConfiguration = OIDCConfiguration(
|
||||
authority: 'https://example.com',
|
||||
clientId: 'client-id',
|
||||
scopes: ['scope1', 'scope2', 'scope3']);
|
||||
}
|
||||
Reference in New Issue
Block a user