From 763673241f5bc8d05c543659a50843863c49ecf7 Mon Sep 17 00:00:00 2001 From: Eslam Date: Wed, 2 Jul 2025 05:29:05 +0300 Subject: [PATCH 01/12] feat(auth): Implement user profile data retrieval functionality --- lib/core/utils/di/di.config.dart | 46 ++++++------ lib/data/auth/api/auth_retrofit_client.dart | 4 ++ lib/data/auth/api/auth_retrofit_client.g.dart | 44 +++++++++++- .../contract/auth_remote_data_source.dart | 6 +- .../remote/auth_remote_data_source_impl.dart | 13 +++- .../auth/models/user_data_response_dto.dart | 22 ++++++ .../auth/models/user_data_response_dto.g.dart | 22 ++++++ lib/data/auth/models/user_dto.dart | 70 +++++++++++++++++++ lib/data/auth/models/user_dto.g.dart | 37 ++++++++++ lib/data/auth/repo_impl/auth_repo_impl.dart | 20 +++++- 10 files changed, 257 insertions(+), 27 deletions(-) create mode 100644 lib/data/auth/models/user_data_response_dto.dart create mode 100644 lib/data/auth/models/user_data_response_dto.g.dart create mode 100644 lib/data/auth/models/user_dto.dart create mode 100644 lib/data/auth/models/user_dto.g.dart diff --git a/lib/core/utils/di/di.config.dart b/lib/core/utils/di/di.config.dart index d86ecb9..dd7406e 100644 --- a/lib/core/utils/di/di.config.dart +++ b/lib/core/utils/di/di.config.dart @@ -26,6 +26,7 @@ import '../../../data/auth/data_source/remote/auth_remote_data_source_impl.dart' as _i173; import '../../../data/auth/repo_impl/auth_repo_impl.dart' as _i15; import '../../../domain/auth/repo/auth_repo.dart' as _i1047; +import '../../../domain/auth/use_case/get_profile_data_use_case.dart' as _i336; import '../../../features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart' as _i393; import '../../functions/inital_route_function.dart' as _i420; @@ -38,12 +39,16 @@ import '../shared_preference_module.dart' as _i60; import '../validator/validator.dart' as _i468; extension GetItInjectableX on _i174.GetIt { - // initializes the registration of main-scope dependencies inside of GetIt +// initializes the registration of main-scope dependencies inside of GetIt Future<_i174.GetIt> init({ String? environment, _i526.EnvironmentFilter? environmentFilter, }) async { - final gh = _i526.GetItHelper(this, environment, environmentFilter); + final gh = _i526.GetItHelper( + this, + environment, + environmentFilter, + ); final sharedPreferenceModule = _$SharedPreferenceModule(); final secureStorageModule = _$SecureStorageModule(); final loggerModule = _$LoggerModule(); @@ -55,33 +60,30 @@ extension GetItInjectableX on _i174.GetIt { gh.singleton<_i28.ApiManager>(() => _i28.ApiManager()); gh.singleton<_i393.MainLayoutCubit>(() => _i393.MainLayoutCubit()); gh.lazySingleton<_i558.FlutterSecureStorage>( - () => secureStorageModule.storage, - ); + () => secureStorageModule.storage); gh.lazySingleton<_i974.Logger>(() => loggerModule.loggerProvider); gh.lazySingleton<_i974.PrettyPrinter>(() => loggerModule.prettyPrinter); gh.lazySingleton<_i468.Validator>(() => _i468.Validator()); gh.factory<_i1063.AuthLocalDataSource>( - () => _i757.AuthLocalDataSourceImpl(), - ); + () => _i757.AuthLocalDataSourceImpl()); gh.singleton<_i649.BlocObserverService>( - () => _i649.BlocObserverService(gh<_i974.Logger>()), - ); - gh.factory<_i420.RouteInitializer>( - () => _i420.RouteInitializer( - flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), - sharedPreferences: gh<_i460.SharedPreferences>(), - ), - ); - gh.factory<_i1047.AuthRepo>(() => _i15.AuthRepoImpl()); - gh.factory<_i774.AuthRemoteDataSource>( - () => _i173.AuthRemoteDataSourceImpl(), - ); + () => _i649.BlocObserverService(gh<_i974.Logger>())); + gh.factory<_i420.RouteInitializer>(() => _i420.RouteInitializer( + flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), + sharedPreferences: gh<_i460.SharedPreferences>(), + )); gh.lazySingleton<_i361.Dio>( - () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>()), - ); + () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>())); gh.factory<_i1064.AuthRetrofitClient>( - () => _i1064.AuthRetrofitClient(gh<_i361.Dio>()), - ); + () => _i1064.AuthRetrofitClient(gh<_i361.Dio>())); + gh.factory<_i774.AuthRemoteDataSource>( + () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>())); + gh.factory<_i1047.AuthRepo>(() => _i15.AuthRepoImpl( + gh<_i28.ApiManager>(), + gh<_i774.AuthRemoteDataSource>(), + )); + gh.factory<_i336.GetProfileDataUseCase>( + () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>())); return this; } } diff --git a/lib/data/auth/api/auth_retrofit_client.dart b/lib/data/auth/api/auth_retrofit_client.dart index 2144c63..d733cf1 100644 --- a/lib/data/auth/api/auth_retrofit_client.dart +++ b/lib/data/auth/api/auth_retrofit_client.dart @@ -1,4 +1,5 @@ import 'package:dio/dio.dart'; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; import 'package:injectable/injectable.dart'; import 'package:retrofit/retrofit.dart'; @@ -11,4 +12,7 @@ part 'auth_retrofit_client.g.dart'; abstract class AuthRetrofitClient { @factoryMethod factory AuthRetrofitClient(Dio dio) = _AuthRetrofitClient; + + @GET(ApiConstants.profileDataRoute) + Future getProfileData(); } diff --git a/lib/data/auth/api/auth_retrofit_client.g.dart b/lib/data/auth/api/auth_retrofit_client.g.dart index 315bee1..3860d59 100644 --- a/lib/data/auth/api/auth_retrofit_client.g.dart +++ b/lib/data/auth/api/auth_retrofit_client.g.dart @@ -9,7 +9,11 @@ part of 'auth_retrofit_client.dart'; // ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations class _AuthRetrofitClient implements AuthRetrofitClient { - _AuthRetrofitClient(this._dio, {this.baseUrl, this.errorLogger}) { + _AuthRetrofitClient( + this._dio, { + this.baseUrl, + this.errorLogger, + }) { baseUrl ??= 'https://fitness.elevateegy.com/api/v1/'; } @@ -19,6 +23,39 @@ class _AuthRetrofitClient implements AuthRetrofitClient { final ParseErrorLogger? errorLogger; + @override + Future getProfileData() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + 'auth/profile-data', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + final _result = await _dio.fetch>(_options); + late UserDataResponseDto _value; + try { + _value = UserDataResponseDto.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + RequestOptions _setStreamType(RequestOptions requestOptions) { if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || @@ -32,7 +69,10 @@ class _AuthRetrofitClient implements AuthRetrofitClient { return requestOptions; } - String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { if (baseUrl == null || baseUrl.trim().isEmpty) { return dioBaseUrl; } diff --git a/lib/data/auth/data_source/contract/auth_remote_data_source.dart b/lib/data/auth/data_source/contract/auth_remote_data_source.dart index 89df1ba..b8d60c6 100644 --- a/lib/data/auth/data_source/contract/auth_remote_data_source.dart +++ b/lib/data/auth/data_source/contract/auth_remote_data_source.dart @@ -1 +1,5 @@ -abstract class AuthRemoteDataSource {} +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; + +abstract class AuthRemoteDataSource { + Future getProfileData(); +} diff --git a/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart b/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart index f63f003..e02e456 100644 --- a/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart +++ b/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart @@ -1,6 +1,17 @@ +import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart'; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; import 'package:injectable/injectable.dart'; import '../contract/auth_remote_data_source.dart'; @Injectable(as: AuthRemoteDataSource) -class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {} +class AuthRemoteDataSourceImpl implements AuthRemoteDataSource { + final AuthRetrofitClient _authRetrofitClient; + + AuthRemoteDataSourceImpl(this._authRetrofitClient); + + @override + Future getProfileData() async { + return await _authRetrofitClient.getProfileData(); + } +} diff --git a/lib/data/auth/models/user_data_response_dto.dart b/lib/data/auth/models/user_data_response_dto.dart new file mode 100644 index 0000000..3d1e17c --- /dev/null +++ b/lib/data/auth/models/user_data_response_dto.dart @@ -0,0 +1,22 @@ +import 'package:fitness_app/data/auth/models/user_dto.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'user_data_response_dto.g.dart'; + +@JsonSerializable() +class UserDataResponseDto { + @JsonKey(name: "message") + final String? message; + @JsonKey(name: "user") + final UserDto? user; + + UserDataResponseDto({this.message, this.user}); + + factory UserDataResponseDto.fromJson(Map json) { + return _$UserDataResponseDtoFromJson(json); + } + + Map toJson() { + return _$UserDataResponseDtoToJson(this); + } +} diff --git a/lib/data/auth/models/user_data_response_dto.g.dart b/lib/data/auth/models/user_data_response_dto.g.dart new file mode 100644 index 0000000..d03115b --- /dev/null +++ b/lib/data/auth/models/user_data_response_dto.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_data_response_dto.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserDataResponseDto _$UserDataResponseDtoFromJson(Map json) => + UserDataResponseDto( + message: json['message'] as String?, + user: json['user'] == null + ? null + : UserDto.fromJson(json['user'] as Map), + ); + +Map _$UserDataResponseDtoToJson( + UserDataResponseDto instance) => + { + 'message': instance.message, + 'user': instance.user, + }; diff --git a/lib/data/auth/models/user_dto.dart b/lib/data/auth/models/user_dto.dart new file mode 100644 index 0000000..91280d2 --- /dev/null +++ b/lib/data/auth/models/user_dto.dart @@ -0,0 +1,70 @@ +import 'package:fitness_app/domain/auth/entity/user_entity.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'user_dto.g.dart'; + +@JsonSerializable() +class UserDto { + @JsonKey(name: "_id") + final String? id; + @JsonKey(name: "firstName") + final String? firstName; + @JsonKey(name: "lastName") + final String? lastName; + @JsonKey(name: "email") + final String? email; + @JsonKey(name: "gender") + final String? gender; + @JsonKey(name: "age") + final int? age; + @JsonKey(name: "weight") + final int? weight; + @JsonKey(name: "height") + final int? height; + @JsonKey(name: "activityLevel") + final String? activityLevel; + @JsonKey(name: "goal") + final String? goal; + @JsonKey(name: "photo") + final String? photo; + @JsonKey(name: "createdAt") + final String? createdAt; + + UserDto({ + this.id, + this.firstName, + this.lastName, + this.email, + this.gender, + this.age, + this.weight, + this.height, + this.activityLevel, + this.goal, + this.photo, + this.createdAt, + }); + + factory UserDto.fromJson(Map json) { + return _$UserDtoFromJson(json); + } + + Map toJson() { + return _$UserDtoToJson(this); + } + + UserEntity toEntity() { + return UserEntity( + firstName: firstName, + lastName: lastName, + email: email, + gender: gender, + age: age, + weight: weight, + height: height, + activityLevel: activityLevel, + goal: goal, + photo: photo, + ); + } +} diff --git a/lib/data/auth/models/user_dto.g.dart b/lib/data/auth/models/user_dto.g.dart new file mode 100644 index 0000000..2797dee --- /dev/null +++ b/lib/data/auth/models/user_dto.g.dart @@ -0,0 +1,37 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_dto.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserDto _$UserDtoFromJson(Map json) => UserDto( + id: json['_id'] as String?, + firstName: json['firstName'] as String?, + lastName: json['lastName'] as String?, + email: json['email'] as String?, + gender: json['gender'] as String?, + age: (json['age'] as num?)?.toInt(), + weight: (json['weight'] as num?)?.toInt(), + height: (json['height'] as num?)?.toInt(), + activityLevel: json['activityLevel'] as String?, + goal: json['goal'] as String?, + photo: json['photo'] as String?, + createdAt: json['createdAt'] as String?, + ); + +Map _$UserDtoToJson(UserDto instance) => { + '_id': instance.id, + 'firstName': instance.firstName, + 'lastName': instance.lastName, + 'email': instance.email, + 'gender': instance.gender, + 'age': instance.age, + 'weight': instance.weight, + 'height': instance.height, + 'activityLevel': instance.activityLevel, + 'goal': instance.goal, + 'photo': instance.photo, + 'createdAt': instance.createdAt, + }; diff --git a/lib/data/auth/repo_impl/auth_repo_impl.dart b/lib/data/auth/repo_impl/auth_repo_impl.dart index 395dc06..4fa0d6a 100644 --- a/lib/data/auth/repo_impl/auth_repo_impl.dart +++ b/lib/data/auth/repo_impl/auth_repo_impl.dart @@ -1,6 +1,24 @@ +import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart'; +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart'; +import 'package:fitness_app/domain/auth/entity/user_entity.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/auth/repo/auth_repo.dart'; @Injectable(as: AuthRepo) -class AuthRepoImpl implements AuthRepo {} +class AuthRepoImpl implements AuthRepo { + final ApiManager _apiManager; + final AuthRemoteDataSource _authRemoteDataSource; + + AuthRepoImpl(this._apiManager, this._authRemoteDataSource); + + @override + Future> getProfileData() async { + final result = await _apiManager.execute(() async { + final response = await _authRemoteDataSource.getProfileData(); + return response.user!.toEntity(); + }); + return result; + } +} From ad00a0bc778df34ca087da061b418a5c72533243 Mon Sep 17 00:00:00 2001 From: Eslam Date: Wed, 2 Jul 2025 05:29:55 +0300 Subject: [PATCH 02/12] feat(auth): Add user entity and profile data retrieval use case --- lib/domain/auth/entity/user_entity.dart | 25 +++++++++++++++++++ lib/domain/auth/repo/auth_repo.dart | 7 +++++- .../use_case/get_profile_data_use_case.dart | 16 ++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 lib/domain/auth/entity/user_entity.dart create mode 100644 lib/domain/auth/use_case/get_profile_data_use_case.dart diff --git a/lib/domain/auth/entity/user_entity.dart b/lib/domain/auth/entity/user_entity.dart new file mode 100644 index 0000000..f59b9f6 --- /dev/null +++ b/lib/domain/auth/entity/user_entity.dart @@ -0,0 +1,25 @@ +class UserEntity { + final String? firstName; + final String? lastName; + final String? email; + final String? gender; + final int? age; + final int? weight; + final int? height; + final String? activityLevel; + final String? goal; + final String? photo; + + UserEntity({ + this.firstName, + this.lastName, + this.email, + this.gender, + this.age, + this.weight, + this.height, + this.activityLevel, + this.goal, + this.photo, + }); +} diff --git a/lib/domain/auth/repo/auth_repo.dart b/lib/domain/auth/repo/auth_repo.dart index b0c9690..90983e1 100644 --- a/lib/domain/auth/repo/auth_repo.dart +++ b/lib/domain/auth/repo/auth_repo.dart @@ -1 +1,6 @@ -abstract class AuthRepo {} +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/domain/auth/entity/user_entity.dart'; + +abstract class AuthRepo { + Future> getProfileData(); +} diff --git a/lib/domain/auth/use_case/get_profile_data_use_case.dart b/lib/domain/auth/use_case/get_profile_data_use_case.dart new file mode 100644 index 0000000..a1c998b --- /dev/null +++ b/lib/domain/auth/use_case/get_profile_data_use_case.dart @@ -0,0 +1,16 @@ +import 'package:fitness_app/domain/auth/repo/auth_repo.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../core/utils/datasource_excution/api_result.dart'; +import '../entity/user_entity.dart'; + +@injectable +class GetProfileDataUseCase { + final AuthRepo _authRepo; + + GetProfileDataUseCase(this._authRepo); + + Future> call() async { + return await _authRepo.getProfileData(); + } +} From de4f91fa9d08686a3489f01515c6159efc78cce3 Mon Sep 17 00:00:00 2001 From: Eslam Date: Wed, 2 Jul 2025 05:30:20 +0300 Subject: [PATCH 03/12] feat(auth): Add unit tests for AuthRemoteDataSource and AuthRepo implementation --- .../inital_route_function_test.mocks.dart | 620 +++++++++++------- .../auth_remote_data_source_impl_test.dart | 72 ++ ...th_remote_data_source_impl_test.mocks.dart | 62 ++ .../auth/repo_impl/auth_repo_impl_test.dart | 95 +++ .../repo_impl/auth_repo_impl_test.mocks.dart | 94 +++ .../view/main_layout_screen_test.mocks.dart | 142 ++-- 6 files changed, 777 insertions(+), 308 deletions(-) create mode 100644 test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart create mode 100644 test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart create mode 100644 test/data/auth/repo_impl/auth_repo_impl_test.dart create mode 100644 test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart diff --git a/test/core/functions/inital_route_function_test.mocks.dart b/test/core/functions/inital_route_function_test.mocks.dart index 85f461d..8351c57 100644 --- a/test/core/functions/inital_route_function_test.mocks.dart +++ b/test/core/functions/inital_route_function_test.mocks.dart @@ -25,35 +25,65 @@ import 'package:shared_preferences/src/shared_preferences_legacy.dart' as _i3; // ignore_for_file: subtype_of_sealed_class class _FakeIOSOptions_0 extends _i1.SmartFake implements _i2.IOSOptions { - _FakeIOSOptions_0(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeIOSOptions_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeAndroidOptions_1 extends _i1.SmartFake implements _i2.AndroidOptions { - _FakeAndroidOptions_1(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeAndroidOptions_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeLinuxOptions_2 extends _i1.SmartFake implements _i2.LinuxOptions { - _FakeLinuxOptions_2(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeLinuxOptions_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeWindowsOptions_3 extends _i1.SmartFake implements _i2.WindowsOptions { - _FakeWindowsOptions_3(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeWindowsOptions_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeWebOptions_4 extends _i1.SmartFake implements _i2.WebOptions { - _FakeWebOptions_4(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeWebOptions_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeMacOsOptions_5 extends _i1.SmartFake implements _i2.MacOsOptions { - _FakeMacOsOptions_5(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeMacOsOptions_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } /// A class which mocks [SharedPreferences]. @@ -65,118 +95,176 @@ class MockSharedPreferences extends _i1.Mock implements _i3.SharedPreferences { } @override - Set getKeys() => - (super.noSuchMethod( - Invocation.method(#getKeys, []), - returnValue: {}, - ) - as Set); + Set getKeys() => (super.noSuchMethod( + Invocation.method( + #getKeys, + [], + ), + returnValue: {}, + ) as Set); @override - Object? get(String? key) => - (super.noSuchMethod(Invocation.method(#get, [key])) as Object?); + Object? get(String? key) => (super.noSuchMethod(Invocation.method( + #get, + [key], + )) as Object?); @override - bool? getBool(String? key) => - (super.noSuchMethod(Invocation.method(#getBool, [key])) as bool?); + bool? getBool(String? key) => (super.noSuchMethod(Invocation.method( + #getBool, + [key], + )) as bool?); @override - int? getInt(String? key) => - (super.noSuchMethod(Invocation.method(#getInt, [key])) as int?); + int? getInt(String? key) => (super.noSuchMethod(Invocation.method( + #getInt, + [key], + )) as int?); @override - double? getDouble(String? key) => - (super.noSuchMethod(Invocation.method(#getDouble, [key])) as double?); + double? getDouble(String? key) => (super.noSuchMethod(Invocation.method( + #getDouble, + [key], + )) as double?); @override - String? getString(String? key) => - (super.noSuchMethod(Invocation.method(#getString, [key])) as String?); + String? getString(String? key) => (super.noSuchMethod(Invocation.method( + #getString, + [key], + )) as String?); @override - bool containsKey(String? key) => - (super.noSuchMethod( - Invocation.method(#containsKey, [key]), - returnValue: false, - ) - as bool); + bool containsKey(String? key) => (super.noSuchMethod( + Invocation.method( + #containsKey, + [key], + ), + returnValue: false, + ) as bool); @override List? getStringList(String? key) => - (super.noSuchMethod(Invocation.method(#getStringList, [key])) - as List?); - - @override - _i4.Future setBool(String? key, bool? value) => - (super.noSuchMethod( - Invocation.method(#setBool, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future setInt(String? key, int? value) => - (super.noSuchMethod( - Invocation.method(#setInt, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future setDouble(String? key, double? value) => - (super.noSuchMethod( - Invocation.method(#setDouble, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); + (super.noSuchMethod(Invocation.method( + #getStringList, + [key], + )) as List?); @override - _i4.Future setString(String? key, String? value) => + _i4.Future setBool( + String? key, + bool? value, + ) => (super.noSuchMethod( - Invocation.method(#setString, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future setStringList(String? key, List? value) => + Invocation.method( + #setBool, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setInt( + String? key, + int? value, + ) => (super.noSuchMethod( - Invocation.method(#setStringList, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future remove(String? key) => + Invocation.method( + #setInt, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setDouble( + String? key, + double? value, + ) => (super.noSuchMethod( - Invocation.method(#remove, [key]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future commit() => + Invocation.method( + #setDouble, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setString( + String? key, + String? value, + ) => (super.noSuchMethod( - Invocation.method(#commit, []), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future clear() => + Invocation.method( + #setString, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setStringList( + String? key, + List? value, + ) => (super.noSuchMethod( - Invocation.method(#clear, []), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future reload() => - (super.noSuchMethod( - Invocation.method(#reload, []), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #setStringList, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future remove(String? key) => (super.noSuchMethod( + Invocation.method( + #remove, + [key], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future commit() => (super.noSuchMethod( + Invocation.method( + #commit, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future clear() => (super.noSuchMethod( + Invocation.method( + #clear, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future reload() => (super.noSuchMethod( + Invocation.method( + #reload, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); } /// A class which mocks [FlutterSecureStorage]. @@ -189,101 +277,112 @@ class MockFlutterSecureStorage extends _i1.Mock } @override - _i2.IOSOptions get iOptions => - (super.noSuchMethod( - Invocation.getter(#iOptions), - returnValue: _FakeIOSOptions_0(this, Invocation.getter(#iOptions)), - ) - as _i2.IOSOptions); + _i2.IOSOptions get iOptions => (super.noSuchMethod( + Invocation.getter(#iOptions), + returnValue: _FakeIOSOptions_0( + this, + Invocation.getter(#iOptions), + ), + ) as _i2.IOSOptions); @override - _i2.AndroidOptions get aOptions => - (super.noSuchMethod( - Invocation.getter(#aOptions), - returnValue: _FakeAndroidOptions_1( - this, - Invocation.getter(#aOptions), - ), - ) - as _i2.AndroidOptions); + _i2.AndroidOptions get aOptions => (super.noSuchMethod( + Invocation.getter(#aOptions), + returnValue: _FakeAndroidOptions_1( + this, + Invocation.getter(#aOptions), + ), + ) as _i2.AndroidOptions); @override - _i2.LinuxOptions get lOptions => - (super.noSuchMethod( - Invocation.getter(#lOptions), - returnValue: _FakeLinuxOptions_2( - this, - Invocation.getter(#lOptions), - ), - ) - as _i2.LinuxOptions); + _i2.LinuxOptions get lOptions => (super.noSuchMethod( + Invocation.getter(#lOptions), + returnValue: _FakeLinuxOptions_2( + this, + Invocation.getter(#lOptions), + ), + ) as _i2.LinuxOptions); @override - _i2.WindowsOptions get wOptions => - (super.noSuchMethod( - Invocation.getter(#wOptions), - returnValue: _FakeWindowsOptions_3( - this, - Invocation.getter(#wOptions), - ), - ) - as _i2.WindowsOptions); + _i2.WindowsOptions get wOptions => (super.noSuchMethod( + Invocation.getter(#wOptions), + returnValue: _FakeWindowsOptions_3( + this, + Invocation.getter(#wOptions), + ), + ) as _i2.WindowsOptions); @override - _i2.WebOptions get webOptions => - (super.noSuchMethod( - Invocation.getter(#webOptions), - returnValue: _FakeWebOptions_4( - this, - Invocation.getter(#webOptions), - ), - ) - as _i2.WebOptions); + _i2.WebOptions get webOptions => (super.noSuchMethod( + Invocation.getter(#webOptions), + returnValue: _FakeWebOptions_4( + this, + Invocation.getter(#webOptions), + ), + ) as _i2.WebOptions); @override - _i2.MacOsOptions get mOptions => - (super.noSuchMethod( - Invocation.getter(#mOptions), - returnValue: _FakeMacOsOptions_5( - this, - Invocation.getter(#mOptions), - ), - ) - as _i2.MacOsOptions); + _i2.MacOsOptions get mOptions => (super.noSuchMethod( + Invocation.getter(#mOptions), + returnValue: _FakeMacOsOptions_5( + this, + Invocation.getter(#mOptions), + ), + ) as _i2.MacOsOptions); @override void registerListener({ required String? key, required _i5.ValueChanged? listener, - }) => super.noSuchMethod( - Invocation.method(#registerListener, [], {#key: key, #listener: listener}), - returnValueForMissingStub: null, - ); + }) => + super.noSuchMethod( + Invocation.method( + #registerListener, + [], + { + #key: key, + #listener: listener, + }, + ), + returnValueForMissingStub: null, + ); @override void unregisterListener({ required String? key, required _i5.ValueChanged? listener, - }) => super.noSuchMethod( - Invocation.method(#unregisterListener, [], { - #key: key, - #listener: listener, - }), - returnValueForMissingStub: null, - ); + }) => + super.noSuchMethod( + Invocation.method( + #unregisterListener, + [], + { + #key: key, + #listener: listener, + }, + ), + returnValueForMissingStub: null, + ); @override void unregisterAllListenersForKey({required String? key}) => super.noSuchMethod( - Invocation.method(#unregisterAllListenersForKey, [], {#key: key}), + Invocation.method( + #unregisterAllListenersForKey, + [], + {#key: key}, + ), returnValueForMissingStub: null, ); @override void unregisterAllListeners() => super.noSuchMethod( - Invocation.method(#unregisterAllListeners, []), - returnValueForMissingStub: null, - ); + Invocation.method( + #unregisterAllListeners, + [], + ), + returnValueForMissingStub: null, + ); @override _i4.Future write({ @@ -297,20 +396,23 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#write, [], { - #key: key, - #value: value, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #write, + [], + { + #key: key, + #value: value, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override _i4.Future read({ @@ -323,18 +425,21 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#read, [], { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #read, + [], + { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); @override _i4.Future containsKey({ @@ -347,18 +452,21 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#containsKey, [], { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); + Invocation.method( + #containsKey, + [], + { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override _i4.Future delete({ @@ -371,19 +479,22 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#delete, [], { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #delete, + [], + { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override _i4.Future> readAll({ @@ -395,19 +506,20 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#readAll, [], { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future>.value( - {}, - ), - ) - as _i4.Future>); + Invocation.method( + #readAll, + [], + { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future>.value({}), + ) as _i4.Future>); @override _i4.Future deleteAll({ @@ -419,24 +531,28 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#deleteAll, [], { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); - - @override - _i4.Future isCupertinoProtectedDataAvailable() => - (super.noSuchMethod( - Invocation.method(#isCupertinoProtectedDataAvailable, []), - returnValue: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #deleteAll, + [], + { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future isCupertinoProtectedDataAvailable() => (super.noSuchMethod( + Invocation.method( + #isCupertinoProtectedDataAvailable, + [], + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); } diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart new file mode 100644 index 0000000..344d2cb --- /dev/null +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart @@ -0,0 +1,72 @@ +import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart'; +import 'package:fitness_app/data/auth/data_source/remote/auth_remote_data_source_impl.dart'; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; +import 'package:fitness_app/data/auth/models/user_dto.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'auth_remote_data_source_impl_test.mocks.dart'; + +@GenerateMocks([AuthRetrofitClient]) +void main() { + late AuthRemoteDataSourceImpl authRemoteDataSourceImpl; + late MockAuthRetrofitClient mockAuthRetrofitClient; + + setUp(() { + mockAuthRetrofitClient = MockAuthRetrofitClient(); + authRemoteDataSourceImpl = AuthRemoteDataSourceImpl(mockAuthRetrofitClient); + }); + + group('Auth Remote Data Source Test', () { + group('getProfileData', () { + test( + 'should return UserDataResponseDto when API call is successful', + () async { + // Arrange + final user = UserDto( + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + gender: 'male', + age: 30, + weight: 70, + height: 175, + activityLevel: 'level1', + goal: 'Gain More Flexible', + photo: 'url', + ); + final expectedResponse = UserDataResponseDto( + message: 'Success', + user: user, + ); + when( + mockAuthRetrofitClient.getProfileData(), + ).thenAnswer((_) async => expectedResponse); + + // Act + final result = await authRemoteDataSourceImpl.getProfileData(); + + // Assert + verify(mockAuthRetrofitClient.getProfileData()).called(1); + expect(result, isA()); + }, + ); + + test('should throw exception when API fails', () { + // Arrange + final exception = Exception('API error'); + when( + mockAuthRetrofitClient.getProfileData(), + ).thenAnswer((_) async => throw exception); + + // Act + final result = authRemoteDataSourceImpl.getProfileData(); + + // Assert + verify(mockAuthRetrofitClient.getProfileData()).called(1); + expect(result, throwsA(isA())); + }); + }); + }); +} diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart new file mode 100644 index 0000000..e36d1e9 --- /dev/null +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart @@ -0,0 +1,62 @@ +// Mocks generated by Mockito 5.4.5 from annotations +// in fitness_app/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i3; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeUserDataResponseDto_0 extends _i1.SmartFake + implements _i2.UserDataResponseDto { + _FakeUserDataResponseDto_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [AuthRetrofitClient]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAuthRetrofitClient extends _i1.Mock + implements _i3.AuthRetrofitClient { + MockAuthRetrofitClient() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( + Invocation.method( + #getProfileData, + [], + ), + returnValue: _i4.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( + this, + Invocation.method( + #getProfileData, + [], + ), + )), + ) as _i4.Future<_i2.UserDataResponseDto>); +} diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.dart b/test/data/auth/repo_impl/auth_repo_impl_test.dart new file mode 100644 index 0000000..a992251 --- /dev/null +++ b/test/data/auth/repo_impl/auth_repo_impl_test.dart @@ -0,0 +1,95 @@ +import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart'; +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart'; +import 'package:fitness_app/data/auth/models/user_dto.dart'; +import 'package:fitness_app/data/auth/repo_impl/auth_repo_impl.dart'; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; +import 'package:fitness_app/domain/auth/entity/user_entity.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'auth_repo_impl_test.mocks.dart'; + +@GenerateMocks([ApiManager, AuthRemoteDataSource]) +void main() { + late AuthRepoImpl authRepoImpl; + late MockApiManager mockApiManager; + late MockAuthRemoteDataSource mockAuthRemoteDataSource; + + setUp(() { + mockApiManager = MockApiManager(); + mockAuthRemoteDataSource = MockAuthRemoteDataSource(); + authRepoImpl = AuthRepoImpl(mockApiManager, mockAuthRemoteDataSource); + }); + + group('AuthRepoImpl Tests', () { + group('getProfileData', () { + test('returns SuccessResult on success', () async { + // Prepare DTO and expected entity + final userDto = UserDto( + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + gender: 'male', + age: 30, + weight: 70, + height: 175, + activityLevel: 'level1', + goal: 'Gain More Flexible', + photo: 'url', + ); + final userResponseDto = UserDataResponseDto( + message: 'OK', + user: userDto, + ); + + final expectedEntity = userDto.toEntity(); + + // Register dummy for generics + provideDummy>( + SuccessResult(expectedEntity), + ); + + // Stub remote data source + when( + mockAuthRemoteDataSource.getProfileData(), + ).thenAnswer((_) async => userResponseDto); + // Stub API manager + when( + mockApiManager.execute(any), + ).thenAnswer((_) async => SuccessResult(expectedEntity)); + + // Act + final result = await authRepoImpl.getProfileData(); + + // Assert + verify(mockApiManager.execute(any)).called(1); + expect(result, isA>()); + }); + + test('returns FailureResult on failure', () async { + final error = Exception('Network error'); + // Register dummy for generics + provideDummy>(FailureResult(error)); + + // Stub remote data source + final userDto = UserDataResponseDto(message: 'OK', user: null); + when( + mockAuthRemoteDataSource.getProfileData(), + ).thenAnswer((_) async => userDto); + // Stub API manager to return failure + when( + mockApiManager.execute(any), + ).thenAnswer((_) async => FailureResult(error)); + + // Act + final result = await authRepoImpl.getProfileData(); + + // Assert + verify(mockApiManager.execute(any)).called(1); + expect(result, isA>()); + }); + }); + }); +} diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart new file mode 100644 index 0000000..718e102 --- /dev/null +++ b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart @@ -0,0 +1,94 @@ +// Mocks generated by Mockito 5.4.5 from annotations +// in fitness_app/test/data/auth/repo_impl/auth_repo_impl_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; + +import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart' + as _i3; +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart' + as _i5; +import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart' + as _i7; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i6; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeUserDataResponseDto_0 extends _i1.SmartFake + implements _i2.UserDataResponseDto { + _FakeUserDataResponseDto_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [ApiManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockApiManager extends _i1.Mock implements _i3.ApiManager { + MockApiManager() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i5.Result> execute(_i4.Future Function()? apiCall) => + (super.noSuchMethod( + Invocation.method( + #execute, + [apiCall], + ), + returnValue: + _i4.Future<_i5.Result>.value(_i6.dummyValue<_i5.Result>( + this, + Invocation.method( + #execute, + [apiCall], + ), + )), + ) as _i4.Future<_i5.Result>); +} + +/// A class which mocks [AuthRemoteDataSource]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAuthRemoteDataSource extends _i1.Mock + implements _i7.AuthRemoteDataSource { + MockAuthRemoteDataSource() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( + Invocation.method( + #getProfileData, + [], + ), + returnValue: _i4.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( + this, + Invocation.method( + #getProfileData, + [], + ), + )), + ) as _i4.Future<_i2.UserDataResponseDto>); +} diff --git a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart index e9865dd..6258fc1 100644 --- a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart +++ b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart @@ -35,94 +35,124 @@ class MockMainLayoutCubit extends _i1.Mock implements _i2.MainLayoutCubit { } @override - _i2.MainLayoutTabs get currentTab => - (super.noSuchMethod( - Invocation.getter(#currentTab), - returnValue: _i2.MainLayoutTabs.home, - ) - as _i2.MainLayoutTabs); + _i2.MainLayoutTabs get currentTab => (super.noSuchMethod( + Invocation.getter(#currentTab), + returnValue: _i2.MainLayoutTabs.home, + ) as _i2.MainLayoutTabs); @override set currentTab(_i2.MainLayoutTabs? _currentTab) => super.noSuchMethod( - Invocation.setter(#currentTab, _currentTab), - returnValueForMissingStub: null, - ); + Invocation.setter( + #currentTab, + _currentTab, + ), + returnValueForMissingStub: null, + ); @override Map<_i2.MainLayoutTabs, _i3.Widget Function()> get tabs => (super.noSuchMethod( - Invocation.getter(#tabs), - returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, - ) - as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); + Invocation.getter(#tabs), + returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, + ) as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); @override set tabs(Map<_i2.MainLayoutTabs, _i3.Widget Function()>? _tabs) => super.noSuchMethod( - Invocation.setter(#tabs, _tabs), + Invocation.setter( + #tabs, + _tabs, + ), returnValueForMissingStub: null, ); @override - _i2.MainLayoutState get state => - (super.noSuchMethod( - Invocation.getter(#state), - returnValue: _i4.dummyValue<_i2.MainLayoutState>( - this, - Invocation.getter(#state), - ), - ) - as _i2.MainLayoutState); + _i2.MainLayoutState get state => (super.noSuchMethod( + Invocation.getter(#state), + returnValue: _i4.dummyValue<_i2.MainLayoutState>( + this, + Invocation.getter(#state), + ), + ) as _i2.MainLayoutState); @override - _i5.Stream<_i2.MainLayoutState> get stream => - (super.noSuchMethod( - Invocation.getter(#stream), - returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), - ) - as _i5.Stream<_i2.MainLayoutState>); + _i5.Stream<_i2.MainLayoutState> get stream => (super.noSuchMethod( + Invocation.getter(#stream), + returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), + ) as _i5.Stream<_i2.MainLayoutState>); @override - bool get isClosed => - (super.noSuchMethod(Invocation.getter(#isClosed), returnValue: false) - as bool); + bool get isClosed => (super.noSuchMethod( + Invocation.getter(#isClosed), + returnValue: false, + ) as bool); @override void doIntent(_i2.MainLayoutActions? action) => super.noSuchMethod( - Invocation.method(#doIntent, [action]), - returnValueForMissingStub: null, - ); + Invocation.method( + #doIntent, + [action], + ), + returnValueForMissingStub: null, + ); @override void emit(_i2.MainLayoutState? state) => super.noSuchMethod( - Invocation.method(#emit, [state]), - returnValueForMissingStub: null, - ); + Invocation.method( + #emit, + [state], + ), + returnValueForMissingStub: null, + ); @override void onChange(_i6.Change<_i2.MainLayoutState>? change) => super.noSuchMethod( - Invocation.method(#onChange, [change]), - returnValueForMissingStub: null, - ); + Invocation.method( + #onChange, + [change], + ), + returnValueForMissingStub: null, + ); @override - void addError(Object? error, [StackTrace? stackTrace]) => super.noSuchMethod( - Invocation.method(#addError, [error, stackTrace]), - returnValueForMissingStub: null, - ); + void addError( + Object? error, [ + StackTrace? stackTrace, + ]) => + super.noSuchMethod( + Invocation.method( + #addError, + [ + error, + stackTrace, + ], + ), + returnValueForMissingStub: null, + ); @override - void onError(Object? error, StackTrace? stackTrace) => super.noSuchMethod( - Invocation.method(#onError, [error, stackTrace]), - returnValueForMissingStub: null, - ); + void onError( + Object? error, + StackTrace? stackTrace, + ) => + super.noSuchMethod( + Invocation.method( + #onError, + [ + error, + stackTrace, + ], + ), + returnValueForMissingStub: null, + ); @override - _i5.Future close() => - (super.noSuchMethod( - Invocation.method(#close, []), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) - as _i5.Future); + _i5.Future close() => (super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); } From 1addad3bf6d5bac439afb7e1e38c46d39ee9c3b0 Mon Sep 17 00:00:00 2001 From: Eslam Date: Wed, 2 Jul 2025 05:30:36 +0300 Subject: [PATCH 04/12] feat(auth): Add unit tests for GetProfileDataUseCase --- .../get_profile_data_use_case_test.dart | 68 +++++++++++++++++++ .../get_profile_data_use_case_test.mocks.dart | 53 +++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 test/domain/auth/use_case/get_profile_data_use_case_test.dart create mode 100644 test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart diff --git a/test/domain/auth/use_case/get_profile_data_use_case_test.dart b/test/domain/auth/use_case/get_profile_data_use_case_test.dart new file mode 100644 index 0000000..dd82cd6 --- /dev/null +++ b/test/domain/auth/use_case/get_profile_data_use_case_test.dart @@ -0,0 +1,68 @@ +import 'package:fitness_app/domain/auth/repo/auth_repo.dart'; +import 'package:fitness_app/domain/auth/use_case/get_profile_data_use_case.dart'; +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/domain/auth/entity/user_entity.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; + +import 'get_profile_data_use_case_test.mocks.dart'; + +@GenerateMocks([AuthRepo]) +void main() { + late MockAuthRepo mockAuthRepo; + late GetProfileDataUseCase getProfileDataUseCase; + + setUp(() { + mockAuthRepo = MockAuthRepo(); + getProfileDataUseCase = GetProfileDataUseCase(mockAuthRepo); + }); + + group('GetProfileDataUseCase', () { + test( + 'returns SuccessResult when repository succeeds', + () async { + // Arrange + final user = UserEntity( + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + gender: 'male', + age: 30, + weight: 70, + height: 175, + activityLevel: 'level1', + goal: 'Gain More Flexible', + photo: 'url', + ); + provideDummy>(SuccessResult(user)); + when( + mockAuthRepo.getProfileData(), + ).thenAnswer((_) async => SuccessResult(user)); + + // Act + final result = await getProfileDataUseCase.call(); + + // Assert + verify(mockAuthRepo.getProfileData()).called(1); + expect(result, isA>()); + }, + ); + + test('returns FailureResult when repository fails', () async { + // Arrange + final exception = Exception('Repo error'); + provideDummy>(FailureResult(exception)); + when( + mockAuthRepo.getProfileData(), + ).thenAnswer((_) async => FailureResult(exception)); + + // Act + final result = await getProfileDataUseCase.call(); + + // Assert + verify(mockAuthRepo.getProfileData()).called(1); + expect(result, isA>()); + }); + }); +} diff --git a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart new file mode 100644 index 0000000..bb47948 --- /dev/null +++ b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart @@ -0,0 +1,53 @@ +// Mocks generated by Mockito 5.4.5 from annotations +// in fitness_app/test/domain/auth/use_case/get_profile_data_use_case_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i3; + +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart' + as _i4; +import 'package:fitness_app/domain/auth/entity/user_entity.dart' as _i5; +import 'package:fitness_app/domain/auth/repo/auth_repo.dart' as _i2; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i6; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +/// A class which mocks [AuthRepo]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAuthRepo extends _i1.Mock implements _i2.AuthRepo { + MockAuthRepo() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i4.Result<_i5.UserEntity>> getProfileData() => + (super.noSuchMethod( + Invocation.method( + #getProfileData, + [], + ), + returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( + _i6.dummyValue<_i4.Result<_i5.UserEntity>>( + this, + Invocation.method( + #getProfileData, + [], + ), + )), + ) as _i3.Future<_i4.Result<_i5.UserEntity>>); +} From 7138022777a32514b7ce74a4d7a7c012fef639a6 Mon Sep 17 00:00:00 2001 From: Eslam Date: Wed, 2 Jul 2025 05:32:40 +0300 Subject: [PATCH 05/12] format(auth): Formated files so no conflicts happen because of it --- lib/core/utils/di/di.config.dart | 49 +- lib/data/auth/api/auth_retrofit_client.g.dart | 37 +- .../auth/models/user_data_response_dto.g.dart | 7 +- lib/data/auth/models/user_dto.g.dart | 52 +- .../inital_route_function_test.mocks.dart | 620 +++++++----------- ...th_remote_data_source_impl_test.mocks.dart | 34 +- .../repo_impl/auth_repo_impl_test.mocks.dart | 56 +- .../get_profile_data_use_case_test.mocks.dart | 22 +- .../view/main_layout_screen_test.mocks.dart | 142 ++-- 9 files changed, 420 insertions(+), 599 deletions(-) diff --git a/lib/core/utils/di/di.config.dart b/lib/core/utils/di/di.config.dart index dd7406e..01904bf 100644 --- a/lib/core/utils/di/di.config.dart +++ b/lib/core/utils/di/di.config.dart @@ -39,16 +39,12 @@ import '../shared_preference_module.dart' as _i60; import '../validator/validator.dart' as _i468; extension GetItInjectableX on _i174.GetIt { -// initializes the registration of main-scope dependencies inside of GetIt + // initializes the registration of main-scope dependencies inside of GetIt Future<_i174.GetIt> init({ String? environment, _i526.EnvironmentFilter? environmentFilter, }) async { - final gh = _i526.GetItHelper( - this, - environment, - environmentFilter, - ); + final gh = _i526.GetItHelper(this, environment, environmentFilter); final sharedPreferenceModule = _$SharedPreferenceModule(); final secureStorageModule = _$SecureStorageModule(); final loggerModule = _$LoggerModule(); @@ -60,30 +56,41 @@ extension GetItInjectableX on _i174.GetIt { gh.singleton<_i28.ApiManager>(() => _i28.ApiManager()); gh.singleton<_i393.MainLayoutCubit>(() => _i393.MainLayoutCubit()); gh.lazySingleton<_i558.FlutterSecureStorage>( - () => secureStorageModule.storage); + () => secureStorageModule.storage, + ); gh.lazySingleton<_i974.Logger>(() => loggerModule.loggerProvider); gh.lazySingleton<_i974.PrettyPrinter>(() => loggerModule.prettyPrinter); gh.lazySingleton<_i468.Validator>(() => _i468.Validator()); gh.factory<_i1063.AuthLocalDataSource>( - () => _i757.AuthLocalDataSourceImpl()); + () => _i757.AuthLocalDataSourceImpl(), + ); gh.singleton<_i649.BlocObserverService>( - () => _i649.BlocObserverService(gh<_i974.Logger>())); - gh.factory<_i420.RouteInitializer>(() => _i420.RouteInitializer( - flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), - sharedPreferences: gh<_i460.SharedPreferences>(), - )); + () => _i649.BlocObserverService(gh<_i974.Logger>()), + ); + gh.factory<_i420.RouteInitializer>( + () => _i420.RouteInitializer( + flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), + sharedPreferences: gh<_i460.SharedPreferences>(), + ), + ); gh.lazySingleton<_i361.Dio>( - () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>())); + () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>()), + ); gh.factory<_i1064.AuthRetrofitClient>( - () => _i1064.AuthRetrofitClient(gh<_i361.Dio>())); + () => _i1064.AuthRetrofitClient(gh<_i361.Dio>()), + ); gh.factory<_i774.AuthRemoteDataSource>( - () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>())); - gh.factory<_i1047.AuthRepo>(() => _i15.AuthRepoImpl( - gh<_i28.ApiManager>(), - gh<_i774.AuthRemoteDataSource>(), - )); + () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>()), + ); + gh.factory<_i1047.AuthRepo>( + () => _i15.AuthRepoImpl( + gh<_i28.ApiManager>(), + gh<_i774.AuthRemoteDataSource>(), + ), + ); gh.factory<_i336.GetProfileDataUseCase>( - () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>())); + () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>()), + ); return this; } } diff --git a/lib/data/auth/api/auth_retrofit_client.g.dart b/lib/data/auth/api/auth_retrofit_client.g.dart index 3860d59..ee0b7cb 100644 --- a/lib/data/auth/api/auth_retrofit_client.g.dart +++ b/lib/data/auth/api/auth_retrofit_client.g.dart @@ -9,11 +9,7 @@ part of 'auth_retrofit_client.dart'; // ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations class _AuthRetrofitClient implements AuthRetrofitClient { - _AuthRetrofitClient( - this._dio, { - this.baseUrl, - this.errorLogger, - }) { + _AuthRetrofitClient(this._dio, {this.baseUrl, this.errorLogger}) { baseUrl ??= 'https://fitness.elevateegy.com/api/v1/'; } @@ -29,22 +25,16 @@ class _AuthRetrofitClient implements AuthRetrofitClient { final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType(Options( - method: 'GET', - headers: _headers, - extra: _extra, - ) - .compose( - _dio.options, - 'auth/profile-data', - queryParameters: queryParameters, - data: _data, - ) - .copyWith( - baseUrl: _combineBaseUrls( - _dio.options.baseUrl, - baseUrl, - ))); + final _options = _setStreamType( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'auth/profile-data', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); final _result = await _dio.fetch>(_options); late UserDataResponseDto _value; try { @@ -69,10 +59,7 @@ class _AuthRetrofitClient implements AuthRetrofitClient { return requestOptions; } - String _combineBaseUrls( - String dioBaseUrl, - String? baseUrl, - ) { + String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { if (baseUrl == null || baseUrl.trim().isEmpty) { return dioBaseUrl; } diff --git a/lib/data/auth/models/user_data_response_dto.g.dart b/lib/data/auth/models/user_data_response_dto.g.dart index d03115b..ded4a1d 100644 --- a/lib/data/auth/models/user_data_response_dto.g.dart +++ b/lib/data/auth/models/user_data_response_dto.g.dart @@ -15,8 +15,5 @@ UserDataResponseDto _$UserDataResponseDtoFromJson(Map json) => ); Map _$UserDataResponseDtoToJson( - UserDataResponseDto instance) => - { - 'message': instance.message, - 'user': instance.user, - }; + UserDataResponseDto instance, +) => {'message': instance.message, 'user': instance.user}; diff --git a/lib/data/auth/models/user_dto.g.dart b/lib/data/auth/models/user_dto.g.dart index 2797dee..49c97ec 100644 --- a/lib/data/auth/models/user_dto.g.dart +++ b/lib/data/auth/models/user_dto.g.dart @@ -7,31 +7,31 @@ part of 'user_dto.dart'; // ************************************************************************** UserDto _$UserDtoFromJson(Map json) => UserDto( - id: json['_id'] as String?, - firstName: json['firstName'] as String?, - lastName: json['lastName'] as String?, - email: json['email'] as String?, - gender: json['gender'] as String?, - age: (json['age'] as num?)?.toInt(), - weight: (json['weight'] as num?)?.toInt(), - height: (json['height'] as num?)?.toInt(), - activityLevel: json['activityLevel'] as String?, - goal: json['goal'] as String?, - photo: json['photo'] as String?, - createdAt: json['createdAt'] as String?, - ); + id: json['_id'] as String?, + firstName: json['firstName'] as String?, + lastName: json['lastName'] as String?, + email: json['email'] as String?, + gender: json['gender'] as String?, + age: (json['age'] as num?)?.toInt(), + weight: (json['weight'] as num?)?.toInt(), + height: (json['height'] as num?)?.toInt(), + activityLevel: json['activityLevel'] as String?, + goal: json['goal'] as String?, + photo: json['photo'] as String?, + createdAt: json['createdAt'] as String?, +); Map _$UserDtoToJson(UserDto instance) => { - '_id': instance.id, - 'firstName': instance.firstName, - 'lastName': instance.lastName, - 'email': instance.email, - 'gender': instance.gender, - 'age': instance.age, - 'weight': instance.weight, - 'height': instance.height, - 'activityLevel': instance.activityLevel, - 'goal': instance.goal, - 'photo': instance.photo, - 'createdAt': instance.createdAt, - }; + '_id': instance.id, + 'firstName': instance.firstName, + 'lastName': instance.lastName, + 'email': instance.email, + 'gender': instance.gender, + 'age': instance.age, + 'weight': instance.weight, + 'height': instance.height, + 'activityLevel': instance.activityLevel, + 'goal': instance.goal, + 'photo': instance.photo, + 'createdAt': instance.createdAt, +}; diff --git a/test/core/functions/inital_route_function_test.mocks.dart b/test/core/functions/inital_route_function_test.mocks.dart index 8351c57..85f461d 100644 --- a/test/core/functions/inital_route_function_test.mocks.dart +++ b/test/core/functions/inital_route_function_test.mocks.dart @@ -25,65 +25,35 @@ import 'package:shared_preferences/src/shared_preferences_legacy.dart' as _i3; // ignore_for_file: subtype_of_sealed_class class _FakeIOSOptions_0 extends _i1.SmartFake implements _i2.IOSOptions { - _FakeIOSOptions_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeIOSOptions_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeAndroidOptions_1 extends _i1.SmartFake implements _i2.AndroidOptions { - _FakeAndroidOptions_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeAndroidOptions_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeLinuxOptions_2 extends _i1.SmartFake implements _i2.LinuxOptions { - _FakeLinuxOptions_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeLinuxOptions_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeWindowsOptions_3 extends _i1.SmartFake implements _i2.WindowsOptions { - _FakeWindowsOptions_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeWindowsOptions_3(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeWebOptions_4 extends _i1.SmartFake implements _i2.WebOptions { - _FakeWebOptions_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeWebOptions_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeMacOsOptions_5 extends _i1.SmartFake implements _i2.MacOsOptions { - _FakeMacOsOptions_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeMacOsOptions_5(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [SharedPreferences]. @@ -95,176 +65,118 @@ class MockSharedPreferences extends _i1.Mock implements _i3.SharedPreferences { } @override - Set getKeys() => (super.noSuchMethod( - Invocation.method( - #getKeys, - [], - ), - returnValue: {}, - ) as Set); + Set getKeys() => + (super.noSuchMethod( + Invocation.method(#getKeys, []), + returnValue: {}, + ) + as Set); @override - Object? get(String? key) => (super.noSuchMethod(Invocation.method( - #get, - [key], - )) as Object?); + Object? get(String? key) => + (super.noSuchMethod(Invocation.method(#get, [key])) as Object?); @override - bool? getBool(String? key) => (super.noSuchMethod(Invocation.method( - #getBool, - [key], - )) as bool?); + bool? getBool(String? key) => + (super.noSuchMethod(Invocation.method(#getBool, [key])) as bool?); @override - int? getInt(String? key) => (super.noSuchMethod(Invocation.method( - #getInt, - [key], - )) as int?); + int? getInt(String? key) => + (super.noSuchMethod(Invocation.method(#getInt, [key])) as int?); @override - double? getDouble(String? key) => (super.noSuchMethod(Invocation.method( - #getDouble, - [key], - )) as double?); + double? getDouble(String? key) => + (super.noSuchMethod(Invocation.method(#getDouble, [key])) as double?); @override - String? getString(String? key) => (super.noSuchMethod(Invocation.method( - #getString, - [key], - )) as String?); + String? getString(String? key) => + (super.noSuchMethod(Invocation.method(#getString, [key])) as String?); @override - bool containsKey(String? key) => (super.noSuchMethod( - Invocation.method( - #containsKey, - [key], - ), - returnValue: false, - ) as bool); + bool containsKey(String? key) => + (super.noSuchMethod( + Invocation.method(#containsKey, [key]), + returnValue: false, + ) + as bool); @override List? getStringList(String? key) => - (super.noSuchMethod(Invocation.method( - #getStringList, - [key], - )) as List?); + (super.noSuchMethod(Invocation.method(#getStringList, [key])) + as List?); + + @override + _i4.Future setBool(String? key, bool? value) => + (super.noSuchMethod( + Invocation.method(#setBool, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future setInt(String? key, int? value) => + (super.noSuchMethod( + Invocation.method(#setInt, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future setDouble(String? key, double? value) => + (super.noSuchMethod( + Invocation.method(#setDouble, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); @override - _i4.Future setBool( - String? key, - bool? value, - ) => + _i4.Future setString(String? key, String? value) => (super.noSuchMethod( - Invocation.method( - #setBool, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setInt( - String? key, - int? value, - ) => + Invocation.method(#setString, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future setStringList(String? key, List? value) => (super.noSuchMethod( - Invocation.method( - #setInt, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setDouble( - String? key, - double? value, - ) => + Invocation.method(#setStringList, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future remove(String? key) => (super.noSuchMethod( - Invocation.method( - #setDouble, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setString( - String? key, - String? value, - ) => + Invocation.method(#remove, [key]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future commit() => (super.noSuchMethod( - Invocation.method( - #setString, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setStringList( - String? key, - List? value, - ) => + Invocation.method(#commit, []), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future clear() => (super.noSuchMethod( - Invocation.method( - #setStringList, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future remove(String? key) => (super.noSuchMethod( - Invocation.method( - #remove, - [key], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future commit() => (super.noSuchMethod( - Invocation.method( - #commit, - [], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future clear() => (super.noSuchMethod( - Invocation.method( - #clear, - [], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future reload() => (super.noSuchMethod( - Invocation.method( - #reload, - [], - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#clear, []), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future reload() => + (super.noSuchMethod( + Invocation.method(#reload, []), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); } /// A class which mocks [FlutterSecureStorage]. @@ -277,112 +189,101 @@ class MockFlutterSecureStorage extends _i1.Mock } @override - _i2.IOSOptions get iOptions => (super.noSuchMethod( - Invocation.getter(#iOptions), - returnValue: _FakeIOSOptions_0( - this, - Invocation.getter(#iOptions), - ), - ) as _i2.IOSOptions); + _i2.IOSOptions get iOptions => + (super.noSuchMethod( + Invocation.getter(#iOptions), + returnValue: _FakeIOSOptions_0(this, Invocation.getter(#iOptions)), + ) + as _i2.IOSOptions); @override - _i2.AndroidOptions get aOptions => (super.noSuchMethod( - Invocation.getter(#aOptions), - returnValue: _FakeAndroidOptions_1( - this, - Invocation.getter(#aOptions), - ), - ) as _i2.AndroidOptions); + _i2.AndroidOptions get aOptions => + (super.noSuchMethod( + Invocation.getter(#aOptions), + returnValue: _FakeAndroidOptions_1( + this, + Invocation.getter(#aOptions), + ), + ) + as _i2.AndroidOptions); @override - _i2.LinuxOptions get lOptions => (super.noSuchMethod( - Invocation.getter(#lOptions), - returnValue: _FakeLinuxOptions_2( - this, - Invocation.getter(#lOptions), - ), - ) as _i2.LinuxOptions); + _i2.LinuxOptions get lOptions => + (super.noSuchMethod( + Invocation.getter(#lOptions), + returnValue: _FakeLinuxOptions_2( + this, + Invocation.getter(#lOptions), + ), + ) + as _i2.LinuxOptions); @override - _i2.WindowsOptions get wOptions => (super.noSuchMethod( - Invocation.getter(#wOptions), - returnValue: _FakeWindowsOptions_3( - this, - Invocation.getter(#wOptions), - ), - ) as _i2.WindowsOptions); + _i2.WindowsOptions get wOptions => + (super.noSuchMethod( + Invocation.getter(#wOptions), + returnValue: _FakeWindowsOptions_3( + this, + Invocation.getter(#wOptions), + ), + ) + as _i2.WindowsOptions); @override - _i2.WebOptions get webOptions => (super.noSuchMethod( - Invocation.getter(#webOptions), - returnValue: _FakeWebOptions_4( - this, - Invocation.getter(#webOptions), - ), - ) as _i2.WebOptions); + _i2.WebOptions get webOptions => + (super.noSuchMethod( + Invocation.getter(#webOptions), + returnValue: _FakeWebOptions_4( + this, + Invocation.getter(#webOptions), + ), + ) + as _i2.WebOptions); @override - _i2.MacOsOptions get mOptions => (super.noSuchMethod( - Invocation.getter(#mOptions), - returnValue: _FakeMacOsOptions_5( - this, - Invocation.getter(#mOptions), - ), - ) as _i2.MacOsOptions); + _i2.MacOsOptions get mOptions => + (super.noSuchMethod( + Invocation.getter(#mOptions), + returnValue: _FakeMacOsOptions_5( + this, + Invocation.getter(#mOptions), + ), + ) + as _i2.MacOsOptions); @override void registerListener({ required String? key, required _i5.ValueChanged? listener, - }) => - super.noSuchMethod( - Invocation.method( - #registerListener, - [], - { - #key: key, - #listener: listener, - }, - ), - returnValueForMissingStub: null, - ); + }) => super.noSuchMethod( + Invocation.method(#registerListener, [], {#key: key, #listener: listener}), + returnValueForMissingStub: null, + ); @override void unregisterListener({ required String? key, required _i5.ValueChanged? listener, - }) => - super.noSuchMethod( - Invocation.method( - #unregisterListener, - [], - { - #key: key, - #listener: listener, - }, - ), - returnValueForMissingStub: null, - ); + }) => super.noSuchMethod( + Invocation.method(#unregisterListener, [], { + #key: key, + #listener: listener, + }), + returnValueForMissingStub: null, + ); @override void unregisterAllListenersForKey({required String? key}) => super.noSuchMethod( - Invocation.method( - #unregisterAllListenersForKey, - [], - {#key: key}, - ), + Invocation.method(#unregisterAllListenersForKey, [], {#key: key}), returnValueForMissingStub: null, ); @override void unregisterAllListeners() => super.noSuchMethod( - Invocation.method( - #unregisterAllListeners, - [], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#unregisterAllListeners, []), + returnValueForMissingStub: null, + ); @override _i4.Future write({ @@ -396,23 +297,20 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #write, - [], - { - #key: key, - #value: value, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#write, [], { + #key: key, + #value: value, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); @override _i4.Future read({ @@ -425,21 +323,18 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #read, - [], - { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#read, [], { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + ) + as _i4.Future); @override _i4.Future containsKey({ @@ -452,21 +347,18 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #containsKey, - [], - { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); + Invocation.method(#containsKey, [], { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); @override _i4.Future delete({ @@ -479,22 +371,19 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #delete, - [], - { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#delete, [], { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); @override _i4.Future> readAll({ @@ -506,20 +395,19 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #readAll, - [], - { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future>.value({}), - ) as _i4.Future>); + Invocation.method(#readAll, [], { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future>.value( + {}, + ), + ) + as _i4.Future>); @override _i4.Future deleteAll({ @@ -531,28 +419,24 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #deleteAll, - [], - { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); - - @override - _i4.Future isCupertinoProtectedDataAvailable() => (super.noSuchMethod( - Invocation.method( - #isCupertinoProtectedDataAvailable, - [], - ), - returnValue: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#deleteAll, [], { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); + + @override + _i4.Future isCupertinoProtectedDataAvailable() => + (super.noSuchMethod( + Invocation.method(#isCupertinoProtectedDataAvailable, []), + returnValue: _i4.Future.value(), + ) + as _i4.Future); } diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart index e36d1e9..091a6e3 100644 --- a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart @@ -26,13 +26,8 @@ import 'package:mockito/mockito.dart' as _i1; class _FakeUserDataResponseDto_0 extends _i1.SmartFake implements _i2.UserDataResponseDto { - _FakeUserDataResponseDto_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserDataResponseDto_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [AuthRetrofitClient]. @@ -45,18 +40,15 @@ class MockAuthRetrofitClient extends _i1.Mock } @override - _i4.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( - Invocation.method( - #getProfileData, - [], - ), - returnValue: _i4.Future<_i2.UserDataResponseDto>.value( - _FakeUserDataResponseDto_0( - this, - Invocation.method( - #getProfileData, - [], - ), - )), - ) as _i4.Future<_i2.UserDataResponseDto>); + _i4.Future<_i2.UserDataResponseDto> getProfileData() => + (super.noSuchMethod( + Invocation.method(#getProfileData, []), + returnValue: _i4.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i4.Future<_i2.UserDataResponseDto>); } diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart index 718e102..1a52d5e 100644 --- a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart +++ b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart @@ -32,13 +32,8 @@ import 'package:mockito/src/dummies.dart' as _i6; class _FakeUserDataResponseDto_0 extends _i1.SmartFake implements _i2.UserDataResponseDto { - _FakeUserDataResponseDto_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserDataResponseDto_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [ApiManager]. @@ -52,19 +47,15 @@ class MockApiManager extends _i1.Mock implements _i3.ApiManager { @override _i4.Future<_i5.Result> execute(_i4.Future Function()? apiCall) => (super.noSuchMethod( - Invocation.method( - #execute, - [apiCall], - ), - returnValue: - _i4.Future<_i5.Result>.value(_i6.dummyValue<_i5.Result>( - this, - Invocation.method( - #execute, - [apiCall], - ), - )), - ) as _i4.Future<_i5.Result>); + Invocation.method(#execute, [apiCall]), + returnValue: _i4.Future<_i5.Result>.value( + _i6.dummyValue<_i5.Result>( + this, + Invocation.method(#execute, [apiCall]), + ), + ), + ) + as _i4.Future<_i5.Result>); } /// A class which mocks [AuthRemoteDataSource]. @@ -77,18 +68,15 @@ class MockAuthRemoteDataSource extends _i1.Mock } @override - _i4.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( - Invocation.method( - #getProfileData, - [], - ), - returnValue: _i4.Future<_i2.UserDataResponseDto>.value( - _FakeUserDataResponseDto_0( - this, - Invocation.method( - #getProfileData, - [], - ), - )), - ) as _i4.Future<_i2.UserDataResponseDto>); + _i4.Future<_i2.UserDataResponseDto> getProfileData() => + (super.noSuchMethod( + Invocation.method(#getProfileData, []), + returnValue: _i4.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i4.Future<_i2.UserDataResponseDto>); } diff --git a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart index bb47948..4dc62d4 100644 --- a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart +++ b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart @@ -37,17 +37,13 @@ class MockAuthRepo extends _i1.Mock implements _i2.AuthRepo { @override _i3.Future<_i4.Result<_i5.UserEntity>> getProfileData() => (super.noSuchMethod( - Invocation.method( - #getProfileData, - [], - ), - returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( - _i6.dummyValue<_i4.Result<_i5.UserEntity>>( - this, - Invocation.method( - #getProfileData, - [], - ), - )), - ) as _i3.Future<_i4.Result<_i5.UserEntity>>); + Invocation.method(#getProfileData, []), + returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( + _i6.dummyValue<_i4.Result<_i5.UserEntity>>( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i3.Future<_i4.Result<_i5.UserEntity>>); } diff --git a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart index 6258fc1..e9865dd 100644 --- a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart +++ b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart @@ -35,124 +35,94 @@ class MockMainLayoutCubit extends _i1.Mock implements _i2.MainLayoutCubit { } @override - _i2.MainLayoutTabs get currentTab => (super.noSuchMethod( - Invocation.getter(#currentTab), - returnValue: _i2.MainLayoutTabs.home, - ) as _i2.MainLayoutTabs); + _i2.MainLayoutTabs get currentTab => + (super.noSuchMethod( + Invocation.getter(#currentTab), + returnValue: _i2.MainLayoutTabs.home, + ) + as _i2.MainLayoutTabs); @override set currentTab(_i2.MainLayoutTabs? _currentTab) => super.noSuchMethod( - Invocation.setter( - #currentTab, - _currentTab, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#currentTab, _currentTab), + returnValueForMissingStub: null, + ); @override Map<_i2.MainLayoutTabs, _i3.Widget Function()> get tabs => (super.noSuchMethod( - Invocation.getter(#tabs), - returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, - ) as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); + Invocation.getter(#tabs), + returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, + ) + as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); @override set tabs(Map<_i2.MainLayoutTabs, _i3.Widget Function()>? _tabs) => super.noSuchMethod( - Invocation.setter( - #tabs, - _tabs, - ), + Invocation.setter(#tabs, _tabs), returnValueForMissingStub: null, ); @override - _i2.MainLayoutState get state => (super.noSuchMethod( - Invocation.getter(#state), - returnValue: _i4.dummyValue<_i2.MainLayoutState>( - this, - Invocation.getter(#state), - ), - ) as _i2.MainLayoutState); + _i2.MainLayoutState get state => + (super.noSuchMethod( + Invocation.getter(#state), + returnValue: _i4.dummyValue<_i2.MainLayoutState>( + this, + Invocation.getter(#state), + ), + ) + as _i2.MainLayoutState); @override - _i5.Stream<_i2.MainLayoutState> get stream => (super.noSuchMethod( - Invocation.getter(#stream), - returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), - ) as _i5.Stream<_i2.MainLayoutState>); + _i5.Stream<_i2.MainLayoutState> get stream => + (super.noSuchMethod( + Invocation.getter(#stream), + returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), + ) + as _i5.Stream<_i2.MainLayoutState>); @override - bool get isClosed => (super.noSuchMethod( - Invocation.getter(#isClosed), - returnValue: false, - ) as bool); + bool get isClosed => + (super.noSuchMethod(Invocation.getter(#isClosed), returnValue: false) + as bool); @override void doIntent(_i2.MainLayoutActions? action) => super.noSuchMethod( - Invocation.method( - #doIntent, - [action], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#doIntent, [action]), + returnValueForMissingStub: null, + ); @override void emit(_i2.MainLayoutState? state) => super.noSuchMethod( - Invocation.method( - #emit, - [state], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#emit, [state]), + returnValueForMissingStub: null, + ); @override void onChange(_i6.Change<_i2.MainLayoutState>? change) => super.noSuchMethod( - Invocation.method( - #onChange, - [change], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#onChange, [change]), + returnValueForMissingStub: null, + ); @override - void addError( - Object? error, [ - StackTrace? stackTrace, - ]) => - super.noSuchMethod( - Invocation.method( - #addError, - [ - error, - stackTrace, - ], - ), - returnValueForMissingStub: null, - ); + void addError(Object? error, [StackTrace? stackTrace]) => super.noSuchMethod( + Invocation.method(#addError, [error, stackTrace]), + returnValueForMissingStub: null, + ); @override - void onError( - Object? error, - StackTrace? stackTrace, - ) => - super.noSuchMethod( - Invocation.method( - #onError, - [ - error, - stackTrace, - ], - ), - returnValueForMissingStub: null, - ); + void onError(Object? error, StackTrace? stackTrace) => super.noSuchMethod( + Invocation.method(#onError, [error, stackTrace]), + returnValueForMissingStub: null, + ); @override - _i5.Future close() => (super.noSuchMethod( - Invocation.method( - #close, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future close() => + (super.noSuchMethod( + Invocation.method(#close, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } From 55cbc08a2aa352de9bdc088e9f6153d86d508961 Mon Sep 17 00:00:00 2001 From: Eslam Date: Thu, 3 Jul 2025 06:48:16 +0300 Subject: [PATCH 06/12] feat(auth): Implement logout functionality and language selection use cases --- lib/core/utils/di/di.config.dart | 54 +- lib/data/auth/api/auth_retrofit_client.dart | 4 + lib/data/auth/api/auth_retrofit_client.g.dart | 70 +- .../contract/auth_local_data_source.dart | 6 +- .../contract/auth_remote_data_source.dart | 3 + .../local/auth_local_data_source_impl.dart | 23 +- .../remote/auth_remote_data_source_impl.dart | 6 + lib/data/auth/models/logout_response_dto.dart | 23 + .../auth/models/logout_response_dto.g.dart | 17 + lib/data/auth/repo_impl/auth_repo_impl.dart | 26 +- lib/domain/auth/repo/auth_repo.dart | 4 + lib/domain/auth/use_case/logout_use_case.dart | 12 + .../use_case/select_language_use_case.dart | 12 + .../view_model/profile_cubit.dart | 75 +++ .../view_model/profile_state.dart | 31 + .../inital_route_function_test.mocks.dart | 620 +++++++++++------- ...th_remote_data_source_impl_test.mocks.dart | 74 ++- .../auth/repo_impl/auth_repo_impl_test.dart | 11 +- .../repo_impl/auth_repo_impl_test.mocks.dart | 131 +++- .../get_profile_data_use_case_test.mocks.dart | 55 +- .../view/main_layout_screen_test.mocks.dart | 142 ++-- 21 files changed, 987 insertions(+), 412 deletions(-) create mode 100644 lib/data/auth/models/logout_response_dto.dart create mode 100644 lib/data/auth/models/logout_response_dto.g.dart create mode 100644 lib/domain/auth/use_case/logout_use_case.dart create mode 100644 lib/domain/auth/use_case/select_language_use_case.dart create mode 100644 lib/features/profile/presentation/view_model/profile_cubit.dart create mode 100644 lib/features/profile/presentation/view_model/profile_state.dart diff --git a/lib/core/utils/di/di.config.dart b/lib/core/utils/di/di.config.dart index 01904bf..b362652 100644 --- a/lib/core/utils/di/di.config.dart +++ b/lib/core/utils/di/di.config.dart @@ -39,12 +39,16 @@ import '../shared_preference_module.dart' as _i60; import '../validator/validator.dart' as _i468; extension GetItInjectableX on _i174.GetIt { - // initializes the registration of main-scope dependencies inside of GetIt +// initializes the registration of main-scope dependencies inside of GetIt Future<_i174.GetIt> init({ String? environment, _i526.EnvironmentFilter? environmentFilter, }) async { - final gh = _i526.GetItHelper(this, environment, environmentFilter); + final gh = _i526.GetItHelper( + this, + environment, + environmentFilter, + ); final sharedPreferenceModule = _$SharedPreferenceModule(); final secureStorageModule = _$SecureStorageModule(); final loggerModule = _$LoggerModule(); @@ -56,41 +60,33 @@ extension GetItInjectableX on _i174.GetIt { gh.singleton<_i28.ApiManager>(() => _i28.ApiManager()); gh.singleton<_i393.MainLayoutCubit>(() => _i393.MainLayoutCubit()); gh.lazySingleton<_i558.FlutterSecureStorage>( - () => secureStorageModule.storage, - ); + () => secureStorageModule.storage); gh.lazySingleton<_i974.Logger>(() => loggerModule.loggerProvider); gh.lazySingleton<_i974.PrettyPrinter>(() => loggerModule.prettyPrinter); gh.lazySingleton<_i468.Validator>(() => _i468.Validator()); - gh.factory<_i1063.AuthLocalDataSource>( - () => _i757.AuthLocalDataSourceImpl(), - ); gh.singleton<_i649.BlocObserverService>( - () => _i649.BlocObserverService(gh<_i974.Logger>()), - ); - gh.factory<_i420.RouteInitializer>( - () => _i420.RouteInitializer( - flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), - sharedPreferences: gh<_i460.SharedPreferences>(), - ), - ); + () => _i649.BlocObserverService(gh<_i974.Logger>())); + gh.factory<_i420.RouteInitializer>(() => _i420.RouteInitializer( + flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), + sharedPreferences: gh<_i460.SharedPreferences>(), + )); + gh.factory<_i1063.AuthLocalDataSource>(() => _i757.AuthLocalDataSourceImpl( + gh<_i460.SharedPreferences>(), + gh<_i558.FlutterSecureStorage>(), + )); gh.lazySingleton<_i361.Dio>( - () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>()), - ); + () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>())); gh.factory<_i1064.AuthRetrofitClient>( - () => _i1064.AuthRetrofitClient(gh<_i361.Dio>()), - ); + () => _i1064.AuthRetrofitClient(gh<_i361.Dio>())); gh.factory<_i774.AuthRemoteDataSource>( - () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>()), - ); - gh.factory<_i1047.AuthRepo>( - () => _i15.AuthRepoImpl( - gh<_i28.ApiManager>(), - gh<_i774.AuthRemoteDataSource>(), - ), - ); + () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>())); + gh.factory<_i1047.AuthRepo>(() => _i15.AuthRepoImpl( + gh<_i28.ApiManager>(), + gh<_i1063.AuthLocalDataSource>(), + gh<_i774.AuthRemoteDataSource>(), + )); gh.factory<_i336.GetProfileDataUseCase>( - () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>()), - ); + () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>())); return this; } } diff --git a/lib/data/auth/api/auth_retrofit_client.dart b/lib/data/auth/api/auth_retrofit_client.dart index d733cf1..cb29f66 100644 --- a/lib/data/auth/api/auth_retrofit_client.dart +++ b/lib/data/auth/api/auth_retrofit_client.dart @@ -1,4 +1,5 @@ import 'package:dio/dio.dart'; +import 'package:fitness_app/data/auth/models/logout_response_dto.dart'; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; import 'package:injectable/injectable.dart'; import 'package:retrofit/retrofit.dart'; @@ -13,6 +14,9 @@ abstract class AuthRetrofitClient { @factoryMethod factory AuthRetrofitClient(Dio dio) = _AuthRetrofitClient; + @GET(ApiConstants.logoutRoute) + Future logout(); + @GET(ApiConstants.profileDataRoute) Future getProfileData(); } diff --git a/lib/data/auth/api/auth_retrofit_client.g.dart b/lib/data/auth/api/auth_retrofit_client.g.dart index ee0b7cb..6a87ccf 100644 --- a/lib/data/auth/api/auth_retrofit_client.g.dart +++ b/lib/data/auth/api/auth_retrofit_client.g.dart @@ -9,7 +9,11 @@ part of 'auth_retrofit_client.dart'; // ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations class _AuthRetrofitClient implements AuthRetrofitClient { - _AuthRetrofitClient(this._dio, {this.baseUrl, this.errorLogger}) { + _AuthRetrofitClient( + this._dio, { + this.baseUrl, + this.errorLogger, + }) { baseUrl ??= 'https://fitness.elevateegy.com/api/v1/'; } @@ -19,22 +23,61 @@ class _AuthRetrofitClient implements AuthRetrofitClient { final ParseErrorLogger? errorLogger; + @override + Future logout() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + 'auth/logout', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); + final _result = await _dio.fetch>(_options); + late LogoutResponseDto _value; + try { + _value = LogoutResponseDto.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + @override Future getProfileData() async { final _extra = {}; final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType( - Options(method: 'GET', headers: _headers, extra: _extra) - .compose( - _dio.options, - 'auth/profile-data', - queryParameters: queryParameters, - data: _data, - ) - .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), - ); + final _options = _setStreamType(Options( + method: 'GET', + headers: _headers, + extra: _extra, + ) + .compose( + _dio.options, + 'auth/profile-data', + queryParameters: queryParameters, + data: _data, + ) + .copyWith( + baseUrl: _combineBaseUrls( + _dio.options.baseUrl, + baseUrl, + ))); final _result = await _dio.fetch>(_options); late UserDataResponseDto _value; try { @@ -59,7 +102,10 @@ class _AuthRetrofitClient implements AuthRetrofitClient { return requestOptions; } - String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { + String _combineBaseUrls( + String dioBaseUrl, + String? baseUrl, + ) { if (baseUrl == null || baseUrl.trim().isEmpty) { return dioBaseUrl; } diff --git a/lib/data/auth/data_source/contract/auth_local_data_source.dart b/lib/data/auth/data_source/contract/auth_local_data_source.dart index 4157124..9e44fdf 100644 --- a/lib/data/auth/data_source/contract/auth_local_data_source.dart +++ b/lib/data/auth/data_source/contract/auth_local_data_source.dart @@ -1 +1,5 @@ -abstract class AuthLocalDataSource {} +abstract class AuthLocalDataSource { + Future clearAll(); + + Future selectLanguage(String languageCode); +} diff --git a/lib/data/auth/data_source/contract/auth_remote_data_source.dart b/lib/data/auth/data_source/contract/auth_remote_data_source.dart index b8d60c6..be2a301 100644 --- a/lib/data/auth/data_source/contract/auth_remote_data_source.dart +++ b/lib/data/auth/data_source/contract/auth_remote_data_source.dart @@ -1,5 +1,8 @@ +import 'package:fitness_app/data/auth/models/logout_response_dto.dart'; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; abstract class AuthRemoteDataSource { Future getProfileData(); + + Future logout(); } diff --git a/lib/data/auth/data_source/local/auth_local_data_source_impl.dart b/lib/data/auth/data_source/local/auth_local_data_source_impl.dart index 039ce12..7fdd2b5 100644 --- a/lib/data/auth/data_source/local/auth_local_data_source_impl.dart +++ b/lib/data/auth/data_source/local/auth_local_data_source_impl.dart @@ -1,6 +1,27 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:injectable/injectable.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import '../../../../core/utils/constants.dart'; import '../contract/auth_local_data_source.dart'; @Injectable(as: AuthLocalDataSource) -class AuthLocalDataSourceImpl implements AuthLocalDataSource {} +class AuthLocalDataSourceImpl implements AuthLocalDataSource { + final SharedPreferences _sharedPreferences; + final FlutterSecureStorage _flutterSecureStorage; + + AuthLocalDataSourceImpl(this._sharedPreferences, this._flutterSecureStorage); + + @override + Future clearAll() async { + return await _flutterSecureStorage.deleteAll(); + } + + @override + Future selectLanguage(String languageCode) async { + return await _sharedPreferences.setString( + Constants.selectedLanguageCode, + languageCode, + ); + } +} diff --git a/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart b/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart index e02e456..5956f1f 100644 --- a/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart +++ b/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart @@ -1,4 +1,5 @@ import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart'; +import 'package:fitness_app/data/auth/models/logout_response_dto.dart'; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; import 'package:injectable/injectable.dart'; @@ -14,4 +15,9 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource { Future getProfileData() async { return await _authRetrofitClient.getProfileData(); } + + @override + Future logout() async { + return await _authRetrofitClient.logout(); + } } diff --git a/lib/data/auth/models/logout_response_dto.dart b/lib/data/auth/models/logout_response_dto.dart new file mode 100644 index 0000000..536aece --- /dev/null +++ b/lib/data/auth/models/logout_response_dto.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'logout_response_dto.g.dart'; + +@JsonSerializable() +class LogoutResponseDto { + @JsonKey(name: "message") + final String? message; + + LogoutResponseDto ({ + this.message, + }); + + factory LogoutResponseDto.fromJson(Map json) { + return _$LogoutResponseDtoFromJson(json); + } + + Map toJson() { + return _$LogoutResponseDtoToJson(this); + } +} + + diff --git a/lib/data/auth/models/logout_response_dto.g.dart b/lib/data/auth/models/logout_response_dto.g.dart new file mode 100644 index 0000000..2209ea1 --- /dev/null +++ b/lib/data/auth/models/logout_response_dto.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'logout_response_dto.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LogoutResponseDto _$LogoutResponseDtoFromJson(Map json) => + LogoutResponseDto( + message: json['message'] as String?, + ); + +Map _$LogoutResponseDtoToJson(LogoutResponseDto instance) => + { + 'message': instance.message, + }; diff --git a/lib/data/auth/repo_impl/auth_repo_impl.dart b/lib/data/auth/repo_impl/auth_repo_impl.dart index 4fa0d6a..d4baff7 100644 --- a/lib/data/auth/repo_impl/auth_repo_impl.dart +++ b/lib/data/auth/repo_impl/auth_repo_impl.dart @@ -1,5 +1,6 @@ import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart'; import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/data/auth/data_source/contract/auth_local_data_source.dart'; import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart'; import 'package:fitness_app/domain/auth/entity/user_entity.dart'; import 'package:injectable/injectable.dart'; @@ -9,9 +10,14 @@ import '../../../domain/auth/repo/auth_repo.dart'; @Injectable(as: AuthRepo) class AuthRepoImpl implements AuthRepo { final ApiManager _apiManager; + final AuthLocalDataSource _authLocalDataSource; final AuthRemoteDataSource _authRemoteDataSource; - AuthRepoImpl(this._apiManager, this._authRemoteDataSource); + AuthRepoImpl( + this._apiManager, + this._authLocalDataSource, + this._authRemoteDataSource, + ); @override Future> getProfileData() async { @@ -21,4 +27,22 @@ class AuthRepoImpl implements AuthRepo { }); return result; } + + @override + Future> logout() async { + final result = await _apiManager.execute(() async { + await _authRemoteDataSource.logout(); + await _authLocalDataSource.clearAll(); + }); + return result; + } + + @override + Future> selectLanguage(String languageCode) async { + final result = await _apiManager.execute(() async { + final response = await _authLocalDataSource.selectLanguage(languageCode); + return response; + }); + return result; + } } diff --git a/lib/domain/auth/repo/auth_repo.dart b/lib/domain/auth/repo/auth_repo.dart index 90983e1..d44e442 100644 --- a/lib/domain/auth/repo/auth_repo.dart +++ b/lib/domain/auth/repo/auth_repo.dart @@ -3,4 +3,8 @@ import 'package:fitness_app/domain/auth/entity/user_entity.dart'; abstract class AuthRepo { Future> getProfileData(); + + Future> logout(); + + Future> selectLanguage(String languageCode); } diff --git a/lib/domain/auth/use_case/logout_use_case.dart b/lib/domain/auth/use_case/logout_use_case.dart new file mode 100644 index 0000000..4f83d3c --- /dev/null +++ b/lib/domain/auth/use_case/logout_use_case.dart @@ -0,0 +1,12 @@ +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/domain/auth/repo/auth_repo.dart'; + +class LogoutUseCase { + final AuthRepo _authRepo; + + LogoutUseCase(this._authRepo); + + Future> call() async { + return await _authRepo.logout(); + } +} diff --git a/lib/domain/auth/use_case/select_language_use_case.dart b/lib/domain/auth/use_case/select_language_use_case.dart new file mode 100644 index 0000000..c1cec63 --- /dev/null +++ b/lib/domain/auth/use_case/select_language_use_case.dart @@ -0,0 +1,12 @@ +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/domain/auth/repo/auth_repo.dart'; + +class SelectLanguageUseCase { + final AuthRepo _authRepo; + + SelectLanguageUseCase(this._authRepo); + + Future> call(String languageCode) async { + return await _authRepo.selectLanguage(languageCode); + } +} diff --git a/lib/features/profile/presentation/view_model/profile_cubit.dart b/lib/features/profile/presentation/view_model/profile_cubit.dart new file mode 100644 index 0000000..374bb8f --- /dev/null +++ b/lib/features/profile/presentation/view_model/profile_cubit.dart @@ -0,0 +1,75 @@ +import 'package:fitness_app/core/base/base_state.dart'; +import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/domain/auth/entity/user_entity.dart'; +import 'package:fitness_app/features/profile/presentation/view_model/profile_state.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../domain/auth/use_case/get_profile_data_use_case.dart'; +import '../../../../domain/auth/use_case/logout_use_case.dart'; +import '../../../../domain/auth/use_case/select_language_use_case.dart'; + +class ProfileCubit extends Cubit { + final GetProfileDataUseCase _getProfileDataUseCase; + final LogoutUseCase _logoutUseCase; + final SelectLanguageUseCase _selectLanguageUseCase; + + ProfileCubit( + this._getProfileDataUseCase, + this._logoutUseCase, + this._selectLanguageUseCase, + ) : super( + (ProfileState( + profileState: BaseInitialState(), + logoutState: BaseInitialState(), + )), + ); + + void doIntent(ProfileAction action) { + switch (action) { + case GetProfileAction(): + _getProfile(); + case LogoutAction(): + _logout(); + case SelectLanguageAction(): + _selectLanguage(action.languageCode); + } + } + + Future _getProfile() async { + emit(state.copyWith(profileState: BaseLoadingState())); + final result = await _getProfileDataUseCase.call(); + switch (result) { + case SuccessResult(): + emit(state.copyWith(profileState: BaseSuccessState(data: result.data))); + case FailureResult(): + emit( + state.copyWith( + profileState: BaseErrorState( + errorMessage: result.exception.toString(), + ), + ), + ); + } + } + + Future _logout() async { + emit(state.copyWith(logoutState: BaseLoadingState())); + final result = await _logoutUseCase.call(); + switch (result) { + case SuccessResult(): + emit(state.copyWith(logoutState: BaseSuccessState())); + case FailureResult(): + emit( + state.copyWith( + logoutState: BaseErrorState( + errorMessage: result.exception.toString(), + ), + ), + ); + } + } + + Future _selectLanguage(String languageCode) async { + await _selectLanguageUseCase.call(languageCode); + } +} diff --git a/lib/features/profile/presentation/view_model/profile_state.dart b/lib/features/profile/presentation/view_model/profile_state.dart new file mode 100644 index 0000000..5520a43 --- /dev/null +++ b/lib/features/profile/presentation/view_model/profile_state.dart @@ -0,0 +1,31 @@ +import 'package:equatable/equatable.dart'; +import 'package:fitness_app/core/base/base_state.dart'; + +final class ProfileState extends Equatable { + final BaseState profileState; + final BaseState logoutState; + + const ProfileState({required this.profileState, required this.logoutState}); + + ProfileState copyWith({BaseState? profileState, BaseState? logoutState}) { + return ProfileState( + profileState: profileState ?? this.profileState, + logoutState: logoutState ?? this.logoutState, + ); + } + + @override + List get props => [profileState, logoutState]; +} + +sealed class ProfileAction {} + +final class GetProfileAction extends ProfileAction {} + +final class LogoutAction extends ProfileAction {} + +final class SelectLanguageAction extends ProfileAction { + final String languageCode; + + SelectLanguageAction(this.languageCode); +} diff --git a/test/core/functions/inital_route_function_test.mocks.dart b/test/core/functions/inital_route_function_test.mocks.dart index 85f461d..8351c57 100644 --- a/test/core/functions/inital_route_function_test.mocks.dart +++ b/test/core/functions/inital_route_function_test.mocks.dart @@ -25,35 +25,65 @@ import 'package:shared_preferences/src/shared_preferences_legacy.dart' as _i3; // ignore_for_file: subtype_of_sealed_class class _FakeIOSOptions_0 extends _i1.SmartFake implements _i2.IOSOptions { - _FakeIOSOptions_0(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeIOSOptions_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeAndroidOptions_1 extends _i1.SmartFake implements _i2.AndroidOptions { - _FakeAndroidOptions_1(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeAndroidOptions_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeLinuxOptions_2 extends _i1.SmartFake implements _i2.LinuxOptions { - _FakeLinuxOptions_2(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeLinuxOptions_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeWindowsOptions_3 extends _i1.SmartFake implements _i2.WindowsOptions { - _FakeWindowsOptions_3(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeWindowsOptions_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeWebOptions_4 extends _i1.SmartFake implements _i2.WebOptions { - _FakeWebOptions_4(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeWebOptions_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } class _FakeMacOsOptions_5 extends _i1.SmartFake implements _i2.MacOsOptions { - _FakeMacOsOptions_5(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeMacOsOptions_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } /// A class which mocks [SharedPreferences]. @@ -65,118 +95,176 @@ class MockSharedPreferences extends _i1.Mock implements _i3.SharedPreferences { } @override - Set getKeys() => - (super.noSuchMethod( - Invocation.method(#getKeys, []), - returnValue: {}, - ) - as Set); + Set getKeys() => (super.noSuchMethod( + Invocation.method( + #getKeys, + [], + ), + returnValue: {}, + ) as Set); @override - Object? get(String? key) => - (super.noSuchMethod(Invocation.method(#get, [key])) as Object?); + Object? get(String? key) => (super.noSuchMethod(Invocation.method( + #get, + [key], + )) as Object?); @override - bool? getBool(String? key) => - (super.noSuchMethod(Invocation.method(#getBool, [key])) as bool?); + bool? getBool(String? key) => (super.noSuchMethod(Invocation.method( + #getBool, + [key], + )) as bool?); @override - int? getInt(String? key) => - (super.noSuchMethod(Invocation.method(#getInt, [key])) as int?); + int? getInt(String? key) => (super.noSuchMethod(Invocation.method( + #getInt, + [key], + )) as int?); @override - double? getDouble(String? key) => - (super.noSuchMethod(Invocation.method(#getDouble, [key])) as double?); + double? getDouble(String? key) => (super.noSuchMethod(Invocation.method( + #getDouble, + [key], + )) as double?); @override - String? getString(String? key) => - (super.noSuchMethod(Invocation.method(#getString, [key])) as String?); + String? getString(String? key) => (super.noSuchMethod(Invocation.method( + #getString, + [key], + )) as String?); @override - bool containsKey(String? key) => - (super.noSuchMethod( - Invocation.method(#containsKey, [key]), - returnValue: false, - ) - as bool); + bool containsKey(String? key) => (super.noSuchMethod( + Invocation.method( + #containsKey, + [key], + ), + returnValue: false, + ) as bool); @override List? getStringList(String? key) => - (super.noSuchMethod(Invocation.method(#getStringList, [key])) - as List?); - - @override - _i4.Future setBool(String? key, bool? value) => - (super.noSuchMethod( - Invocation.method(#setBool, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future setInt(String? key, int? value) => - (super.noSuchMethod( - Invocation.method(#setInt, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future setDouble(String? key, double? value) => - (super.noSuchMethod( - Invocation.method(#setDouble, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); + (super.noSuchMethod(Invocation.method( + #getStringList, + [key], + )) as List?); @override - _i4.Future setString(String? key, String? value) => + _i4.Future setBool( + String? key, + bool? value, + ) => (super.noSuchMethod( - Invocation.method(#setString, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future setStringList(String? key, List? value) => + Invocation.method( + #setBool, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setInt( + String? key, + int? value, + ) => (super.noSuchMethod( - Invocation.method(#setStringList, [key, value]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future remove(String? key) => + Invocation.method( + #setInt, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setDouble( + String? key, + double? value, + ) => (super.noSuchMethod( - Invocation.method(#remove, [key]), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future commit() => + Invocation.method( + #setDouble, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setString( + String? key, + String? value, + ) => (super.noSuchMethod( - Invocation.method(#commit, []), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future clear() => + Invocation.method( + #setString, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future setStringList( + String? key, + List? value, + ) => (super.noSuchMethod( - Invocation.method(#clear, []), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); - - @override - _i4.Future reload() => - (super.noSuchMethod( - Invocation.method(#reload, []), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #setStringList, + [ + key, + value, + ], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future remove(String? key) => (super.noSuchMethod( + Invocation.method( + #remove, + [key], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future commit() => (super.noSuchMethod( + Invocation.method( + #commit, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future clear() => (super.noSuchMethod( + Invocation.method( + #clear, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future reload() => (super.noSuchMethod( + Invocation.method( + #reload, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); } /// A class which mocks [FlutterSecureStorage]. @@ -189,101 +277,112 @@ class MockFlutterSecureStorage extends _i1.Mock } @override - _i2.IOSOptions get iOptions => - (super.noSuchMethod( - Invocation.getter(#iOptions), - returnValue: _FakeIOSOptions_0(this, Invocation.getter(#iOptions)), - ) - as _i2.IOSOptions); + _i2.IOSOptions get iOptions => (super.noSuchMethod( + Invocation.getter(#iOptions), + returnValue: _FakeIOSOptions_0( + this, + Invocation.getter(#iOptions), + ), + ) as _i2.IOSOptions); @override - _i2.AndroidOptions get aOptions => - (super.noSuchMethod( - Invocation.getter(#aOptions), - returnValue: _FakeAndroidOptions_1( - this, - Invocation.getter(#aOptions), - ), - ) - as _i2.AndroidOptions); + _i2.AndroidOptions get aOptions => (super.noSuchMethod( + Invocation.getter(#aOptions), + returnValue: _FakeAndroidOptions_1( + this, + Invocation.getter(#aOptions), + ), + ) as _i2.AndroidOptions); @override - _i2.LinuxOptions get lOptions => - (super.noSuchMethod( - Invocation.getter(#lOptions), - returnValue: _FakeLinuxOptions_2( - this, - Invocation.getter(#lOptions), - ), - ) - as _i2.LinuxOptions); + _i2.LinuxOptions get lOptions => (super.noSuchMethod( + Invocation.getter(#lOptions), + returnValue: _FakeLinuxOptions_2( + this, + Invocation.getter(#lOptions), + ), + ) as _i2.LinuxOptions); @override - _i2.WindowsOptions get wOptions => - (super.noSuchMethod( - Invocation.getter(#wOptions), - returnValue: _FakeWindowsOptions_3( - this, - Invocation.getter(#wOptions), - ), - ) - as _i2.WindowsOptions); + _i2.WindowsOptions get wOptions => (super.noSuchMethod( + Invocation.getter(#wOptions), + returnValue: _FakeWindowsOptions_3( + this, + Invocation.getter(#wOptions), + ), + ) as _i2.WindowsOptions); @override - _i2.WebOptions get webOptions => - (super.noSuchMethod( - Invocation.getter(#webOptions), - returnValue: _FakeWebOptions_4( - this, - Invocation.getter(#webOptions), - ), - ) - as _i2.WebOptions); + _i2.WebOptions get webOptions => (super.noSuchMethod( + Invocation.getter(#webOptions), + returnValue: _FakeWebOptions_4( + this, + Invocation.getter(#webOptions), + ), + ) as _i2.WebOptions); @override - _i2.MacOsOptions get mOptions => - (super.noSuchMethod( - Invocation.getter(#mOptions), - returnValue: _FakeMacOsOptions_5( - this, - Invocation.getter(#mOptions), - ), - ) - as _i2.MacOsOptions); + _i2.MacOsOptions get mOptions => (super.noSuchMethod( + Invocation.getter(#mOptions), + returnValue: _FakeMacOsOptions_5( + this, + Invocation.getter(#mOptions), + ), + ) as _i2.MacOsOptions); @override void registerListener({ required String? key, required _i5.ValueChanged? listener, - }) => super.noSuchMethod( - Invocation.method(#registerListener, [], {#key: key, #listener: listener}), - returnValueForMissingStub: null, - ); + }) => + super.noSuchMethod( + Invocation.method( + #registerListener, + [], + { + #key: key, + #listener: listener, + }, + ), + returnValueForMissingStub: null, + ); @override void unregisterListener({ required String? key, required _i5.ValueChanged? listener, - }) => super.noSuchMethod( - Invocation.method(#unregisterListener, [], { - #key: key, - #listener: listener, - }), - returnValueForMissingStub: null, - ); + }) => + super.noSuchMethod( + Invocation.method( + #unregisterListener, + [], + { + #key: key, + #listener: listener, + }, + ), + returnValueForMissingStub: null, + ); @override void unregisterAllListenersForKey({required String? key}) => super.noSuchMethod( - Invocation.method(#unregisterAllListenersForKey, [], {#key: key}), + Invocation.method( + #unregisterAllListenersForKey, + [], + {#key: key}, + ), returnValueForMissingStub: null, ); @override void unregisterAllListeners() => super.noSuchMethod( - Invocation.method(#unregisterAllListeners, []), - returnValueForMissingStub: null, - ); + Invocation.method( + #unregisterAllListeners, + [], + ), + returnValueForMissingStub: null, + ); @override _i4.Future write({ @@ -297,20 +396,23 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#write, [], { - #key: key, - #value: value, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #write, + [], + { + #key: key, + #value: value, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override _i4.Future read({ @@ -323,18 +425,21 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#read, [], { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #read, + [], + { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); @override _i4.Future containsKey({ @@ -347,18 +452,21 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#containsKey, [], { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(false), - ) - as _i4.Future); + Invocation.method( + #containsKey, + [], + { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); @override _i4.Future delete({ @@ -371,19 +479,22 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#delete, [], { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #delete, + [], + { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override _i4.Future> readAll({ @@ -395,19 +506,20 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#readAll, [], { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future>.value( - {}, - ), - ) - as _i4.Future>); + Invocation.method( + #readAll, + [], + { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future>.value({}), + ) as _i4.Future>); @override _i4.Future deleteAll({ @@ -419,24 +531,28 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method(#deleteAll, [], { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) - as _i4.Future); - - @override - _i4.Future isCupertinoProtectedDataAvailable() => - (super.noSuchMethod( - Invocation.method(#isCupertinoProtectedDataAvailable, []), - returnValue: _i4.Future.value(), - ) - as _i4.Future); + Invocation.method( + #deleteAll, + [], + { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future isCupertinoProtectedDataAvailable() => (super.noSuchMethod( + Invocation.method( + #isCupertinoProtectedDataAvailable, + [], + ), + returnValue: _i4.Future.value(), + ) as _i4.Future); } diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart index 091a6e3..e11c627 100644 --- a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart @@ -3,11 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i4; +import 'dart:async' as _i5; -import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i3; +import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i4; +import 'package:fitness_app/data/auth/models/logout_response_dto.dart' as _i2; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' - as _i2; + as _i3; import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint @@ -24,31 +25,66 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeUserDataResponseDto_0 extends _i1.SmartFake - implements _i2.UserDataResponseDto { - _FakeUserDataResponseDto_0(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); +class _FakeLogoutResponseDto_0 extends _i1.SmartFake + implements _i2.LogoutResponseDto { + _FakeLogoutResponseDto_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeUserDataResponseDto_1 extends _i1.SmartFake + implements _i3.UserDataResponseDto { + _FakeUserDataResponseDto_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } /// A class which mocks [AuthRetrofitClient]. /// /// See the documentation for Mockito's code generation for more information. class MockAuthRetrofitClient extends _i1.Mock - implements _i3.AuthRetrofitClient { + implements _i4.AuthRetrofitClient { MockAuthRetrofitClient() { _i1.throwOnMissingStub(this); } @override - _i4.Future<_i2.UserDataResponseDto> getProfileData() => - (super.noSuchMethod( - Invocation.method(#getProfileData, []), - returnValue: _i4.Future<_i2.UserDataResponseDto>.value( - _FakeUserDataResponseDto_0( - this, - Invocation.method(#getProfileData, []), - ), - ), - ) - as _i4.Future<_i2.UserDataResponseDto>); + _i5.Future<_i2.LogoutResponseDto> logout() => (super.noSuchMethod( + Invocation.method( + #logout, + [], + ), + returnValue: + _i5.Future<_i2.LogoutResponseDto>.value(_FakeLogoutResponseDto_0( + this, + Invocation.method( + #logout, + [], + ), + )), + ) as _i5.Future<_i2.LogoutResponseDto>); + + @override + _i5.Future<_i3.UserDataResponseDto> getProfileData() => (super.noSuchMethod( + Invocation.method( + #getProfileData, + [], + ), + returnValue: _i5.Future<_i3.UserDataResponseDto>.value( + _FakeUserDataResponseDto_1( + this, + Invocation.method( + #getProfileData, + [], + ), + )), + ) as _i5.Future<_i3.UserDataResponseDto>); } diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.dart b/test/data/auth/repo_impl/auth_repo_impl_test.dart index a992251..65838eb 100644 --- a/test/data/auth/repo_impl/auth_repo_impl_test.dart +++ b/test/data/auth/repo_impl/auth_repo_impl_test.dart @@ -1,5 +1,6 @@ import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart'; import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; +import 'package:fitness_app/data/auth/data_source/contract/auth_local_data_source.dart'; import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart'; import 'package:fitness_app/data/auth/models/user_dto.dart'; import 'package:fitness_app/data/auth/repo_impl/auth_repo_impl.dart'; @@ -11,16 +12,22 @@ import 'package:mockito/mockito.dart'; import 'auth_repo_impl_test.mocks.dart'; -@GenerateMocks([ApiManager, AuthRemoteDataSource]) +@GenerateMocks([ApiManager, AuthLocalDataSource, AuthRemoteDataSource]) void main() { late AuthRepoImpl authRepoImpl; late MockApiManager mockApiManager; + late MockAuthLocalDataSource mockAuthLocalDataSource; late MockAuthRemoteDataSource mockAuthRemoteDataSource; setUp(() { mockApiManager = MockApiManager(); + mockAuthLocalDataSource = MockAuthLocalDataSource(); mockAuthRemoteDataSource = MockAuthRemoteDataSource(); - authRepoImpl = AuthRepoImpl(mockApiManager, mockAuthRemoteDataSource); + authRepoImpl = AuthRepoImpl( + mockApiManager, + mockAuthLocalDataSource, + mockAuthRemoteDataSource, + ); }); group('AuthRepoImpl Tests', () { diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart index 1a52d5e..8382d1c 100644 --- a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart +++ b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart @@ -3,18 +3,21 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i4; +import 'dart:async' as _i5; import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart' - as _i3; + as _i4; import 'package:fitness_app/core/utils/datasource_excution/api_result.dart' - as _i5; + as _i6; +import 'package:fitness_app/data/auth/data_source/contract/auth_local_data_source.dart' + as _i8; import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart' - as _i7; + as _i9; +import 'package:fitness_app/data/auth/models/logout_response_dto.dart' as _i3; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i6; +import 'package:mockito/src/dummies.dart' as _i7; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -32,51 +35,119 @@ import 'package:mockito/src/dummies.dart' as _i6; class _FakeUserDataResponseDto_0 extends _i1.SmartFake implements _i2.UserDataResponseDto { - _FakeUserDataResponseDto_0(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); + _FakeUserDataResponseDto_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeLogoutResponseDto_1 extends _i1.SmartFake + implements _i3.LogoutResponseDto { + _FakeLogoutResponseDto_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); } /// A class which mocks [ApiManager]. /// /// See the documentation for Mockito's code generation for more information. -class MockApiManager extends _i1.Mock implements _i3.ApiManager { +class MockApiManager extends _i1.Mock implements _i4.ApiManager { MockApiManager() { _i1.throwOnMissingStub(this); } @override - _i4.Future<_i5.Result> execute(_i4.Future Function()? apiCall) => + _i5.Future<_i6.Result> execute(_i5.Future Function()? apiCall) => (super.noSuchMethod( - Invocation.method(#execute, [apiCall]), - returnValue: _i4.Future<_i5.Result>.value( - _i6.dummyValue<_i5.Result>( - this, - Invocation.method(#execute, [apiCall]), - ), - ), - ) - as _i4.Future<_i5.Result>); + Invocation.method( + #execute, + [apiCall], + ), + returnValue: + _i5.Future<_i6.Result>.value(_i7.dummyValue<_i6.Result>( + this, + Invocation.method( + #execute, + [apiCall], + ), + )), + ) as _i5.Future<_i6.Result>); +} + +/// A class which mocks [AuthLocalDataSource]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAuthLocalDataSource extends _i1.Mock + implements _i8.AuthLocalDataSource { + MockAuthLocalDataSource() { + _i1.throwOnMissingStub(this); + } + + @override + _i5.Future clearAll() => (super.noSuchMethod( + Invocation.method( + #clearAll, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future selectLanguage(String? languageCode) => (super.noSuchMethod( + Invocation.method( + #selectLanguage, + [languageCode], + ), + returnValue: _i5.Future.value(false), + ) as _i5.Future); } /// A class which mocks [AuthRemoteDataSource]. /// /// See the documentation for Mockito's code generation for more information. class MockAuthRemoteDataSource extends _i1.Mock - implements _i7.AuthRemoteDataSource { + implements _i9.AuthRemoteDataSource { MockAuthRemoteDataSource() { _i1.throwOnMissingStub(this); } @override - _i4.Future<_i2.UserDataResponseDto> getProfileData() => - (super.noSuchMethod( - Invocation.method(#getProfileData, []), - returnValue: _i4.Future<_i2.UserDataResponseDto>.value( - _FakeUserDataResponseDto_0( - this, - Invocation.method(#getProfileData, []), - ), - ), - ) - as _i4.Future<_i2.UserDataResponseDto>); + _i5.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( + Invocation.method( + #getProfileData, + [], + ), + returnValue: _i5.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( + this, + Invocation.method( + #getProfileData, + [], + ), + )), + ) as _i5.Future<_i2.UserDataResponseDto>); + + @override + _i5.Future<_i3.LogoutResponseDto> logout() => (super.noSuchMethod( + Invocation.method( + #logout, + [], + ), + returnValue: + _i5.Future<_i3.LogoutResponseDto>.value(_FakeLogoutResponseDto_1( + this, + Invocation.method( + #logout, + [], + ), + )), + ) as _i5.Future<_i3.LogoutResponseDto>); } diff --git a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart index 4dc62d4..14df73d 100644 --- a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart +++ b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart @@ -37,13 +37,50 @@ class MockAuthRepo extends _i1.Mock implements _i2.AuthRepo { @override _i3.Future<_i4.Result<_i5.UserEntity>> getProfileData() => (super.noSuchMethod( - Invocation.method(#getProfileData, []), - returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( - _i6.dummyValue<_i4.Result<_i5.UserEntity>>( - this, - Invocation.method(#getProfileData, []), - ), - ), - ) - as _i3.Future<_i4.Result<_i5.UserEntity>>); + Invocation.method( + #getProfileData, + [], + ), + returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( + _i6.dummyValue<_i4.Result<_i5.UserEntity>>( + this, + Invocation.method( + #getProfileData, + [], + ), + )), + ) as _i3.Future<_i4.Result<_i5.UserEntity>>); + + @override + _i3.Future<_i4.Result> logout() => (super.noSuchMethod( + Invocation.method( + #logout, + [], + ), + returnValue: + _i3.Future<_i4.Result>.value(_i6.dummyValue<_i4.Result>( + this, + Invocation.method( + #logout, + [], + ), + )), + ) as _i3.Future<_i4.Result>); + + @override + _i3.Future<_i4.Result> selectLanguage(String? languageCode) => + (super.noSuchMethod( + Invocation.method( + #selectLanguage, + [languageCode], + ), + returnValue: + _i3.Future<_i4.Result>.value(_i6.dummyValue<_i4.Result>( + this, + Invocation.method( + #selectLanguage, + [languageCode], + ), + )), + ) as _i3.Future<_i4.Result>); } diff --git a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart index e9865dd..6258fc1 100644 --- a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart +++ b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart @@ -35,94 +35,124 @@ class MockMainLayoutCubit extends _i1.Mock implements _i2.MainLayoutCubit { } @override - _i2.MainLayoutTabs get currentTab => - (super.noSuchMethod( - Invocation.getter(#currentTab), - returnValue: _i2.MainLayoutTabs.home, - ) - as _i2.MainLayoutTabs); + _i2.MainLayoutTabs get currentTab => (super.noSuchMethod( + Invocation.getter(#currentTab), + returnValue: _i2.MainLayoutTabs.home, + ) as _i2.MainLayoutTabs); @override set currentTab(_i2.MainLayoutTabs? _currentTab) => super.noSuchMethod( - Invocation.setter(#currentTab, _currentTab), - returnValueForMissingStub: null, - ); + Invocation.setter( + #currentTab, + _currentTab, + ), + returnValueForMissingStub: null, + ); @override Map<_i2.MainLayoutTabs, _i3.Widget Function()> get tabs => (super.noSuchMethod( - Invocation.getter(#tabs), - returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, - ) - as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); + Invocation.getter(#tabs), + returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, + ) as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); @override set tabs(Map<_i2.MainLayoutTabs, _i3.Widget Function()>? _tabs) => super.noSuchMethod( - Invocation.setter(#tabs, _tabs), + Invocation.setter( + #tabs, + _tabs, + ), returnValueForMissingStub: null, ); @override - _i2.MainLayoutState get state => - (super.noSuchMethod( - Invocation.getter(#state), - returnValue: _i4.dummyValue<_i2.MainLayoutState>( - this, - Invocation.getter(#state), - ), - ) - as _i2.MainLayoutState); + _i2.MainLayoutState get state => (super.noSuchMethod( + Invocation.getter(#state), + returnValue: _i4.dummyValue<_i2.MainLayoutState>( + this, + Invocation.getter(#state), + ), + ) as _i2.MainLayoutState); @override - _i5.Stream<_i2.MainLayoutState> get stream => - (super.noSuchMethod( - Invocation.getter(#stream), - returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), - ) - as _i5.Stream<_i2.MainLayoutState>); + _i5.Stream<_i2.MainLayoutState> get stream => (super.noSuchMethod( + Invocation.getter(#stream), + returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), + ) as _i5.Stream<_i2.MainLayoutState>); @override - bool get isClosed => - (super.noSuchMethod(Invocation.getter(#isClosed), returnValue: false) - as bool); + bool get isClosed => (super.noSuchMethod( + Invocation.getter(#isClosed), + returnValue: false, + ) as bool); @override void doIntent(_i2.MainLayoutActions? action) => super.noSuchMethod( - Invocation.method(#doIntent, [action]), - returnValueForMissingStub: null, - ); + Invocation.method( + #doIntent, + [action], + ), + returnValueForMissingStub: null, + ); @override void emit(_i2.MainLayoutState? state) => super.noSuchMethod( - Invocation.method(#emit, [state]), - returnValueForMissingStub: null, - ); + Invocation.method( + #emit, + [state], + ), + returnValueForMissingStub: null, + ); @override void onChange(_i6.Change<_i2.MainLayoutState>? change) => super.noSuchMethod( - Invocation.method(#onChange, [change]), - returnValueForMissingStub: null, - ); + Invocation.method( + #onChange, + [change], + ), + returnValueForMissingStub: null, + ); @override - void addError(Object? error, [StackTrace? stackTrace]) => super.noSuchMethod( - Invocation.method(#addError, [error, stackTrace]), - returnValueForMissingStub: null, - ); + void addError( + Object? error, [ + StackTrace? stackTrace, + ]) => + super.noSuchMethod( + Invocation.method( + #addError, + [ + error, + stackTrace, + ], + ), + returnValueForMissingStub: null, + ); @override - void onError(Object? error, StackTrace? stackTrace) => super.noSuchMethod( - Invocation.method(#onError, [error, stackTrace]), - returnValueForMissingStub: null, - ); + void onError( + Object? error, + StackTrace? stackTrace, + ) => + super.noSuchMethod( + Invocation.method( + #onError, + [ + error, + stackTrace, + ], + ), + returnValueForMissingStub: null, + ); @override - _i5.Future close() => - (super.noSuchMethod( - Invocation.method(#close, []), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) - as _i5.Future); + _i5.Future close() => (super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); } From 7d51a23f4c6a19edbcc9f19099f294f50e5715af Mon Sep 17 00:00:00 2001 From: Eslam Date: Fri, 4 Jul 2025 03:59:00 +0300 Subject: [PATCH 07/12] feat(profile): Update initial route to profile and implement profile screen with menu options --- assets/svgs/change_language_icon.svg | 7 + assets/svgs/change_password_icon.svg | 3 + assets/svgs/help_icon.svg | 3 + assets/svgs/lock_settings_icon.svg | 10 + assets/svgs/logout_icon.svg | 3 + assets/svgs/security_warning_icon.svg | 3 + lib/core/assets/app_icons.dart | 10 + lib/core/utils/di/di.config.dart | 75 ++- lib/core/utils/routes/app_routes.dart | 5 +- .../shared_widgets/blured_container.dart | 30 + lib/data/auth/api/auth_retrofit_client.g.dart | 63 +- lib/data/auth/models/logout_response_dto.dart | 6 +- .../auth/models/logout_response_dto.g.dart | 8 +- lib/domain/auth/use_case/logout_use_case.dart | 2 + .../use_case/select_language_use_case.dart | 2 + .../view_model/cubit/main_layout_cubit.dart | 4 +- .../presentation/view/profile_screen.dart | 12 - .../view/screens/profile_screen.dart | 91 +++ .../view/widgets/profile_body.dart | 51 ++ .../widgets/profile_menu_item_widget.dart | 49 ++ .../widgets/profile_menu_list_widget.dart | 80 +++ .../view_model/profile_cubit.dart | 2 + lib/main.dart | 2 +- .../inital_route_function_test.mocks.dart | 620 +++++++----------- ...th_remote_data_source_impl_test.mocks.dart | 65 +- .../repo_impl/auth_repo_impl_test.mocks.dart | 115 ++-- .../get_profile_data_use_case_test.mocks.dart | 71 +- .../view/main_layout_screen_test.mocks.dart | 142 ++-- .../view_model/main_layout_cubit_test.dart | 2 +- 29 files changed, 834 insertions(+), 702 deletions(-) create mode 100644 assets/svgs/change_language_icon.svg create mode 100644 assets/svgs/change_password_icon.svg create mode 100644 assets/svgs/help_icon.svg create mode 100644 assets/svgs/lock_settings_icon.svg create mode 100644 assets/svgs/logout_icon.svg create mode 100644 assets/svgs/security_warning_icon.svg create mode 100644 lib/core/utils/shared_widgets/blured_container.dart delete mode 100644 lib/features/profile/presentation/view/profile_screen.dart create mode 100644 lib/features/profile/presentation/view/screens/profile_screen.dart create mode 100644 lib/features/profile/presentation/view/widgets/profile_body.dart create mode 100644 lib/features/profile/presentation/view/widgets/profile_menu_item_widget.dart create mode 100644 lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart diff --git a/assets/svgs/change_language_icon.svg b/assets/svgs/change_language_icon.svg new file mode 100644 index 0000000..99b4d15 --- /dev/null +++ b/assets/svgs/change_language_icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/svgs/change_password_icon.svg b/assets/svgs/change_password_icon.svg new file mode 100644 index 0000000..0e8ff3f --- /dev/null +++ b/assets/svgs/change_password_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/svgs/help_icon.svg b/assets/svgs/help_icon.svg new file mode 100644 index 0000000..d0ca6bf --- /dev/null +++ b/assets/svgs/help_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/svgs/lock_settings_icon.svg b/assets/svgs/lock_settings_icon.svg new file mode 100644 index 0000000..8fdb55f --- /dev/null +++ b/assets/svgs/lock_settings_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/svgs/logout_icon.svg b/assets/svgs/logout_icon.svg new file mode 100644 index 0000000..0b323cc --- /dev/null +++ b/assets/svgs/logout_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/svgs/security_warning_icon.svg b/assets/svgs/security_warning_icon.svg new file mode 100644 index 0000000..6f27036 --- /dev/null +++ b/assets/svgs/security_warning_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/core/assets/app_icons.dart b/lib/core/assets/app_icons.dart index 4a4d76c..5cd48d9 100644 --- a/lib/core/assets/app_icons.dart +++ b/lib/core/assets/app_icons.dart @@ -1,5 +1,6 @@ class AppIcons { AppIcons._(); + static const String fitnessOne = 'assets/svgs/fitness_1.svg'; static const String fitnessTwo = 'assets/svgs/fitness_2.svg'; static const String fitnessThree = 'assets/svgs/fitness_3.svg'; @@ -38,4 +39,13 @@ class AppIcons { static const String profileIcon = 'assets/svgs/profile_icon.svg'; static const String chatIcon = 'assets/svgs/chat_icon.svg'; static const String workoutIcon = 'assets/svgs/workout_icon.svg'; + static const String changePasswordIcon = + 'assets/svgs/change_password_icon.svg'; + static const String logoutIcon = 'assets/svgs/logout_icon.svg'; + static const String helpIcon = 'assets/svgs/help_icon.svg'; + static const String lockSettingsIcon = 'assets/svgs/lock_settings_icon.svg'; + static const String securityWarningIcon = + 'assets/svgs/security_warning_icon.svg'; + static const String changeLanguageIcon = + 'assets/svgs/change_language_icon.svg'; } diff --git a/lib/core/utils/di/di.config.dart b/lib/core/utils/di/di.config.dart index b362652..47e43ce 100644 --- a/lib/core/utils/di/di.config.dart +++ b/lib/core/utils/di/di.config.dart @@ -27,8 +27,12 @@ import '../../../data/auth/data_source/remote/auth_remote_data_source_impl.dart' import '../../../data/auth/repo_impl/auth_repo_impl.dart' as _i15; import '../../../domain/auth/repo/auth_repo.dart' as _i1047; import '../../../domain/auth/use_case/get_profile_data_use_case.dart' as _i336; +import '../../../domain/auth/use_case/logout_use_case.dart' as _i1046; +import '../../../domain/auth/use_case/select_language_use_case.dart' as _i753; import '../../../features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart' as _i393; +import '../../../features/profile/presentation/view_model/profile_cubit.dart' + as _i782; import '../../functions/inital_route_function.dart' as _i420; import '../bloc_observer/bloc_observer_service.dart' as _i649; import '../datasource_excution/api_manager.dart' as _i28; @@ -39,16 +43,12 @@ import '../shared_preference_module.dart' as _i60; import '../validator/validator.dart' as _i468; extension GetItInjectableX on _i174.GetIt { -// initializes the registration of main-scope dependencies inside of GetIt + // initializes the registration of main-scope dependencies inside of GetIt Future<_i174.GetIt> init({ String? environment, _i526.EnvironmentFilter? environmentFilter, }) async { - final gh = _i526.GetItHelper( - this, - environment, - environmentFilter, - ); + final gh = _i526.GetItHelper(this, environment, environmentFilter); final sharedPreferenceModule = _$SharedPreferenceModule(); final secureStorageModule = _$SecureStorageModule(); final loggerModule = _$LoggerModule(); @@ -60,33 +60,58 @@ extension GetItInjectableX on _i174.GetIt { gh.singleton<_i28.ApiManager>(() => _i28.ApiManager()); gh.singleton<_i393.MainLayoutCubit>(() => _i393.MainLayoutCubit()); gh.lazySingleton<_i558.FlutterSecureStorage>( - () => secureStorageModule.storage); + () => secureStorageModule.storage, + ); gh.lazySingleton<_i974.Logger>(() => loggerModule.loggerProvider); gh.lazySingleton<_i974.PrettyPrinter>(() => loggerModule.prettyPrinter); gh.lazySingleton<_i468.Validator>(() => _i468.Validator()); gh.singleton<_i649.BlocObserverService>( - () => _i649.BlocObserverService(gh<_i974.Logger>())); - gh.factory<_i420.RouteInitializer>(() => _i420.RouteInitializer( - flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), - sharedPreferences: gh<_i460.SharedPreferences>(), - )); - gh.factory<_i1063.AuthLocalDataSource>(() => _i757.AuthLocalDataSourceImpl( - gh<_i460.SharedPreferences>(), - gh<_i558.FlutterSecureStorage>(), - )); + () => _i649.BlocObserverService(gh<_i974.Logger>()), + ); + gh.factory<_i420.RouteInitializer>( + () => _i420.RouteInitializer( + flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), + sharedPreferences: gh<_i460.SharedPreferences>(), + ), + ); + gh.factory<_i1063.AuthLocalDataSource>( + () => _i757.AuthLocalDataSourceImpl( + gh<_i460.SharedPreferences>(), + gh<_i558.FlutterSecureStorage>(), + ), + ); gh.lazySingleton<_i361.Dio>( - () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>())); + () => dioModule.provideDio(gh<_i558.FlutterSecureStorage>()), + ); gh.factory<_i1064.AuthRetrofitClient>( - () => _i1064.AuthRetrofitClient(gh<_i361.Dio>())); + () => _i1064.AuthRetrofitClient(gh<_i361.Dio>()), + ); gh.factory<_i774.AuthRemoteDataSource>( - () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>())); - gh.factory<_i1047.AuthRepo>(() => _i15.AuthRepoImpl( - gh<_i28.ApiManager>(), - gh<_i1063.AuthLocalDataSource>(), - gh<_i774.AuthRemoteDataSource>(), - )); + () => _i173.AuthRemoteDataSourceImpl(gh<_i1064.AuthRetrofitClient>()), + ); + gh.factory<_i1047.AuthRepo>( + () => _i15.AuthRepoImpl( + gh<_i28.ApiManager>(), + gh<_i1063.AuthLocalDataSource>(), + gh<_i774.AuthRemoteDataSource>(), + ), + ); gh.factory<_i336.GetProfileDataUseCase>( - () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>())); + () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i1046.LogoutUseCase>( + () => _i1046.LogoutUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i753.SelectLanguageUseCase>( + () => _i753.SelectLanguageUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i782.ProfileCubit>( + () => _i782.ProfileCubit( + gh<_i336.GetProfileDataUseCase>(), + gh<_i1046.LogoutUseCase>(), + gh<_i753.SelectLanguageUseCase>(), + ), + ); return this; } } diff --git a/lib/core/utils/routes/app_routes.dart b/lib/core/utils/routes/app_routes.dart index 2a59f01..24d973e 100644 --- a/lib/core/utils/routes/app_routes.dart +++ b/lib/core/utils/routes/app_routes.dart @@ -3,11 +3,12 @@ import 'package:flutter/material.dart'; import '../../../features/chat_bot/presentation/view/chat_bot_screen.dart'; import '../../../features/home/presentation/view/home_screen.dart'; import '../../../features/main_layout/presentation/view/main_layout_screen.dart'; -import '../../../features/profile/presentation/view/profile_screen.dart'; +import '../../../features/profile/presentation/view/screens/profile_screen.dart'; import '../../../features/workouts/presentation/view/workouts_screen.dart'; class AppRoutes { AppRoutes._(); + static const String loginRoute = "/login"; static const String registerRoute = "/register"; static const String forgetPasswordRoute = "/forgetPassword"; @@ -21,7 +22,7 @@ class AppRoutes { static Map routes = { mainLayoutRoute: (context) => const MainLayoutScreen(), - profileRoute: (context) => const ProfileScreen(), + profileRoute: (context) => ProfileScreen(), homeRoute: (context) => const HomeScreen(), workoutRoute: (context) => const WorkoutsScreen(), chatBotRoute: (context) => const ChatBotScreen(), diff --git a/lib/core/utils/shared_widgets/blured_container.dart b/lib/core/utils/shared_widgets/blured_container.dart new file mode 100644 index 0000000..aa4868d --- /dev/null +++ b/lib/core/utils/shared_widgets/blured_container.dart @@ -0,0 +1,30 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import '../../assets/app_colors.dart'; + +class BluredContainer extends StatelessWidget { + const BluredContainer({super.key, required this.child, this.padding}); + + final Widget child; + final EdgeInsets? padding; + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular(50), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), + child: AnimatedContainer( + padding: + padding ?? + const EdgeInsets.symmetric(vertical: 24, horizontal: 16), + color: AppColors.darkgrey.withAlpha(150), + duration: const Duration(milliseconds: 3000), + child: child, + ), + ), + ); + } +} diff --git a/lib/data/auth/api/auth_retrofit_client.g.dart b/lib/data/auth/api/auth_retrofit_client.g.dart index 6a87ccf..eee7a0d 100644 --- a/lib/data/auth/api/auth_retrofit_client.g.dart +++ b/lib/data/auth/api/auth_retrofit_client.g.dart @@ -9,11 +9,7 @@ part of 'auth_retrofit_client.dart'; // ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations class _AuthRetrofitClient implements AuthRetrofitClient { - _AuthRetrofitClient( - this._dio, { - this.baseUrl, - this.errorLogger, - }) { + _AuthRetrofitClient(this._dio, {this.baseUrl, this.errorLogger}) { baseUrl ??= 'https://fitness.elevateegy.com/api/v1/'; } @@ -29,22 +25,16 @@ class _AuthRetrofitClient implements AuthRetrofitClient { final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType(Options( - method: 'GET', - headers: _headers, - extra: _extra, - ) - .compose( - _dio.options, - 'auth/logout', - queryParameters: queryParameters, - data: _data, - ) - .copyWith( - baseUrl: _combineBaseUrls( - _dio.options.baseUrl, - baseUrl, - ))); + final _options = _setStreamType( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'auth/logout', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); final _result = await _dio.fetch>(_options); late LogoutResponseDto _value; try { @@ -62,22 +52,16 @@ class _AuthRetrofitClient implements AuthRetrofitClient { final queryParameters = {}; final _headers = {}; const Map? _data = null; - final _options = _setStreamType(Options( - method: 'GET', - headers: _headers, - extra: _extra, - ) - .compose( - _dio.options, - 'auth/profile-data', - queryParameters: queryParameters, - data: _data, - ) - .copyWith( - baseUrl: _combineBaseUrls( - _dio.options.baseUrl, - baseUrl, - ))); + final _options = _setStreamType( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'auth/profile-data', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); final _result = await _dio.fetch>(_options); late UserDataResponseDto _value; try { @@ -102,10 +86,7 @@ class _AuthRetrofitClient implements AuthRetrofitClient { return requestOptions; } - String _combineBaseUrls( - String dioBaseUrl, - String? baseUrl, - ) { + String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { if (baseUrl == null || baseUrl.trim().isEmpty) { return dioBaseUrl; } diff --git a/lib/data/auth/models/logout_response_dto.dart b/lib/data/auth/models/logout_response_dto.dart index 536aece..122e5d1 100644 --- a/lib/data/auth/models/logout_response_dto.dart +++ b/lib/data/auth/models/logout_response_dto.dart @@ -7,9 +7,7 @@ class LogoutResponseDto { @JsonKey(name: "message") final String? message; - LogoutResponseDto ({ - this.message, - }); + LogoutResponseDto({this.message}); factory LogoutResponseDto.fromJson(Map json) { return _$LogoutResponseDtoFromJson(json); @@ -19,5 +17,3 @@ class LogoutResponseDto { return _$LogoutResponseDtoToJson(this); } } - - diff --git a/lib/data/auth/models/logout_response_dto.g.dart b/lib/data/auth/models/logout_response_dto.g.dart index 2209ea1..df9754d 100644 --- a/lib/data/auth/models/logout_response_dto.g.dart +++ b/lib/data/auth/models/logout_response_dto.g.dart @@ -7,11 +7,7 @@ part of 'logout_response_dto.dart'; // ************************************************************************** LogoutResponseDto _$LogoutResponseDtoFromJson(Map json) => - LogoutResponseDto( - message: json['message'] as String?, - ); + LogoutResponseDto(message: json['message'] as String?); Map _$LogoutResponseDtoToJson(LogoutResponseDto instance) => - { - 'message': instance.message, - }; + {'message': instance.message}; diff --git a/lib/domain/auth/use_case/logout_use_case.dart b/lib/domain/auth/use_case/logout_use_case.dart index 4f83d3c..d6c768e 100644 --- a/lib/domain/auth/use_case/logout_use_case.dart +++ b/lib/domain/auth/use_case/logout_use_case.dart @@ -1,6 +1,8 @@ import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; import 'package:fitness_app/domain/auth/repo/auth_repo.dart'; +import 'package:injectable/injectable.dart'; +@injectable class LogoutUseCase { final AuthRepo _authRepo; diff --git a/lib/domain/auth/use_case/select_language_use_case.dart b/lib/domain/auth/use_case/select_language_use_case.dart index c1cec63..0de1d16 100644 --- a/lib/domain/auth/use_case/select_language_use_case.dart +++ b/lib/domain/auth/use_case/select_language_use_case.dart @@ -1,6 +1,8 @@ import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; import 'package:fitness_app/domain/auth/repo/auth_repo.dart'; +import 'package:injectable/injectable.dart'; +@injectable class SelectLanguageUseCase { final AuthRepo _authRepo; diff --git a/lib/features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart b/lib/features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart index 54a219d..d5dd2de 100644 --- a/lib/features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart +++ b/lib/features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart @@ -4,7 +4,7 @@ import 'package:injectable/injectable.dart'; import '../../../../chat_bot/presentation/view/chat_bot_screen.dart'; import '../../../../home/presentation/view/home_screen.dart'; -import '../../../../profile/presentation/view/profile_screen.dart'; +import '../../../../profile/presentation/view/screens/profile_screen.dart'; import '../../../../workouts/presentation/view/workouts_screen.dart'; part 'main_layout_state.dart'; @@ -24,7 +24,7 @@ class MainLayoutCubit extends Cubit { MainLayoutTabs.home: () => const HomeScreen(), MainLayoutTabs.fitnessAI: () => const ChatBotScreen(), MainLayoutTabs.workouts: () => const WorkoutsScreen(), - MainLayoutTabs.profile: () => const ProfileScreen(), + MainLayoutTabs.profile: () => ProfileScreen(), }; } diff --git a/lib/features/profile/presentation/view/profile_screen.dart b/lib/features/profile/presentation/view/profile_screen.dart deleted file mode 100644 index 6ce8330..0000000 --- a/lib/features/profile/presentation/view/profile_screen.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class ProfileScreen extends StatelessWidget { - const ProfileScreen({super.key}); - - @override - Widget build(BuildContext context) { - return const Scaffold( - body: Center(child: Text('Welcome to the Profile Screen!')), - ); - } -} diff --git a/lib/features/profile/presentation/view/screens/profile_screen.dart b/lib/features/profile/presentation/view/screens/profile_screen.dart new file mode 100644 index 0000000..ec94ace --- /dev/null +++ b/lib/features/profile/presentation/view/screens/profile_screen.dart @@ -0,0 +1,91 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:fitness_app/core/assets/app_images.dart'; +import 'package:fitness_app/core/utils/di/di.dart'; +import 'package:fitness_app/core/utils/dialogs/app_dialogs.dart'; +import 'package:fitness_app/core/utils/l10n/locale_keys.g.dart'; +import 'package:fitness_app/features/profile/presentation/view/widgets/profile_body.dart'; +import 'package:fitness_app/features/profile/presentation/view_model/profile_cubit.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../core/assets/app_colors.dart'; +import '../../../../../core/base/base_state.dart'; +import '../../../../../core/utils/routes/app_routes.dart'; +import '../../view_model/profile_state.dart'; + +class ProfileScreen extends StatelessWidget { + final ProfileCubit viewModel = getIt(); + + ProfileScreen({super.key}); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => viewModel..doIntent(GetProfileAction()), + child: BlocListener( + listener: (context, state) { + final logoutState = state.logoutState; + if (state.profileState is BaseErrorState) { + AppDialogs.showFailureDialog( + context, + message: (state.profileState as BaseErrorState).errorMessage, + ); + } + if (logoutState is BaseSuccessState) { + Navigator.pushNamedAndRemoveUntil( + context, + AppRoutes.loginRoute, + (route) => false, + ); + } else if (logoutState is BaseErrorState) { + AppDialogs.showFailureDialog( + context, + message: logoutState.errorMessage, + ); + } + }, + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + centerTitle: true, + title: Text( + LocaleKeys.Profile.tr(), + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + fontSize: 24, + ), + ), + leading: IconButton( + padding: EdgeInsets.zero, + constraints: BoxConstraints.tight(const Size(24, 24)), + style: IconButton.styleFrom( + backgroundColor: AppColors.orange, + shape: const CircleBorder(), + ), + icon: const Icon( + Icons.arrow_back, + color: AppColors.white, + size: 10, + ), + onPressed: () => Navigator.of(context).pop(), + ), + ), + extendBodyBehindAppBar: true, + body: Container( + width: double.infinity, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage(AppImages.backgroundThree), + fit: BoxFit.fill, + ), + ), + child: const Padding( + padding: EdgeInsets.symmetric(horizontal: 16), + child: ProfileBody(), + ), + ), + ), + ), + ); + } +} diff --git a/lib/features/profile/presentation/view/widgets/profile_body.dart b/lib/features/profile/presentation/view/widgets/profile_body.dart new file mode 100644 index 0000000..1a59b49 --- /dev/null +++ b/lib/features/profile/presentation/view/widgets/profile_body.dart @@ -0,0 +1,51 @@ +import 'package:fitness_app/features/profile/presentation/view/widgets/profile_menu_list_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../core/base/base_state.dart'; +import '../../../../../core/utils/shared_widgets/blured_container.dart'; +import '../../../../../domain/auth/entity/user_entity.dart'; +import '../../view_model/profile_cubit.dart'; +import '../../view_model/profile_state.dart'; + +class ProfileBody extends StatelessWidget { + const ProfileBody({super.key}); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final profileState = state.profileState; + if (profileState is BaseLoadingState) { + return const Center(child: CircularProgressIndicator()); + } + if (profileState is BaseSuccessState) { + final user = profileState.data!; + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircleAvatar( + radius: 50, + backgroundImage: NetworkImage(user.photo!), + ), + const SizedBox(height: 8), + Text( + '${user.firstName!} ${user.lastName!}', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w600, + fontSize: 20, + ), + ), + const SizedBox(height: 40), + const BluredContainer( + padding: EdgeInsets.symmetric(vertical: 8), + child: ProfileMenuList(), + ), + ], + ); + } + return const SizedBox.shrink(); + }, + ); + } +} diff --git a/lib/features/profile/presentation/view/widgets/profile_menu_item_widget.dart b/lib/features/profile/presentation/view/widgets/profile_menu_item_widget.dart new file mode 100644 index 0000000..5815463 --- /dev/null +++ b/lib/features/profile/presentation/view/widgets/profile_menu_item_widget.dart @@ -0,0 +1,49 @@ +import 'package:fitness_app/core/assets/app_colors.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class ProfileMenuItemWidget extends StatelessWidget { + final String icon; + final String label; + final Widget? trailing; + final VoidCallback? onTap; + final Color? labelColor; + + const ProfileMenuItemWidget({ + super.key, + required this.icon, + required this.label, + this.trailing, + this.onTap, + this.labelColor, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + leading: SvgPicture.asset( + icon, + width: 24, + height: 24, + colorFilter: const ColorFilter.mode(AppColors.orange, BlendMode.srcIn), + ), + title: Text( + label, + style: Theme.of(context).textTheme.labelLarge!.copyWith( + fontWeight: FontWeight.w600, + fontStyle: FontStyle.normal, + fontSize: 14, + color: labelColor ?? AppColors.white, + ), + ), + trailing: + trailing ?? + const Icon( + Icons.arrow_forward_ios, + color: AppColors.orange, + size: 16, + ), + onTap: onTap, + ); + } +} diff --git a/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart b/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart new file mode 100644 index 0000000..0afbdc9 --- /dev/null +++ b/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart @@ -0,0 +1,80 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:fitness_app/features/profile/presentation/view_model/profile_cubit.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../core/assets/app_colors.dart'; +import '../../../../../core/assets/app_icons.dart'; +import '../../../../../core/utils/constants.dart'; +import '../../../../../core/utils/l10n/locale_keys.g.dart'; +import '../../../../../core/utils/routes/app_routes.dart'; +import '../../view_model/profile_state.dart'; +import 'profile_menu_item_widget.dart'; + +class ProfileMenuList extends StatelessWidget { + const ProfileMenuList({super.key}); + + @override + Widget build(BuildContext context) { + final viewModel = context.read(); + return Column( + children: [ + ProfileMenuItemWidget( + icon: AppIcons.profileIcon, + label: LocaleKeys.EditProfile.tr(), + onTap: () => Navigator.pushNamed(context, AppRoutes.editProfileRoute), + ), + ProfileMenuItemWidget( + icon: AppIcons.changePasswordIcon, + label: LocaleKeys.ChangePassword.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.changeLanguageIcon, + label: + '${LocaleKeys.SelectLanguage.tr()} (${context.locale.languageCode == Constants.en ? LocaleKeys.English.tr() : LocaleKeys.Arabic.tr()})', + trailing: Transform.scale( + scale: 0.8, + child: Switch( + padding: EdgeInsets.zero, + activeColor: AppColors.white, + activeTrackColor: AppColors.orange, + inactiveThumbColor: AppColors.white, + inactiveTrackColor: AppColors.darkgrey, + value: context.locale.languageCode == Constants.en, + onChanged: (value) { + viewModel.doIntent( + SelectLanguageAction(value ? Constants.en : Constants.ar), + ); + context.setLocale(Locale(value ? Constants.en : Constants.ar)); + }, + ), + ), + ), + ProfileMenuItemWidget( + icon: AppIcons.lockSettingsIcon, + label: LocaleKeys.Security.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.securityWarningIcon, + label: LocaleKeys.PrivacyPolicy.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.helpIcon, + label: LocaleKeys.Help.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.logoutIcon, + label: LocaleKeys.Logout.tr(), + labelColor: AppColors.orange, + onTap: () { + viewModel.doIntent(LogoutAction()); + }, + ), + ], + ); + } +} diff --git a/lib/features/profile/presentation/view_model/profile_cubit.dart b/lib/features/profile/presentation/view_model/profile_cubit.dart index 374bb8f..b0744ad 100644 --- a/lib/features/profile/presentation/view_model/profile_cubit.dart +++ b/lib/features/profile/presentation/view_model/profile_cubit.dart @@ -3,11 +3,13 @@ import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; import 'package:fitness_app/domain/auth/entity/user_entity.dart'; import 'package:fitness_app/features/profile/presentation/view_model/profile_state.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:injectable/injectable.dart'; import '../../../../domain/auth/use_case/get_profile_data_use_case.dart'; import '../../../../domain/auth/use_case/logout_use_case.dart'; import '../../../../domain/auth/use_case/select_language_use_case.dart'; +@injectable class ProfileCubit extends Cubit { final GetProfileDataUseCase _getProfileDataUseCase; final LogoutUseCase _logoutUseCase; diff --git a/lib/main.dart b/lib/main.dart index e0a688d..56266ba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -67,7 +67,7 @@ class _MyAppState extends State { title: Constants.appName, routes: AppRoutes.routes, theme: AppTheme.appTheme, - initialRoute: AppRoutes.mainLayoutRoute, + initialRoute: AppRoutes.profileRoute, ); }, ); diff --git a/test/core/functions/inital_route_function_test.mocks.dart b/test/core/functions/inital_route_function_test.mocks.dart index 8351c57..85f461d 100644 --- a/test/core/functions/inital_route_function_test.mocks.dart +++ b/test/core/functions/inital_route_function_test.mocks.dart @@ -25,65 +25,35 @@ import 'package:shared_preferences/src/shared_preferences_legacy.dart' as _i3; // ignore_for_file: subtype_of_sealed_class class _FakeIOSOptions_0 extends _i1.SmartFake implements _i2.IOSOptions { - _FakeIOSOptions_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeIOSOptions_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeAndroidOptions_1 extends _i1.SmartFake implements _i2.AndroidOptions { - _FakeAndroidOptions_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeAndroidOptions_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeLinuxOptions_2 extends _i1.SmartFake implements _i2.LinuxOptions { - _FakeLinuxOptions_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeLinuxOptions_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeWindowsOptions_3 extends _i1.SmartFake implements _i2.WindowsOptions { - _FakeWindowsOptions_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeWindowsOptions_3(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeWebOptions_4 extends _i1.SmartFake implements _i2.WebOptions { - _FakeWebOptions_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeWebOptions_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeMacOsOptions_5 extends _i1.SmartFake implements _i2.MacOsOptions { - _FakeMacOsOptions_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeMacOsOptions_5(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [SharedPreferences]. @@ -95,176 +65,118 @@ class MockSharedPreferences extends _i1.Mock implements _i3.SharedPreferences { } @override - Set getKeys() => (super.noSuchMethod( - Invocation.method( - #getKeys, - [], - ), - returnValue: {}, - ) as Set); + Set getKeys() => + (super.noSuchMethod( + Invocation.method(#getKeys, []), + returnValue: {}, + ) + as Set); @override - Object? get(String? key) => (super.noSuchMethod(Invocation.method( - #get, - [key], - )) as Object?); + Object? get(String? key) => + (super.noSuchMethod(Invocation.method(#get, [key])) as Object?); @override - bool? getBool(String? key) => (super.noSuchMethod(Invocation.method( - #getBool, - [key], - )) as bool?); + bool? getBool(String? key) => + (super.noSuchMethod(Invocation.method(#getBool, [key])) as bool?); @override - int? getInt(String? key) => (super.noSuchMethod(Invocation.method( - #getInt, - [key], - )) as int?); + int? getInt(String? key) => + (super.noSuchMethod(Invocation.method(#getInt, [key])) as int?); @override - double? getDouble(String? key) => (super.noSuchMethod(Invocation.method( - #getDouble, - [key], - )) as double?); + double? getDouble(String? key) => + (super.noSuchMethod(Invocation.method(#getDouble, [key])) as double?); @override - String? getString(String? key) => (super.noSuchMethod(Invocation.method( - #getString, - [key], - )) as String?); + String? getString(String? key) => + (super.noSuchMethod(Invocation.method(#getString, [key])) as String?); @override - bool containsKey(String? key) => (super.noSuchMethod( - Invocation.method( - #containsKey, - [key], - ), - returnValue: false, - ) as bool); + bool containsKey(String? key) => + (super.noSuchMethod( + Invocation.method(#containsKey, [key]), + returnValue: false, + ) + as bool); @override List? getStringList(String? key) => - (super.noSuchMethod(Invocation.method( - #getStringList, - [key], - )) as List?); + (super.noSuchMethod(Invocation.method(#getStringList, [key])) + as List?); + + @override + _i4.Future setBool(String? key, bool? value) => + (super.noSuchMethod( + Invocation.method(#setBool, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future setInt(String? key, int? value) => + (super.noSuchMethod( + Invocation.method(#setInt, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future setDouble(String? key, double? value) => + (super.noSuchMethod( + Invocation.method(#setDouble, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); @override - _i4.Future setBool( - String? key, - bool? value, - ) => + _i4.Future setString(String? key, String? value) => (super.noSuchMethod( - Invocation.method( - #setBool, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setInt( - String? key, - int? value, - ) => + Invocation.method(#setString, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future setStringList(String? key, List? value) => (super.noSuchMethod( - Invocation.method( - #setInt, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setDouble( - String? key, - double? value, - ) => + Invocation.method(#setStringList, [key, value]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future remove(String? key) => (super.noSuchMethod( - Invocation.method( - #setDouble, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setString( - String? key, - String? value, - ) => + Invocation.method(#remove, [key]), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future commit() => (super.noSuchMethod( - Invocation.method( - #setString, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future setStringList( - String? key, - List? value, - ) => + Invocation.method(#commit, []), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future clear() => (super.noSuchMethod( - Invocation.method( - #setStringList, - [ - key, - value, - ], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future remove(String? key) => (super.noSuchMethod( - Invocation.method( - #remove, - [key], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future commit() => (super.noSuchMethod( - Invocation.method( - #commit, - [], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future clear() => (super.noSuchMethod( - Invocation.method( - #clear, - [], - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); - - @override - _i4.Future reload() => (super.noSuchMethod( - Invocation.method( - #reload, - [], - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#clear, []), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); + + @override + _i4.Future reload() => + (super.noSuchMethod( + Invocation.method(#reload, []), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); } /// A class which mocks [FlutterSecureStorage]. @@ -277,112 +189,101 @@ class MockFlutterSecureStorage extends _i1.Mock } @override - _i2.IOSOptions get iOptions => (super.noSuchMethod( - Invocation.getter(#iOptions), - returnValue: _FakeIOSOptions_0( - this, - Invocation.getter(#iOptions), - ), - ) as _i2.IOSOptions); + _i2.IOSOptions get iOptions => + (super.noSuchMethod( + Invocation.getter(#iOptions), + returnValue: _FakeIOSOptions_0(this, Invocation.getter(#iOptions)), + ) + as _i2.IOSOptions); @override - _i2.AndroidOptions get aOptions => (super.noSuchMethod( - Invocation.getter(#aOptions), - returnValue: _FakeAndroidOptions_1( - this, - Invocation.getter(#aOptions), - ), - ) as _i2.AndroidOptions); + _i2.AndroidOptions get aOptions => + (super.noSuchMethod( + Invocation.getter(#aOptions), + returnValue: _FakeAndroidOptions_1( + this, + Invocation.getter(#aOptions), + ), + ) + as _i2.AndroidOptions); @override - _i2.LinuxOptions get lOptions => (super.noSuchMethod( - Invocation.getter(#lOptions), - returnValue: _FakeLinuxOptions_2( - this, - Invocation.getter(#lOptions), - ), - ) as _i2.LinuxOptions); + _i2.LinuxOptions get lOptions => + (super.noSuchMethod( + Invocation.getter(#lOptions), + returnValue: _FakeLinuxOptions_2( + this, + Invocation.getter(#lOptions), + ), + ) + as _i2.LinuxOptions); @override - _i2.WindowsOptions get wOptions => (super.noSuchMethod( - Invocation.getter(#wOptions), - returnValue: _FakeWindowsOptions_3( - this, - Invocation.getter(#wOptions), - ), - ) as _i2.WindowsOptions); + _i2.WindowsOptions get wOptions => + (super.noSuchMethod( + Invocation.getter(#wOptions), + returnValue: _FakeWindowsOptions_3( + this, + Invocation.getter(#wOptions), + ), + ) + as _i2.WindowsOptions); @override - _i2.WebOptions get webOptions => (super.noSuchMethod( - Invocation.getter(#webOptions), - returnValue: _FakeWebOptions_4( - this, - Invocation.getter(#webOptions), - ), - ) as _i2.WebOptions); + _i2.WebOptions get webOptions => + (super.noSuchMethod( + Invocation.getter(#webOptions), + returnValue: _FakeWebOptions_4( + this, + Invocation.getter(#webOptions), + ), + ) + as _i2.WebOptions); @override - _i2.MacOsOptions get mOptions => (super.noSuchMethod( - Invocation.getter(#mOptions), - returnValue: _FakeMacOsOptions_5( - this, - Invocation.getter(#mOptions), - ), - ) as _i2.MacOsOptions); + _i2.MacOsOptions get mOptions => + (super.noSuchMethod( + Invocation.getter(#mOptions), + returnValue: _FakeMacOsOptions_5( + this, + Invocation.getter(#mOptions), + ), + ) + as _i2.MacOsOptions); @override void registerListener({ required String? key, required _i5.ValueChanged? listener, - }) => - super.noSuchMethod( - Invocation.method( - #registerListener, - [], - { - #key: key, - #listener: listener, - }, - ), - returnValueForMissingStub: null, - ); + }) => super.noSuchMethod( + Invocation.method(#registerListener, [], {#key: key, #listener: listener}), + returnValueForMissingStub: null, + ); @override void unregisterListener({ required String? key, required _i5.ValueChanged? listener, - }) => - super.noSuchMethod( - Invocation.method( - #unregisterListener, - [], - { - #key: key, - #listener: listener, - }, - ), - returnValueForMissingStub: null, - ); + }) => super.noSuchMethod( + Invocation.method(#unregisterListener, [], { + #key: key, + #listener: listener, + }), + returnValueForMissingStub: null, + ); @override void unregisterAllListenersForKey({required String? key}) => super.noSuchMethod( - Invocation.method( - #unregisterAllListenersForKey, - [], - {#key: key}, - ), + Invocation.method(#unregisterAllListenersForKey, [], {#key: key}), returnValueForMissingStub: null, ); @override void unregisterAllListeners() => super.noSuchMethod( - Invocation.method( - #unregisterAllListeners, - [], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#unregisterAllListeners, []), + returnValueForMissingStub: null, + ); @override _i4.Future write({ @@ -396,23 +297,20 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #write, - [], - { - #key: key, - #value: value, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#write, [], { + #key: key, + #value: value, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); @override _i4.Future read({ @@ -425,21 +323,18 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #read, - [], - { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#read, [], { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + ) + as _i4.Future); @override _i4.Future containsKey({ @@ -452,21 +347,18 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #containsKey, - [], - { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); + Invocation.method(#containsKey, [], { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(false), + ) + as _i4.Future); @override _i4.Future delete({ @@ -479,22 +371,19 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #delete, - [], - { - #key: key, - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#delete, [], { + #key: key, + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); @override _i4.Future> readAll({ @@ -506,20 +395,19 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #readAll, - [], - { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future>.value({}), - ) as _i4.Future>); + Invocation.method(#readAll, [], { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future>.value( + {}, + ), + ) + as _i4.Future>); @override _i4.Future deleteAll({ @@ -531,28 +419,24 @@ class MockFlutterSecureStorage extends _i1.Mock _i2.WindowsOptions? wOptions, }) => (super.noSuchMethod( - Invocation.method( - #deleteAll, - [], - { - #iOptions: iOptions, - #aOptions: aOptions, - #lOptions: lOptions, - #webOptions: webOptions, - #mOptions: mOptions, - #wOptions: wOptions, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); - - @override - _i4.Future isCupertinoProtectedDataAvailable() => (super.noSuchMethod( - Invocation.method( - #isCupertinoProtectedDataAvailable, - [], - ), - returnValue: _i4.Future.value(), - ) as _i4.Future); + Invocation.method(#deleteAll, [], { + #iOptions: iOptions, + #aOptions: aOptions, + #lOptions: lOptions, + #webOptions: webOptions, + #mOptions: mOptions, + #wOptions: wOptions, + }), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); + + @override + _i4.Future isCupertinoProtectedDataAvailable() => + (super.noSuchMethod( + Invocation.method(#isCupertinoProtectedDataAvailable, []), + returnValue: _i4.Future.value(), + ) + as _i4.Future); } diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart index e11c627..ff9efcc 100644 --- a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart @@ -27,24 +27,14 @@ import 'package:mockito/mockito.dart' as _i1; class _FakeLogoutResponseDto_0 extends _i1.SmartFake implements _i2.LogoutResponseDto { - _FakeLogoutResponseDto_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeLogoutResponseDto_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUserDataResponseDto_1 extends _i1.SmartFake implements _i3.UserDataResponseDto { - _FakeUserDataResponseDto_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserDataResponseDto_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [AuthRetrofitClient]. @@ -57,34 +47,25 @@ class MockAuthRetrofitClient extends _i1.Mock } @override - _i5.Future<_i2.LogoutResponseDto> logout() => (super.noSuchMethod( - Invocation.method( - #logout, - [], - ), - returnValue: - _i5.Future<_i2.LogoutResponseDto>.value(_FakeLogoutResponseDto_0( - this, - Invocation.method( - #logout, - [], - ), - )), - ) as _i5.Future<_i2.LogoutResponseDto>); + _i5.Future<_i2.LogoutResponseDto> logout() => + (super.noSuchMethod( + Invocation.method(#logout, []), + returnValue: _i5.Future<_i2.LogoutResponseDto>.value( + _FakeLogoutResponseDto_0(this, Invocation.method(#logout, [])), + ), + ) + as _i5.Future<_i2.LogoutResponseDto>); @override - _i5.Future<_i3.UserDataResponseDto> getProfileData() => (super.noSuchMethod( - Invocation.method( - #getProfileData, - [], - ), - returnValue: _i5.Future<_i3.UserDataResponseDto>.value( - _FakeUserDataResponseDto_1( - this, - Invocation.method( - #getProfileData, - [], - ), - )), - ) as _i5.Future<_i3.UserDataResponseDto>); + _i5.Future<_i3.UserDataResponseDto> getProfileData() => + (super.noSuchMethod( + Invocation.method(#getProfileData, []), + returnValue: _i5.Future<_i3.UserDataResponseDto>.value( + _FakeUserDataResponseDto_1( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i5.Future<_i3.UserDataResponseDto>); } diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart index 8382d1c..5c1f3c4 100644 --- a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart +++ b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart @@ -35,24 +35,14 @@ import 'package:mockito/src/dummies.dart' as _i7; class _FakeUserDataResponseDto_0 extends _i1.SmartFake implements _i2.UserDataResponseDto { - _FakeUserDataResponseDto_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserDataResponseDto_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeLogoutResponseDto_1 extends _i1.SmartFake implements _i3.LogoutResponseDto { - _FakeLogoutResponseDto_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeLogoutResponseDto_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [ApiManager]. @@ -66,19 +56,15 @@ class MockApiManager extends _i1.Mock implements _i4.ApiManager { @override _i5.Future<_i6.Result> execute(_i5.Future Function()? apiCall) => (super.noSuchMethod( - Invocation.method( - #execute, - [apiCall], - ), - returnValue: - _i5.Future<_i6.Result>.value(_i7.dummyValue<_i6.Result>( - this, - Invocation.method( - #execute, - [apiCall], - ), - )), - ) as _i5.Future<_i6.Result>); + Invocation.method(#execute, [apiCall]), + returnValue: _i5.Future<_i6.Result>.value( + _i7.dummyValue<_i6.Result>( + this, + Invocation.method(#execute, [apiCall]), + ), + ), + ) + as _i5.Future<_i6.Result>); } /// A class which mocks [AuthLocalDataSource]. @@ -91,23 +77,21 @@ class MockAuthLocalDataSource extends _i1.Mock } @override - _i5.Future clearAll() => (super.noSuchMethod( - Invocation.method( - #clearAll, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future clearAll() => + (super.noSuchMethod( + Invocation.method(#clearAll, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future selectLanguage(String? languageCode) => (super.noSuchMethod( - Invocation.method( - #selectLanguage, - [languageCode], - ), - returnValue: _i5.Future.value(false), - ) as _i5.Future); + _i5.Future selectLanguage(String? languageCode) => + (super.noSuchMethod( + Invocation.method(#selectLanguage, [languageCode]), + returnValue: _i5.Future.value(false), + ) + as _i5.Future); } /// A class which mocks [AuthRemoteDataSource]. @@ -120,34 +104,25 @@ class MockAuthRemoteDataSource extends _i1.Mock } @override - _i5.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( - Invocation.method( - #getProfileData, - [], - ), - returnValue: _i5.Future<_i2.UserDataResponseDto>.value( - _FakeUserDataResponseDto_0( - this, - Invocation.method( - #getProfileData, - [], - ), - )), - ) as _i5.Future<_i2.UserDataResponseDto>); + _i5.Future<_i2.UserDataResponseDto> getProfileData() => + (super.noSuchMethod( + Invocation.method(#getProfileData, []), + returnValue: _i5.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i5.Future<_i2.UserDataResponseDto>); @override - _i5.Future<_i3.LogoutResponseDto> logout() => (super.noSuchMethod( - Invocation.method( - #logout, - [], - ), - returnValue: - _i5.Future<_i3.LogoutResponseDto>.value(_FakeLogoutResponseDto_1( - this, - Invocation.method( - #logout, - [], - ), - )), - ) as _i5.Future<_i3.LogoutResponseDto>); + _i5.Future<_i3.LogoutResponseDto> logout() => + (super.noSuchMethod( + Invocation.method(#logout, []), + returnValue: _i5.Future<_i3.LogoutResponseDto>.value( + _FakeLogoutResponseDto_1(this, Invocation.method(#logout, [])), + ), + ) + as _i5.Future<_i3.LogoutResponseDto>); } diff --git a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart index 14df73d..c37144c 100644 --- a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart +++ b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart @@ -37,50 +37,39 @@ class MockAuthRepo extends _i1.Mock implements _i2.AuthRepo { @override _i3.Future<_i4.Result<_i5.UserEntity>> getProfileData() => (super.noSuchMethod( - Invocation.method( - #getProfileData, - [], - ), - returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( - _i6.dummyValue<_i4.Result<_i5.UserEntity>>( - this, - Invocation.method( - #getProfileData, - [], - ), - )), - ) as _i3.Future<_i4.Result<_i5.UserEntity>>); + Invocation.method(#getProfileData, []), + returnValue: _i3.Future<_i4.Result<_i5.UserEntity>>.value( + _i6.dummyValue<_i4.Result<_i5.UserEntity>>( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i3.Future<_i4.Result<_i5.UserEntity>>); @override - _i3.Future<_i4.Result> logout() => (super.noSuchMethod( - Invocation.method( - #logout, - [], - ), - returnValue: - _i3.Future<_i4.Result>.value(_i6.dummyValue<_i4.Result>( - this, - Invocation.method( - #logout, - [], - ), - )), - ) as _i3.Future<_i4.Result>); + _i3.Future<_i4.Result> logout() => + (super.noSuchMethod( + Invocation.method(#logout, []), + returnValue: _i3.Future<_i4.Result>.value( + _i6.dummyValue<_i4.Result>( + this, + Invocation.method(#logout, []), + ), + ), + ) + as _i3.Future<_i4.Result>); @override - _i3.Future<_i4.Result> selectLanguage(String? languageCode) => + _i3.Future<_i4.Result> selectLanguage(String? languageCode) => (super.noSuchMethod( - Invocation.method( - #selectLanguage, - [languageCode], - ), - returnValue: - _i3.Future<_i4.Result>.value(_i6.dummyValue<_i4.Result>( - this, - Invocation.method( - #selectLanguage, - [languageCode], - ), - )), - ) as _i3.Future<_i4.Result>); + Invocation.method(#selectLanguage, [languageCode]), + returnValue: _i3.Future<_i4.Result>.value( + _i6.dummyValue<_i4.Result>( + this, + Invocation.method(#selectLanguage, [languageCode]), + ), + ), + ) + as _i3.Future<_i4.Result>); } diff --git a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart index 6258fc1..e9865dd 100644 --- a/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart +++ b/test/features/main_layout/presentation/view/main_layout_screen_test.mocks.dart @@ -35,124 +35,94 @@ class MockMainLayoutCubit extends _i1.Mock implements _i2.MainLayoutCubit { } @override - _i2.MainLayoutTabs get currentTab => (super.noSuchMethod( - Invocation.getter(#currentTab), - returnValue: _i2.MainLayoutTabs.home, - ) as _i2.MainLayoutTabs); + _i2.MainLayoutTabs get currentTab => + (super.noSuchMethod( + Invocation.getter(#currentTab), + returnValue: _i2.MainLayoutTabs.home, + ) + as _i2.MainLayoutTabs); @override set currentTab(_i2.MainLayoutTabs? _currentTab) => super.noSuchMethod( - Invocation.setter( - #currentTab, - _currentTab, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#currentTab, _currentTab), + returnValueForMissingStub: null, + ); @override Map<_i2.MainLayoutTabs, _i3.Widget Function()> get tabs => (super.noSuchMethod( - Invocation.getter(#tabs), - returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, - ) as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); + Invocation.getter(#tabs), + returnValue: <_i2.MainLayoutTabs, _i3.Widget Function()>{}, + ) + as Map<_i2.MainLayoutTabs, _i3.Widget Function()>); @override set tabs(Map<_i2.MainLayoutTabs, _i3.Widget Function()>? _tabs) => super.noSuchMethod( - Invocation.setter( - #tabs, - _tabs, - ), + Invocation.setter(#tabs, _tabs), returnValueForMissingStub: null, ); @override - _i2.MainLayoutState get state => (super.noSuchMethod( - Invocation.getter(#state), - returnValue: _i4.dummyValue<_i2.MainLayoutState>( - this, - Invocation.getter(#state), - ), - ) as _i2.MainLayoutState); + _i2.MainLayoutState get state => + (super.noSuchMethod( + Invocation.getter(#state), + returnValue: _i4.dummyValue<_i2.MainLayoutState>( + this, + Invocation.getter(#state), + ), + ) + as _i2.MainLayoutState); @override - _i5.Stream<_i2.MainLayoutState> get stream => (super.noSuchMethod( - Invocation.getter(#stream), - returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), - ) as _i5.Stream<_i2.MainLayoutState>); + _i5.Stream<_i2.MainLayoutState> get stream => + (super.noSuchMethod( + Invocation.getter(#stream), + returnValue: _i5.Stream<_i2.MainLayoutState>.empty(), + ) + as _i5.Stream<_i2.MainLayoutState>); @override - bool get isClosed => (super.noSuchMethod( - Invocation.getter(#isClosed), - returnValue: false, - ) as bool); + bool get isClosed => + (super.noSuchMethod(Invocation.getter(#isClosed), returnValue: false) + as bool); @override void doIntent(_i2.MainLayoutActions? action) => super.noSuchMethod( - Invocation.method( - #doIntent, - [action], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#doIntent, [action]), + returnValueForMissingStub: null, + ); @override void emit(_i2.MainLayoutState? state) => super.noSuchMethod( - Invocation.method( - #emit, - [state], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#emit, [state]), + returnValueForMissingStub: null, + ); @override void onChange(_i6.Change<_i2.MainLayoutState>? change) => super.noSuchMethod( - Invocation.method( - #onChange, - [change], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#onChange, [change]), + returnValueForMissingStub: null, + ); @override - void addError( - Object? error, [ - StackTrace? stackTrace, - ]) => - super.noSuchMethod( - Invocation.method( - #addError, - [ - error, - stackTrace, - ], - ), - returnValueForMissingStub: null, - ); + void addError(Object? error, [StackTrace? stackTrace]) => super.noSuchMethod( + Invocation.method(#addError, [error, stackTrace]), + returnValueForMissingStub: null, + ); @override - void onError( - Object? error, - StackTrace? stackTrace, - ) => - super.noSuchMethod( - Invocation.method( - #onError, - [ - error, - stackTrace, - ], - ), - returnValueForMissingStub: null, - ); + void onError(Object? error, StackTrace? stackTrace) => super.noSuchMethod( + Invocation.method(#onError, [error, stackTrace]), + returnValueForMissingStub: null, + ); @override - _i5.Future close() => (super.noSuchMethod( - Invocation.method( - #close, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future close() => + (super.noSuchMethod( + Invocation.method(#close, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } diff --git a/test/features/main_layout/presentation/view_model/main_layout_cubit_test.dart b/test/features/main_layout/presentation/view_model/main_layout_cubit_test.dart index c20c8f0..a78b318 100644 --- a/test/features/main_layout/presentation/view_model/main_layout_cubit_test.dart +++ b/test/features/main_layout/presentation/view_model/main_layout_cubit_test.dart @@ -2,7 +2,7 @@ import 'package:bloc_test/bloc_test.dart'; import 'package:fitness_app/features/chat_bot/presentation/view/chat_bot_screen.dart'; import 'package:fitness_app/features/home/presentation/view/home_screen.dart'; import 'package:fitness_app/features/main_layout/presentation/view_model/cubit/main_layout_cubit.dart'; -import 'package:fitness_app/features/profile/presentation/view/profile_screen.dart'; +import 'package:fitness_app/features/profile/presentation/view/screens/profile_screen.dart'; import 'package:fitness_app/features/workouts/presentation/view/workouts_screen.dart'; import 'package:flutter_test/flutter_test.dart'; From 7505edbc457dc9b687a15b95cdb1f9f84b64febd Mon Sep 17 00:00:00 2001 From: Eslam Date: Fri, 4 Jul 2025 20:30:35 +0300 Subject: [PATCH 08/12] feat(profile): Enhance logout functionality with confirmation dialog --- .../presentation/view/screens/profile_screen.dart | 1 + .../view/widgets/profile_menu_list_widget.dart | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/features/profile/presentation/view/screens/profile_screen.dart b/lib/features/profile/presentation/view/screens/profile_screen.dart index ec94ace..6b2fbe6 100644 --- a/lib/features/profile/presentation/view/screens/profile_screen.dart +++ b/lib/features/profile/presentation/view/screens/profile_screen.dart @@ -32,6 +32,7 @@ class ProfileScreen extends StatelessWidget { ); } if (logoutState is BaseSuccessState) { + AppDialogs.hideLoading(context); Navigator.pushNamedAndRemoveUntil( context, AppRoutes.loginRoute, diff --git a/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart b/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart index 0afbdc9..12b3506 100644 --- a/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart +++ b/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart @@ -1,4 +1,5 @@ import 'package:easy_localization/easy_localization.dart'; +import 'package:fitness_app/core/utils/dialogs/app_dialogs.dart'; import 'package:fitness_app/features/profile/presentation/view_model/profile_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -71,7 +72,16 @@ class ProfileMenuList extends StatelessWidget { label: LocaleKeys.Logout.tr(), labelColor: AppColors.orange, onTap: () { - viewModel.doIntent(LogoutAction()); + AppDialogs.showSuccessDialog( + context, + message: LocaleKeys.AreYouSureToCloseTheApplication.tr(), + firstButtonText: LocaleKeys.No.tr(), + secondButtonText: LocaleKeys.Yes.tr(), + firstButtonAction: () => Navigator.of(context).pop(), + secondButtonAction: () { + viewModel.doIntent(LogoutAction()); + }, + ); }, ), ], From 8babc2234e195c6e835707525c958669332bf0e3 Mon Sep 17 00:00:00 2001 From: Eslam Date: Fri, 4 Jul 2025 20:45:00 +0300 Subject: [PATCH 09/12] refactor(profile): merged dev and solved conflicts --- lib/core/utils/di/di.config.dart | 80 +++--- lib/data/auth/api/auth_retrofit_client.g.dart | 54 ++++ .../contract/auth_remote_data_source.dart | 12 +- .../local/auth_local_data_source_impl.dart | 1 - .../remote/auth_remote_data_source_impl.dart | 13 +- lib/data/auth/repo_impl/auth_repo_impl.dart | 16 +- lib/domain/auth/repo/auth_repo.dart | 13 +- ...th_remote_data_source_impl_test.mocks.dart | 104 +++++--- ...th_remote_data_source_impl_test.mocks.dart | 93 ++++++- .../auth/repo_impl/auth_repo_impl_test.dart | 61 +++-- .../repo_impl/auth_repo_impl_test.mocks.dart | 231 +++++++++++------- .../get_profile_data_use_case_test.mocks.dart | 60 +++++ 12 files changed, 517 insertions(+), 221 deletions(-) diff --git a/lib/core/utils/di/di.config.dart b/lib/core/utils/di/di.config.dart index 44435b9..95ae64e 100644 --- a/lib/core/utils/di/di.config.dart +++ b/lib/core/utils/di/di.config.dart @@ -37,8 +37,11 @@ import '../../../data/home/data_source/remote/home_remote_data_source_impl.dart' import '../../../data/home/repo_impl/home_repo_impl.dart' as _i779; import '../../../domain/auth/repo/auth_repo.dart' as _i1047; import '../../../domain/auth/use_case/forget_password_use_case.dart' as _i728; +import '../../../domain/auth/use_case/get_profile_data_use_case.dart' as _i336; +import '../../../domain/auth/use_case/logout_use_case.dart' as _i1046; import '../../../domain/auth/use_case/otp_verification_use_case.dart' as _i777; import '../../../domain/auth/use_case/reset_password_use_case.dart' as _i55; +import '../../../domain/auth/use_case/select_language_use_case.dart' as _i753; import '../../../domain/home/repo/home_repo.dart' as _i81; import '../../../domain/home/use_case/get_all_muscles_use_case.dart' as _i840; import '../../../domain/home/use_case/get_daily_recommendation_exercise_use_case.dart' @@ -59,6 +62,8 @@ import '../../../features/onBoarding/presentation/view_model/cubit/on_boarding_c as _i485; import '../../../features/otp_verification/presentation/view_model/cubit/otp_verification_cubit.dart' as _i662; +import '../../../features/profile/presentation/view_model/profile_cubit.dart' + as _i782; import '../../../features/reset_password/presentation/view_model/cubit/reset_password_cubit.dart' as _i893; import '../../functions/inital_route_function.dart' as _i420; @@ -97,15 +102,18 @@ extension GetItInjectableX on _i174.GetIt { gh.singleton<_i649.BlocObserverService>( () => _i649.BlocObserverService(gh<_i974.Logger>()), ); - gh.factory<_i1063.AuthLocalDataSource>( - () => _i757.AuthLocalDataSourceImpl(gh<_i558.FlutterSecureStorage>()), - ); gh.factory<_i420.RouteInitializer>( () => _i420.RouteInitializer( flutterSecureStorage: gh<_i558.FlutterSecureStorage>(), sharedPreferences: gh<_i460.SharedPreferences>(), ), ); + gh.factory<_i1063.AuthLocalDataSource>( + () => _i757.AuthLocalDataSourceImpl( + gh<_i460.SharedPreferences>(), + gh<_i558.FlutterSecureStorage>(), + ), + ); gh.factory<_i368.HomeLocalDataSource>( () => _i410.HomeLocalDataSourceImpl(), ); @@ -127,10 +135,28 @@ extension GetItInjectableX on _i174.GetIt { gh.factory<_i1047.AuthRepo>( () => _i15.AuthRepoImpl( gh<_i28.ApiManager>(), - gh<_i774.AuthRemoteDataSource>(), gh<_i1063.AuthLocalDataSource>(), + gh<_i774.AuthRemoteDataSource>(), ), ); + gh.factory<_i728.ForgetPasswordUseCase>( + () => _i728.ForgetPasswordUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i336.GetProfileDataUseCase>( + () => _i336.GetProfileDataUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i1046.LogoutUseCase>( + () => _i1046.LogoutUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i777.OtpVerificationUseCase>( + () => _i777.OtpVerificationUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i55.ResetPasswordUseCase>( + () => _i55.ResetPasswordUseCase(gh<_i1047.AuthRepo>()), + ); + gh.factory<_i753.SelectLanguageUseCase>( + () => _i753.SelectLanguageUseCase(gh<_i1047.AuthRepo>()), + ); gh.factory<_i81.HomeRepo>( () => _i779.HomeRepoImpl( gh<_i958.HomeRemoteDataSource>(), @@ -138,14 +164,30 @@ extension GetItInjectableX on _i174.GetIt { gh<_i28.ApiManager>(), ), ); - gh.factory<_i728.ForgetPasswordUseCase>( - () => _i728.ForgetPasswordUseCase(gh<_i1047.AuthRepo>()), + gh.factory<_i782.ProfileCubit>( + () => _i782.ProfileCubit( + gh<_i336.GetProfileDataUseCase>(), + gh<_i1046.LogoutUseCase>(), + gh<_i753.SelectLanguageUseCase>(), + ), ); - gh.factory<_i777.OtpVerificationUseCase>( - () => _i777.OtpVerificationUseCase(gh<_i1047.AuthRepo>()), + gh.factory<_i662.OtpVerificationCubit>( + () => _i662.OtpVerificationCubit( + gh<_i777.OtpVerificationUseCase>(), + gh<_i728.ForgetPasswordUseCase>(), + ), ); - gh.factory<_i55.ResetPasswordUseCase>( - () => _i55.ResetPasswordUseCase(gh<_i1047.AuthRepo>()), + gh.factory<_i893.ResetPasswordCubit>( + () => _i893.ResetPasswordCubit( + gh<_i55.ResetPasswordUseCase>(), + gh<_i468.Validator>(), + ), + ); + gh.factory<_i70.ForgetPasswordCubit>( + () => _i70.ForgetPasswordCubit( + gh<_i728.ForgetPasswordUseCase>(), + gh<_i468.Validator>(), + ), ); gh.factory<_i840.GetAllMusclesUseCase>( () => _i840.GetAllMusclesUseCase(gh<_i81.HomeRepo>()), @@ -171,24 +213,6 @@ extension GetItInjectableX on _i174.GetIt { gh<_i840.GetAllMusclesUseCase>(), ), ); - gh.factory<_i662.OtpVerificationCubit>( - () => _i662.OtpVerificationCubit( - gh<_i777.OtpVerificationUseCase>(), - gh<_i728.ForgetPasswordUseCase>(), - ), - ); - gh.factory<_i893.ResetPasswordCubit>( - () => _i893.ResetPasswordCubit( - gh<_i55.ResetPasswordUseCase>(), - gh<_i468.Validator>(), - ), - ); - gh.factory<_i70.ForgetPasswordCubit>( - () => _i70.ForgetPasswordCubit( - gh<_i728.ForgetPasswordUseCase>(), - gh<_i468.Validator>(), - ), - ); return this; } } diff --git a/lib/data/auth/api/auth_retrofit_client.g.dart b/lib/data/auth/api/auth_retrofit_client.g.dart index 92a048e..a56799e 100644 --- a/lib/data/auth/api/auth_retrofit_client.g.dart +++ b/lib/data/auth/api/auth_retrofit_client.g.dart @@ -19,6 +19,60 @@ class _AuthRetrofitClient implements AuthRetrofitClient { final ParseErrorLogger? errorLogger; + @override + Future logout() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'auth/logout', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch>(_options); + late LogoutResponseDto _value; + try { + _value = LogoutResponseDto.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + + @override + Future getProfileData() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'auth/profile-data', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch>(_options); + late UserDataResponseDto _value; + try { + _value = UserDataResponseDto.fromJson(_result.data!); + } on Object catch (e, s) { + errorLogger?.logError(e, s, _options); + rethrow; + } + return _value; + } + @override Future forgetPassword( ForgetPasswordRequestDto request, diff --git a/lib/data/auth/data_source/contract/auth_remote_data_source.dart b/lib/data/auth/data_source/contract/auth_remote_data_source.dart index 4c4f19e..9e4ebf0 100644 --- a/lib/data/auth/data_source/contract/auth_remote_data_source.dart +++ b/lib/data/auth/data_source/contract/auth_remote_data_source.dart @@ -13,14 +13,14 @@ abstract class AuthRemoteDataSource { Future logout(); Future forgetPassword( - ForgetPasswordRequestDto request, - ); + ForgetPasswordRequestDto request, + ); Future verifyOtp( - OtpVerificationRequestDto request, - ); + OtpVerificationRequestDto request, + ); Future resetPassword( - ResetPasswordRequestDto request, - ); + ResetPasswordRequestDto request, + ); } diff --git a/lib/data/auth/data_source/local/auth_local_data_source_impl.dart b/lib/data/auth/data_source/local/auth_local_data_source_impl.dart index 152f7cf..b2fa7ac 100644 --- a/lib/data/auth/data_source/local/auth_local_data_source_impl.dart +++ b/lib/data/auth/data_source/local/auth_local_data_source_impl.dart @@ -39,5 +39,4 @@ class AuthLocalDataSourceImpl implements AuthLocalDataSource { Future saveToken(String key, String value) async { await _flutterSecureStorage.write(key: key, value: value); } - } diff --git a/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart b/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart index 0b2bfbb..da31bce 100644 --- a/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart +++ b/lib/data/auth/data_source/remote/auth_remote_data_source_impl.dart @@ -3,7 +3,6 @@ import 'package:fitness_app/data/auth/models/logout_response_dto.dart'; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; import 'package:injectable/injectable.dart'; -import '../../api/auth_retrofit_client.dart'; import '../../models/forget_password/request/forget_password_request_dto.dart'; import '../../models/forget_password/response/forget_password_response_dto.dart'; import '../../models/otp_verification/request/otp_verification_request_dto.dart'; @@ -30,24 +29,24 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource { @override Future forgetPassword( - ForgetPasswordRequestDto request, - ) async { + ForgetPasswordRequestDto request, + ) async { var response = await _authRetrofitClient.forgetPassword(request); return response; } @override Future verifyOtp( - OtpVerificationRequestDto request, - ) async { + OtpVerificationRequestDto request, + ) async { var response = await _authRetrofitClient.verifyOtp(request); return response; } @override Future resetPassword( - ResetPasswordRequestDto request, - ) async { + ResetPasswordRequestDto request, + ) async { var response = await _authRetrofitClient.resetPassword(request); return response; } diff --git a/lib/data/auth/repo_impl/auth_repo_impl.dart b/lib/data/auth/repo_impl/auth_repo_impl.dart index 32abb54..37f8b9e 100644 --- a/lib/data/auth/repo_impl/auth_repo_impl.dart +++ b/lib/data/auth/repo_impl/auth_repo_impl.dart @@ -6,8 +6,6 @@ import 'package:fitness_app/domain/auth/entity/user_entity.dart'; import 'package:injectable/injectable.dart'; import '../../../core/utils/constants.dart'; -import '../../../core/utils/datasource_excution/api_manager.dart'; -import '../../../core/utils/datasource_excution/api_result.dart'; import '../../../domain/auth/entity/forget_password/forget_password_request_entity.dart'; import '../../../domain/auth/entity/forget_password/forget_password_response_entity.dart'; import '../../../domain/auth/entity/otp_verification/request/otp_verification_request_entity.dart'; @@ -15,8 +13,6 @@ import '../../../domain/auth/entity/otp_verification/response/otp_verification_r import '../../../domain/auth/entity/reset_password/request/reset_password_request_entity.dart'; import '../../../domain/auth/entity/reset_password/response/reset_password_response_entity.dart'; import '../../../domain/auth/repo/auth_repo.dart'; -import '../data_source/contract/auth_local_data_source.dart'; -import '../data_source/contract/auth_remote_data_source.dart'; import '../models/forget_password/request/forget_password_request_dto.dart'; import '../models/otp_verification/request/otp_verification_request_dto.dart'; import '../models/reset_password/request/reset_password_request_dto.dart'; @@ -62,8 +58,8 @@ class AuthRepoImpl implements AuthRepo { @override Future> forgetPassword( - ForgetPasswordRequestEntity request, - ) { + ForgetPasswordRequestEntity request, + ) { var response = _apiManager.execute(() async { var response = await _authRemoteDataSource.forgetPassword( ForgetPasswordRequestDto.fromDomain(request), @@ -75,8 +71,8 @@ class AuthRepoImpl implements AuthRepo { @override Future> verifyOtp( - OtpVerificationRequestEntity request, - ) { + OtpVerificationRequestEntity request, + ) { var response = _apiManager.execute(() async { var response = await _authRemoteDataSource.verifyOtp( OtpVerificationRequestDto.fromDomain(request), @@ -88,8 +84,8 @@ class AuthRepoImpl implements AuthRepo { @override Future> resetPassword( - ResetPasswordRequestEntity request, - ) { + ResetPasswordRequestEntity request, + ) { var response = _apiManager.execute(() async { var response = await _authRemoteDataSource.resetPassword( ResetPasswordRequestDto.fromDomain(request), diff --git a/lib/domain/auth/repo/auth_repo.dart b/lib/domain/auth/repo/auth_repo.dart index 85456d1..955df4f 100644 --- a/lib/domain/auth/repo/auth_repo.dart +++ b/lib/domain/auth/repo/auth_repo.dart @@ -1,6 +1,5 @@ import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; import 'package:fitness_app/domain/auth/entity/user_entity.dart'; -import '../../../core/utils/datasource_excution/api_result.dart'; import '../entity/forget_password/forget_password_request_entity.dart'; import '../entity/forget_password/forget_password_response_entity.dart'; import '../entity/otp_verification/request/otp_verification_request_entity.dart'; @@ -16,14 +15,14 @@ abstract class AuthRepo { Future> selectLanguage(String languageCode); Future> forgetPassword( - ForgetPasswordRequestEntity request, - ); + ForgetPasswordRequestEntity request, + ); Future> verifyOtp( - OtpVerificationRequestEntity request, - ); + OtpVerificationRequestEntity request, + ); Future> resetPassword( - ResetPasswordRequestEntity request, - ); + ResetPasswordRequestEntity request, + ); } diff --git a/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart index 21c15ca..ebcb894 100644 --- a/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart +++ b/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart @@ -3,21 +3,24 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i6; +import 'dart:async' as _i8; -import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i5; +import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i7; import 'package:fitness_app/data/auth/models/forget_password/request/forget_password_request_dto.dart' - as _i7; + as _i9; import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart' - as _i2; + as _i4; +import 'package:fitness_app/data/auth/models/logout_response_dto.dart' as _i2; import 'package:fitness_app/data/auth/models/otp_verification/request/otp_verification_request_dto.dart' - as _i8; + as _i10; import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart' - as _i3; + as _i5; import 'package:fitness_app/data/auth/models/reset_password/request/reset_password_request_dto.dart' - as _i9; + as _i11; import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart' - as _i4; + as _i6; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' + as _i3; import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint @@ -34,21 +37,33 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeForgetPasswordResponseDto_0 extends _i1.SmartFake - implements _i2.ForgetPasswordResponseDto { - _FakeForgetPasswordResponseDto_0(Object parent, Invocation parentInvocation) +class _FakeLogoutResponseDto_0 extends _i1.SmartFake + implements _i2.LogoutResponseDto { + _FakeLogoutResponseDto_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeUserDataResponseDto_1 extends _i1.SmartFake + implements _i3.UserDataResponseDto { + _FakeUserDataResponseDto_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeForgetPasswordResponseDto_2 extends _i1.SmartFake + implements _i4.ForgetPasswordResponseDto { + _FakeForgetPasswordResponseDto_2(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeOtpVerificationResponseDto_1 extends _i1.SmartFake - implements _i3.OtpVerificationResponseDto { - _FakeOtpVerificationResponseDto_1(Object parent, Invocation parentInvocation) +class _FakeOtpVerificationResponseDto_3 extends _i1.SmartFake + implements _i5.OtpVerificationResponseDto { + _FakeOtpVerificationResponseDto_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeResetPasswordResponseDto_2 extends _i1.SmartFake - implements _i4.ResetPasswordResponseDto { - _FakeResetPasswordResponseDto_2(Object parent, Invocation parentInvocation) +class _FakeResetPasswordResponseDto_4 extends _i1.SmartFake + implements _i6.ResetPasswordResponseDto { + _FakeResetPasswordResponseDto_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } @@ -56,53 +71,76 @@ class _FakeResetPasswordResponseDto_2 extends _i1.SmartFake /// /// See the documentation for Mockito's code generation for more information. class MockAuthRetrofitClient extends _i1.Mock - implements _i5.AuthRetrofitClient { + implements _i7.AuthRetrofitClient { MockAuthRetrofitClient() { _i1.throwOnMissingStub(this); } @override - _i6.Future<_i2.ForgetPasswordResponseDto> forgetPassword( - _i7.ForgetPasswordRequestDto? request, + _i8.Future<_i2.LogoutResponseDto> logout() => + (super.noSuchMethod( + Invocation.method(#logout, []), + returnValue: _i8.Future<_i2.LogoutResponseDto>.value( + _FakeLogoutResponseDto_0(this, Invocation.method(#logout, [])), + ), + ) + as _i8.Future<_i2.LogoutResponseDto>); + + @override + _i8.Future<_i3.UserDataResponseDto> getProfileData() => + (super.noSuchMethod( + Invocation.method(#getProfileData, []), + returnValue: _i8.Future<_i3.UserDataResponseDto>.value( + _FakeUserDataResponseDto_1( + this, + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i8.Future<_i3.UserDataResponseDto>); + + @override + _i8.Future<_i4.ForgetPasswordResponseDto> forgetPassword( + _i9.ForgetPasswordRequestDto? request, ) => (super.noSuchMethod( Invocation.method(#forgetPassword, [request]), - returnValue: _i6.Future<_i2.ForgetPasswordResponseDto>.value( - _FakeForgetPasswordResponseDto_0( + returnValue: _i8.Future<_i4.ForgetPasswordResponseDto>.value( + _FakeForgetPasswordResponseDto_2( this, Invocation.method(#forgetPassword, [request]), ), ), ) - as _i6.Future<_i2.ForgetPasswordResponseDto>); + as _i8.Future<_i4.ForgetPasswordResponseDto>); @override - _i6.Future<_i3.OtpVerificationResponseDto> verifyOtp( - _i8.OtpVerificationRequestDto? request, + _i8.Future<_i5.OtpVerificationResponseDto> verifyOtp( + _i10.OtpVerificationRequestDto? request, ) => (super.noSuchMethod( Invocation.method(#verifyOtp, [request]), - returnValue: _i6.Future<_i3.OtpVerificationResponseDto>.value( - _FakeOtpVerificationResponseDto_1( + returnValue: _i8.Future<_i5.OtpVerificationResponseDto>.value( + _FakeOtpVerificationResponseDto_3( this, Invocation.method(#verifyOtp, [request]), ), ), ) - as _i6.Future<_i3.OtpVerificationResponseDto>); + as _i8.Future<_i5.OtpVerificationResponseDto>); @override - _i6.Future<_i4.ResetPasswordResponseDto> resetPassword( - _i9.ResetPasswordRequestDto? request, + _i8.Future<_i6.ResetPasswordResponseDto> resetPassword( + _i11.ResetPasswordRequestDto? request, ) => (super.noSuchMethod( Invocation.method(#resetPassword, [request]), - returnValue: _i6.Future<_i4.ResetPasswordResponseDto>.value( - _FakeResetPasswordResponseDto_2( + returnValue: _i8.Future<_i6.ResetPasswordResponseDto>.value( + _FakeResetPasswordResponseDto_4( this, Invocation.method(#resetPassword, [request]), ), ), ) - as _i6.Future<_i4.ResetPasswordResponseDto>); + as _i8.Future<_i6.ResetPasswordResponseDto>); } diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart index ff9efcc..b41ca2d 100644 --- a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.mocks.dart @@ -3,10 +3,22 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i5; +import 'dart:async' as _i8; -import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i4; +import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i7; +import 'package:fitness_app/data/auth/models/forget_password/request/forget_password_request_dto.dart' + as _i9; +import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart' + as _i4; import 'package:fitness_app/data/auth/models/logout_response_dto.dart' as _i2; +import 'package:fitness_app/data/auth/models/otp_verification/request/otp_verification_request_dto.dart' + as _i10; +import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart' + as _i5; +import 'package:fitness_app/data/auth/models/reset_password/request/reset_password_request_dto.dart' + as _i11; +import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart' + as _i6; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' as _i3; import 'package:mockito/mockito.dart' as _i1; @@ -37,35 +49,98 @@ class _FakeUserDataResponseDto_1 extends _i1.SmartFake : super(parent, parentInvocation); } +class _FakeForgetPasswordResponseDto_2 extends _i1.SmartFake + implements _i4.ForgetPasswordResponseDto { + _FakeForgetPasswordResponseDto_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeOtpVerificationResponseDto_3 extends _i1.SmartFake + implements _i5.OtpVerificationResponseDto { + _FakeOtpVerificationResponseDto_3(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeResetPasswordResponseDto_4 extends _i1.SmartFake + implements _i6.ResetPasswordResponseDto { + _FakeResetPasswordResponseDto_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + /// A class which mocks [AuthRetrofitClient]. /// /// See the documentation for Mockito's code generation for more information. class MockAuthRetrofitClient extends _i1.Mock - implements _i4.AuthRetrofitClient { + implements _i7.AuthRetrofitClient { MockAuthRetrofitClient() { _i1.throwOnMissingStub(this); } @override - _i5.Future<_i2.LogoutResponseDto> logout() => + _i8.Future<_i2.LogoutResponseDto> logout() => (super.noSuchMethod( Invocation.method(#logout, []), - returnValue: _i5.Future<_i2.LogoutResponseDto>.value( + returnValue: _i8.Future<_i2.LogoutResponseDto>.value( _FakeLogoutResponseDto_0(this, Invocation.method(#logout, [])), ), ) - as _i5.Future<_i2.LogoutResponseDto>); + as _i8.Future<_i2.LogoutResponseDto>); @override - _i5.Future<_i3.UserDataResponseDto> getProfileData() => + _i8.Future<_i3.UserDataResponseDto> getProfileData() => (super.noSuchMethod( Invocation.method(#getProfileData, []), - returnValue: _i5.Future<_i3.UserDataResponseDto>.value( + returnValue: _i8.Future<_i3.UserDataResponseDto>.value( _FakeUserDataResponseDto_1( this, Invocation.method(#getProfileData, []), ), ), ) - as _i5.Future<_i3.UserDataResponseDto>); + as _i8.Future<_i3.UserDataResponseDto>); + + @override + _i8.Future<_i4.ForgetPasswordResponseDto> forgetPassword( + _i9.ForgetPasswordRequestDto? request, + ) => + (super.noSuchMethod( + Invocation.method(#forgetPassword, [request]), + returnValue: _i8.Future<_i4.ForgetPasswordResponseDto>.value( + _FakeForgetPasswordResponseDto_2( + this, + Invocation.method(#forgetPassword, [request]), + ), + ), + ) + as _i8.Future<_i4.ForgetPasswordResponseDto>); + + @override + _i8.Future<_i5.OtpVerificationResponseDto> verifyOtp( + _i10.OtpVerificationRequestDto? request, + ) => + (super.noSuchMethod( + Invocation.method(#verifyOtp, [request]), + returnValue: _i8.Future<_i5.OtpVerificationResponseDto>.value( + _FakeOtpVerificationResponseDto_3( + this, + Invocation.method(#verifyOtp, [request]), + ), + ), + ) + as _i8.Future<_i5.OtpVerificationResponseDto>); + + @override + _i8.Future<_i6.ResetPasswordResponseDto> resetPassword( + _i11.ResetPasswordRequestDto? request, + ) => + (super.noSuchMethod( + Invocation.method(#resetPassword, [request]), + returnValue: _i8.Future<_i6.ResetPasswordResponseDto>.value( + _FakeResetPasswordResponseDto_4( + this, + Invocation.method(#resetPassword, [request]), + ), + ), + ) + as _i8.Future<_i6.ResetPasswordResponseDto>); } diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.dart b/test/data/auth/repo_impl/auth_repo_impl_test.dart index bb4ca40..61cb607 100644 --- a/test/data/auth/repo_impl/auth_repo_impl_test.dart +++ b/test/data/auth/repo_impl/auth_repo_impl_test.dart @@ -4,8 +4,6 @@ import 'package:fitness_app/core/utils/datasource_excution/api_result.dart'; import 'package:fitness_app/data/auth/data_source/contract/auth_local_data_source.dart'; import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart'; import 'package:fitness_app/data/auth/models/user_dto.dart'; -import 'package:fitness_app/data/auth/data_source/local/auth_local_data_source_impl.dart'; -import 'package:fitness_app/data/auth/data_source/remote/auth_remote_data_source_impl.dart'; import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart'; import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart'; import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart'; @@ -160,7 +158,7 @@ void main() { group('forgetPassword', () { test( 'should return SuccessResult when forgetPassword is successful', - () async { + () async { // Arrange provideDummy>( SuccessResult( @@ -176,8 +174,8 @@ void main() { mockApiManager.execute(any), ).thenAnswer((invocation) async { final function = - invocation.positionalArguments.first - as Future Function(); + invocation.positionalArguments.first + as Future Function(); final result = await function(); return SuccessResult(result); }); @@ -196,7 +194,7 @@ void main() { test( 'should return FailureResult when forgetPassword throws an exception', - () async { + () async { // Arrange provideDummy>( FailureResult(networkException), @@ -228,7 +226,7 @@ void main() { test( 'should return FailureResult when forgetPassword returns null or invalid response', - () async { + () async { // Arrange provideDummy>( FailureResult(invalidOrNullException), @@ -262,7 +260,7 @@ void main() { test( 'should throw exception when apiManager.execute throws unexpected exception', - () async { + () async { // Arrange provideDummy>( FailureResult(unexpectedException), @@ -278,11 +276,11 @@ void main() { // Act & Assert expect( - () async => - await authRepoImpl.forgetPassword(forgetPasswordRequestEntity), + () async => + await authRepoImpl.forgetPassword(forgetPasswordRequestEntity), throwsA( isA().having( - (e) => e.toString(), + (e) => e.toString(), 'message', contains(unexcpctedError), ), @@ -309,8 +307,8 @@ void main() { mockApiManager.execute(any), ).thenAnswer((invocation) async { final function = - invocation.positionalArguments.first - as Future Function(); + invocation.positionalArguments.first + as Future Function(); final result = await function(); return SuccessResult(result); }); @@ -325,7 +323,7 @@ void main() { test( 'should return FailureResult when verifyOtp throws an exception', - () async { + () async { // Arrange provideDummy>( FailureResult(networkException), @@ -357,7 +355,7 @@ void main() { test( 'should return FailureResult when verifyOtp returns null or invalid response', - () async { + () async { // Arrange provideDummy>( FailureResult(invalidOrNullException), @@ -391,7 +389,7 @@ void main() { test( 'should throw exception when apiManager.execute throws unexpected exception', - () async { + () async { // Arrange provideDummy>( FailureResult(unexpectedException), @@ -407,11 +405,11 @@ void main() { // Act & Assert expect( - () async => - await authRepoImpl.verifyOtp(otpVerificationRequestEntity), + () async => + await authRepoImpl.verifyOtp(otpVerificationRequestEntity), throwsA( isA().having( - (e) => e.toString(), + (e) => e.toString(), 'message', contains(unexcpctedError), ), @@ -424,7 +422,7 @@ void main() { group('resetPassword', () { test( 'should return SuccessResult when resetPassword is successful', - () async { + () async { // Arrange provideDummy>( SuccessResult( @@ -444,8 +442,8 @@ void main() { mockApiManager.execute(any), ).thenAnswer((invocation) async { final function = - invocation.positionalArguments.first - as Future Function(); + invocation.positionalArguments.first + as Future Function(); final result = await function(); return SuccessResult(result); }); @@ -484,10 +482,10 @@ void main() { ).thenThrow(storageException); when(mockApiManager.execute(any)).thenAnswer( - (invocation) async { + (invocation) async { final function = - invocation.positionalArguments.first - as Future Function(); + invocation.positionalArguments.first + as Future Function(); try { final result = await function(); return SuccessResult(result); @@ -514,7 +512,7 @@ void main() { test( 'should return FailureResult when resetPassword throws an exception', - () async { + () async { // Arrange provideDummy>( FailureResult(networkException), @@ -546,7 +544,7 @@ void main() { test( 'should return FailureResult when resetPassword returns null or invalid response', - () async { + () async { // Arrange provideDummy>( FailureResult(invalidOrNullException), @@ -580,7 +578,7 @@ void main() { test( 'should throw exception when apiManager.execute throws unexpected exception', - () async { + () async { // Arrange provideDummy>( FailureResult(unexpectedException), @@ -596,11 +594,11 @@ void main() { // Act & Assert expect( - () async => - await authRepoImpl.resetPassword(resetPasswordRequestEntity), + () async => + await authRepoImpl.resetPassword(resetPasswordRequestEntity), throwsA( isA().having( - (e) => e.toString(), + (e) => e.toString(), 'message', contains(unexcpctedError), ), @@ -609,5 +607,4 @@ void main() { }, ); }); - } diff --git a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart index af185d0..b3cbc59 100644 --- a/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart +++ b/test/data/auth/repo_impl/auth_repo_impl_test.mocks.dart @@ -3,30 +3,33 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i6; +import 'dart:async' as _i8; import 'package:fitness_app/core/utils/datasource_excution/api_manager.dart' - as _i11; + as _i7; import 'package:fitness_app/core/utils/datasource_excution/api_result.dart' + as _i9; +import 'package:fitness_app/data/auth/data_source/contract/auth_local_data_source.dart' + as _i11; +import 'package:fitness_app/data/auth/data_source/contract/auth_remote_data_source.dart' as _i12; -import 'package:fitness_app/data/auth/data_source/local/auth_local_data_source_impl.dart' - as _i10; -import 'package:fitness_app/data/auth/data_source/remote/auth_remote_data_source_impl.dart' - as _i5; import 'package:fitness_app/data/auth/models/forget_password/request/forget_password_request_dto.dart' - as _i7; + as _i13; import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart' - as _i2; + as _i4; +import 'package:fitness_app/data/auth/models/logout_response_dto.dart' as _i3; import 'package:fitness_app/data/auth/models/otp_verification/request/otp_verification_request_dto.dart' - as _i8; + as _i14; import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart' - as _i3; + as _i5; import 'package:fitness_app/data/auth/models/reset_password/request/reset_password_request_dto.dart' - as _i9; + as _i15; import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart' - as _i4; + as _i6; +import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' + as _i2; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i13; +import 'package:mockito/src/dummies.dart' as _i10; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -42,133 +45,185 @@ import 'package:mockito/src/dummies.dart' as _i13; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeForgetPasswordResponseDto_0 extends _i1.SmartFake - implements _i2.ForgetPasswordResponseDto { - _FakeForgetPasswordResponseDto_0(Object parent, Invocation parentInvocation) +class _FakeUserDataResponseDto_0 extends _i1.SmartFake + implements _i2.UserDataResponseDto { + _FakeUserDataResponseDto_0(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeOtpVerificationResponseDto_1 extends _i1.SmartFake - implements _i3.OtpVerificationResponseDto { - _FakeOtpVerificationResponseDto_1(Object parent, Invocation parentInvocation) +class _FakeLogoutResponseDto_1 extends _i1.SmartFake + implements _i3.LogoutResponseDto { + _FakeLogoutResponseDto_1(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeResetPasswordResponseDto_2 extends _i1.SmartFake - implements _i4.ResetPasswordResponseDto { - _FakeResetPasswordResponseDto_2(Object parent, Invocation parentInvocation) +class _FakeForgetPasswordResponseDto_2 extends _i1.SmartFake + implements _i4.ForgetPasswordResponseDto { + _FakeForgetPasswordResponseDto_2(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -/// A class which mocks [AuthRemoteDataSourceImpl]. +class _FakeOtpVerificationResponseDto_3 extends _i1.SmartFake + implements _i5.OtpVerificationResponseDto { + _FakeOtpVerificationResponseDto_3(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +class _FakeResetPasswordResponseDto_4 extends _i1.SmartFake + implements _i6.ResetPasswordResponseDto { + _FakeResetPasswordResponseDto_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); +} + +/// A class which mocks [ApiManager]. /// /// See the documentation for Mockito's code generation for more information. -class MockAuthRemoteDataSourceImpl extends _i1.Mock - implements _i5.AuthRemoteDataSourceImpl { - MockAuthRemoteDataSourceImpl() { +class MockApiManager extends _i1.Mock implements _i7.ApiManager { + MockApiManager() { _i1.throwOnMissingStub(this); } @override - _i6.Future<_i2.ForgetPasswordResponseDto> forgetPassword( - _i7.ForgetPasswordRequestDto? request, - ) => + _i8.Future<_i9.Result> execute(_i8.Future Function()? apiCall) => (super.noSuchMethod( - Invocation.method(#forgetPassword, [request]), - returnValue: _i6.Future<_i2.ForgetPasswordResponseDto>.value( - _FakeForgetPasswordResponseDto_0( + Invocation.method(#execute, [apiCall]), + returnValue: _i8.Future<_i9.Result>.value( + _i10.dummyValue<_i9.Result>( this, - Invocation.method(#forgetPassword, [request]), + Invocation.method(#execute, [apiCall]), ), ), ) - as _i6.Future<_i2.ForgetPasswordResponseDto>); + as _i8.Future<_i9.Result>); +} + +/// A class which mocks [AuthLocalDataSource]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockAuthLocalDataSource extends _i1.Mock + implements _i11.AuthLocalDataSource { + MockAuthLocalDataSource() { + _i1.throwOnMissingStub(this); + } @override - _i6.Future<_i3.OtpVerificationResponseDto> verifyOtp( - _i8.OtpVerificationRequestDto? request, - ) => + _i8.Future clearAll() => (super.noSuchMethod( - Invocation.method(#verifyOtp, [request]), - returnValue: _i6.Future<_i3.OtpVerificationResponseDto>.value( - _FakeOtpVerificationResponseDto_1( - this, - Invocation.method(#verifyOtp, [request]), - ), - ), + Invocation.method(#clearAll, []), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), ) - as _i6.Future<_i3.OtpVerificationResponseDto>); + as _i8.Future); @override - _i6.Future<_i4.ResetPasswordResponseDto> resetPassword( - _i9.ResetPasswordRequestDto? request, - ) => + _i8.Future selectLanguage(String? languageCode) => (super.noSuchMethod( - Invocation.method(#resetPassword, [request]), - returnValue: _i6.Future<_i4.ResetPasswordResponseDto>.value( - _FakeResetPasswordResponseDto_2( - this, - Invocation.method(#resetPassword, [request]), - ), - ), + Invocation.method(#selectLanguage, [languageCode]), + returnValue: _i8.Future.value(false), ) - as _i6.Future<_i4.ResetPasswordResponseDto>); -} - -/// A class which mocks [AuthLocalDataSourceImpl]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockAuthLocalDataSourceImpl extends _i1.Mock - implements _i10.AuthLocalDataSourceImpl { - MockAuthLocalDataSourceImpl() { - _i1.throwOnMissingStub(this); - } + as _i8.Future); @override - _i6.Future deleteToken(String? key) => + _i8.Future saveToken(String? key, String? value) => (super.noSuchMethod( - Invocation.method(#deleteToken, [key]), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), + Invocation.method(#saveToken, [key, value]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), ) - as _i6.Future); + as _i8.Future); @override - _i6.Future getToken(String? key) => + _i8.Future getToken(String? key) => (super.noSuchMethod( Invocation.method(#getToken, [key]), - returnValue: _i6.Future.value(), + returnValue: _i8.Future.value(), ) - as _i6.Future); + as _i8.Future); @override - _i6.Future saveToken(String? key, String? value) => + _i8.Future deleteToken(String? key) => (super.noSuchMethod( - Invocation.method(#saveToken, [key, value]), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), + Invocation.method(#deleteToken, [key]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), ) - as _i6.Future); + as _i8.Future); } -/// A class which mocks [ApiManager]. +/// A class which mocks [AuthRemoteDataSource]. /// /// See the documentation for Mockito's code generation for more information. -class MockApiManager extends _i1.Mock implements _i11.ApiManager { - MockApiManager() { +class MockAuthRemoteDataSource extends _i1.Mock + implements _i12.AuthRemoteDataSource { + MockAuthRemoteDataSource() { _i1.throwOnMissingStub(this); } @override - _i6.Future<_i12.Result> execute(_i6.Future Function()? apiCall) => + _i8.Future<_i2.UserDataResponseDto> getProfileData() => (super.noSuchMethod( - Invocation.method(#execute, [apiCall]), - returnValue: _i6.Future<_i12.Result>.value( - _i13.dummyValue<_i12.Result>( + Invocation.method(#getProfileData, []), + returnValue: _i8.Future<_i2.UserDataResponseDto>.value( + _FakeUserDataResponseDto_0( this, - Invocation.method(#execute, [apiCall]), + Invocation.method(#getProfileData, []), + ), + ), + ) + as _i8.Future<_i2.UserDataResponseDto>); + + @override + _i8.Future<_i3.LogoutResponseDto> logout() => + (super.noSuchMethod( + Invocation.method(#logout, []), + returnValue: _i8.Future<_i3.LogoutResponseDto>.value( + _FakeLogoutResponseDto_1(this, Invocation.method(#logout, [])), + ), + ) + as _i8.Future<_i3.LogoutResponseDto>); + + @override + _i8.Future<_i4.ForgetPasswordResponseDto> forgetPassword( + _i13.ForgetPasswordRequestDto? request, + ) => + (super.noSuchMethod( + Invocation.method(#forgetPassword, [request]), + returnValue: _i8.Future<_i4.ForgetPasswordResponseDto>.value( + _FakeForgetPasswordResponseDto_2( + this, + Invocation.method(#forgetPassword, [request]), + ), + ), + ) + as _i8.Future<_i4.ForgetPasswordResponseDto>); + + @override + _i8.Future<_i5.OtpVerificationResponseDto> verifyOtp( + _i14.OtpVerificationRequestDto? request, + ) => + (super.noSuchMethod( + Invocation.method(#verifyOtp, [request]), + returnValue: _i8.Future<_i5.OtpVerificationResponseDto>.value( + _FakeOtpVerificationResponseDto_3( + this, + Invocation.method(#verifyOtp, [request]), + ), + ), + ) + as _i8.Future<_i5.OtpVerificationResponseDto>); + + @override + _i8.Future<_i6.ResetPasswordResponseDto> resetPassword( + _i15.ResetPasswordRequestDto? request, + ) => + (super.noSuchMethod( + Invocation.method(#resetPassword, [request]), + returnValue: _i8.Future<_i6.ResetPasswordResponseDto>.value( + _FakeResetPasswordResponseDto_4( + this, + Invocation.method(#resetPassword, [request]), ), ), ) - as _i6.Future<_i12.Result>); + as _i8.Future<_i6.ResetPasswordResponseDto>); } diff --git a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart index c37144c..48b7a21 100644 --- a/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart +++ b/test/domain/auth/use_case/get_profile_data_use_case_test.mocks.dart @@ -7,6 +7,18 @@ import 'dart:async' as _i3; import 'package:fitness_app/core/utils/datasource_excution/api_result.dart' as _i4; +import 'package:fitness_app/domain/auth/entity/forget_password/forget_password_request_entity.dart' + as _i8; +import 'package:fitness_app/domain/auth/entity/forget_password/forget_password_response_entity.dart' + as _i7; +import 'package:fitness_app/domain/auth/entity/otp_verification/request/otp_verification_request_entity.dart' + as _i10; +import 'package:fitness_app/domain/auth/entity/otp_verification/response/otp_verification_response_entity.dart' + as _i9; +import 'package:fitness_app/domain/auth/entity/reset_password/request/reset_password_request_entity.dart' + as _i12; +import 'package:fitness_app/domain/auth/entity/reset_password/response/reset_password_response_entity.dart' + as _i11; import 'package:fitness_app/domain/auth/entity/user_entity.dart' as _i5; import 'package:fitness_app/domain/auth/repo/auth_repo.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; @@ -72,4 +84,52 @@ class MockAuthRepo extends _i1.Mock implements _i2.AuthRepo { ), ) as _i3.Future<_i4.Result>); + + @override + _i3.Future<_i4.Result<_i7.ForgetPasswordResponseEntity>> forgetPassword( + _i8.ForgetPasswordRequestEntity? request, + ) => + (super.noSuchMethod( + Invocation.method(#forgetPassword, [request]), + returnValue: + _i3.Future<_i4.Result<_i7.ForgetPasswordResponseEntity>>.value( + _i6.dummyValue<_i4.Result<_i7.ForgetPasswordResponseEntity>>( + this, + Invocation.method(#forgetPassword, [request]), + ), + ), + ) + as _i3.Future<_i4.Result<_i7.ForgetPasswordResponseEntity>>); + + @override + _i3.Future<_i4.Result<_i9.OtpVerificationResponseEntity>> verifyOtp( + _i10.OtpVerificationRequestEntity? request, + ) => + (super.noSuchMethod( + Invocation.method(#verifyOtp, [request]), + returnValue: + _i3.Future<_i4.Result<_i9.OtpVerificationResponseEntity>>.value( + _i6.dummyValue<_i4.Result<_i9.OtpVerificationResponseEntity>>( + this, + Invocation.method(#verifyOtp, [request]), + ), + ), + ) + as _i3.Future<_i4.Result<_i9.OtpVerificationResponseEntity>>); + + @override + _i3.Future<_i4.Result<_i11.ResetPasswordResponseEntity>> resetPassword( + _i12.ResetPasswordRequestEntity? request, + ) => + (super.noSuchMethod( + Invocation.method(#resetPassword, [request]), + returnValue: + _i3.Future<_i4.Result<_i11.ResetPasswordResponseEntity>>.value( + _i6.dummyValue<_i4.Result<_i11.ResetPasswordResponseEntity>>( + this, + Invocation.method(#resetPassword, [request]), + ), + ), + ) + as _i3.Future<_i4.Result<_i11.ResetPasswordResponseEntity>>); } From f545a7c149788a6fd1263bb3830ea289deb7eecc Mon Sep 17 00:00:00 2001 From: Eslam Date: Fri, 4 Jul 2025 21:15:15 +0300 Subject: [PATCH 10/12] refactor_test(auth): followed same structure of folder data_source for test --- .../auth_remote_data_source_impl_test.dart | 360 ------------------ ...th_remote_data_source_impl_test.mocks.dart | 146 ------- .../auth_remote_data_source_impl_test.dart | 346 +++++++++++++++++ 3 files changed, 346 insertions(+), 506 deletions(-) delete mode 100644 test/data/auth/data_source/auth_remote_data_source_impl_test.dart delete mode 100644 test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart diff --git a/test/data/auth/data_source/auth_remote_data_source_impl_test.dart b/test/data/auth/data_source/auth_remote_data_source_impl_test.dart deleted file mode 100644 index a9bcc04..0000000 --- a/test/data/auth/data_source/auth_remote_data_source_impl_test.dart +++ /dev/null @@ -1,360 +0,0 @@ -import 'package:dio/dio.dart'; -import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart'; -import 'package:fitness_app/data/auth/data_source/remote/auth_remote_data_source_impl.dart'; -import 'package:fitness_app/data/auth/models/forget_password/request/forget_password_request_dto.dart'; -import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart'; -import 'package:fitness_app/data/auth/models/otp_verification/request/otp_verification_request_dto.dart'; -import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart'; -import 'package:fitness_app/data/auth/models/reset_password/request/reset_password_request_dto.dart'; -import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; - -import '../../../test_constants.dart'; -import 'auth_remote_data_source_impl_test.mocks.dart'; - -@GenerateMocks([AuthRetrofitClient]) -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - late AuthRemoteDataSourceImpl authDataSource; - late MockAuthRetrofitClient mockAuthRetrofitClient; - - // Test constants - const testEmail = 'ahmed@example.com'; - const testNewPassword = 'Aa12@com'; - const successMessage = 'Success'; - const successInfo = 'OTP Send To Your Email'; - const resetPasswordSuccessInfo = 'Reset Password Successfully'; - const errorMessage = 'There is no account with this email address $testEmail'; - const forbiddenMessage = 'Forbidden Route'; - const unknownErrorMessage = 'Unknown Exception'; - const timeoutMessage = 'Timeout: Waiting for Response...'; - const testResetCode = '456213'; - - // Test objects - late ForgetPasswordRequestDto forgetPasswordRequest; - late ForgetPasswordResponseDto forgetPasswordSuccessResponse; - late OtpVerificationRequestDto otpVerificationRequest; - late OtpVerificationResponseDto otpVerificationSuccessResponse; - late ResetPasswordRequestDto resetPasswordRequest; - late ResetPasswordResponseDto resetPasswordSuccessResponse; - late Map notFoundErrorResponse; - late Response notFoundDioResponse; - late Response forbiddenDioResponse; - late Response timeoutDioResponse; - late DioException notFoundDioException; - late DioException forbiddenDioException; - late DioException timeoutException; - - setUpAll(() { - forgetPasswordRequest = ForgetPasswordRequestDto(email: testEmail); - forgetPasswordSuccessResponse = ForgetPasswordResponseDto( - message: successMessage, - info: successInfo, - ); - otpVerificationRequest = OtpVerificationRequestDto( - resetCode: testResetCode, - ); - otpVerificationSuccessResponse = OtpVerificationResponseDto( - status: successMessage, - ); - resetPasswordRequest = ResetPasswordRequestDto( - email: testEmail, - newPassword: testNewPassword, - ); - resetPasswordSuccessResponse = ResetPasswordResponseDto( - message: resetPasswordSuccessInfo, - token: TestConstants.fakeToken, - ); - notFoundErrorResponse = {'error': errorMessage}; - notFoundDioResponse = Response( - requestOptions: RequestOptions(path: TestConstants.notFoundRoute), - data: notFoundErrorResponse, - statusCode: TestConstants.notFoundStatusCode, - ); - forbiddenDioResponse = Response( - requestOptions: RequestOptions(path: TestConstants.notFoundRoute), - data: forbiddenMessage, - statusCode: TestConstants.forbiddenStatusCode, - ); - timeoutDioResponse = Response( - requestOptions: RequestOptions(path: TestConstants.notFoundRoute), - data: timeoutMessage, - statusCode: TestConstants.timeoutStatusCode, - ); - notFoundDioException = DioException( - requestOptions: RequestOptions(path: TestConstants.notFoundRoute), - response: notFoundDioResponse, - ); - forbiddenDioException = DioException( - requestOptions: RequestOptions(path: TestConstants.notFoundRoute), - response: forbiddenDioResponse, - type: DioExceptionType.badResponse, - ); - timeoutException = DioException( - requestOptions: RequestOptions(path: TestConstants.notFoundRoute), - response: timeoutDioResponse, - type: DioExceptionType.badResponse, - ); - }); - - setUp(() { - mockAuthRetrofitClient = MockAuthRetrofitClient(); - authDataSource = AuthRemoteDataSourceImpl(mockAuthRetrofitClient); - }); - - group('forgetPassword', () { - test( - 'should return ForgetPasswordResponseDto when API call is successful', - () async { - // Arrange - when( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).thenAnswer((_) async => forgetPasswordSuccessResponse); - - // Act - final result = await authDataSource.forgetPassword( - forgetPasswordRequest, - ); - - // Assert - expect(result, equals(forgetPasswordSuccessResponse)); - verify( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).called(1); - }, - ); - - test( - 'should throw DioException when API call fails with 404 status', - () async { - // Arrange - when( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).thenThrow(notFoundDioException); - - // Act & Assert - expect( - () => authDataSource.forgetPassword(forgetPasswordRequest), - throwsA(isA()), - ); - verify( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).called(1); - }, - ); - - test( - 'should throw Exception when API call fails with unknown error', - () async { - // Arrange - when( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).thenThrow(Exception(unknownErrorMessage)); - - // Act & Assert - expect( - () => authDataSource.forgetPassword(forgetPasswordRequest), - throwsA(predicate((e) => e.toString().contains(unknownErrorMessage))), - ); - verify( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).called(1); - }, - ); - - test( - 'should throw DioException with badResponse type when API call fails with 403 status', - () async { - // Arrange - when( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).thenThrow(forbiddenDioException); - - // Act & Assert - expect( - () => authDataSource.forgetPassword(forgetPasswordRequest), - throwsA( - isA().having( - (e) => e.type, - 'type', - DioExceptionType.badResponse, - ), - ), - ); - verify( - mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), - ).called(1); - }, - ); - }); - - group('verifyOtp', () { - test( - 'should return OtpVerificationResponseDto when API call is successful', - () async { - // Arrange - when( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).thenAnswer((_) async => otpVerificationSuccessResponse); - - // Act - final result = await authDataSource.verifyOtp(otpVerificationRequest); - - // Assert - expect(result, equals(otpVerificationSuccessResponse)); - verify( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).called(1); - }, - ); - - test( - 'should throw DioException when API call fails with 404 status', - () async { - // Arrange - when( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).thenThrow(notFoundDioException); - - // Act & Assert - expect( - () => authDataSource.verifyOtp(otpVerificationRequest), - throwsA(isA()), - ); - verify( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).called(1); - }, - ); - - test( - 'should throw Exception when API call fails with unknown error', - () async { - // Arrange - when( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).thenThrow(Exception(unknownErrorMessage)); - - // Act & Assert - expect( - () => authDataSource.verifyOtp(otpVerificationRequest), - throwsA(predicate((e) => e.toString().contains(unknownErrorMessage))), - ); - verify( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).called(1); - }, - ); - - test( - 'should throw DioException with badResponse type when API call fails with 403 status', - () async { - // Arrange - when( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).thenThrow(forbiddenDioException); - - // Act & Assert - expect( - () => authDataSource.verifyOtp(otpVerificationRequest), - throwsA( - isA().having( - (e) => e.type, - 'type', - DioExceptionType.badResponse, - ), - ), - ); - verify( - mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), - ).called(1); - }, - ); - }); - - group('resetPassword', () { - test( - 'should return ResetPasswordResponseDto when API call is successful', - () async { - // Arrange - when( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).thenAnswer((_) async => resetPasswordSuccessResponse); - - // Act - final result = await authDataSource.resetPassword(resetPasswordRequest); - - // Assert - expect(result, equals(resetPasswordSuccessResponse)); - verify( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).called(1); - }, - ); - - test( - 'should throw DioException(Timeout) when API call fails with 408 status', - () async { - // Arrange - when( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).thenThrow(timeoutException); - - // Act & Assert - expect( - () => authDataSource.resetPassword(resetPasswordRequest), - throwsA(isA()), - ); - verify( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).called(1); - }, - ); - - test( - 'should throw Exception when API call fails with unknown error', - () async { - // Arrange - when( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).thenThrow(Exception(unknownErrorMessage)); - - // Act & Assert - expect( - () => authDataSource.resetPassword(resetPasswordRequest), - throwsA(predicate((e) => e.toString().contains(unknownErrorMessage))), - ); - verify( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).called(1); - }, - ); - - test( - 'should throw DioException(Forbidden) with badResponse type when API call fails with 403 status', - () async { - // Arrange - when( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).thenThrow(forbiddenDioException); - - // Act & Assert - expect( - () => authDataSource.resetPassword(resetPasswordRequest), - throwsA( - isA().having( - (e) => e.type, - 'type', - DioExceptionType.badResponse, - ), - ), - ); - verify( - mockAuthRetrofitClient.resetPassword(resetPasswordRequest), - ).called(1); - }, - ); - }); -} diff --git a/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart b/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart deleted file mode 100644 index ebcb894..0000000 --- a/test/data/auth/data_source/auth_remote_data_source_impl_test.mocks.dart +++ /dev/null @@ -1,146 +0,0 @@ -// Mocks generated by Mockito 5.4.5 from annotations -// in fitness_app/test/data/auth/data_source/auth_remote_data_source_impl_test.dart. -// Do not manually edit this file. - -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i8; - -import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart' as _i7; -import 'package:fitness_app/data/auth/models/forget_password/request/forget_password_request_dto.dart' - as _i9; -import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart' - as _i4; -import 'package:fitness_app/data/auth/models/logout_response_dto.dart' as _i2; -import 'package:fitness_app/data/auth/models/otp_verification/request/otp_verification_request_dto.dart' - as _i10; -import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart' - as _i5; -import 'package:fitness_app/data/auth/models/reset_password/request/reset_password_request_dto.dart' - as _i11; -import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart' - as _i6; -import 'package:fitness_app/data/auth/models/user_data_response_dto.dart' - as _i3; -import 'package:mockito/mockito.dart' as _i1; - -// ignore_for_file: type=lint -// ignore_for_file: avoid_redundant_argument_values -// ignore_for_file: avoid_setters_without_getters -// ignore_for_file: comment_references -// ignore_for_file: deprecated_member_use -// ignore_for_file: deprecated_member_use_from_same_package -// ignore_for_file: implementation_imports -// ignore_for_file: invalid_use_of_visible_for_testing_member -// ignore_for_file: must_be_immutable -// ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types -// ignore_for_file: subtype_of_sealed_class - -class _FakeLogoutResponseDto_0 extends _i1.SmartFake - implements _i2.LogoutResponseDto { - _FakeLogoutResponseDto_0(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); -} - -class _FakeUserDataResponseDto_1 extends _i1.SmartFake - implements _i3.UserDataResponseDto { - _FakeUserDataResponseDto_1(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); -} - -class _FakeForgetPasswordResponseDto_2 extends _i1.SmartFake - implements _i4.ForgetPasswordResponseDto { - _FakeForgetPasswordResponseDto_2(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); -} - -class _FakeOtpVerificationResponseDto_3 extends _i1.SmartFake - implements _i5.OtpVerificationResponseDto { - _FakeOtpVerificationResponseDto_3(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); -} - -class _FakeResetPasswordResponseDto_4 extends _i1.SmartFake - implements _i6.ResetPasswordResponseDto { - _FakeResetPasswordResponseDto_4(Object parent, Invocation parentInvocation) - : super(parent, parentInvocation); -} - -/// A class which mocks [AuthRetrofitClient]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockAuthRetrofitClient extends _i1.Mock - implements _i7.AuthRetrofitClient { - MockAuthRetrofitClient() { - _i1.throwOnMissingStub(this); - } - - @override - _i8.Future<_i2.LogoutResponseDto> logout() => - (super.noSuchMethod( - Invocation.method(#logout, []), - returnValue: _i8.Future<_i2.LogoutResponseDto>.value( - _FakeLogoutResponseDto_0(this, Invocation.method(#logout, [])), - ), - ) - as _i8.Future<_i2.LogoutResponseDto>); - - @override - _i8.Future<_i3.UserDataResponseDto> getProfileData() => - (super.noSuchMethod( - Invocation.method(#getProfileData, []), - returnValue: _i8.Future<_i3.UserDataResponseDto>.value( - _FakeUserDataResponseDto_1( - this, - Invocation.method(#getProfileData, []), - ), - ), - ) - as _i8.Future<_i3.UserDataResponseDto>); - - @override - _i8.Future<_i4.ForgetPasswordResponseDto> forgetPassword( - _i9.ForgetPasswordRequestDto? request, - ) => - (super.noSuchMethod( - Invocation.method(#forgetPassword, [request]), - returnValue: _i8.Future<_i4.ForgetPasswordResponseDto>.value( - _FakeForgetPasswordResponseDto_2( - this, - Invocation.method(#forgetPassword, [request]), - ), - ), - ) - as _i8.Future<_i4.ForgetPasswordResponseDto>); - - @override - _i8.Future<_i5.OtpVerificationResponseDto> verifyOtp( - _i10.OtpVerificationRequestDto? request, - ) => - (super.noSuchMethod( - Invocation.method(#verifyOtp, [request]), - returnValue: _i8.Future<_i5.OtpVerificationResponseDto>.value( - _FakeOtpVerificationResponseDto_3( - this, - Invocation.method(#verifyOtp, [request]), - ), - ), - ) - as _i8.Future<_i5.OtpVerificationResponseDto>); - - @override - _i8.Future<_i6.ResetPasswordResponseDto> resetPassword( - _i11.ResetPasswordRequestDto? request, - ) => - (super.noSuchMethod( - Invocation.method(#resetPassword, [request]), - returnValue: _i8.Future<_i6.ResetPasswordResponseDto>.value( - _FakeResetPasswordResponseDto_4( - this, - Invocation.method(#resetPassword, [request]), - ), - ), - ) - as _i8.Future<_i6.ResetPasswordResponseDto>); -} diff --git a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart index 344d2cb..4d02ca7 100644 --- a/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart +++ b/test/data/auth/data_source/remote/auth_remote_data_source_impl_test.dart @@ -1,18 +1,106 @@ +import 'package:dio/dio.dart'; import 'package:fitness_app/data/auth/api/auth_retrofit_client.dart'; import 'package:fitness_app/data/auth/data_source/remote/auth_remote_data_source_impl.dart'; +import 'package:fitness_app/data/auth/models/forget_password/request/forget_password_request_dto.dart'; +import 'package:fitness_app/data/auth/models/forget_password/response/forget_password_response_dto.dart'; +import 'package:fitness_app/data/auth/models/otp_verification/request/otp_verification_request_dto.dart'; +import 'package:fitness_app/data/auth/models/otp_verification/response/otp_verification_response_dto.dart'; +import 'package:fitness_app/data/auth/models/reset_password/request/reset_password_request_dto.dart'; +import 'package:fitness_app/data/auth/models/reset_password/response/reset_password_response_dto.dart'; import 'package:fitness_app/data/auth/models/user_data_response_dto.dart'; import 'package:fitness_app/data/auth/models/user_dto.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +import '../../../../test_constants.dart'; import 'auth_remote_data_source_impl_test.mocks.dart'; @GenerateMocks([AuthRetrofitClient]) void main() { + TestWidgetsFlutterBinding.ensureInitialized(); late AuthRemoteDataSourceImpl authRemoteDataSourceImpl; late MockAuthRetrofitClient mockAuthRetrofitClient; + // Test constants + const testEmail = 'ahmed@example.com'; + const testNewPassword = 'Aa12@com'; + const successMessage = 'Success'; + const successInfo = 'OTP Send To Your Email'; + const resetPasswordSuccessInfo = 'Reset Password Successfully'; + const errorMessage = 'There is no account with this email address $testEmail'; + const forbiddenMessage = 'Forbidden Route'; + const unknownErrorMessage = 'Unknown Exception'; + const timeoutMessage = 'Timeout: Waiting for Response...'; + const testResetCode = '456213'; + + // Test objects + late ForgetPasswordRequestDto forgetPasswordRequest; + late ForgetPasswordResponseDto forgetPasswordSuccessResponse; + late OtpVerificationRequestDto otpVerificationRequest; + late OtpVerificationResponseDto otpVerificationSuccessResponse; + late ResetPasswordRequestDto resetPasswordRequest; + late ResetPasswordResponseDto resetPasswordSuccessResponse; + late Map notFoundErrorResponse; + late Response notFoundDioResponse; + late Response forbiddenDioResponse; + late Response timeoutDioResponse; + late DioException notFoundDioException; + late DioException forbiddenDioException; + late DioException timeoutException; + + setUpAll(() { + forgetPasswordRequest = ForgetPasswordRequestDto(email: testEmail); + forgetPasswordSuccessResponse = ForgetPasswordResponseDto( + message: successMessage, + info: successInfo, + ); + otpVerificationRequest = OtpVerificationRequestDto( + resetCode: testResetCode, + ); + otpVerificationSuccessResponse = OtpVerificationResponseDto( + status: successMessage, + ); + resetPasswordRequest = ResetPasswordRequestDto( + email: testEmail, + newPassword: testNewPassword, + ); + resetPasswordSuccessResponse = ResetPasswordResponseDto( + message: resetPasswordSuccessInfo, + token: TestConstants.fakeToken, + ); + notFoundErrorResponse = {'error': errorMessage}; + notFoundDioResponse = Response( + requestOptions: RequestOptions(path: TestConstants.notFoundRoute), + data: notFoundErrorResponse, + statusCode: TestConstants.notFoundStatusCode, + ); + forbiddenDioResponse = Response( + requestOptions: RequestOptions(path: TestConstants.notFoundRoute), + data: forbiddenMessage, + statusCode: TestConstants.forbiddenStatusCode, + ); + timeoutDioResponse = Response( + requestOptions: RequestOptions(path: TestConstants.notFoundRoute), + data: timeoutMessage, + statusCode: TestConstants.timeoutStatusCode, + ); + notFoundDioException = DioException( + requestOptions: RequestOptions(path: TestConstants.notFoundRoute), + response: notFoundDioResponse, + ); + forbiddenDioException = DioException( + requestOptions: RequestOptions(path: TestConstants.notFoundRoute), + response: forbiddenDioResponse, + type: DioExceptionType.badResponse, + ); + timeoutException = DioException( + requestOptions: RequestOptions(path: TestConstants.notFoundRoute), + response: timeoutDioResponse, + type: DioExceptionType.badResponse, + ); + }); + setUp(() { mockAuthRetrofitClient = MockAuthRetrofitClient(); authRemoteDataSourceImpl = AuthRemoteDataSourceImpl(mockAuthRetrofitClient); @@ -69,4 +157,262 @@ void main() { }); }); }); + + group('forgetPassword', () { + test( + 'should return ForgetPasswordResponseDto when API call is successful', + () async { + // Arrange + when( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).thenAnswer((_) async => forgetPasswordSuccessResponse); + + // Act + final result = await authRemoteDataSourceImpl.forgetPassword( + forgetPasswordRequest, + ); + + // Assert + expect(result, equals(forgetPasswordSuccessResponse)); + verify( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).called(1); + }, + ); + + test( + 'should throw DioException when API call fails with 404 status', + () async { + // Arrange + when( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).thenThrow(notFoundDioException); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.forgetPassword(forgetPasswordRequest), + throwsA(isA()), + ); + verify( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).called(1); + }, + ); + + test( + 'should throw Exception when API call fails with unknown error', + () async { + // Arrange + when( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).thenThrow(Exception(unknownErrorMessage)); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.forgetPassword(forgetPasswordRequest), + throwsA(predicate((e) => e.toString().contains(unknownErrorMessage))), + ); + verify( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).called(1); + }, + ); + + test( + 'should throw DioException with badResponse type when API call fails with 403 status', + () async { + // Arrange + when( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).thenThrow(forbiddenDioException); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.forgetPassword(forgetPasswordRequest), + throwsA( + isA().having( + (e) => e.type, + 'type', + DioExceptionType.badResponse, + ), + ), + ); + verify( + mockAuthRetrofitClient.forgetPassword(forgetPasswordRequest), + ).called(1); + }, + ); + }); + + group('verifyOtp', () { + test( + 'should return OtpVerificationResponseDto when API call is successful', + () async { + // Arrange + when( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).thenAnswer((_) async => otpVerificationSuccessResponse); + + // Act + final result = await authRemoteDataSourceImpl.verifyOtp( + otpVerificationRequest, + ); + + // Assert + expect(result, equals(otpVerificationSuccessResponse)); + verify( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).called(1); + }, + ); + + test( + 'should throw DioException when API call fails with 404 status', + () async { + // Arrange + when( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).thenThrow(notFoundDioException); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.verifyOtp(otpVerificationRequest), + throwsA(isA()), + ); + verify( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).called(1); + }, + ); + + test( + 'should throw Exception when API call fails with unknown error', + () async { + // Arrange + when( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).thenThrow(Exception(unknownErrorMessage)); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.verifyOtp(otpVerificationRequest), + throwsA(predicate((e) => e.toString().contains(unknownErrorMessage))), + ); + verify( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).called(1); + }, + ); + + test( + 'should throw DioException with badResponse type when API call fails with 403 status', + () async { + // Arrange + when( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).thenThrow(forbiddenDioException); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.verifyOtp(otpVerificationRequest), + throwsA( + isA().having( + (e) => e.type, + 'type', + DioExceptionType.badResponse, + ), + ), + ); + verify( + mockAuthRetrofitClient.verifyOtp(otpVerificationRequest), + ).called(1); + }, + ); + }); + + group('resetPassword', () { + test( + 'should return ResetPasswordResponseDto when API call is successful', + () async { + // Arrange + when( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).thenAnswer((_) async => resetPasswordSuccessResponse); + + // Act + final result = await authRemoteDataSourceImpl.resetPassword( + resetPasswordRequest, + ); + + // Assert + expect(result, equals(resetPasswordSuccessResponse)); + verify( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).called(1); + }, + ); + + test( + 'should throw DioException(Timeout) when API call fails with 408 status', + () async { + // Arrange + when( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).thenThrow(timeoutException); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.resetPassword(resetPasswordRequest), + throwsA(isA()), + ); + verify( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).called(1); + }, + ); + + test( + 'should throw Exception when API call fails with unknown error', + () async { + // Arrange + when( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).thenThrow(Exception(unknownErrorMessage)); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.resetPassword(resetPasswordRequest), + throwsA(predicate((e) => e.toString().contains(unknownErrorMessage))), + ); + verify( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).called(1); + }, + ); + + test( + 'should throw DioException(Forbidden) with badResponse type when API call fails with 403 status', + () async { + // Arrange + when( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).thenThrow(forbiddenDioException); + + // Act & Assert + expect( + () => authRemoteDataSourceImpl.resetPassword(resetPasswordRequest), + throwsA( + isA().having( + (e) => e.type, + 'type', + DioExceptionType.badResponse, + ), + ), + ); + verify( + mockAuthRetrofitClient.resetPassword(resetPasswordRequest), + ).called(1); + }, + ); + }); } From c27aece495d72409c0d6ba50f059c43d0e5e37b5 Mon Sep 17 00:00:00 2001 From: Eslam Date: Sun, 6 Jul 2025 00:06:17 +0300 Subject: [PATCH 11/12] refactor(profile): add confirmation dialog for logout and improve profile header --- assets/translations/en.json | 2 +- lib/core/utils/dialogs/app_dialogs.dart | 71 +++++++++ lib/core/utils/l10n/locale_keys.g.dart | 30 ++-- .../view/screens/profile_screen.dart | 22 +-- .../view/widgets/profile_body.dart | 52 ++---- .../view/widgets/profile_header_widget.dart | 55 +++++++ .../widgets/profile_menu_list_widget.dart | 149 ++++++++++-------- 7 files changed, 238 insertions(+), 143 deletions(-) create mode 100644 lib/features/profile/presentation/view/widgets/profile_header_widget.dart diff --git a/assets/translations/en.json b/assets/translations/en.json index 4d38970..01e57c9 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -96,7 +96,7 @@ "Logout": "Logout", "PrivacyPolicy": "Privacy Policy", "EditProfile": "Edit Profile", - "AreYouSureToCloseTheApplication": "Are you sure to close the \napplication?", + "AreYouSureToCloseTheApplication": "Are You Sure To Close The \nApplication?", "Yes": "Yes", "No": "No", "TapToEdit": "tap to edit", diff --git a/lib/core/utils/dialogs/app_dialogs.dart b/lib/core/utils/dialogs/app_dialogs.dart index 2513b0d..54bb097 100644 --- a/lib/core/utils/dialogs/app_dialogs.dart +++ b/lib/core/utils/dialogs/app_dialogs.dart @@ -191,4 +191,75 @@ class AppDialogs { ), ); } + + // Show a confirmation dialog + static Future showConfirmationDialog( + BuildContext context, { + required String message, + String? description, + String? firstButtonText, + String? secondButtonText, + VoidCallback? firstButtonAction, + VoidCallback? secondButtonAction, + }) async { + await showDialog( + context: context, + builder: (context) => AlertDialog( + backgroundColor: AppColors.darkgrey, + titlePadding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0), + actionsPadding: const EdgeInsets.all(16.0), + titleTextStyle: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w600), + content: description != null + ? Text(description, textAlign: TextAlign.center, maxLines: 2) + : null, + contentPadding: const EdgeInsets.only( + left: 55, + right: 55, + top: 20, + bottom: 35, + ), + contentTextStyle: Theme.of(context).textTheme.bodyLarge?.copyWith( + color: AppColors.white[AppColors.colorCode40], + fontWeight: FontWeight.w500, + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (firstButtonText != null) + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: AppColors.darkgrey, + side: const BorderSide(color: AppColors.orange), + ), + onPressed: firstButtonAction ?? () => Navigator.pop(context), + child: Text( + firstButtonText, + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(color: AppColors.white), + ), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: AppColors.orange, + ), + onPressed: secondButtonAction ?? () => Navigator.pop(context), + child: Text( + secondButtonText ?? LocaleKeys.Ok.tr(), + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(color: AppColors.white), + ), + ), + ], + ), + ], + + title: Text(message, textAlign: TextAlign.center), + ), + ); + } } diff --git a/lib/core/utils/l10n/locale_keys.g.dart b/lib/core/utils/l10n/locale_keys.g.dart index 50df9ae..bd81035 100644 --- a/lib/core/utils/l10n/locale_keys.g.dart +++ b/lib/core/utils/l10n/locale_keys.g.dart @@ -2,7 +2,7 @@ // ignore_for_file: constant_identifier_names -abstract class LocaleKeys { +abstract class LocaleKeys { static const InvalidCredentials = 'InvalidCredentials'; static const Receive_timeout = 'Receive_timeout'; static const Timeout_occurred = 'Timeout_occurred'; @@ -23,10 +23,8 @@ abstract class LocaleKeys { static const Service_unavailable = 'Service_unavailable'; static const DataParsingException = 'DataParsingException'; static const OtpCodeIsInvalidOrExpired = 'OtpCodeIsInvalidOrExpired'; - static const ThePriceOfExcellenceIsDiscipline = - 'ThePriceOfExcellenceIsDiscipline'; - static const LoremIpsumDolorSitAmetConsecteturEuUrnaUtGravidaQuisIdPretiumPurusMaurIsMassa = - 'LoremIpsumDolorSitAmetConsecteturEuUrnaUtGravidaQuisIdPretiumPurusMaurIsMassa'; + static const ThePriceOfExcellenceIsDiscipline = 'ThePriceOfExcellenceIsDiscipline'; + static const LoremIpsumDolorSitAmetConsecteturEuUrnaUtGravidaQuisIdPretiumPurusMaurIsMassa = 'LoremIpsumDolorSitAmetConsecteturEuUrnaUtGravidaQuisIdPretiumPurusMaurIsMassa'; static const FitnessHasNeverBeenSoMuchFun = 'FitnessHasNeverBeenSoMuchFun'; static const NOMOREEXCUSESDoItNow = 'NOMOREEXCUSESDoItNow'; static const Back = 'Back'; @@ -45,17 +43,14 @@ abstract class LocaleKeys { static const FirstName = 'FirstName'; static const LastName = 'LastName'; static const AlreadyHaveAnAccount = 'AlreadyHaveAnAccount'; - static const TellUsAboutYourselfWeNeedToKnowYourGender = - 'TellUsAboutYourselfWeNeedToKnowYourGender'; + static const TellUsAboutYourselfWeNeedToKnowYourGender = 'TellUsAboutYourselfWeNeedToKnowYourGender'; static const Male = 'Male'; static const Female = 'Female'; static const Year = 'Year'; - static const HowOldAreYouThisHelpsUsCreateYourPersonalizedPlan = - 'HowOldAreYouThisHelpsUsCreateYourPersonalizedPlan'; + static const HowOldAreYouThisHelpsUsCreateYourPersonalizedPlan = 'HowOldAreYouThisHelpsUsCreateYourPersonalizedPlan'; static const Done = 'Done'; static const WhatIsYourWeight = 'WhatIsYourWeight'; - static const ThisHelpsUsCreateYourPersonalizedPlan = - 'ThisHelpsUsCreateYourPersonalizedPlan'; + static const ThisHelpsUsCreateYourPersonalizedPlan = 'ThisHelpsUsCreateYourPersonalizedPlan'; static const WhatIsYourHight = 'WhatIsYourHight'; static const whatIsYourGoal = 'whatIsYourGoal'; static const GainWeight = 'GainWeight'; @@ -68,8 +63,7 @@ abstract class LocaleKeys { static const Intermediate = 'Intermediate'; static const Advanced = 'Advanced'; static const TrueBeast = 'TrueBeast'; - static const YourRegularPhysicalActivityLevel = - 'YourRegularPhysicalActivityLevel'; + static const YourRegularPhysicalActivityLevel = 'YourRegularPhysicalActivityLevel'; static const EnterYourEmail = 'EnterYourEmail'; static const EnterYourPassword = 'EnterYourPassword'; static const SendOTP = 'SendOTP'; @@ -104,8 +98,7 @@ abstract class LocaleKeys { static const Logout = 'Logout'; static const PrivacyPolicy = 'PrivacyPolicy'; static const EditProfile = 'EditProfile'; - static const AreYouSureToCloseTheApplication = - 'AreYouSureToCloseTheApplication'; + static const AreYouSureToCloseTheApplication = 'AreYouSureToCloseTheApplication'; static const Yes = 'Yes'; static const No = 'No'; static const TapToEdit = 'TapToEdit'; @@ -122,8 +115,7 @@ abstract class LocaleKeys { static const PasswordCannotBeEmpty = 'PasswordCannotBeEmpty'; static const InvalidPassword = 'InvalidPassword'; static const InvalidEmailFormat = 'InvalidEmailFormat'; - static const PasswordMustBeAtLeast8Characters = - 'PasswordMustBeAtLeast8Characters'; + static const PasswordMustBeAtLeast8Characters = 'PasswordMustBeAtLeast8Characters'; static const NameCannotBeEmpty = 'NameCannotBeEmpty'; static const InvalidName = 'InvalidName'; static const EnterAValidEmail = 'EnterAValidEmail'; @@ -138,9 +130,9 @@ abstract class LocaleKeys { static const ResetPasswordSuccessfully = 'ResetPasswordSuccessfully'; static const ConfirmPassword = 'ConfirmPassword'; static const OtpVerificationSuccessfully = 'OtpVerificationSuccessfully'; - static const SomethingWentWrongPleaseTryAgainLater = - 'SomethingWentWrongPleaseTryAgainLater'; + static const SomethingWentWrongPleaseTryAgainLater = 'SomethingWentWrongPleaseTryAgainLater'; static const Home = 'Home'; static const FitnessAI = 'FitnessAI'; static const DoIt = 'DoIt'; + } diff --git a/lib/features/profile/presentation/view/screens/profile_screen.dart b/lib/features/profile/presentation/view/screens/profile_screen.dart index 6b2fbe6..a6e07a0 100644 --- a/lib/features/profile/presentation/view/screens/profile_screen.dart +++ b/lib/features/profile/presentation/view/screens/profile_screen.dart @@ -8,7 +8,6 @@ import 'package:fitness_app/features/profile/presentation/view_model/profile_cub import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../../../../core/assets/app_colors.dart'; import '../../../../../core/base/base_state.dart'; import '../../../../../core/utils/routes/app_routes.dart'; import '../../view_model/profile_state.dart'; @@ -30,6 +29,11 @@ class ProfileScreen extends StatelessWidget { context, message: (state.profileState as BaseErrorState).errorMessage, ); + Navigator.pushNamedAndRemoveUntil( + context, + AppRoutes.loginRoute, + (route) => false, + ); } if (logoutState is BaseSuccessState) { AppDialogs.hideLoading(context); @@ -56,20 +60,6 @@ class ProfileScreen extends StatelessWidget { fontSize: 24, ), ), - leading: IconButton( - padding: EdgeInsets.zero, - constraints: BoxConstraints.tight(const Size(24, 24)), - style: IconButton.styleFrom( - backgroundColor: AppColors.orange, - shape: const CircleBorder(), - ), - icon: const Icon( - Icons.arrow_back, - color: AppColors.white, - size: 10, - ), - onPressed: () => Navigator.of(context).pop(), - ), ), extendBodyBehindAppBar: true, body: Container( @@ -77,7 +67,7 @@ class ProfileScreen extends StatelessWidget { decoration: const BoxDecoration( image: DecorationImage( image: AssetImage(AppImages.backgroundThree), - fit: BoxFit.fill, + fit: BoxFit.cover, ), ), child: const Padding( diff --git a/lib/features/profile/presentation/view/widgets/profile_body.dart b/lib/features/profile/presentation/view/widgets/profile_body.dart index 1a59b49..25e7ade 100644 --- a/lib/features/profile/presentation/view/widgets/profile_body.dart +++ b/lib/features/profile/presentation/view/widgets/profile_body.dart @@ -1,51 +1,23 @@ -import 'package:fitness_app/features/profile/presentation/view/widgets/profile_menu_list_widget.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -import '../../../../../core/base/base_state.dart'; import '../../../../../core/utils/shared_widgets/blured_container.dart'; -import '../../../../../domain/auth/entity/user_entity.dart'; -import '../../view_model/profile_cubit.dart'; -import '../../view_model/profile_state.dart'; +import 'profile_menu_list_widget.dart'; +import 'profile_header_widget.dart'; class ProfileBody extends StatelessWidget { const ProfileBody({super.key}); @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - final profileState = state.profileState; - if (profileState is BaseLoadingState) { - return const Center(child: CircularProgressIndicator()); - } - if (profileState is BaseSuccessState) { - final user = profileState.data!; - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CircleAvatar( - radius: 50, - backgroundImage: NetworkImage(user.photo!), - ), - const SizedBox(height: 8), - Text( - '${user.firstName!} ${user.lastName!}', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - fontSize: 20, - ), - ), - const SizedBox(height: 40), - const BluredContainer( - padding: EdgeInsets.symmetric(vertical: 8), - child: ProfileMenuList(), - ), - ], - ); - } - return const SizedBox.shrink(); - }, + return const Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ProfileHeaderWidget(), + SizedBox(height: 40), + BluredContainer( + padding: EdgeInsets.symmetric(vertical: 8), + child: ProfileMenuList(), + ), + ], ); } } diff --git a/lib/features/profile/presentation/view/widgets/profile_header_widget.dart b/lib/features/profile/presentation/view/widgets/profile_header_widget.dart new file mode 100644 index 0000000..d767141 --- /dev/null +++ b/lib/features/profile/presentation/view/widgets/profile_header_widget.dart @@ -0,0 +1,55 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:fitness_app/core/utils/l10n/locale_keys.g.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:skeletonizer/skeletonizer.dart'; + +import '../../../../../core/base/base_state.dart'; +import '../../../../../domain/auth/entity/user_entity.dart'; +import '../../view_model/profile_cubit.dart'; +import '../../view_model/profile_state.dart'; + +class ProfileHeaderWidget extends StatelessWidget { + const ProfileHeaderWidget({super.key}); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + final profileState = state.profileState; + + final isLoading = profileState is BaseLoadingState; + final user = (profileState is BaseSuccessState) + ? profileState.data + : null; + + return Skeletonizer( + enabled: isLoading, + child: Column( + children: [ + CircleAvatar( + radius: 50, + backgroundImage: user?.photo != null + ? NetworkImage(user!.photo!) + : null, + child: user?.photo == null + ? const Icon(Icons.person, size: 40) + : null, + ), + const SizedBox(height: 8), + Text( + user != null + ? '${user.firstName ?? ''} ${user.lastName ?? ''}' + : LocaleKeys.Loading.tr(), + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w600, + fontSize: 20, + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart b/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart index 12b3506..6a72db9 100644 --- a/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart +++ b/lib/features/profile/presentation/view/widgets/profile_menu_list_widget.dart @@ -3,9 +3,11 @@ import 'package:fitness_app/core/utils/dialogs/app_dialogs.dart'; import 'package:fitness_app/features/profile/presentation/view_model/profile_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:skeletonizer/skeletonizer.dart'; import '../../../../../core/assets/app_colors.dart'; import '../../../../../core/assets/app_icons.dart'; +import '../../../../../core/base/base_state.dart'; import '../../../../../core/utils/constants.dart'; import '../../../../../core/utils/l10n/locale_keys.g.dart'; import '../../../../../core/utils/routes/app_routes.dart'; @@ -17,74 +19,87 @@ class ProfileMenuList extends StatelessWidget { @override Widget build(BuildContext context) { - final viewModel = context.read(); - return Column( - children: [ - ProfileMenuItemWidget( - icon: AppIcons.profileIcon, - label: LocaleKeys.EditProfile.tr(), - onTap: () => Navigator.pushNamed(context, AppRoutes.editProfileRoute), - ), - ProfileMenuItemWidget( - icon: AppIcons.changePasswordIcon, - label: LocaleKeys.ChangePassword.tr(), - onTap: () {}, - ), - ProfileMenuItemWidget( - icon: AppIcons.changeLanguageIcon, - label: - '${LocaleKeys.SelectLanguage.tr()} (${context.locale.languageCode == Constants.en ? LocaleKeys.English.tr() : LocaleKeys.Arabic.tr()})', - trailing: Transform.scale( - scale: 0.8, - child: Switch( - padding: EdgeInsets.zero, - activeColor: AppColors.white, - activeTrackColor: AppColors.orange, - inactiveThumbColor: AppColors.white, - inactiveTrackColor: AppColors.darkgrey, - value: context.locale.languageCode == Constants.en, - onChanged: (value) { - viewModel.doIntent( - SelectLanguageAction(value ? Constants.en : Constants.ar), - ); - context.setLocale(Locale(value ? Constants.en : Constants.ar)); - }, - ), + return BlocBuilder( + builder: (context, state) { + final viewModel = context.read(); + final isLoading = state.profileState is BaseLoadingState; + + return Skeletonizer( + enabled: isLoading, + child: Column( + children: [ + ProfileMenuItemWidget( + icon: AppIcons.profileIcon, + label: LocaleKeys.EditProfile.tr(), + onTap: () => + Navigator.pushNamed(context, AppRoutes.editProfileRoute), + ), + ProfileMenuItemWidget( + icon: AppIcons.changePasswordIcon, + label: LocaleKeys.ChangePassword.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.changeLanguageIcon, + label: + '${LocaleKeys.SelectLanguage.tr()} (${context.locale.languageCode == Constants.en ? LocaleKeys.English.tr() : LocaleKeys.Arabic.tr()})', + trailing: Transform.scale( + scale: 0.8, + child: Switch( + padding: EdgeInsets.zero, + activeColor: AppColors.white, + activeTrackColor: AppColors.orange, + inactiveThumbColor: AppColors.white, + inactiveTrackColor: AppColors.darkgrey, + value: context.locale.languageCode == Constants.en, + onChanged: (value) { + viewModel.doIntent( + SelectLanguageAction( + value ? Constants.en : Constants.ar, + ), + ); + context.setLocale( + Locale(value ? Constants.en : Constants.ar), + ); + }, + ), + ), + ), + ProfileMenuItemWidget( + icon: AppIcons.lockSettingsIcon, + label: LocaleKeys.Security.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.securityWarningIcon, + label: LocaleKeys.PrivacyPolicy.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.helpIcon, + label: LocaleKeys.Help.tr(), + onTap: () {}, + ), + ProfileMenuItemWidget( + icon: AppIcons.logoutIcon, + label: LocaleKeys.Logout.tr(), + labelColor: AppColors.orange, + onTap: () { + AppDialogs.showConfirmationDialog( + context, + message: LocaleKeys.AreYouSureToCloseTheApplication.tr(), + firstButtonText: LocaleKeys.No.tr(), + secondButtonText: LocaleKeys.Yes.tr(), + secondButtonAction: () { + viewModel.doIntent(LogoutAction()); + }, + ); + }, + ), + ], ), - ), - ProfileMenuItemWidget( - icon: AppIcons.lockSettingsIcon, - label: LocaleKeys.Security.tr(), - onTap: () {}, - ), - ProfileMenuItemWidget( - icon: AppIcons.securityWarningIcon, - label: LocaleKeys.PrivacyPolicy.tr(), - onTap: () {}, - ), - ProfileMenuItemWidget( - icon: AppIcons.helpIcon, - label: LocaleKeys.Help.tr(), - onTap: () {}, - ), - ProfileMenuItemWidget( - icon: AppIcons.logoutIcon, - label: LocaleKeys.Logout.tr(), - labelColor: AppColors.orange, - onTap: () { - AppDialogs.showSuccessDialog( - context, - message: LocaleKeys.AreYouSureToCloseTheApplication.tr(), - firstButtonText: LocaleKeys.No.tr(), - secondButtonText: LocaleKeys.Yes.tr(), - firstButtonAction: () => Navigator.of(context).pop(), - secondButtonAction: () { - viewModel.doIntent(LogoutAction()); - }, - ); - }, - ), - ], + ); + }, ); } } From 7ab885d0366d32415dab5e742df17c6ce2b40b98 Mon Sep 17 00:00:00 2001 From: Eslam Date: Sun, 6 Jul 2025 00:20:52 +0300 Subject: [PATCH 12/12] refactor(dialogs): enhance title and button text styles in confirmation dialog --- lib/core/utils/dialogs/app_dialogs.dart | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/core/utils/dialogs/app_dialogs.dart b/lib/core/utils/dialogs/app_dialogs.dart index 54bb097..2d0808d 100644 --- a/lib/core/utils/dialogs/app_dialogs.dart +++ b/lib/core/utils/dialogs/app_dialogs.dart @@ -208,9 +208,10 @@ class AppDialogs { backgroundColor: AppColors.darkgrey, titlePadding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0), actionsPadding: const EdgeInsets.all(16.0), - titleTextStyle: Theme.of( - context, - ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w600), + titleTextStyle: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + fontSize: 20, + ), content: description != null ? Text(description, textAlign: TextAlign.center, maxLines: 2) : null, @@ -237,9 +238,10 @@ class AppDialogs { onPressed: firstButtonAction ?? () => Navigator.pop(context), child: Text( firstButtonText, - style: Theme.of( - context, - ).textTheme.titleMedium?.copyWith(color: AppColors.white), + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w800, + fontSize: 14, + ), ), ), ElevatedButton( @@ -249,15 +251,15 @@ class AppDialogs { onPressed: secondButtonAction ?? () => Navigator.pop(context), child: Text( secondButtonText ?? LocaleKeys.Ok.tr(), - style: Theme.of( - context, - ).textTheme.titleMedium?.copyWith(color: AppColors.white), + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w800, + fontSize: 14, + ), ), ), ], ), ], - title: Text(message, textAlign: TextAlign.center), ), );