소셜 로그인 진행 중 로딩 표시 · 중복 입력 방지
This commit is contained in:
@@ -209,6 +209,7 @@ class _SimpleLoginScreenState extends State<SimpleLoginScreen> {
|
|||||||
bool _busy = false;
|
bool _busy = false;
|
||||||
|
|
||||||
Future<void> _signIn(SocialProvider provider) async {
|
Future<void> _signIn(SocialProvider provider) async {
|
||||||
|
if (_busy) return;
|
||||||
if (widget.signUp) {
|
if (widget.signUp) {
|
||||||
final agreed = await Navigator.of(context).push<Set<String>>(
|
final agreed = await Navigator.of(context).push<Set<String>>(
|
||||||
MaterialPageRoute(builder: (_) => const TermsScreen()),
|
MaterialPageRoute(builder: (_) => const TermsScreen()),
|
||||||
@@ -217,6 +218,8 @@ class _SimpleLoginScreenState extends State<SimpleLoginScreen> {
|
|||||||
// 인증 뒤 동의가 필요한 계정이면 이 동의를 서버에 기록한다(약관을 다시 묻지 않는다).
|
// 인증 뒤 동의가 필요한 계정이면 이 동의를 서버에 기록한다(약관을 다시 묻지 않는다).
|
||||||
widget.auth.pendingConsent = agreed;
|
widget.auth.pendingConsent = agreed;
|
||||||
}
|
}
|
||||||
|
// 제공자 화면에서 돌아온 뒤에도 서버 토큰 교환 · 로그인에 몇 초 걸린다(Kakao · LINE).
|
||||||
|
// 끝날 때까지 화면 전체를 막고 진행 표시를 띄운다 — 다시 누르지 못하게.
|
||||||
setState(() => _busy = true);
|
setState(() => _busy = true);
|
||||||
final outcome = await widget.auth.signIn(provider);
|
final outcome = await widget.auth.signIn(provider);
|
||||||
if (outcome is! AuthSucceeded) widget.auth.pendingConsent = null;
|
if (outcome is! AuthSucceeded) widget.auth.pendingConsent = null;
|
||||||
@@ -348,7 +351,10 @@ class _SimpleLoginScreenState extends State<SimpleLoginScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return scaffold;
|
return PopScope(
|
||||||
|
canPop: !_busy,
|
||||||
|
child: Stack(children: [scaffold, if (_busy) const BlockingProgress()]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import 'package:fancake/core/firebase/firebase_boot.dart';
|
|||||||
import 'package:fancake/features/auth/auth.dart';
|
import 'package:fancake/features/auth/auth.dart';
|
||||||
import 'package:fancake/features/auth/auth_repository.dart';
|
import 'package:fancake/features/auth/auth_repository.dart';
|
||||||
import 'package:fancake/features/auth/login_screen.dart';
|
import 'package:fancake/features/auth/login_screen.dart';
|
||||||
|
import 'package:fancake/features/auth/signup_screens.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
/// 가입 약관 — 동의 기록이 없는 계정은 HOME 대신 약관으로 가고, 동의를 기록한 뒤에만 HOME 에 들어간다.
|
/// 가입 약관 — 동의 기록이 없는 계정은 HOME 대신 약관으로 가고, 동의를 기록한 뒤에만 HOME 에 들어간다.
|
||||||
|
/// 소셜 로그인 진행 중에는 화면 전체를 막고 진행 표시를 띄운다.
|
||||||
void main() {
|
void main() {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
FirebaseBoot.debugSetMode(FirebaseMode.mock, reason: '가입 약관 위젯 테스트');
|
FirebaseBoot.debugSetMode(FirebaseMode.mock, reason: '가입 약관 위젯 테스트');
|
||||||
@@ -19,7 +21,9 @@ void main() {
|
|||||||
provider: AuthProviderKind.kakao,
|
provider: AuthProviderKind.kakao,
|
||||||
);
|
);
|
||||||
|
|
||||||
testWidgets('동의 없는 새 계정은 약관 → 필수 동의 → HOME', (tester) async {
|
testWidgets('로그인 진행 중 로딩 · 중복 입력 막음 → 동의 없는 새 계정은 약관 → 필수 동의 → HOME', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
final signIn = Completer<AuthOutcome>();
|
final signIn = Completer<AuthOutcome>();
|
||||||
final provider = _Provider(AuthProviderKind.kakao, () => signIn.future);
|
final provider = _Provider(AuthProviderKind.kakao, () => signIn.future);
|
||||||
Set<String>? recorded;
|
Set<String>? recorded;
|
||||||
@@ -34,8 +38,15 @@ void main() {
|
|||||||
await tester.tap(find.widgetWithText(FilledButton, '로그인'));
|
await tester.tap(find.widgetWithText(FilledButton, '로그인'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
await tester.tap(find.text(providerButtonLabel(AuthProviderKind.kakao)));
|
final kakao = find.text(providerButtonLabel(AuthProviderKind.kakao));
|
||||||
|
await tester.tap(kakao);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
expect(find.byType(BlockingProgress), findsOneWidget);
|
||||||
|
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
||||||
|
await tester.tap(kakao, warnIfMissed: false);
|
||||||
|
await tester.pump();
|
||||||
|
expect(provider.calls, 1);
|
||||||
|
|
||||||
signIn.complete(const AuthSucceeded(newUser));
|
signIn.complete(const AuthSucceeded(newUser));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(find.byType(NavigationBar), findsNothing);
|
expect(find.byType(NavigationBar), findsNothing);
|
||||||
@@ -67,6 +78,7 @@ void main() {
|
|||||||
|
|
||||||
expect(recorded, {'service', 'privacy', 'age'});
|
expect(recorded, {'service', 'privacy', 'age'});
|
||||||
expect(find.byType(NavigationBar), findsOneWidget);
|
expect(find.byType(NavigationBar), findsOneWidget);
|
||||||
|
expect(find.byType(BlockingProgress), findsNothing);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('이미 동의한 계정은 약관 없이 HOME', (tester) async {
|
testWidgets('이미 동의한 계정은 약관 없이 HOME', (tester) async {
|
||||||
|
|||||||
Reference in New Issue
Block a user