feat: BLoC tests complets + sécurité production + freerasp 7.5.1 migration

## Tests BLoC (Task P2.4 Mobile)
- 25 nouveaux fichiers *_bloc_test.dart + mocks générés (build_runner)
- Features couvertes : authentication, admin_users, adhesions, backup,
  communication/messaging, contributions, dashboard, finance (approval/budget),
  events, explore/network, feed, logs_monitoring, notifications, onboarding,
  organizations (switcher/types/CRUD), profile, reports, settings, solidarity
- ~380 tests, > 80% coverage BLoCs

## Sécurité Production (Task P2.2)
- lib/core/security/app_integrity_service.dart (freerasp 7.5.1)
- Migration API breaking changes freerasp 7.5.1 :
  - onRootDetected → onPrivilegedAccess
  - onDebuggerDetected → onDebug
  - onSignatureDetected → onAppIntegrity
  - onHookDetected → onHooks
  - onEmulatorDetected → onSimulator
  - onUntrustedInstallationSourceDetected → onUnofficialStore
  - onDeviceBindingDetected → onDeviceBinding
  - onObfuscationIssuesDetected → onObfuscationIssues
  - Talsec.start() split → start() + attachListener()
  - const AndroidConfig/IOSConfig → final (constructors call ConfigVerifier)
  - supportedAlternativeStores → supportedStores

## Pubspec
- bloc_test: ^9.1.7 → ^10.0.0 (compat flutter_bloc ^9.0.0)
- freerasp 7.5.1

## Config
- android/app/build.gradle : ajustements release
- lib/core/config/environment.dart : URLs API actualisées
- lib/main.dart + app_router : intégrations sécurité/BLoC

## Cleanup
- Suppression docs intermédiaires (TACHES_*.md, TASK_*_COMPLETION_REPORT.md,
  TESTS_UNITAIRES_PROGRESS.md)
- .g.dart régénérés (json_serializable)
- .mocks.dart régénérés (mockito)

## Résultat
- 142 fichiers, +27 596 insertions
- Toutes les tâches P2 mobile complétées

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
dahoud
2026-04-21 12:42:35 +00:00
parent 33f5b5a707
commit 37db88672b
142 changed files with 27599 additions and 16068 deletions

View File

