refactor(frontend): adapt to RESTful API routes
This commit is contained in:
@@ -63,4 +63,28 @@ class ApiClient {
|
||||
throw ApiException.fromDioError(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Response<T>> patch<T>(
|
||||
String path, {
|
||||
dynamic data,
|
||||
Options? options,
|
||||
}) async {
|
||||
try {
|
||||
return await _dio.patch<T>(path, data: data, options: options);
|
||||
} on DioException catch (e) {
|
||||
throw ApiException.fromDioError(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Response<T>> delete<T>(
|
||||
String path, {
|
||||
dynamic data,
|
||||
Options? options,
|
||||
}) async {
|
||||
try {
|
||||
return await _dio.delete<T>(path, data: data, options: options);
|
||||
} on DioException catch (e) {
|
||||
throw ApiException.fromDioError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ Future<void> configureDependencies() async {
|
||||
|
||||
apiClient.setRefreshCallback((token) async {
|
||||
try {
|
||||
await authRepository.refresh(token);
|
||||
await authRepository.refreshSession(token);
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
|
||||
@@ -9,47 +9,45 @@ class AuthApi {
|
||||
|
||||
AuthApi(this._client);
|
||||
|
||||
Future<SignupStartResponse> signupStart(SignupStartRequest request) async {
|
||||
Future<VerificationCreateResponse> createVerification(
|
||||
SignupStartRequest request,
|
||||
) async {
|
||||
final response = await _client.post(
|
||||
'$_prefix/signup/start',
|
||||
'$_prefix/verifications',
|
||||
data: request.toJson(),
|
||||
);
|
||||
return SignupStartResponse.fromJson(response.data);
|
||||
return VerificationCreateResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
Future<AuthResponse> signupVerify(SignupVerifyRequest request) async {
|
||||
Future<AuthResponse> verifyVerification(SignupVerifyRequest request) async {
|
||||
final response = await _client.post(
|
||||
'$_prefix/signup/verify',
|
||||
'$_prefix/verifications/verify',
|
||||
data: request.toJson(),
|
||||
);
|
||||
return AuthResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
Future<SignupResendResponse> signupResend(SignupResendRequest request) async {
|
||||
final response = await _client.post(
|
||||
'$_prefix/signup/resend',
|
||||
data: request.toJson(),
|
||||
);
|
||||
return SignupResendResponse.fromJson(response.data);
|
||||
Future<void> resendVerification(SignupResendRequest request) async {
|
||||
await _client.post('$_prefix/verifications/resend', data: request.toJson());
|
||||
}
|
||||
|
||||
Future<AuthResponse> login(LoginRequest request) async {
|
||||
Future<AuthResponse> createSession(LoginRequest request) async {
|
||||
final response = await _client.post(
|
||||
'$_prefix/login',
|
||||
'$_prefix/sessions',
|
||||
data: request.toJson(),
|
||||
);
|
||||
return AuthResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
Future<AuthResponse> refresh(RefreshRequest request) async {
|
||||
Future<AuthResponse> refreshSession(RefreshRequest request) async {
|
||||
final response = await _client.post(
|
||||
'$_prefix/refresh',
|
||||
'$_prefix/sessions/refresh',
|
||||
data: request.toJson(),
|
||||
);
|
||||
return AuthResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
Future<void> logout(LogoutRequest request) async {
|
||||
await _client.post('$_prefix/logout', data: request.toJson());
|
||||
Future<void> deleteSession(LogoutRequest request) async {
|
||||
await _client.delete('$_prefix/sessions', data: request.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@ import 'package:social_app/features/auth/data/models/login_request.dart';
|
||||
import 'package:social_app/features/auth/data/models/auth_response.dart';
|
||||
|
||||
abstract class AuthRepository {
|
||||
Future<SignupStartResponse> signupStart(SignupStartRequest request);
|
||||
Future<AuthResponse> signupVerify(SignupVerifyRequest request);
|
||||
Future<SignupResendResponse> signupResend(SignupResendRequest request);
|
||||
Future<AuthResponse> login(LoginRequest request);
|
||||
Future<AuthResponse> refresh(String refreshToken);
|
||||
Future<void> logout();
|
||||
Future<VerificationCreateResponse> createVerification(
|
||||
SignupStartRequest request,
|
||||
);
|
||||
Future<AuthResponse> verifyVerification(SignupVerifyRequest request);
|
||||
Future<void> resendVerification(SignupResendRequest request);
|
||||
Future<AuthResponse> createSession(LoginRequest request);
|
||||
Future<AuthResponse> refreshSession(String refreshToken);
|
||||
Future<void> deleteSession();
|
||||
Future<String?> getAccessToken();
|
||||
Future<String?> getRefreshToken();
|
||||
Future<bool> isAuthenticated();
|
||||
|
||||
@@ -14,13 +14,15 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
_tokenStorage = tokenStorage;
|
||||
|
||||
@override
|
||||
Future<SignupStartResponse> signupStart(SignupStartRequest request) {
|
||||
return _api.signupStart(request);
|
||||
Future<VerificationCreateResponse> createVerification(
|
||||
SignupStartRequest request,
|
||||
) {
|
||||
return _api.createVerification(request);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AuthResponse> signupVerify(SignupVerifyRequest request) async {
|
||||
final response = await _api.signupVerify(request);
|
||||
Future<AuthResponse> verifyVerification(SignupVerifyRequest request) async {
|
||||
final response = await _api.verifyVerification(request);
|
||||
await _tokenStorage.saveTokens(
|
||||
access: response.accessToken,
|
||||
refresh: response.refreshToken,
|
||||
@@ -29,13 +31,13 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SignupResendResponse> signupResend(SignupResendRequest request) {
|
||||
return _api.signupResend(request);
|
||||
Future<void> resendVerification(SignupResendRequest request) {
|
||||
return _api.resendVerification(request);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AuthResponse> login(LoginRequest request) async {
|
||||
final response = await _api.login(request);
|
||||
Future<AuthResponse> createSession(LoginRequest request) async {
|
||||
final response = await _api.createSession(request);
|
||||
await _tokenStorage.saveTokens(
|
||||
access: response.accessToken,
|
||||
refresh: response.refreshToken,
|
||||
@@ -44,8 +46,8 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AuthResponse> refresh(String refreshToken) async {
|
||||
final response = await _api.refresh(
|
||||
Future<AuthResponse> refreshSession(String refreshToken) async {
|
||||
final response = await _api.refreshSession(
|
||||
RefreshRequest(refreshToken: refreshToken),
|
||||
);
|
||||
await _tokenStorage.saveTokens(
|
||||
@@ -56,10 +58,10 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> logout() async {
|
||||
Future<void> deleteSession() async {
|
||||
final refreshToken = await _tokenStorage.getRefreshToken();
|
||||
if (refreshToken != null) {
|
||||
await _api.logout(LogoutRequest(refreshToken: refreshToken));
|
||||
await _api.deleteSession(LogoutRequest(refreshToken: refreshToken));
|
||||
}
|
||||
await _tokenStorage.clear();
|
||||
}
|
||||
|
||||
@@ -35,32 +35,12 @@ class AuthResponse {
|
||||
}
|
||||
}
|
||||
|
||||
class SignupStartResponse {
|
||||
final String status;
|
||||
class VerificationCreateResponse {
|
||||
final String email;
|
||||
final String message;
|
||||
|
||||
const SignupStartResponse({
|
||||
required this.status,
|
||||
required this.email,
|
||||
required this.message,
|
||||
});
|
||||
const VerificationCreateResponse({required this.email});
|
||||
|
||||
factory SignupStartResponse.fromJson(Map<String, dynamic> json) {
|
||||
return SignupStartResponse(
|
||||
status: json['status'] as String,
|
||||
email: json['email'] as String,
|
||||
message: json['message'] as String,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SignupResendResponse {
|
||||
final String message;
|
||||
|
||||
const SignupResendResponse({required this.message});
|
||||
|
||||
factory SignupResendResponse.fromJson(Map<String, dynamic> json) {
|
||||
return SignupResendResponse(message: json['message'] as String);
|
||||
factory VerificationCreateResponse.fromJson(Map<String, dynamic> json) {
|
||||
return VerificationCreateResponse(email: json['email'] as String);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||
final refreshToken = await _repository.getRefreshToken();
|
||||
if (refreshToken != null) {
|
||||
try {
|
||||
final response = await _repository.refresh(refreshToken);
|
||||
final response = await _repository.refreshSession(refreshToken);
|
||||
emit(
|
||||
AuthAuthenticated(
|
||||
user: AuthUser(id: response.user.id, email: response.user.email),
|
||||
@@ -25,7 +25,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||
);
|
||||
return;
|
||||
} catch (_) {
|
||||
await _repository.logout();
|
||||
await _repository.deleteSession();
|
||||
}
|
||||
}
|
||||
emit(AuthUnauthenticated());
|
||||
@@ -39,7 +39,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||
AuthLoggedOut event,
|
||||
Emitter<AuthState> emit,
|
||||
) async {
|
||||
await _repository.logout();
|
||||
await _repository.deleteSession();
|
||||
emit(AuthUnauthenticated());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class LoginCubit extends Cubit<LoginState> {
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.inProgress));
|
||||
|
||||
try {
|
||||
final response = await _repository.login(
|
||||
final response = await _repository.createSession(
|
||||
LoginRequest(email: state.email.value, password: state.password.value),
|
||||
);
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.success));
|
||||
|
||||
@@ -99,7 +99,7 @@ class RegisterCubit extends Cubit<RegisterState> {
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.inProgress));
|
||||
|
||||
try {
|
||||
final response = await _repository.signupStart(
|
||||
final response = await _repository.createVerification(
|
||||
SignupStartRequest(
|
||||
username: state.username.value,
|
||||
email: state.email.value,
|
||||
@@ -132,7 +132,7 @@ class RegisterCubit extends Cubit<RegisterState> {
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.inProgress));
|
||||
|
||||
try {
|
||||
final response = await _repository.signupVerify(
|
||||
final response = await _repository.verifyVerification(
|
||||
SignupVerifyRequest(
|
||||
email: state.pendingEmail!,
|
||||
token: state.verificationCode.value,
|
||||
@@ -166,7 +166,7 @@ class RegisterCubit extends Cubit<RegisterState> {
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.inProgress));
|
||||
|
||||
try {
|
||||
await _repository.signupResend(
|
||||
await _repository.resendVerification(
|
||||
SignupResendRequest(email: state.pendingEmail!),
|
||||
);
|
||||
emit(
|
||||
@@ -197,7 +197,7 @@ class RegisterCubit extends Cubit<RegisterState> {
|
||||
);
|
||||
|
||||
try {
|
||||
final response = await _repository.signupStart(
|
||||
final response = await _repository.createVerification(
|
||||
SignupStartRequest(
|
||||
username: state.username.value,
|
||||
email: state.email.value,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
class UserResponse {
|
||||
final String id;
|
||||
final String username;
|
||||
final String? avatarUrl;
|
||||
final String? bio;
|
||||
|
||||
const UserResponse({
|
||||
required this.id,
|
||||
required this.username,
|
||||
this.avatarUrl,
|
||||
this.bio,
|
||||
});
|
||||
|
||||
factory UserResponse.fromJson(Map<String, dynamic> json) {
|
||||
return UserResponse(
|
||||
id: json['id'] as String,
|
||||
username: json['username'] as String,
|
||||
avatarUrl: json['avatar_url'] as String?,
|
||||
bio: json['bio'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UserUpdateRequest {
|
||||
final String? username;
|
||||
final String? avatarUrl;
|
||||
final String? bio;
|
||||
|
||||
const UserUpdateRequest({this.username, this.avatarUrl, this.bio});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
if (username != null) 'username': username,
|
||||
if (avatarUrl != null) 'avatar_url': avatarUrl,
|
||||
if (bio != null) 'bio': bio,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'package:social_app/core/api/api_client.dart';
|
||||
import 'models/user_response.dart';
|
||||
|
||||
class UsersApi {
|
||||
final ApiClient _client;
|
||||
static const _prefix = '/api/v1/users';
|
||||
|
||||
UsersApi(this._client);
|
||||
|
||||
Future<UserResponse> getMe() async {
|
||||
final response = await _client.get('$_prefix/me');
|
||||
return UserResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
Future<UserResponse> updateMe(UserUpdateRequest request) async {
|
||||
final response = await _client.patch('$_prefix/me', data: request.toJson());
|
||||
return UserResponse.fromJson(response.data);
|
||||
}
|
||||
|
||||
Future<UserResponse> getByUsername(String username) async {
|
||||
final response = await _client.get('$_prefix/$username');
|
||||
return UserResponse.fromJson(response.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import 'models/user_response.dart';
|
||||
|
||||
abstract class UsersRepository {
|
||||
Future<UserResponse> getMe();
|
||||
Future<UserResponse> updateMe(UserUpdateRequest request);
|
||||
Future<UserResponse> getByUsername(String username);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import 'users_api.dart';
|
||||
import 'users_repository.dart';
|
||||
import 'models/user_response.dart';
|
||||
|
||||
class UsersRepositoryImpl implements UsersRepository {
|
||||
final UsersApi _api;
|
||||
|
||||
UsersRepositoryImpl({required UsersApi api}) : _api = api;
|
||||
|
||||
@override
|
||||
Future<UserResponse> getMe() {
|
||||
return _api.getMe();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<UserResponse> updateMe(UserUpdateRequest request) {
|
||||
return _api.updateMe(request);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<UserResponse> getByUsername(String username) {
|
||||
return _api.getByUsername(username);
|
||||
}
|
||||
}
|
||||
@@ -34,16 +34,13 @@ void main() {
|
||||
});
|
||||
|
||||
group('AuthRepositoryImpl', () {
|
||||
test('signupStart calls api and returns response', () async {
|
||||
when(() => mockApi.signupStart(any())).thenAnswer(
|
||||
(_) async => const SignupStartResponse(
|
||||
status: 'pending_verification',
|
||||
email: 'test@example.com',
|
||||
message: 'Verification code sent',
|
||||
),
|
||||
test('createVerification calls api and returns response', () async {
|
||||
when(() => mockApi.createVerification(any())).thenAnswer(
|
||||
(_) async =>
|
||||
const VerificationCreateResponse(email: 'test@example.com'),
|
||||
);
|
||||
|
||||
final result = await repository.signupStart(
|
||||
final result = await repository.createVerification(
|
||||
const SignupStartRequest(
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
@@ -51,12 +48,12 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
expect(result.status, 'pending_verification');
|
||||
verify(() => mockApi.signupStart(any())).called(1);
|
||||
expect(result.email, 'test@example.com');
|
||||
verify(() => mockApi.createVerification(any())).called(1);
|
||||
});
|
||||
|
||||
test('login calls api and saves tokens', () async {
|
||||
when(() => mockApi.login(any())).thenAnswer(
|
||||
test('createSession calls api and saves tokens', () async {
|
||||
when(() => mockApi.createSession(any())).thenAnswer(
|
||||
(_) async => AuthResponse(
|
||||
accessToken: 'access_token',
|
||||
refreshToken: 'refresh_token',
|
||||
@@ -72,7 +69,7 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
final result = await repository.login(
|
||||
final result = await repository.createSession(
|
||||
const LoginRequest(email: 'test@example.com', password: 'password123'),
|
||||
);
|
||||
|
||||
@@ -85,21 +82,24 @@ void main() {
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('logout calls api with refresh token and clears storage', () async {
|
||||
when(
|
||||
() => mockStorage.getRefreshToken(),
|
||||
).thenAnswer((_) async => 'refresh_token');
|
||||
when(() => mockApi.logout(any())).thenAnswer((_) async {});
|
||||
when(() => mockStorage.clear()).thenAnswer((_) async {});
|
||||
test(
|
||||
'deleteSession calls api with refresh token and clears storage',
|
||||
() async {
|
||||
when(
|
||||
() => mockStorage.getRefreshToken(),
|
||||
).thenAnswer((_) async => 'refresh_token');
|
||||
when(() => mockApi.deleteSession(any())).thenAnswer((_) async {});
|
||||
when(() => mockStorage.clear()).thenAnswer((_) async {});
|
||||
|
||||
await repository.logout();
|
||||
await repository.deleteSession();
|
||||
|
||||
verify(() => mockApi.logout(any())).called(1);
|
||||
verify(() => mockStorage.clear()).called(1);
|
||||
});
|
||||
verify(() => mockApi.deleteSession(any())).called(1);
|
||||
verify(() => mockStorage.clear()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('refresh saves new tokens', () async {
|
||||
when(() => mockApi.refresh(any())).thenAnswer(
|
||||
test('refreshSession saves new tokens', () async {
|
||||
when(() => mockApi.refreshSession(any())).thenAnswer(
|
||||
(_) async => AuthResponse(
|
||||
accessToken: 'new_access',
|
||||
refreshToken: 'new_refresh',
|
||||
@@ -115,7 +115,7 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
final result = await repository.refresh('old_refresh');
|
||||
final result = await repository.refreshSession('old_refresh');
|
||||
|
||||
expect(result.accessToken, 'new_access');
|
||||
verify(
|
||||
|
||||
@@ -41,7 +41,7 @@ void main() {
|
||||
when(
|
||||
() => mockRepository.getRefreshToken(),
|
||||
).thenAnswer((_) async => 'valid_refresh');
|
||||
when(() => mockRepository.refresh('valid_refresh')).thenAnswer(
|
||||
when(() => mockRepository.refreshSession('valid_refresh')).thenAnswer(
|
||||
(_) async => AuthResponse(
|
||||
accessToken: 'new_access',
|
||||
refreshToken: 'new_refresh',
|
||||
@@ -63,9 +63,9 @@ void main() {
|
||||
() => mockRepository.getRefreshToken(),
|
||||
).thenAnswer((_) async => 'expired_refresh');
|
||||
when(
|
||||
() => mockRepository.refresh('expired_refresh'),
|
||||
() => mockRepository.refreshSession('expired_refresh'),
|
||||
).thenThrow(Exception('Invalid refresh token'));
|
||||
when(() => mockRepository.logout()).thenAnswer((_) async {});
|
||||
when(() => mockRepository.deleteSession()).thenAnswer((_) async {});
|
||||
return authBloc;
|
||||
},
|
||||
act: (bloc) => bloc.add(AuthStarted()),
|
||||
@@ -86,7 +86,7 @@ void main() {
|
||||
blocTest<AuthBloc, AuthState>(
|
||||
'emits [AuthUnauthenticated] when AuthLoggedOut',
|
||||
build: () {
|
||||
when(() => mockRepository.logout()).thenAnswer((_) async {});
|
||||
when(() => mockRepository.deleteSession()).thenAnswer((_) async {});
|
||||
return authBloc;
|
||||
},
|
||||
seed: () => AuthAuthenticated(
|
||||
|
||||
@@ -65,12 +65,8 @@ void main() {
|
||||
password: const Password.dirty('password123'),
|
||||
),
|
||||
setUp: () {
|
||||
when(() => mockRepository.signupStart(any())).thenAnswer(
|
||||
(_) async => SignupStartResponse(
|
||||
status: 'ok',
|
||||
email: 'test@example.com',
|
||||
message: 'Code sent',
|
||||
),
|
||||
when(() => mockRepository.createVerification(any())).thenAnswer(
|
||||
(_) async => VerificationCreateResponse(email: 'test@example.com'),
|
||||
);
|
||||
},
|
||||
act: (c) => c.sendCodeSilently(),
|
||||
@@ -85,7 +81,7 @@ void main() {
|
||||
),
|
||||
],
|
||||
verify: (_) {
|
||||
verify(() => mockRepository.signupStart(any())).called(1);
|
||||
verify(() => mockRepository.createVerification(any())).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -99,7 +95,7 @@ void main() {
|
||||
),
|
||||
setUp: () {
|
||||
when(
|
||||
() => mockRepository.signupStart(any()),
|
||||
() => mockRepository.createVerification(any()),
|
||||
).thenThrow(ServerException('Network error'));
|
||||
},
|
||||
act: (c) => c.sendCodeSilently(),
|
||||
@@ -113,12 +109,12 @@ void main() {
|
||||
),
|
||||
],
|
||||
verify: (_) {
|
||||
verify(() => mockRepository.signupStart(any())).called(1);
|
||||
verify(() => mockRepository.createVerification(any())).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<RegisterCubit, RegisterState>(
|
||||
'does not call signupStart when input is invalid',
|
||||
'does not call createVerification when input is invalid',
|
||||
build: () => cubit,
|
||||
seed: () => RegisterState(
|
||||
username: const Username.dirty(''),
|
||||
@@ -128,7 +124,7 @@ void main() {
|
||||
act: (c) => c.sendCodeSilently(),
|
||||
expect: () => [],
|
||||
verify: (_) {
|
||||
verifyNever(() => mockRepository.signupStart(any()));
|
||||
verifyNever(() => mockRepository.createVerification(any()));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -144,7 +140,7 @@ void main() {
|
||||
act: (c) => c.sendCodeSilently(),
|
||||
expect: () => [],
|
||||
verify: (_) {
|
||||
verifyNever(() => mockRepository.signupStart(any()));
|
||||
verifyNever(() => mockRepository.createVerification(any()));
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -161,7 +157,7 @@ void main() {
|
||||
.having((s) => s.errorMessage, 'errorMessage', '验证码发送失败,请返回上一步重试'),
|
||||
],
|
||||
verify: (_) {
|
||||
verifyNever(() => mockRepository.signupResend(any()));
|
||||
verifyNever(() => mockRepository.resendVerification(any()));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -171,8 +167,8 @@ void main() {
|
||||
seed: () => RegisterState(pendingEmail: 'test@example.com'),
|
||||
setUp: () {
|
||||
when(
|
||||
() => mockRepository.signupResend(any()),
|
||||
).thenAnswer((_) async => SignupResendResponse(message: 'Code sent'));
|
||||
() => mockRepository.resendVerification(any()),
|
||||
).thenAnswer((_) async {});
|
||||
},
|
||||
act: (c) => c.resendCode(),
|
||||
expect: () => [
|
||||
@@ -188,7 +184,7 @@ void main() {
|
||||
),
|
||||
],
|
||||
verify: (_) {
|
||||
verify(() => mockRepository.signupResend(any())).called(1);
|
||||
verify(() => mockRepository.resendVerification(any())).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -198,7 +194,7 @@ void main() {
|
||||
seed: () => RegisterState(pendingEmail: 'test@example.com'),
|
||||
setUp: () {
|
||||
when(
|
||||
() => mockRepository.signupResend(any()),
|
||||
() => mockRepository.resendVerification(any()),
|
||||
).thenThrow(ServerException('Network error'));
|
||||
},
|
||||
act: (c) => c.resendCode(),
|
||||
|
||||
Reference in New Issue
Block a user