소셜 웹 로그인 중단·실패를 이메일 오류 대신 소셜 로그인 문구로 안내 · 네트워크 오류 안내 · Android 중단된 웹 로그인 정리 후 재시도
This commit is contained in:
@@ -8,6 +8,7 @@ import 'package:fancake/features/auth/social_providers.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart' as fb;
|
||||
import 'package:firebase_auth_mocks/firebase_auth_mocks.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
@@ -112,6 +113,52 @@ void main() {
|
||||
expect(outcome, isA<AuthCancelled>());
|
||||
});
|
||||
|
||||
group('웹 흐름 중단 뒤 재시도', () {
|
||||
late List<String> cleared;
|
||||
setUp(() {
|
||||
cleared = [];
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(const MethodChannel('kr.co.fanuzu.app/auth'), (call) async {
|
||||
cleared.add(call.method);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
tearDown(() => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(const MethodChannel('kr.co.fanuzu.app/auth'), null));
|
||||
|
||||
test('앞선 흐름이 남아 막히면(web-context-already-presented) 정리하고 한 번 다시 열어 로그인된다', () async {
|
||||
final auth = _StaleThenOkAuth();
|
||||
final outcome = await line(auth).signIn();
|
||||
expect(outcome, isA<AuthSucceeded>());
|
||||
expect(auth.calls, 2);
|
||||
expect(cleared, ['cancelPendingWebSignIn']);
|
||||
});
|
||||
|
||||
test('정리 뒤에도 막히면 소셜 문구로 실패 — 「이메일 또는 비밀번호」가 아니다', () async {
|
||||
final outcome = await line(_ThrowingAuth('web-context-already-presented')).signIn();
|
||||
expect((outcome as AuthFailed).code, 'E-AUTH-03');
|
||||
expect(outcome.message, '로그인이 완료되지 않았습니다. 다시 시도해 주세요.');
|
||||
});
|
||||
|
||||
test('망 오류도 소셜 경로 문구', () async {
|
||||
final outcome = await line(_ThrowingAuth('web-network-request-failed')).signIn();
|
||||
expect((outcome as AuthFailed).code, 'E-AUTH-03');
|
||||
expect(outcome.message, '네트워크 연결을 확인한 뒤 다시 시도해 주세요.');
|
||||
});
|
||||
|
||||
testWidgets('Android: 결과 없이 돌아와 취소로 풀릴 때 Firebase 대기도 정리한다', (tester) async {
|
||||
late AuthOutcome outcome;
|
||||
line(_HangingAuth()).signIn().then((o) => outcome = o);
|
||||
for (final s in [AppLifecycleState.inactive, AppLifecycleState.hidden, AppLifecycleState.paused,
|
||||
AppLifecycleState.hidden, AppLifecycleState.inactive, AppLifecycleState.resumed]) {
|
||||
tester.binding.handleAppLifecycleStateChanged(s);
|
||||
}
|
||||
await tester.pump(const Duration(seconds: 9));
|
||||
expect(outcome, isA<AuthCancelled>());
|
||||
expect(cleared, ['cancelPendingWebSignIn']);
|
||||
});
|
||||
});
|
||||
|
||||
group('계정 연결', () {
|
||||
test('같은 UID 에 oidc.line 을 붙인다', () async {
|
||||
final user = _LinkingUser(linkedEmail: 'fan@fanuzu.co.kr');
|
||||
@@ -219,6 +266,19 @@ class _ThrowingAuth extends MockFirebaseAuth {
|
||||
throw fb.FirebaseAuthException(code: code);
|
||||
}
|
||||
|
||||
/// 앞선 웹 흐름이 남아 첫 시도가 막히는 Firebase(Android `web-context-already-presented`).
|
||||
class _StaleThenOkAuth extends MockFirebaseAuth {
|
||||
_StaleThenOkAuth() : super(mockUser: MockUser(uid: 'line-1'));
|
||||
var calls = 0;
|
||||
|
||||
@override
|
||||
Future<fb.UserCredential> signInWithProvider(fb.AuthProvider provider) {
|
||||
calls += 1;
|
||||
if (calls == 1) throw fb.FirebaseAuthException(code: 'web-context-already-presented');
|
||||
return super.signInWithProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
/// 콜백을 잃어 영영 끝나지 않는 Firebase 대기 Task.
|
||||
class _HangingAuth extends MockFirebaseAuth {
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user