@@ -0,0 +1,633 @@
import 'package:bloc_test/bloc_test.dart';
import 'package:dio/dio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:unionflow_mobile_apps/features/profile/presentation/bloc/profile_bloc.dart';
import 'package:unionflow_mobile_apps/features/profile/domain/usecases/get_profile.dart';
import 'package:unionflow_mobile_apps/features/profile/domain/usecases/update_profile.dart';
import 'package:unionflow_mobile_apps/features/profile/domain/repositories/profile_repository.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';
@GenerateMocks([GetProfile, UpdateProfile, IProfileRepository])
import 'profile_bloc_test.mocks.dart';
// ─── Fixtures ────────────────────────────────────────────────────────────────
MembreCompletModel _membre({String id = 'membre-1'}) => MembreCompletModel(
id: id,
nom: 'Dupont',
prenom: 'Jean',
email: 'jean.dupont@test.com',
);
DioException _dioError(int statusCode) => DioException(
requestOptions: RequestOptions(path: '/api/membres/me'),
response: Response(
requestOptions: RequestOptions(path: '/api/membres/me'),
statusCode: statusCode,
),
type: DioExceptionType.badResponse,
);
DioException _networkError() => DioException(
requestOptions: RequestOptions(path: '/api/membres/me'),
type: DioExceptionType.connectionTimeout,
);
// ─── Tests ───────────────────────────────────────────────────────────────────
void main() {
late ProfileBloc bloc;
late MockGetProfile mockGetProfile;
late MockUpdateProfile mockUpdateProfile;
late MockIProfileRepository mockRepository;
setUp(() {
mockGetProfile = MockGetProfile();
mockUpdateProfile = MockUpdateProfile();
mockRepository = MockIProfileRepository();
bloc = ProfileBloc(mockGetProfile, mockUpdateProfile, mockRepository);
});
tearDown(() => bloc.close());
// ─── Initial state ──────────────────────────────────────────────────────────
test('initial state is ProfileInitial', () {
expect(bloc.state, isA<ProfileInitial>());
});
// ─── LoadMe ─────────────────────────────────────────────────────────────────
group('LoadMe', () {
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileLoaded] on success',
build: () {
when(mockGetProfile()).thenAnswer((_) async => _membre());
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileLoaded>()
.having((s) => s.membre.id, 'id', 'membre-1')
.having((s) => s.membre.email, 'email', 'jean.dupont@test.com'),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileNotFound] when getProfile returns null',
build: () {
when(mockGetProfile()).thenAnswer((_) async => null);
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [isA<ProfileLoading>(), isA<ProfileNotFound>()],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on DioException (401)',
build: () {
when(mockGetProfile()).thenThrow(_dioError(401));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>().having(
(s) => s.message,
'message',
contains('Non autorisé'),
),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on DioException (403)',
build: () {
when(mockGetProfile()).thenThrow(_dioError(403));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Accès refusé')),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on DioException (404)',
build: () {
when(mockGetProfile()).thenThrow(_dioError(404));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('non trouvé')),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on DioException (500)',
build: () {
when(mockGetProfile()).thenThrow(_dioError(500));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Erreur serveur')),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on network timeout',
build: () {
when(mockGetProfile()).thenThrow(_networkError());
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>().having(
(s) => s.message,
'message',
contains('Délai de connexion'),
),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on generic exception',
build: () {
when(mockGetProfile()).thenThrow(Exception('Unexpected failure'));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>().having(
(s) => s.message,
'message',
contains('Erreur lors du chargement'),
),
],
);
});
// ─── LoadMyProfile ──────────────────────────────────────────────────────────
group('LoadMyProfile', () {
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileLoaded] on success',
build: () {
when(mockRepository.getProfileByEmail('jean@test.com'))
.thenAnswer((_) async => _membre());
return bloc;
},
act: (b) => b.add(const LoadMyProfile('jean@test.com')),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileLoaded>().having((s) => s.membre.id, 'id', 'membre-1'),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileNotFound] when repository returns null',
build: () {
when(mockRepository.getProfileByEmail(any))
.thenAnswer((_) async => null);
return bloc;
},
act: (b) => b.add(const LoadMyProfile('unknown@test.com')),
expect: () => [isA<ProfileLoading>(), isA<ProfileNotFound>()],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on DioException',
build: () {
when(mockRepository.getProfileByEmail(any))
.thenThrow(_dioError(404));
return bloc;
},
act: (b) => b.add(const LoadMyProfile('jean@test.com')),
expect: () => [isA<ProfileLoading>(), isA<ProfileError>()],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileLoading, ProfileError] on generic exception',
build: () {
when(mockRepository.getProfileByEmail(any))
.thenThrow(Exception('DB error'));
return bloc;
},
act: (b) => b.add(const LoadMyProfile('jean@test.com')),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Erreur lors du chargement')),
],
);
});
// ─── UpdateMyProfile ────────────────────────────────────────────────────────
group('UpdateMyProfile', () {
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileUpdating, ProfileUpdated] when state is ProfileLoaded on success',
build: () {
final updatedMembre = _membre(id: 'membre-1');
when(mockUpdateProfile('membre-1', any))
.thenAnswer((_) async => updatedMembre);
return bloc;
},
seed: () => ProfileLoaded(_membre()),
act: (b) => b.add(UpdateMyProfile(
membreId: 'membre-1',
membre: _membre(),
)),
expect: () => [
isA<ProfileUpdating>().having((s) => s.membre.id, 'id', 'membre-1'),
isA<ProfileUpdated>().having((s) => s.membre.id, 'id', 'membre-1'),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileUpdated] from ProfileInitial (no ProfileUpdating)',
build: () {
when(mockUpdateProfile('membre-1', any))
.thenAnswer((_) async => _membre());
return bloc;
},
// No seed → initial state is ProfileInitial (not ProfileLoaded)
act: (b) => b.add(UpdateMyProfile(
membreId: 'membre-1',
membre: _membre(),
)),
expect: () => [isA<ProfileUpdated>()],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileUpdating, ProfileLoaded, ProfileError] on DioException when state is ProfileLoaded',
build: () {
when(mockUpdateProfile(any, any)).thenThrow(_dioError(400));
return bloc;
},
seed: () => ProfileLoaded(_membre()),
act: (b) => b.add(UpdateMyProfile(
membreId: 'membre-1',
membre: _membre(),
)),
expect: () => [
isA<ProfileUpdating>(),
isA<ProfileLoaded>(), // restored previous state
isA<ProfileError>(),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileError] on DioException when state is not ProfileLoaded',
build: () {
when(mockUpdateProfile(any, any)).thenThrow(_dioError(500));
return bloc;
},
act: (b) => b.add(UpdateMyProfile(
membreId: 'membre-1',
membre: _membre(),
)),
expect: () => [isA<ProfileError>()],
);
blocTest<ProfileBloc, ProfileState>(
'emits [ProfileUpdating, ProfileError] on generic exception when state is ProfileLoaded',
build: () {
when(mockUpdateProfile(any, any))
.thenThrow(Exception('Serialization error'));
return bloc;
},
seed: () => ProfileLoaded(_membre()),
act: (b) => b.add(UpdateMyProfile(
membreId: 'membre-1',
membre: _membre(),
)),
expect: () => [
isA<ProfileUpdating>(),
isA<ProfileLoaded>(),
isA<ProfileError>().having(
(s) => s.message,
'message',
contains('mise à jour'),
),
],
);
});
// ─── ChangePassword ─────────────────────────────────────────────────────────
group('ChangePassword', () {
blocTest<ProfileBloc, ProfileState>(
'emits [PasswordChanging, PasswordChanged] on success from ProfileInitial',
build: () {
when(mockRepository.changePassword('membre-1', 'old123', 'new456'))
.thenAnswer((_) async {});
return bloc;
},
act: (b) => b.add(const ChangePassword(
membreId: 'membre-1',
oldPassword: 'old123',
newPassword: 'new456',
)),
expect: () => [isA<PasswordChanging>(), isA<PasswordChanged>()],
);
blocTest<ProfileBloc, ProfileState>(
'restores ProfileLoaded after PasswordChanged when previous state was ProfileLoaded',
build: () {
when(mockRepository.changePassword(any, any, any))
.thenAnswer((_) async {});
return bloc;
},
seed: () => ProfileLoaded(_membre()),
act: (b) => b.add(const ChangePassword(
membreId: 'membre-1',
oldPassword: 'old123',
newPassword: 'new456',
)),
expect: () => [
isA<PasswordChanging>(),
isA<PasswordChanged>(),
isA<ProfileLoaded>(), // restored
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [PasswordChanging, ProfileError] on DioException (403)',
build: () {
when(mockRepository.changePassword(any, any, any))
.thenThrow(_dioError(403));
return bloc;
},
act: (b) => b.add(const ChangePassword(
membreId: 'membre-1',
oldPassword: 'wrong',
newPassword: 'new',
)),
expect: () => [
isA<PasswordChanging>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Accès refusé')),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [PasswordChanging, ProfileError, ProfileLoaded] on DioException when state is ProfileLoaded',
build: () {
when(mockRepository.changePassword(any, any, any))
.thenThrow(_dioError(401));
return bloc;
},
seed: () => ProfileLoaded(_membre()),
act: (b) => b.add(const ChangePassword(
membreId: 'membre-1',
oldPassword: 'old',
newPassword: 'new',
)),
expect: () => [
isA<PasswordChanging>(),
isA<ProfileError>(),
isA<ProfileLoaded>(), // restored
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [PasswordChanging, ProfileError] on generic exception',
build: () {
when(mockRepository.changePassword(any, any, any))
.thenThrow(Exception('Wrong old password'));
return bloc;
},
act: (b) => b.add(const ChangePassword(
membreId: 'membre-1',
oldPassword: 'wrong',
newPassword: 'new456',
)),
expect: () => [
isA<PasswordChanging>(),
isA<ProfileError>(),
],
);
blocTest<ProfileBloc, ProfileState>(
'strips Exception: prefix from generic error message',
build: () {
when(mockRepository.changePassword(any, any, any))
.thenThrow(Exception('Custom error message'));
return bloc;
},
act: (b) => b.add(const ChangePassword(
membreId: 'membre-1',
oldPassword: 'x',
newPassword: 'y',
)),
expect: () => [
isA<PasswordChanging>(),
isA<ProfileError>().having(
(s) => s.message,
'message',
isNot(contains('Exception:')),
),
],
);
});
// ─── DeleteAccount ──────────────────────────────────────────────────────────
group('DeleteAccount', () {
blocTest<ProfileBloc, ProfileState>(
'emits [AccountDeleting, AccountDeleted] on success',
build: () {
when(mockRepository.deleteAccount('membre-1'))
.thenAnswer((_) async {});
return bloc;
},
act: (b) => b.add(const DeleteAccount('membre-1')),
expect: () => [isA<AccountDeleting>(), isA<AccountDeleted>()],
);
blocTest<ProfileBloc, ProfileState>(
'emits [AccountDeleting, ProfileError] on DioException (401)',
build: () {
when(mockRepository.deleteAccount(any)).thenThrow(_dioError(401));
return bloc;
},
act: (b) => b.add(const DeleteAccount('membre-1')),
expect: () => [
isA<AccountDeleting>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Non autorisé')),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [AccountDeleting, ProfileError] on DioException (403)',
build: () {
when(mockRepository.deleteAccount(any)).thenThrow(_dioError(403));
return bloc;
},
act: (b) => b.add(const DeleteAccount('membre-1')),
expect: () => [
isA<AccountDeleting>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Accès refusé')),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [AccountDeleting, ProfileError] on network error',
build: () {
when(mockRepository.deleteAccount(any)).thenThrow(_networkError());
return bloc;
},
act: (b) => b.add(const DeleteAccount('membre-1')),
expect: () => [
isA<AccountDeleting>(),
isA<ProfileError>().having(
(s) => s.message,
'message',
contains('Délai de connexion'),
),
],
);
blocTest<ProfileBloc, ProfileState>(
'emits [AccountDeleting, ProfileError] on generic exception',
build: () {
when(mockRepository.deleteAccount(any))
.thenThrow(Exception('Server unreachable'));
return bloc;
},
act: (b) => b.add(const DeleteAccount('membre-1')),
expect: () => [isA<AccountDeleting>(), isA<ProfileError>()],
);
});
// ─── _networkErrorMessage coverage ─────────────────────────────────────────
group('_networkErrorMessage DioExceptionType coverage', () {
blocTest<ProfileBloc, ProfileState>(
'sendTimeout returns Délai de connexion dépassé',
build: () {
when(mockGetProfile()).thenThrow(DioException(
requestOptions: RequestOptions(path: '/'),
type: DioExceptionType.sendTimeout,
));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Délai de connexion')),
],
);
blocTest<ProfileBloc, ProfileState>(
'receiveTimeout returns Délai de connexion dépassé',
build: () {
when(mockGetProfile()).thenThrow(DioException(
requestOptions: RequestOptions(path: '/'),
type: DioExceptionType.receiveTimeout,
));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Délai de connexion')),
],
);
blocTest<ProfileBloc, ProfileState>(
'unknown DioExceptionType returns Erreur réseau',
build: () {
when(mockGetProfile()).thenThrow(DioException(
requestOptions: RequestOptions(path: '/'),
type: DioExceptionType.unknown,
));
return bloc;
},
act: (b) => b.add(const LoadMe()),
expect: () => [
isA<ProfileLoading>(),
isA<ProfileError>()
.having((s) => s.message, 'message', contains('Erreur réseau')),
],
);
});
// ─── State equality ─────────────────────────────────────────────────────────
group('ProfileState equality', () {
test('ProfileLoaded with same membre are equal', () {
final m = _membre();
expect(ProfileLoaded(m), equals(ProfileLoaded(m)));
});
test('ProfileError with same message are equal', () {
const s1 = ProfileError('error');
const s2 = ProfileError('error');
expect(s1, equals(s2));
});
test('ProfileError with different messages are not equal', () {
expect(const ProfileError('a'), isNot(equals(const ProfileError('b'))));
});
test('ProfileUpdating contains membre in props', () {
final m = _membre();
expect(ProfileUpdating(m).props, contains(m));
});
test('ProfileUpdated contains membre in props', () {
final m = _membre();
expect(ProfileUpdated(m).props, contains(m));
});
});
// ─── ProfileEvent equality ──────────────────────────────────────────────────
group('ProfileEvent equality', () {
test('LoadMe events are equal', () {
expect(const LoadMe(), equals(const LoadMe()));
});
test('LoadMyProfile with same email are equal', () {
expect(
const LoadMyProfile('a@b.com'),
equals(const LoadMyProfile('a@b.com')),
);
});
test('ChangePassword props are correct', () {
const event = ChangePassword(
membreId: 'm-1',
oldPassword: 'old',
newPassword: 'new',
);
expect(event.props, containsAll(['m-1', 'old', 'new']));
});
test('DeleteAccount props are correct', () {
const event = DeleteAccount('m-99');
expect(event.props, contains('m-99'));
});
});
}

View File

@@ -0,0 +1,172 @@
// Mocks generated by Mockito 5.4.6 from annotations
// in unionflow_mobile_apps/test/features/profile/bloc/profile_bloc_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i4;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i2;
import 'package:unionflow_mobile_apps/features/profile/domain/repositories/profile_repository.dart'
as _i6;
import 'package:unionflow_mobile_apps/features/profile/domain/usecases/get_profile.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/profile/domain/usecases/update_profile.dart'
as _i5;
// 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
// ignore_for_file: invalid_use_of_internal_member
class _FakeMembreCompletModel_0 extends _i1.SmartFake
implements _i2.MembreCompletModel {
_FakeMembreCompletModel_0(Object parent, Invocation parentInvocation)
: super(parent, parentInvocation);
}
/// A class which mocks [GetProfile].
///
/// See the documentation for Mockito's code generation for more information.
class MockGetProfile extends _i1.Mock implements _i3.GetProfile {
MockGetProfile() {
_i1.throwOnMissingStub(this);
}
@override
_i4.Future<_i2.MembreCompletModel?> call() =>
(super.noSuchMethod(
Invocation.method(#call, []),
returnValue: _i4.Future<_i2.MembreCompletModel?>.value(),
)
as _i4.Future<_i2.MembreCompletModel?>);
}
/// A class which mocks [UpdateProfile].
///
/// See the documentation for Mockito's code generation for more information.
class MockUpdateProfile extends _i1.Mock implements _i5.UpdateProfile {
MockUpdateProfile() {
_i1.throwOnMissingStub(this);
}
@override
_i4.Future<_i2.MembreCompletModel> call(
String? id,
_i2.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(#call, [id, membre]),
returnValue: _i4.Future<_i2.MembreCompletModel>.value(
_FakeMembreCompletModel_0(
this,
Invocation.method(#call, [id, membre]),
),
),
)
as _i4.Future<_i2.MembreCompletModel>);
}
/// A class which mocks [IProfileRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIProfileRepository extends _i1.Mock
implements _i6.IProfileRepository {
MockIProfileRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i4.Future<_i2.MembreCompletModel?> getMe() =>
(super.noSuchMethod(
Invocation.method(#getMe, []),
returnValue: _i4.Future<_i2.MembreCompletModel?>.value(),
)
as _i4.Future<_i2.MembreCompletModel?>);
@override
_i4.Future<_i2.MembreCompletModel?> getProfileByEmail(String? email) =>
(super.noSuchMethod(
Invocation.method(#getProfileByEmail, [email]),
returnValue: _i4.Future<_i2.MembreCompletModel?>.value(),
)
as _i4.Future<_i2.MembreCompletModel?>);
@override
_i4.Future<_i2.MembreCompletModel> updateProfile(
String? id,
_i2.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(#updateProfile, [id, membre]),
returnValue: _i4.Future<_i2.MembreCompletModel>.value(
_FakeMembreCompletModel_0(
this,
Invocation.method(#updateProfile, [id, membre]),
),
),
)
as _i4.Future<_i2.MembreCompletModel>);
@override
_i4.Future<_i2.MembreCompletModel> updateAvatar(
String? id,
String? photoUrl,
) =>
(super.noSuchMethod(
Invocation.method(#updateAvatar, [id, photoUrl]),
returnValue: _i4.Future<_i2.MembreCompletModel>.value(
_FakeMembreCompletModel_0(
this,
Invocation.method(#updateAvatar, [id, photoUrl]),
),
),
)
as _i4.Future<_i2.MembreCompletModel>);
@override
_i4.Future<void> changePassword(
String? id,
String? oldPassword,
String? newPassword,
) =>
(super.noSuchMethod(
Invocation.method(#changePassword, [id, oldPassword, newPassword]),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
)
as _i4.Future<void>);
@override
_i4.Future<Map<String, dynamic>> updatePreferences(
String? id,
Map<String, dynamic>? preferences,
) =>
(super.noSuchMethod(
Invocation.method(#updatePreferences, [id, preferences]),
returnValue: _i4.Future<Map<String, dynamic>>.value(
<String, dynamic>{},
),
)
as _i4.Future<Map<String, dynamic>>);
@override
_i4.Future<void> deleteAccount(String? id) =>
(super.noSuchMethod(
Invocation.method(#deleteAccount, [id]),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
)
as _i4.Future<void>);
}