feat(auth): transition from email to phone-based OTP authentication
- Replace Email+Password login with Phone+OTP flow - Remove RegisterCubit and registration screens (email verification) - Remove ResetPasswordCubit and reset password screens - Add phone normalization and international dial code support - Update LoginCubit with sendCode/resend cooldown logic - Add new widgets: phone prefix selector, confirm sheet - Update all auth API endpoints: /otp/send, /phone-session - Update form inputs: Email -> Phone with E.164 validation - Update tests for new auth flow
This commit is contained in:
@@ -6,14 +6,11 @@ import 'package:social_app/features/auth/data/models/signup_request.dart';
|
||||
import 'package:social_app/features/auth/data/models/login_request.dart';
|
||||
import 'package:social_app/features/auth/data/models/auth_response.dart';
|
||||
import 'package:social_app/core/storage/token_storage.dart';
|
||||
import 'package:social_app/core/api/api_client.dart';
|
||||
|
||||
class MockAuthApi extends Mock implements AuthApi {}
|
||||
|
||||
class MockTokenStorage extends Mock implements TokenStorage {}
|
||||
|
||||
class MockApiClient extends Mock implements ApiClient {}
|
||||
|
||||
void main() {
|
||||
late AuthRepositoryImpl repository;
|
||||
late MockAuthApi mockApi;
|
||||
@@ -23,43 +20,29 @@ void main() {
|
||||
mockApi = MockAuthApi();
|
||||
mockStorage = MockTokenStorage();
|
||||
repository = AuthRepositoryImpl(api: mockApi, tokenStorage: mockStorage);
|
||||
registerFallbackValue(
|
||||
const SignupStartRequest(username: '', email: '', password: ''),
|
||||
);
|
||||
registerFallbackValue(const LoginRequest(email: '', password: ''));
|
||||
registerFallbackValue(const SignupVerifyRequest(email: '', token: ''));
|
||||
registerFallbackValue(const SignupResendRequest(email: ''));
|
||||
registerFallbackValue(const OtpSendRequest(phone: ''));
|
||||
registerFallbackValue(const LoginRequest(phone: '', token: ''));
|
||||
registerFallbackValue(const LogoutRequest(refreshToken: ''));
|
||||
registerFallbackValue(const RefreshRequest(refreshToken: ''));
|
||||
});
|
||||
|
||||
group('AuthRepositoryImpl', () {
|
||||
test('createVerification calls api and returns response', () async {
|
||||
when(() => mockApi.createVerification(any())).thenAnswer(
|
||||
(_) async =>
|
||||
const VerificationCreateResponse(email: 'test@example.com'),
|
||||
);
|
||||
test('sendOtp calls api', () async {
|
||||
when(() => mockApi.sendOtp(any())).thenAnswer((_) async {});
|
||||
|
||||
final result = await repository.createVerification(
|
||||
const SignupStartRequest(
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
password: 'password123',
|
||||
),
|
||||
);
|
||||
await repository.sendOtp('+8613812345678');
|
||||
|
||||
expect(result.email, 'test@example.com');
|
||||
verify(() => mockApi.createVerification(any())).called(1);
|
||||
verify(() => mockApi.sendOtp(any())).called(1);
|
||||
});
|
||||
|
||||
test('createSession calls api and saves tokens', () async {
|
||||
when(() => mockApi.createSession(any())).thenAnswer(
|
||||
test('createPhoneSession calls api and saves tokens', () async {
|
||||
when(() => mockApi.createPhoneSession(any())).thenAnswer(
|
||||
(_) async => AuthResponse(
|
||||
accessToken: 'access_token',
|
||||
refreshToken: 'refresh_token',
|
||||
expiresIn: 3600,
|
||||
tokenType: 'bearer',
|
||||
user: const AuthUser(id: '123', email: 'test@example.com'),
|
||||
user: const AuthUser(id: '123', phone: '+8613812345678'),
|
||||
),
|
||||
);
|
||||
when(
|
||||
@@ -69,8 +52,9 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
final result = await repository.createSession(
|
||||
const LoginRequest(email: 'test@example.com', password: 'password123'),
|
||||
final result = await repository.createPhoneSession(
|
||||
phone: '+8613812345678',
|
||||
token: '123456',
|
||||
);
|
||||
|
||||
expect(result.accessToken, 'access_token');
|
||||
@@ -117,7 +101,7 @@ void main() {
|
||||
refreshToken: 'new_refresh',
|
||||
expiresIn: 3600,
|
||||
tokenType: 'bearer',
|
||||
user: const AuthUser(id: '123', email: 'test@example.com'),
|
||||
user: const AuthUser(id: '123', phone: '+8613812345678'),
|
||||
),
|
||||
);
|
||||
when(
|
||||
|
||||
Reference in New Issue
Block a user