Kakao 로그인(카카오 SDK · 서버 커스텀 토큰)과 LINE 로그인(Firebase OIDC) 연결 · SNS 연동 · 인증 취소 처리
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import 'package:cloud_functions/cloud_functions.dart';
|
||||
import 'package:fancake/core/firebase/firebase_boot.dart';
|
||||
import 'package:fancake/features/auth/auth.dart';
|
||||
import 'package:fancake/features/auth/firebase_account_linker.dart';
|
||||
import 'package:fancake/features/auth/social_providers.dart';
|
||||
import 'package:firebase_auth_mocks/firebase_auth_mocks.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
/// 카카오 — SDK 로그인(주입) → 서버 교환(주입) → signInWithCustomToken 계약.
|
||||
/// 토큰 검증·기존 oidc.kakao 사용자 매핑은 서버 테스트(functions/test/auth_kakao.test.ts)가 본다.
|
||||
void main() {
|
||||
setUp(() => FirebaseBoot.debugSetMode(FirebaseMode.live, reason: '카카오 테스트'));
|
||||
tearDown(
|
||||
() => FirebaseBoot.debugSetMode(FirebaseMode.mock, reason: '카카오 테스트 끝'),
|
||||
);
|
||||
|
||||
final sent = <Map<String, dynamic>>[];
|
||||
setUp(sent.clear);
|
||||
|
||||
KakaoSignInProvider kakao(
|
||||
MockFirebaseAuth auth, {
|
||||
Future<String> Function()? token,
|
||||
Object? serverError,
|
||||
String appKey = 'test-key',
|
||||
}) => KakaoSignInProvider(
|
||||
accessToken: token ?? () async => 'kakao-access',
|
||||
exchange: (payload) async {
|
||||
sent.add(payload);
|
||||
if (serverError != null) throw serverError;
|
||||
return {
|
||||
'token': 'custom-token',
|
||||
if (payload['link'] == true) 'linked': true,
|
||||
};
|
||||
},
|
||||
firebaseAuth: auth,
|
||||
nativeAppKey: appKey,
|
||||
);
|
||||
|
||||
test('성공 — 카카오 토큰을 서버에 넘기고 커스텀 토큰으로 로그인한다', () async {
|
||||
final auth = MockFirebaseAuth(mockUser: MockUser(uid: 'kakao:1'));
|
||||
final outcome = await kakao(auth).signIn();
|
||||
expect(sent.single, {'accessToken': 'kakao-access'});
|
||||
expect((outcome as AuthSucceeded).account.uid, 'kakao:1');
|
||||
expect(outcome.account.provider, AuthProviderKind.kakao);
|
||||
expect(auth.currentUser?.uid, 'kakao:1');
|
||||
});
|
||||
|
||||
test('앱 키가 없으면 SDK·서버를 부르지 않고 미설정', () async {
|
||||
final outcome = await kakao(MockFirebaseAuth(), appKey: '').signIn();
|
||||
expect(outcome, isA<AuthNotConfigured>());
|
||||
expect(sent, isEmpty);
|
||||
});
|
||||
|
||||
test('카카오 로그인 취소(CANCELED)는 취소 · 서버를 부르지 않는다', () async {
|
||||
final outcome = await kakao(
|
||||
MockFirebaseAuth(),
|
||||
token: () async => throw PlatformException(code: 'CANCELED'),
|
||||
).signIn();
|
||||
expect(outcome, isA<AuthCancelled>());
|
||||
expect(sent, isEmpty);
|
||||
});
|
||||
|
||||
test('서버 오류는 카탈로그 코드로 · 로그인하지 않는다', () async {
|
||||
final auth = MockFirebaseAuth();
|
||||
final outcome = await kakao(
|
||||
auth,
|
||||
serverError: FirebaseFunctionsException(
|
||||
code: 'permission-denied',
|
||||
message: '카카오 인증을 확인하지 못했습니다.',
|
||||
details: {'code': 'E-AUTH-03'},
|
||||
),
|
||||
).signIn();
|
||||
expect((outcome as AuthFailed).code, 'E-AUTH-03');
|
||||
expect(auth.currentUser, isNull);
|
||||
});
|
||||
|
||||
group('SNS 연동', () {
|
||||
test('로그인한 사용자에 link: true 로 붙인다', () async {
|
||||
final auth = MockFirebaseAuth(
|
||||
signedIn: true,
|
||||
mockUser: MockUser(uid: 'u-1'),
|
||||
);
|
||||
final linker = FirebaseAccountLinker(
|
||||
providers: [kakao(auth)],
|
||||
firebaseAuth: auth,
|
||||
);
|
||||
final outcome = await linker.link(AuthProviderKind.kakao);
|
||||
expect(sent.single, {'accessToken': 'kakao-access', 'link': true});
|
||||
expect((outcome as AuthSucceeded).account.uid, 'u-1');
|
||||
});
|
||||
|
||||
test('다른 이메일이면 E-AUTH-08 · 이메일 안내 문구', () async {
|
||||
final auth = MockFirebaseAuth(
|
||||
signedIn: true,
|
||||
mockUser: MockUser(uid: 'u-1'),
|
||||
);
|
||||
final outcome = await kakao(
|
||||
auth,
|
||||
serverError: FirebaseFunctionsException(
|
||||
code: 'already-exists',
|
||||
message: 'x',
|
||||
details: {'code': 'E-AUTH-08', 'reason': 'different-email'},
|
||||
),
|
||||
).link(auth.currentUser!);
|
||||
expect((outcome as AuthFailed).code, 'E-AUTH-08');
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user